这个是用别人的程序修改的,现在遇到几个问题。外部中断接的开机按键需要按几次才能开机。按键左和按键右无法控制切换流水灯模式
单片机源程序如下:
- #include<STC8Hxxx.h>
- #include"intrins.h"
- sbit WS2812 = P3^2;
- sbit Power= P1^0;//ws2812电源开关
- sbit key_left= P2^0;//按键左
- sbit key_right= P2^1;//按键右
- sbit key_ok= P2^2;//按键确认
- sbit key_Return= P2^3;//按键返回
- #define numLEDs 64 //灯的个数
- unsigned char buf_R[numLEDs] = {0};//颜色缓存
- unsigned char buf_G[numLEDs] = {0};
- unsigned char buf_B[numLEDs] = {0};
- unsigned char Timer0_cnt=0;//记录定时器0中断次数
- unsigned char list=1;//播放列表
- void RGB_Set_Up(); //送0码
- void RGB_Set_Down(); //送1码
- void Timer0_Init();//按键扫描定时器0初始化
- void key_service();//按键服务程序
- //void playlist(unsigned char list);
- //真对 STC8系列 IO口初始化 准双向
- void IO_init(void)
- {
- P0M0 = 0X00;
- P0M1 = 0X00;
- P1M0 = 0X01;
- P1M1 = 0X00;
- P2M0 = 0X00;
- P2M1 = 0X00;
- P3M0 = 0X00;
- P3M1 = 0X00;
- P4M0 = 0X00;
- P4M1 = 0X00;
- P5M0 = 0X00;
- P5M1 = 0X00;
- }
- void HAL_Delay(unsigned long t)
- {
- unsigned int x,y;
- for(x=114;x>0;x--)
- for(y=t;y>0;y--);
- }
- //复位延时
- void Delay50us() //@22.1184MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 2;
- j = 15;
- do
- {
- while (--j);
- } while (--i);
- }
- //1码,高电平850ns 低电平400ns 误差正负150ns
- void RGB_Set_Up()
- {
- WS2812 = 1;
- //经过逻辑分析仪调试的的延时
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- WS2812 = 0;
- }
- //1码,高电平400ns 低电平850ns 误差正负150ns
- void RGB_Set_Down()
- {
- WS2812 = 1;
- //经过逻辑分析仪调试的的延时
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- WS2812 = 0;
- }
- //发送24位数据
- void Send_2812_24bits(unsigned char G8,unsigned char R8,unsigned char B8)
- {
- unsigned int n = 0;
- //发送G8位
- for(n=0;n<8;n++)
- {
- G8<<=n;
- if(G8&0x80 == 0x80)
- {
- RGB_Set_Up();
- }
- else
- {
- RGB_Set_Down();
- }
- }
- //发送R8位
- for(n=0;n<8;n++)
- {
- R8<<=n;
- if(R8&0x80 == 0x80)
- {
- RGB_Set_Up();
- }
- else
- {
- RGB_Set_Down();
- }
- }
- //发送B8位
- for(n=0;n<8;n++)
- {
- B8<<=n;
- if(B8&0x80 == 0x80)
- {
- RGB_Set_Up();
- }
- else
- {
- RGB_Set_Down();
- }
- }
-
-
-
- }
- //复位码
- void RGB_Rst()
- {
- WS2812 = 0;
- Delay50us();
- }
- //颜色交换24位不拆分发
- void SetPixelColor(unsigned char num,unsigned long c)
- {
- unsigned char i;
- for(i=0;i<numLEDs;i++)
- {
- buf_R[num] = (unsigned char)(c>>16);
- buf_G[num] = (unsigned char)(c>>8);
- buf_B[num] = (unsigned char)(c);
- }
- for(i=0;i<numLEDs;i++)
- {
- Send_2812_24bits(buf_G[i],buf_R[i],buf_B[i]);
- }
- }
- //复位
- void PixelUpdate()
- {
- RGB_Rst();
- }
- // Fill the dots one after the other with a color
- //用一种颜色填充这些圆点
- void colorWipe(unsigned long c, unsigned int wait)
- {
- unsigned char i=0;
- for( i=0; i<numLEDs; i++)
- {
- SetPixelColor(i, c);
- PixelUpdate();
- HAL_Delay(wait*5);
- }
- }
- void Watercolor(unsigned long c, unsigned int wait)
- {
- unsigned char i=0;
- for( i=0; i<numLEDs; i++)
- {
- SetPixelColor(i, c);
- PixelUpdate();
- HAL_Delay(wait*5);
- SetPixelColor(i, 0);
- PixelUpdate();
- HAL_Delay(wait);
- }
- }
- //颜色
- unsigned long Color(unsigned char r, unsigned char g, unsigned char b)
- {
- return ((unsigned long)r << 16) | ((unsigned long)g << 8) | b;
- }
- //颜色算法
- unsigned long Wheel(unsigned char WheelPos)
- {
- WheelPos = 255 - WheelPos;
- if(WheelPos < 85)
- {
- return Color(255 - WheelPos * 3, 0, WheelPos * 3);
- }
- if(WheelPos < 170) {
- WheelPos -= 85;
- return Color(0, WheelPos * 3, 255 - WheelPos * 3);
- }
- WheelPos -= 170;
- return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
- }
- //彩虹
- void rainbow(unsigned int wait)
- {
- unsigned int i, j;
- for(j=0; j<256; j++)
- {
- for(i=0; i<numLEDs; i++)
- {
- SetPixelColor(i, Wheel((i+j) & 255));
- }
- PixelUpdate();
- HAL_Delay(wait);
- }
- }
- //稍微不同的是,这使得彩虹均匀分布
- void rainbowCycle(unsigned int wait)
- {
- unsigned int i, j;
- for(j=0;j<256*5;j++)
- { // 5 cycles of all colors on wheel 车轮上所有颜色的5个循环
- for(i=0;i<numLEDs;i++)
- {
- SetPixelColor(i, Wheel(((i * 256 / numLEDs) + j) & 255));
- }
- PixelUpdate();
- HAL_Delay (wait);
- }
- }
- //Theatre-style crawling lights with rainbow effect
- //带有彩虹效果的戏剧式爬行灯
- void theaterChaseRainbow(unsigned int wait)
- {
- int j,q;
- unsigned int i;
- for (j=0; j < 256; j++)
- { // cycle all 256 colors in the wheel 在轮子上循环所有256色
- for (q=0; q < 3; q++)
- {
- for (i=0; i < numLEDs; i=i+3)
- {
- SetPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel off 把每一个第三个像素
- }
- PixelUpdate();
- HAL_Delay(wait);
- for (i=0; i < numLEDs; i=i+3)
- {
- SetPixelColor(i+q, 0); //turn every third pixel off 把每一个第三个像素关掉
- }
- }
- }
- }
- void colorWipe_1()//颜色刷1
- {
- colorWipe(0xff0000,1); //红色
- HAL_Delay(10000);
- colorWipe(0xff00,1); //绿色
- HAL_Delay(10000);
- colorWipe(0xff,1);//蓝色
- HAL_Delay(10000);
- colorWipe(0xffff00,1); //黄色
- HAL_Delay(10000);
- colorWipe(0xffff,1); //青色
- HAL_Delay(10000);
- colorWipe(0xff00ff,1); //紫色
- HAL_Delay(10000);
- colorWipe(0xffffff,1); //白色
- HAL_Delay(10000);
- colorWipe(0x00,1); //off
- HAL_Delay(10000);
- }
- void colorWipe_2()//颜色刷2
- {
- Watercolor(0xff0000, 100);//红色
- HAL_Delay(1000);
- Watercolor(0xff00, 100);//绿色
- HAL_Delay(1000);
- Watercolor(0xff, 100);//蓝色
- HAL_Delay(1000);
- Watercolor(0xffff00, 100); //黄色
- HAL_Delay(1000);
- Watercolor(0xffff, 100);//青色
- HAL_Delay(1000);
- Watercolor(0xff00ff, 100); //紫色
- HAL_Delay(1000);
- Watercolor(0xffffff, 100); //白色
- HAL_Delay(1000);
- colorWipe(0x00,1); //off
- HAL_Delay(10000);
- }
- void colorWipe_3()//颜色刷3
- {
- colorWipe(0xff0000,100); //红色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xff00,100); //绿色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xff,100);//蓝色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xffff00,100); //黄色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xffff,100); //青色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xff00ff,100); //紫色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- colorWipe(0xffffff,100); //白色
- HAL_Delay(1000);
- colorWipe(0x00,100); //0ff
- HAL_Delay(1000);
- }
- void main()
- {
- IO_init(); //io口初始化
- IT1 = 1; //设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
- EX1 = 1;//使能INT1中断
- INTCLKO|=0x10;//开启外部中断2
- EA = 1; //开启总中断
- Timer0_Init();//按键扫描定时器0初始化
- while(1)
- {
- key_service();//按键服务程序
- switch(list)
- {
- case 1: colorWipe_1(); break;//颜色刷1
- case 2: colorWipe_2(); break;//颜色刷2
- case 3: colorWipe_3(); break;//颜色刷3
- case 4: rainbow(10); break;//彩虹
- case 5: rainbowCycle(10); break;//彩虹2
- case 6: theaterChaseRainbow(10); break;//彩虹升级
- default:break;
- }
-
-
- }
- }
- //-----------------------------------------
- //按键定时器初始化程序
- void Timer0_Init(void) //20毫秒@22.1184MHz
- {
- AUXR &= 0x7F; //定时器时钟12T模式
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01; //设置定时器模式16位模式
- TL0 = 0x00; //设置定时初始值
- TH0 = 0x70; //设置定时初始值
- TF0 = 0; //清除TF0标志
- //ET0 = 1; //定时器0中断开启
- TR0 = 1; //定时器0开始计时
- }
- void Delay10ms() //@22.1184MHz 按键消抖10ms延时
- {
- unsigned char i, j, k;
- i = 2;
- j = 32;
- k = 60;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- //按键扫描服务程序
- void key_service()//按键服务程序
- {
- if(TF0==1)
- {
- TF0 = 0; //清除TF0标志
- TL0 = 0x9A; //设置定时初始值
- TH0 = 0xA9; //设置定时初始值
- if(key_Return==0)//返回键扫描
- {
- Delay10ms(); //按键消抖延时@22.1184MHz
- if(key_Return==1)
- {
- RGB_Rst();//复位
- colorWipe(0xffffff,100); //白色
- PCON=0x02;//进入掉电模式
- _nop_();
- _nop_();
- }
- while(!key_Return);//等待按键松开
- }
- if(key_ok == 0)//OK键扫描
- {
- Delay10ms(); //按键消抖延时@22.1184MHz
- if(key_ok==0)
- {
- RGB_Rst();//复位
- colorWipe(0xffff00,100); //黄色
- PCON=0x02;//进入掉电模式
- _nop_();
- _nop_();
- }
- while(!key_ok);//等待按键松开
- }
- if( key_left == 0)//按键左键扫描
- {
- Delay10ms(); //按键消抖延时@22.1184MHz
- if(key_left==0)
- {
- RGB_Rst();//复位
- list--;
- }
- while(!key_left);//等待按键松开
- }
- if(key_right == 0)//按键右键扫描
- {
- Delay10ms(); //按键消抖延时@22.1184MHz
- if(key_right==0)
- {
- RGB_Rst();//复位
- list++;
- }
- while(!key_right);//等待按键松开
- }
-
- }
- }
- //中断服务程序
- void exint0() interrupt 2 //INT1中断入口
- {
- colorWipe(0x00,100); //0ff
- Power = 0; //关闭ws2812电源
- P3M0 = 0x00; P3M1 = 0x04;//P3.2高阻输入
- PCON=0x02;//进入掉电模式
- _nop_();
- _nop_();
- }
- //-----------------------------------------
- //中断服务程序
- void exint1() interrupt 10 //INT2中断入口
- {
- EA = 0; //关闭总中断
- PCON=0x00;//取消掉电模式
- P3M0 = 0x00; P3M1 = 0x00;//P3.2准双向输入
- Power = 1; //开启ws2812电源
- EA = 1; //开启总中断
- _nop_();
- _nop_();
- }
复制代码 |