赞
踩
// PWM DMA 完成回调函数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_TIM_PWM_Stop_DMA(&htim1, TIM_CHANNEL_1);
}
uint16_t led_buffer[LED_N*24 + 50]; // 最后50为reset信号,全设置为0
extern TIM_HandleTypeDef htim1;
// 启动DMA载入数据
void WS_Load(void)
{
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)led_buffer, LED_N*24+50);
}
/ 关闭所有LED灯 void WS_Clear(void) { uint16_t i; for(i=0; i<LED_N*24; i++) led_buffer[i] = LED_0; // 写入逻辑0的占空比 for(; i<LED_N*24+50; i++) led_buffer[i] = 0; // 占空比比为0,全为低电平 WS_Load(); } // 全部led灯设置成一样的亮度,其中RGB分别设置亮度 // WS2812的写入顺序是GRB,高位在前面 void WS_Write_RGB(uint8_t n_R, uint8_t n_G, uint8_t n_B) { uint16_t i, j; uint8_t dat[24]; // 将RGB数据进行转换 for(i=0; i<8; i++) { if((n_G&0x80) == 0) dat[i] = LED_0; else dat[i] = LED_1; n_G <<= 1; } for(i=0; i<8; i++) { if((n_R&0x80) == 0) dat[i+8] = LED_0; else dat[i+8] = LED_1; n_R <<= 1; } for(i=0; i<8; i++) { if((n_B&0x80) == 0) dat[i+16] = LED_0; else dat[i+16] = LED_1; n_B <<= 1; } for(i=0; i<LED_N; i++) { for(j=0; j<24; j++) { led_buffer[i*24 + j] = dat[j]; } } for(i=LED_N*24; i<LED_N*24+50; i++) { led_buffer[i] = 0; // 占空比比为0,全为低电平 } WS_Load(); } // 单独打开所有的LED R,亮度为n void WS_Write_R(uint8_t n_R) { WS_Write_RGB(n_R, 0, 0); } void WS_Write_G(uint8_t n_G) { WS_Write_RGB(0, n_G, 0); } void WS_Write_B(uint8_t n_B) { WS_Write_RGB(0, 0, n_B); }
最后,WS2812的工作电压最好超过3.5V,当使用3.3V电压时,亮度和颜色已经不准确(正)了,在5V的时候亮度很正
使用PWM+DMA的可以使STM32不必一直处理这个,只需改变数组内容即可。同时时序控制也非常方便
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。