STM32F103+HAL+PWM+DMA+WS2812
如题:用HAL库,通过stm32f103r8的PWM的DMA模式控制WS2812
硬件使用的是TIM3的CHANNEL1硬件配置如下:
时钟为常规时钟配置
定时器3产生1.25us周期需要的arr为89(计算略)
DMA配置如下:
几个需要注意的地方,
1.DMA
1.1DMA方向 Memory To Peripheral (默认为Peripheral To Memory)
1.2DMA传输位宽 Half Word
2.定义数组
2.1一定要定位为16bit,
3.定义高低位
#define BIT_1 61u //1比较值为61 850us
#define BIT_0 28u //0比较值为28 400us
4. //发送函数
void TM7812_show(void)
{
uint8_t i, j;
for(i = 0; i < PIXEL_MAX; i++)
{
for(j = 0; j < 8; j++)
{
frame.data[24 * i + j] = (rBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;
//将高低位扩展到16bit
frame.data[24 * i + j + 8] = (gBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;
frame.data[24 * i + j + 16] = (bBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;
}
}
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1,
(uint32_t *)&frame, 3 + 24 * PIXEL_MAX + 1); //虽然传的是16bit但是要先转为32bit指针,
//貌似是函数要求为32位无符号指针,但实际传输时,因为之前定义的为half word,所以还是16bit传输;
//不对还请指正
}
5.PWM的DMA完成中断回调函数
因为HAL库自身清楚DMA标志的时候并没有停止PWM所以需要手动停止
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
}