软件STM32cubeIDE下STM32F1xx使用定时器(TIM8)+DMA+PWM点亮灯带WS2812-基础样例
- (1)前言
- (2)环境说明
- (3)先行了解
- 本次调到坑里的两个点问题点
- (1)TIM3_ch2,在STM32F103没有对照DMA请求映射
- (2)时钟频率出现误差。
- (3)软件下载代码失败
- (4)实验过程
- 1)基础配置:配置下载和时钟
- 3)==时钟配置==
- 2)==定时器配置==
- 4)加入后续灯带功能代码
- (5)代码链接
- (6)实验效果
- (7)总结
(1)前言
好长时间不调试灯带ws2812了,最近项目上,要在STM32F1上进行点灯带ws2812,虽然自己之前做了很多了,但是人有个性质,一旦某个事情做完了,你不在去惦记它了,基本会完全抛在脑后。所以才体现记录的重要性,本次在做STM32F1上验证时,即使之前有经验的情况下,还是掉坑里去了,虽然爬的很快,但是觉得有必要记录下来。
(2)环境说明
- 软件环境:STM32cubeIDE 1.8.0
- 硬件芯片:STM32F103VET6(野火:指南者)
- 其它硬件:ws2812灯带,下载器,逻辑分析仪等。
需求:本次需求比较确定,是使用PC7这个引脚输出pwm,带动灯带。
目标:我们的目标也比较明确,当然,可以不一定非要灯带ws2812,有逻辑分析仪,也可以看最后结果,都有就更好了。
(3)先行了解
关于灯带原理,如需要的灯带频率是800Khz这些,其实网上资料是非常多的,本篇主要是具体操作过程,偏重动手实验,具体原理,自己的其它文章和网上文章挺多的,就不在这上花时间。
本次调到坑里的两个点问题点
(1)TIM3_ch2,在STM32F103没有对照DMA请求映射
调试前没有看手册,直接看到PC7上有TIM3_ch2了,以为就是有这个请求映射,如下图,在软件选择时,发现了异样,但是没有在意,因为开始时选择的时TIM3_ch2,这里选择DMA时,发现没有TIM3_ch2,出现TIM3_ch4。
后来一查手册“STM32F10x中文参考手册”,发现DMA1请求映射里没有TIM3_ch2,所以咋调,灯带都不亮。
还有有个定时8,调试后可以使用,所以在PC7引脚上,使用TIM8的TIM8_ch2,做的本实验。
(2)时钟频率出现误差。
使用定时器8进行调试,然后用逻辑分析仪一分析,发现时间周期不对,如下图,不是1.25us左右,而是1.5us
后来想到,F1和F4系统时钟频率是不一样的,如下图。
所以调试的应该注意一下。
调整后,如下图,
再次使用逻辑分析仪就可以。
(3)软件下载代码失败
使用ST-link,或者j-link,会碰见下载失败情况,这种多尝试吧,尝试两个工具交替使用,
要不还其它下载软件尝试。
(4)实验过程
1)基础配置:配置下载和时钟
(1)时钟:基本配置
(2)下载口:基本配置
3)时钟配置
原本这个因为放在前面配置的,但实际上,我们都是后配置时钟的,为了方便理解我先配置时钟,因为TIM8在APB2上,所以是72Mhz。
2)定时器配置
因为定时3的TIM3_ch2无法使用,就选择了TIM8的。因为挂载的总线是APB2 上的,如下图,可以看到在APB2上,我们配置的时钟是72Mhz由此,才有我们后续算式,为啥填写的90,因为72Mhz/800Khz=90,但是IDE这款软件,是让我们后配置时钟界面,无奈,我只能将时钟界面提前,好承上启下。
(1)定时器频率配置
(2)DMA配置,由此保存代码,然后生成。
4)加入后续灯带功能代码
加入灯带功能代码,着需要注意的是,因为时钟84Mhz到72Mhz的改变,相应1和0的实际时间也要改变。
增加的代码段。
#define ONE_PULSE (60) //1 Âë¼ÆÊý¸öÊý
#define ZERO_PULSE (30) //0 Âë¼ÆÊý¸öÊý
#define RESET_PULSE (48) //80 ¸´Î»µçƽ¸öÊý£¨²»ÄܵÍÓÚ40£©
#define LED_NUMS (4) //led ¸öÊý
#define LED_DATA_LEN (24) //led ³¤¶È£¬µ¥¸öÐèÒª24¸ö×Ö½Ú
#define WS2812_DATA_LEN (LED_NUMS*LED_DATA_LEN) //ws2812µÆÌõÐèÒªµÄÊý×鳤¶È
uint16_t static RGB_buffur[RESET_PULSE + WS2812_DATA_LEN] = { 0 };
void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num)
{
//Ö¸ÕëÆ«ÒÆ:ÐèÒªÌø¹ý¸´Î»ÐźŵÄN¸ö0
uint16_t* p = (RGB_buffur + RESET_PULSE) + (num * LED_DATA_LEN);
for (uint16_t i = 0;i < 8;i++)
{
//Ìî³äÊý×é
p[i] = (G << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
p[i + 8] = (R << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
p[i + 16] = (B << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
// __HAL_TIM_SetCompare(htim, TIM_CHANNEL_1,0); //占空比清0,若不清会导致灯珠颜色不�??
// HAL_TIM_PWM_Stop_DMA(htim,TIM_CHANNEL_1);
__HAL_TIM_SetCompare(htim, TIM_CHANNEL_2,0); //占空比清0,若不清会导致灯珠颜色不�??
HAL_TIM_PWM_Stop_DMA(htim,TIM_CHANNEL_2);
}
void ws2812_example(void)
{
//#1.Ìî³äÊý×é
ws2812_set_RGB(0xFF, 0x06, 0x06, 0);
ws2812_set_RGB(0xFF, 0x06, 0x06, 1);
ws2812_set_RGB(0xFF, 0x06, 0x06, 2);
ws2812_set_RGB(0xFF, 0x06, 0x06, 3);
HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,176);
HAL_Delay(5000);
ws2812_set_RGB(0x03, 0xF4, 0x00, 1);
ws2812_set_RGB(0x03, 0xF4, 0x00, 2);
ws2812_set_RGB(0x03, 0xF4, 0x00, 3);
ws2812_set_RGB(0x03, 0xF4, 0x00, 0);
// ws2812_set_RGB(0x22, 0x00, 0x00, 1);
// ws2812_set_RGB(0x00, 0x22, 0x00, 2);
// ws2812_set_RGB(0x00, 0x00, 0x22, 3);
// ws2812_set_RGB(0x22, 0x22, 0x22, 0);
// HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,176);
HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,176);
HAL_Delay(5000);
}
(5)代码链接
样例代码链接:https://download.csdn.net/download/qq_22146161/87741426
(6)实验效果
如下图,本次实验效果截图
(7)总结
再熟悉的东西,也有可能翻车,但好处是,爬坑非常快。