OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7121|回复: 7

关于STM32F407用TIM-DMA方式驱动WS2812的问题

[复制链接]

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-8-1
在线时间
14 小时
发表于 2021-5-18 14:32:07 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 jinnxf 于 2021-5-20 11:21 编辑

利用原子哥的stm32f411飞控中的ws2812代码,修改端口为PA1,TIM5-CH2,DMA1-CH6-STREAM4,无法点亮,没有输出,但是用端口PC6,TIM3-CH1,DMA1-CH5-STREAM4是正常的,附代码如下,看了一下午不知哪里配置的不对,请各位大神帮忙过过目。
  1. #define TIMING_ONE  80        //80 0.8us电平时间
  2. #define TIMING_ZERO 30        //30 0.3us电平时间

  3. //#define TIMING_ONE  143        //80 0.8us电平时间
  4. //#define TIMING_ZERO 67        //30 0.3us电平时间


  5. u16 dmaBuffer0[24];
  6. u16 dmaBuffer1[24];

  7. static bool isInit = false;
  8. static xSemaphoreHandle allLedDone = NULL;

  9. void ws2812Init_SIG2(void)
  10. {
  11.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  12.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  13.         GPIO_InitTypeDef GPIO_InitStructure;
  14.         DMA_InitTypeDef DMA_InitStructure;
  15.         NVIC_InitTypeDef NVIC_InitStructure;
  16.         
  17.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);        //使能PORTA时钟
  18.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);        //使能TIM5时钟
  19.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);        //使能DMA时钟
  20.         
  21.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                                                        //PA1
  22.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                        //复用功能
  23.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                //推挽输出
  24.         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;                        //GPIO_PuPd_NOPULL
  25.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
  26.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  27.         
  28.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM5);        //配置PA1为定时器5复用
  29.         
  30.         TIM_TimeBaseStructure.TIM_Period = (100 - 1); //800KHz  84M / 100
  31.         TIM_TimeBaseStructure.TIM_Prescaler = 0;
  32.         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  33.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  34.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  35.         TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
  36.         
  37.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  38.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  39.         TIM_OCInitStructure.TIM_Pulse = 0;
  40.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  41.         TIM_OC2Init(TIM5, &TIM_OCInitStructure);
  42.                         
  43.         TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);
  44.         TIM_DMACmd(TIM5, TIM_DMA_CC2, ENABLE);
  45.         
  46.         
  47.         DMA_DeInit(DMA1_Stream4);
  48.         DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&TIM5->CCR2;
  49.         DMA_InitStructure.DMA_Memory0BaseAddr = (u32)dmaBuffer0;
  50.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  51.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  52.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  53.         DMA_InitStructure.DMA_BufferSize = 24;
  54.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  55.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  56.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  57.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  58.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  59.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  60.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  61.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
  62.         DMA_InitStructure.DMA_Channel = DMA_Channel_6;
  63.         
  64.         DMA_DoubleBufferModeCmd(DMA1_Stream4, ENABLE);//使能双缓冲
  65.         DMA_DoubleBufferModeConfig(DMA1_Stream4, (u32)dmaBuffer1, DMA_Memory_0);
  66.         DMA_Init(DMA1_Stream4, &DMA_InitStructure);
  67.         DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);

  68.         NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
  69.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 9;
  70.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  71.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  72.         NVIC_Init(&NVIC_InitStructure);
  73.         
  74.         if(!isInit)
  75.         {
  76.                 vSemaphoreCreateBinary(allLedDone);
  77.         }               
  78.         else
  79.         {
  80.                 xSemaphoreGive(allLedDone);
  81.         }
  82.                
  83. //        ws2812PowerControl(true);
  84.         isInit = true;
  85. }


  86. static void fillLed(u16 *buffer, u8 *color)
  87. {
  88.     int i;

  89.     for(i=0; i<8; i++) // GREEN
  90.         {
  91.             buffer[i] = ((color[1]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
  92.         }
  93.         for(i=0; i<8; i++) // RED
  94.         {
  95.             buffer[8+i] = ((color[0]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
  96.         }
  97.         for(i=0; i<8; i++) // BLUE
  98.         {
  99.             buffer[16+i] = ((color[2]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
  100.         }
  101. }

  102. static int current_led = 0;
  103. static int total_led = 0;
  104. static u8(*color_led)[3] = NULL;
  105. //ws2812颜色发送至DMA
  106. void ws2812Send(u8 (*color)[3], u16 len)
  107. {
  108.         if(len<1) return;

  109.         xSemaphoreTake(allLedDone, portMAX_DELAY);//等待上一次发送完成

  110.         current_led = 0;
  111.         total_led = len;
  112.         color_led = color;
  113.         
  114.         fillLed(dmaBuffer0, color_led[current_led]);
  115.         current_led++;
  116.         fillLed(dmaBuffer1, color_led[current_led]);
  117.         current_led++;
  118.         
  119.         DMA_Cmd(DMA1_Stream4, ENABLE);        //使能DMA
  120.         TIM_Cmd(TIM5, ENABLE);                        //使能定时器
  121. }


  122. void ws2812DmaIsr(void)
  123. {
  124.         portBASE_TYPE xHigherPriorityTaskWoken;

  125.         if (total_led == 0)
  126.         {
  127.                 TIM_Cmd(TIM5, DISABLE);
  128.                 DMA_Cmd(DMA1_Stream4, DISABLE);
  129.         }
  130.         
  131.         if (DMA_GetITStatus(DMA1_Stream4, DMA_IT_TCIF4))
  132.         {
  133.                 DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4);
  134.                 if(DMA_GetCurrentMemoryTarget(DMA1_Stream4) == DMA_Memory_0)//DMA当前使用内存0
  135.                 {
  136.                         if (current_led<total_led)
  137.                                 fillLed(dmaBuffer1, color_led[current_led]);
  138.                         else
  139.                                 memset(dmaBuffer1, 0, sizeof(dmaBuffer1));
  140.                 }
  141.                 else//DMA当前使用内存1
  142.                 {
  143.                         if (current_led<total_led)
  144.                                 fillLed(dmaBuffer0, color_led[current_led]);
  145.                         else               
  146.                                 memset(dmaBuffer0, 0, sizeof(dmaBuffer0));
  147.                 }
  148.                 current_led++;
  149.         }

  150.         if (current_led >= total_led + 2) //多传输2个LED产生60us的低电平
  151.         {
  152.                 xSemaphoreGiveFromISR(allLedDone, &xHigherPriorityTaskWoken);
  153.                 TIM_Cmd(TIM5, DISABLE);                                         
  154.                 DMA_Cmd(DMA1_Stream4, DISABLE);
  155.                 total_led = 0;
  156.         }
  157. }


  158. void  DMA1_Stream4_IRQHandler(void)
  159. {

  160.         ws2812DmaIsr();        
  161. //        else if(getModuleID() == NO_MODULE)
  162. //        {
  163. //                if(lastModuleID == LED_RING)
  164. //                {        
  165. //                        ws2812DmaIsr();               
  166. //                        DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, DISABLE);                        
  167. //                        DMA_Cmd(DMA1_Stream4,DISABLE);                                                
  168. //                }               
  169. //                else if(lastModuleID == OPTICAL_FLOW)
  170. //                {
  171. //                        spiTxDmaIsr();
  172. //                        DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, DISABLE);
  173. //                        DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, DISABLE);
  174. //                        DMA_Cmd(DMA1_Stream3,DISABLE);
  175. //                        DMA_Cmd(DMA1_Stream4,DISABLE);                        
  176. //                }                                
  177. //        }
  178. }
复制代码




最佳答案

查看完整内容[请看2#楼]

终于找到问题所在了……学艺不精,TIM2和TIM5是32位的,其他是16位的,现在问题及已经解决
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-8-1
在线时间
14 小时
 楼主| 发表于 2021-5-18 14:32:08 | 显示全部楼层

终于找到问题所在了……学艺不精,TIM2和TIM5是32位的,其他是16位的,现在问题及已经解决
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2021-5-19 02:13:01 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-8-1
在线时间
14 小时
 楼主| 发表于 2021-5-19 08:44:36 | 显示全部楼层
顶起来,看的我眼睛都快瞎了
回复

使用道具 举报

4

主题

896

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4310
金钱
4310
注册时间
2019-9-4
在线时间
897 小时
发表于 2021-5-19 11:30:33 | 显示全部楼层
帮顶  
回复

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-8-1
在线时间
14 小时
 楼主| 发表于 2021-5-19 13:59:25 | 显示全部楼层
TIM_OC1Init和TIM_OC1PreloadConfig笔误,应该是TIM_OC2Init和TIM_OC2PreloadConfig,目前问题依然没有解决
回复

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-8-1
在线时间
14 小时
 楼主| 发表于 2021-5-20 11:15:33 | 显示全部楼层
本帖最后由 jinnxf 于 2021-5-20 11:20 编辑

现在很奇怪的事,TIM1,TIM3,TIM4的各个通道测试了都没有问题,但是TIM2和TIM5,各个复用的引脚都试过,就是不行,很奇怪了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2021-5-21 02:04:58 | 显示全部楼层
jinnxf 发表于 2021-5-20 11:15
现在很奇怪的事,TIM1,TIM3,TIM4的各个通道测试了都没有问题,但是TIM2和TIM5,各个复用的引脚都试过,就 ...

继续努力
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 17:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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