|
使用的芯片为STC15F104W同系列的IRC15F107W,只有该型号的芯片能驱动WS2812的RGB彩灯!
因为该型号的芯片使用内置24Mhz时钟,而WS2812的时序要求精确到ns级别,于是对时钟的最低要求就是24Mhz
而且IRC15F107W同STC15F104W,只有8个引脚的简单封装,并且内部自带震荡源无须外部晶振,插上电直接就能用
最重要的是和其它C51单片机通用头文件,所以引用的时候只需要包含reg52.h文件即可!
所以该单片机非常适合新手入门,即便是小白看了也能学会!
/*
IRC15F107W 管脚(默认内部震荡源24Mhz)
1 P3.4
2 VCC 3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3
*/
然后是代码部分,我用的双色流水灯做的范例- #include "reg52.h"
- #include "intrins.h"
- #define WS2812_NUM 60 //灯的数量
- sbit Led_Pin = P3^0; //控制灯的引脚
- unsigned short G_0=191;//流水灯第一个颜色定义
- unsigned short R_0=98;
- unsigned short B_0=10;
- unsigned short G_1=11;//流水灯第二个颜色定义
- unsigned short B_1=45;
- unsigned short R_1=14;
复制代码 然后就是用STC烧录软件自带的延时计算器一键推出的延迟函数- void delay_ms(unsigned int ms) //@24.000MHz
- {
- unsigned char data i, j;
- while(ms--){
- _nop_();
- i = 24;
- j = 85;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- void Delay75us(void) //@24.000MHz
- {
- unsigned char data i, j;
- i = 2;
- j = 189;
- do
- {
- while (--j);
- } while (--i);
- }
复制代码 然后是WS2812写入0和1的程序- void ws2812_writebit1(void){
- Led_Pin=1;
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- Led_Pin=!Led_Pin;
- //_nop_();_nop_();_nop_();
- }
- void ws2812_writebit0(void){
- Led_Pin=1;
- _nop_();_nop_();_nop_();_nop_();_nop_();
- Led_Pin=!Led_Pin;
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- }
复制代码 然后是写入单个颜色和总体颜色的程序
- void ws2812_writecolor(unsigned short dat){
- //由于STC8G1K08执行左移或者右移等移位操作耗时太久(2us,无符号短整型都这样),导致时序严重落后,所以用原始的if-else代码进行代替
- if(dat&0x80)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x40)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x20)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x10)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x08)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x04)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x02)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x01)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- }
- void ws2812_writeled(unsigned short green,unsigned short red,unsigned short blue){
- ws2812_writecolor(green);
- ws2812_writecolor(red);
- ws2812_writecolor(blue);
- }
复制代码 然后是WS2812执行到最后一颗灯用的结尾程序,以及清屏程序- void ws2812_rest()
- {
- Led_Pin=0;
-
- Delay75us();
- }
- void ws2812_clear()
- {
- static int j=0;
- for(j=0;j<WS2812_NUM;j++)
- {
- ws2812_writeled(0,0,0);
- }
- ws2812_rest();
- ws2812_rest();
- ws2812_rest();
- }
复制代码 流水灯主程序- void WS2812_DIS()
- {
- static int j=0;
- int i;
- j%=WS2812_NUM;
- j++;
- for(i=0;i<WS2812_NUM;i++)
- {
- if(i>j&&(i<j+10))
- {
- ws2812_writeled(G_0,R_0,B_0);
- }
- else
- {
- ws2812_writeled(G_1,R_1,B_1);
-
- }
- }
-
- }
- void main(void)
- {
- ws2812_clear();
- while(1)
- {
- WS2812_DIS();
- delay_ms(50);
- }
- }
复制代码
希望大家能学到东西!完整代码在压缩包里!
|
评分
-
查看全部评分
|