這個是用別人的程序修改的,現在遇到幾個問題。外部中斷接的開機按鍵需要按幾次才能開機。按鍵左和按鍵右無法控制切換流水燈模式
單片機源程序如下:
- #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_();
- }
復制代碼 |