欢迎来到泰骏兴电子,大家有问题可以直接联系管理员QQ:233619809单片机 QQ群:59194556 各位游客也可以注册玩玩,享受更多权益。温馨提示:本网站仅提供平台学习以及渠道,一切后果自行承担,还望广大用户提高自我意识,请不要轻易相信他人,请不要轻易相信他人,请不要轻易相信他人。为了更好的管理论坛工作,所以现在使用邮箱注册,如果以前的邮箱不能修改的,请联系管理员代为修改

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 175|回复: 0

STM32F1使用PWM+DMA驱动WS2812

[复制链接]
发表于 2025-5-22 08:54:53 | 显示全部楼层 |阅读模式
使用定时器3的PWM驱动
使用WS2812_send函数可以直接驱动LED




  1. .h文件


  2. #define TIMING_ONE  50                        //搞电平时间
  3. #define TIMING_ZERO 25                        //低电平时间
  4. #define W2812_SIZE        29                        //LED个数

  5. extern uint16_t LED_BUF[10+24*W2812_SIZE];//LED数据缓存




  6. void TIME_3_init(void);
  7. void WS2812_send(uint8_t (*color)[3], uint16_t len);
  8. void WS2812_Set_color_bit(u8 r,u8 g,u8 b,u8 lan);//设置单个LED颜色


  9. void WS2812_update(void);//更新显示
  10. void WS2812_OFF(void);
  11. void WS2812_ALL(u8 r,u8 g,u8 b);
复制代码

  1. .c文件

  2. uint16_t LED_BUF[10+24*W2812_SIZE];//LED数据缓存


  3. #define DMA_CH_Channe        DMA1_Channel3
  4. #define DMA_CH_Flag                   DMA1_FLAG_TC3
  5. #define TIME_CH                           TIM3
  6. #define TIME_CCR                CCR3


  7. void TIME_3_init(void)
  8. {
  9.                         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  10.                         TIM_OCInitTypeDef TIM_OCInitStructure;
  11.                         GPIO_InitTypeDef GPIO_InitStructure;
  12.                         DMA_InitTypeDef DMA_InitStructure;

  13.                         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  14.                         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  15.                         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  16.                         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.                         GPIO_Init(GPIOB, &GPIO_InitStructure);

  18.                         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  19.                         TIM_TimeBaseStructure.TIM_Period = 90-1;
  20.                         TIM_TimeBaseStructure.TIM_Prescaler = 0;
  21.                         TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  22.                         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  23.                         TIM_TimeBaseInit(TIME_CH, &TIM_TimeBaseStructure);

  24.                         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  25.                         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  26.                         TIM_OCInitStructure.TIM_Pulse = 45;
  27.                         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  28.                         TIM_OC3Init(TIME_CH, &TIM_OCInitStructure);

  29.                         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);



  30.                         DMA_DeInit(DMA_CH_Channe);

  31.                         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIME_CH->TIME_CCR);
  32.                         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)LED_BUF;
  33.                         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  34.                         DMA_InitStructure.DMA_BufferSize = 42;
  35.                         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  36.                         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  37.                         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  38.                         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  39.                         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  40.                         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  41.                         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  42.                         DMA_Init(DMA_CH_Channe, &DMA_InitStructure);

  43.                         TIM_DMACmd(TIME_CH, TIM_DMA_Update, ENABLE);
  44. }

  45. void WS2812_send(uint8_t (*color)[3], uint16_t len)
  46. {
  47.                         uint8_t i;
  48.                         uint16_t memaddr;
  49.                         uint16_t buffersize;
  50.                         buffersize = (len*24)+43;
  51.                         memaddr = 0;

  52.                         while (len)
  53.         {   
  54.                         for(i=0; i<8; i++)
  55.                 {
  56.                         LED_BUF[memaddr] = ((color[0][1]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  57.                         memaddr++;
  58.                 }
  59.                         for(i=0; i<8; i++)
  60.                 {
  61.                         LED_BUF[memaddr] = ((color[0][0]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  62.                         memaddr++;
  63.                 }
  64.                         for(i=0; i<8; i++)
  65.                 {
  66.                         LED_BUF[memaddr] = ((color[0][2]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  67.                         memaddr++;
  68.                 }
  69.                         len--;
  70.         }



  71.                         LED_BUF[memaddr] = ((color[0][2]<<8) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  72.                         memaddr++;  

  73.                         LED_BUF[memaddr] = ((color[0][2]<<8) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  74.                         memaddr++;

  75.                         while(memaddr < buffersize)
  76.         {
  77.                         LED_BUF[memaddr] = 0;
  78.                         memaddr++;
  79.         }




  80.                         DMA_SetCurrDataCounter(DMA_CH_Channe, buffersize);
  81.                         DMA_Cmd(DMA_CH_Channe, ENABLE);
  82.                         TIM_Cmd(TIME_CH, ENABLE);
  83.                         while(!DMA_GetFlagStatus(DMA_CH_Flag)) ;  
  84.                         TIM_Cmd(TIME_CH, DISABLE);  
  85.                         DMA_Cmd(DMA_CH_Channe, DISABLE);
  86.                         DMA_ClearFlag(DMA_CH_Flag);
  87. }
  88. void WS2812_Set_color_bit(u8 r,u8 g,u8 b,u8 lan)//设置单个LED颜色
  89. {
  90.                         uint8_t i;
  91.                         
  92.                         for(i=0; i<8; i++)
  93.                 {
  94.                         LED_BUF[lan*24+i] = ((g<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  95.                         LED_BUF[lan*24+i+8] = ((r<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  96.                         LED_BUF[lan*24+i+16] = ((b<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
  97.                 }
  98.                         LED_BUF[W2812_SIZE*24+1]=0;
  99.                         LED_BUF[W2812_SIZE*24+2]=0;
  100. }

  101. void WS2812_update()//更新显示
  102. {
  103.                         DMA_SetCurrDataCounter(DMA_CH_Channe, W2812_SIZE*24);
  104.                         DMA_Cmd(DMA_CH_Channe, ENABLE);
  105.                         TIM_Cmd(TIME_CH, ENABLE);
  106.                         while(!DMA_GetFlagStatus(DMA_CH_Flag)) ;  
  107.                         TIM_Cmd(TIME_CH, DISABLE);  
  108.                         DMA_Cmd(DMA_CH_Channe, DISABLE);
  109.                         DMA_ClearFlag(DMA_CH_Flag);
  110. }




  111. void WS2812_OFF()
  112. {
  113.                         u16 q;
  114.                         for(q=0;q<W2812_SIZE;q++)
  115.         {
  116.                         WS2812_Set_color_bit(0,0,0,q);
  117.         }
  118.                         WS2812_update();
  119. }
  120. void WS2812_ALL(u8 r,u8 g,u8 b)
  121. {
  122.                         u16 q;
  123.                         for(q=0;q<W2812_SIZE;q++)
  124.         {
  125.                         WS2812_Set_color_bit(r,g,b,q);
  126.         }
  127.                         WS2812_update();
  128. }



复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|泰骏兴电子科技有限公司 ( 粤ICP备2023060260号-1 ) 单片机爱好者

GMT+8, 2025-10-31 11:31

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表