#include "main.h" /******************************************************************************************* WS2812S的标准时序如下: TH+TL=1.25us±150ns, RES>50us T0H=0.25us±150ns = 0.10us - 0.40us T1H=1.00us±150ns = 0.85us - 1.15us T0L=1.00us±150ns = 0.85us - 1.15us T1L=0.25us±150ns = 0.10us - 0.40us 占空比取1:3,Bit = 0.290us - 0.350us , T=1.160us - 1.40us 用UART的TXD驱动WS2812,采用3M即0.333US的波特率。 那么起始位+D0D1D2位组合成0111做为WS2812的0码,D3D4D5D6位0001做为WS2812的1码; 或者起始位+D0D1D2位组合成0001做为WS2812的1码,D3D4D5D6位0111做为WS2812的0码; 而且剩下的D7+结束位+2位字间空隙组合成固定的1111为新的空闲位。 那么只要外置74HC04做反相功能,即可符合标准的WS2812的接收的时序要求。 即是T0H=0.333US,T0L=0.999US,T1H=0.999US,T1L=0.333US; 即是TH+TL=1.332us 小于周期1.4US,而且 IDLE=1.332uS 小于RES的50us时间,以上状态会保持下去。 结论:用连续12个字节的UART信号即可传送一个WS2812显示像素24位数据。 *********************************************************************************************/ lamp_t lamp; void WS2812Init(uint8_t chn) { UART_InitStructure UART_initStruct; // PORT_Init(PORTP, PIN2, FUNMUX0_UART2_RXD, 1); //GPIOP.2 配置为UART2输入引脚 PORT_Init(PORTP, PIN1, FUNMUX1_UART2_TXD, 0); //GPIOP.1 配置为UART2输出引脚 UART_initStruct.Baudrate = 3000000; //=clk/16/x BIT = 0.333us ,实际测量是260NS UART_initStruct.DataBits = UART_DATA_8BIT; //数据位位数,可取值UART_DATA_8BIT、UART_DATA_9BIT UART_initStruct.Parity = UART_PARITY_NONE; //奇偶校验位,可取值UART_PARITY_NONE、UART_PARITY_ODD、UART_PARITY_EVEN、UART_PARITY_ONE、UART_PARITY_ZERO UART_initStruct.StopBits = UART_STOP_1BIT; //停止位位数,可取值UART_STOP_1BIT、UART_STOP_2BIT UART_initStruct.TXThreshold = 0; //取值0--7 UART_initStruct.TXThresholdIEn = 0; //当TX FIFO中数据个数 <= TXThreshold时触发中断 UART_initStruct.RXThreshold = 0; //取值0--7 UART_initStruct.RXThresholdIEn = 0; //当RX FIFO中数据个数 >= RXThreshold时触发中断 UART_initStruct.TimeoutTime = 0; //超时时长 = TimeoutTime/(Baudrate/10) 秒 UART_initStruct.TimeoutIEn = 0; //超时中断,超过 TimeoutTime/(Baudrate/10) 秒没有在RX线上接收到数据时触发中断 UART_Init(UART2, &UART_initStruct); UART_Open(UART2); } //void Uart2Write(uint8_t data){UART_WriteByte(UART2, data);while(UART_IsTXBusy(UART2)){;}} void Uart2Write(uint8_t data) { while(UART_IsTXFIFOFull(UART2)) {;} UART_WriteByte(UART2, data); } void Ws2812WriteByte(uint8_t byte) { for(uint8_t i = 0; i < 4; i++) { uint8_t data = ((byte & 0x80) ? 0x04 : 0x07) | ((byte & 0x40) ? 0x40 : 0x70) | 0x80; // D0-D2:D3-D6:D7 Uart2Write(data); byte <<= 2; } } void Ws2812Lamp(uint8_t *buf, uint32_t len) { DelayMs(1);//延时1ms以复位 __disable_irq(); while(len--) { Ws2812WriteByte(*buf++); } __enable_irq(); } void LampInit(void) { uint8_t buf[24]; WS2812Init(0xff); for(int i = 0; i < 3; i++) { memset(buf, lampaon, sizeof(buf)); Ws2812Lamp(buf, sizeof(buf)); //while(1); DelayMs(200); memset(buf, lampoff, sizeof(buf)); Ws2812Lamp(buf, sizeof(buf)); DelayMs(200); } // while(1) for(int i = 0; i < 24; i++) { memset(buf, lampoff, sizeof(buf)); buf[i] = lampaon; Ws2812Lamp(buf, sizeof(buf)); DelayMs(200); } memset(&lamp.oiltemp.red, lampoff, sizeof(lamp_t)); // lamp.oiltemp.red=lampon; //油温红灯 OK lamp.oiltemp.green = lampgon; //油温绿灯 OK // lamp.oillevel.red=lampon; //油位红灯 OK lamp.oillevel.green = lampgon; //油位绿灯 OK // lamp.waterlevel.red=lampon; //水位红灯 OK lamp.waterlevel.green = lampgon; //水位绿灯 OK lamp.emerg.green = lampgon; //应急红灯 lamp.emerg.red = lampron; //电源绿灯 lamp.power.red = lampron; //应急红灯 // lamp.power.green=lampgon; //通信绿灯 // lamp.communicate.red=lampron; //通信红灯 OK // lamp.communicate.green=lampgon; //电源红灯 Ws2812Lamp(&lamp.oiltemp.red, sizeof(lamp_t)); // while(1){;} }