欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: DIY全彩燈隨機顏色漸變程序 1677萬色輸出 蜂鳴器放歌 2合1 可同時工作 [打印本頁]

作者: npn    時間: 2016-7-7 11:44
標題: DIY全彩燈隨機顏色漸變程序 1677萬色輸出 蜂鳴器放歌 2合1 可同時工作
蜂鳴器放歌程序用到兩個定時器,分別用于精準控制頻率和時間。
賀卡音樂芯片唯一的制作方法,可加入其他功能,音樂數據可隨意修改。
可直接移植到其他芯片中,在中斷外的程序會嚴重影響到軟件延時。
單片機型號:STC15F104E或STC15L104E或其他8腳STC芯片。
晶振頻率:24Mhz
硬件連接:
紅色到P3.3
公共極直接到P3.2
綠色到P3.1
藍色到P3.0
蜂鳴器連接P3.5(不同型號芯片可能會有不同,根據寄存器決定)
版本更新歷史:
1.修正為逐漸導通掃描LED,防止3v芯片不接電阻,多個LED同時導通而導致顏色顯示不正常。
2.添加了顏色漸變功能。
3.P3.0~P3.3口可直接連接4腳全彩LED,可設置共陰共陽。
        注意:
                片內必須包含控制IO口輸出頻率的特殊功能寄存器,否則將無法輸出頻率。
                晶振頻率過高會導致低頻信號不能鳴叫,同時耗電量增加,看門狗更容易跑飛,
                過低則會導致時間頻率誤差加大。

源碼:

#include <reg51.h>
#include<intrins.h>
#include <stdlib.h>
#include <stdio.h>
//#include <eeprom.h>

#define FOSC 24000000L //晶振頻率
#define public 1 //共陽為1,共陰為0
unsigned int T1MS=65536-FOSC/1000; //計算定時器計時1毫秒需要的時間
sbit io=P3^2; //公共極
sbit io_blue=P3^0; //藍色LED通道
sbit io_green=P3^1;//綠色LED通道
sbit io_red=P3^3;//紅色LED通道
sbit led=P3^4;
//***********************
sfr P3M0 = 0xB1; // 定義P3M1寄存器
sfr P3M1 = 0xB2; // 定義P3M0寄存器
sfr eeprom_data  =  0xC2; //EEPROM數據地址寄存器
sfr eeprom_addrh =  0xC3; //EEPROM高8位地址寄存器
sfr eeprom_addrl =  0xC4; //EEPROM低8位地址寄存器
sfr eeprom_cmd   =  0xC5; //EEPROM模式操作寄存器
sfr eeprom_trig  =  0xC6; //EEPROM命令有效寄存器
sfr eeprom_contr =  0xC7; //EEPROM命令有效寄存器

sfr CLK_DIV     = 0x97;
sfr AUXR      = 0x8e;               //輔助特殊功能寄存器
sfr INT_CLKO  = 0x8f;               //喚醒和時鐘輸出功能寄存器
sbit T1CLKO   = P3^5;               //蜂鳴器連接VCC和P3.5

bit bit_blue=1;
bit bit_green=1;
bit bit_red=1;

unsigned int p=0; //延遲毫秒替減,為0則切換頻率
unsigned char m=0;//當前音樂數據指向的指針
unsigned int code md[212]={ //音樂數據,包含頻率和持續時間的數據。
0,580,600,300,600,100,900,200,1200,350,900,170,1200,200,1500,170,1600,260,1500,260,1180,180,1350,350,0,360,600,250,600,100,900,170,1200,360,900,170,1200,180,1500,170,1600,260,1500,260,1200,170,1330,200,0,150,1500,240,1330,100,1200,350,1200,270,1330,80,1500,170,2000,180,2000,175,1800,170,1600,170,1500,180,1330,170,1600,180,1500,180,1200,170,900,350,1000,350,1000,250,1100,100,1200,180,1500,350,1200,180,1340,170,1500,180,1600,170,1670,170,1800,190,1340,150,900,150,750,200,600,300,600,100,900,200,1200,350,900,170,1200,200,1500,170,1600,260,1500,260,1180,180,1350,350,0,360,600,250,600,100,900,170,1200,360,900,170,1200,180,1500,170,1600,260,1500,260,1200,170,1330,200,0,150,1500,260,1330,90,1200,350,1200,260,1330,90,1500,170,2000,350,1800,170,1600,170,1500,180,1330,170,1600,170,1500,180,1200,170,900,350,1000,350,1000,260,1100,90,1200,170,1500,340,1200,180,1330,170,1200,170,1120,180,1330,170,1200,350,0,250
};
void InitTimer0(void){ //初始化1ms中斷定時器
    TMOD = 0x01;
    TL0 = T1MS;                     //設置計數器低8位
    TH0 = T1MS >> 8;                    //設置計數器高8位
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}


void set_hz(unsigned int hz){ //設置蜂鳴器頻率
    if(0 < (int)(65536-FOSC/2/hz)) { //頻率計算溢出
        hz=65535; //設置頻率為65535Hz
        }

    TMOD = 0x00;                    //設置定時器為模式1(16位自動重裝載)
    TMOD &= ~0x40;                  //C/T1=0, 對內部時鐘進行時鐘輸出
    TL1 = (65536-FOSC/2/hz);                 //初始化計時值
    TH1 = (65536-FOSC/2/hz) >> 8;
    INT_CLKO = 0x02;
    TR1 = 1;  //開始計數



}



void eeprom_init(){ //EEPROM初始化程序
        eeprom_contr        = 0x83;                //把第7位置1允許EEPROM可以讀寫
        eeprom_cmd         = 0x00;                //待機模式無ISP操作
        eeprom_addrh        = 0x00;
        eeprom_addrl        = 0x00;

}

unsigned char eeprom_read_dat(unsigned char addr_h,unsigned char addr_l){ //讀取EEPROM數據
        unsigned char e_dat = 0x00;
        eeprom_cmd         = 0x01;                //模式選擇為讀EEPROM
        eeprom_addrh        = addr_h;
        eeprom_addrl        = addr_l;
        eeprom_trig        = 0x5A;                //使命令有效
        eeprom_trig        = 0xA5;                //使命令有效
        e_dat                = eeprom_data;
        return e_dat;
}

void eeprom_write_dat(unsigned char addr_h,unsigned char addr_l,unsigned char w_dat){ //寫入EEPROM數據
        eeprom_cmd         = 0x02;                //模式選擇為寫EEPROM
        eeprom_addrh        = addr_h;
        eeprom_addrl        = addr_l;
        eeprom_data        = w_dat;
        eeprom_trig        = 0x5A;                //使命令有效
        eeprom_trig        = 0xA5;                //使命令有效

}

void eeprom_erase_dat(unsigned char addr_h,unsigned char addr_l){ //擦除EEPROM數據
        eeprom_cmd         = 0x03;                //模式選擇為擦除EEPROM
        eeprom_addrh        = addr_h;
        eeprom_addrl        = addr_l;
        eeprom_trig        = 0x5A;                //使命令有效
        eeprom_trig        = 0xA5;                //使命令有效
}



        unsigned char delay_led=0; //LED延時
        unsigned char srand_add=0; //隨機數種子(累加)
        unsigned char red_size=0; //當前紅色LED亮度
        unsigned char green_size=0;//當前綠色LED亮度
        unsigned char blue_size=0;//當前藍色LED亮度
        unsigned char new_red_size=0; //到達的紅色LED亮度
        unsigned char new_green_size=0;//到達的綠色LED亮度
        unsigned char new_blue_size=0;//到達的藍色LED亮度
        unsigned int delay_rand=0; //隨機延時
        void set_led_color(unsigned char red,unsigned char green,unsigned char blue){//設置LED顏色(3路不同占空比方波)
        unsigned char input_red,input_green,input_blue;
        unsigned char rgb_switch=1; //RGB切換開關,1是紅色,2是綠色,3是藍色。
        unsigned char while_delay=0xFF; //該變量循環替減,變量等于0后退出循環。
        unsigned char red_delay=input_red; //紅色LED占空比
        unsigned char green_delay=input_green; //綠色LED占空比
        unsigned char blue_delay=input_blue; //藍色LED占空比
        unsigned char not_red_delay=0xFF-input_red; //紅色LED占空比【位取反】
        unsigned char not_green_delay=0xFF-input_green; //綠色LED占空比【位取反】
        unsigned char not_blue_delay=0xFF-input_blue; //藍色LED占空比【位取反】
        bit red_on=1;bit green_on=1;bit blue_on=1; //LED亮滅狀態,1滅0亮。
        bit not_red=1;bit not_green=1; bit not_blue=1; //是否處理某顏色通道 1處理0不處理

                if(public == 1){ //共陽極

                        input_red=0xFF-red; //紅色位取反
                        input_green=0xFF-green; //綠色位取反
                        input_blue=0xFF-blue; //藍色位取反
                } else { //共陰級

                        input_red=red; //紅色位賦值
                        input_green=green; //綠色位賦值
                        input_blue=blue; //藍色位賦值

        }
               


                if(red==0x00){ //紅色亮度等于0
                not_red=0; //不處理紅色通道
                bit_red=public; //紅色亮滅等于公共極
                }

                if(red==0xFF){ //紅色亮度等于255
                not_red=0; //不處理紅色通道
                bit_red=!public; //紅色亮滅等于取反公共極
                }
                                if(green==0x00){ //綠色亮度等于0
                                not_green=0; //不處理綠色通道
                                bit_green=public; //綠色亮滅等于公共極
                                }

                                if(green==0xFF){ //綠色亮度等于255
                                not_green=0; //不處理綠色通道
                                bit_green=!public; //綠色亮滅等于取反公共極
                                }

                                        if(blue==0x00){ //藍色亮度等于0
                                        not_blue=0; //不處理藍色通道
                                        bit_blue=public; //藍色亮滅等于公共極
                                        }

                                        if(blue==0xFF){ //藍色亮度等于255
                                        not_blue=0; //不處理藍色通道
                                        bit_blue=!public; //藍色亮滅等于取反公共極
                                        }



                while( while_delay != 0x00 && not_red_delay + red_delay + not_green_delay + green_delay + not_blue_delay + blue_delay  != 0x00){ //所有替減變量大于或等于0
                while_delay--; //循環變量替減
                if(bit_red==!public){ //紅色LED緩存區與公共極相反
                        io_red=!public; //紅色LED的I/O接口等于取反公共極,可以構成回路,點亮LED。
                        io_green=public;//綠色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        io_blue=public; //藍色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        //delay10us();    //延時10微秒
                }

                if(bit_green==!public){ //綠色LED緩存區與公共極相反
                        io_red=public;    //紅色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        io_green=!public; //綠色LED的I/O接口等于取反公共極,可以構成回路,點亮LED。
                        io_blue=public;   //藍色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        //delay10us();      //延時10微秒
                }

                if(bit_blue==!public){ //藍色LED緩存區與公共極相反
                        io_red=public;   //紅色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        io_green=public; //綠色LED的I/O接口等于公共極,無法構成回路,熄滅LED。
                        io_blue=!public; //藍色LED的I/O接口等于取反公共極,可以構成回路,點亮LED。
                        //delay10us();     //延時10微秒
                }




                        if(rgb_switch == 1 && not_red == 1) { //處理紅色通道
                                 
                                if(red_on == 0){
                                bit_red=0; //將LED亮滅狀態放入緩存區。
                                
                                not_red_delay--; //紅色LED反占空比減1
                                if(not_red_delay == 0) red_on=1; //紅色LED亮滅狀態放入緩存區
                                }

                                if(red_on == 1){
                                bit_red=1; //將LED亮滅狀態放入緩存區。
                                
                                red_delay--; //紅色LED占空比減1
                                if(red_delay == 0) red_on=0; //紅色LED亮滅狀態放入緩存區
                                }

                        rgb_switch++; //切換到綠色通道
                        } else {
                        rgb_switch++; //切換到綠色通道
                        not_red_delay--;
                        red_delay--;

                        }

                        if(rgb_switch == 2 && not_green == 1){ //處理綠色通道
                                 
                                if(green_on == 0){
                                bit_green=0; //將LED亮滅狀態放入緩存區。
                                
                                
                                not_green_delay--; //綠色LED反占空比減1
                                if(not_green_delay == 0) green_on=1; //綠色LED亮滅狀態放入緩存區
                                }

                                if(green_on == 1){
                                bit_green=1; //將LED亮滅狀態放入緩存區。
                                
                                
                                green_delay--; //綠色LED占空比減1
                                if(green_delay == 0) green_on=0; //綠色LED亮滅狀態放入緩存區
                                }
                        rgb_switch++; //切換到藍色通道
                        }  else {
                        rgb_switch++; //切換到藍色通道
                        not_green_delay--;
                        green_delay--;

                        }

                        if(rgb_switch == 3 && not_blue == 1){ //處理藍色通道
                                 
                                if(blue_on == 0){
                                bit_blue=0; //將LED亮滅狀態放入緩存區。
                                
                                
                                not_blue_delay--; //藍色LED反占空比減1
                                if(not_blue_delay == 0) blue_on=1; //藍色LED亮滅狀態放入緩存區
                                }

                                if(blue_on == 1){
                                bit_blue=1;  //將LED亮滅狀態放入緩存區。
                                
                                
                                blue_delay--; //藍色LED占空比減1
                                if(blue_delay == 0) blue_on=0; //藍色LED亮滅狀態放入緩存區
                                }
                        rgb_switch=1; //切換紅色通道
                        

                } else {
                rgb_switch=1; //切換紅色通道
                        not_blue_delay--;
                        blue_delay--;

                }

                }
}
void main(){ //主函數
        AUXR |= 0xC0;
        InitTimer0();
        eeprom_init(); //EEPROM初始化
        srand_add=eeprom_read_dat(0x00,0x01);//從EEPROM中讀取隨機隨種子
        eeprom_erase_dat(0x00,0x01);//從EEPROM中擦除數據
        srand_add++; //隨機數種子累加1個
        eeprom_write_dat(0x00,0x01,srand_add); //將新種子寫入EEPROM中
        srand(srand_add); //初始化隨機數種子,用于每次芯片上電都會產生不重復的顏色。
        delay_led=0;  //LED延時計數器清零
                red_size=0x00; //當前紅色值為0
                green_size=0x00; //當前綠色值為0
                blue_size=0x00; //當前藍色值為0



        if(public==1){ //如果LED為共陽則 (注:修改IO口位置需要修改這里。)

                P3M1 = 0x04;       //定義P3.2口為強上拉輸出,提供更多電流以驅動LED彩燈。

                        } else { //共陰則

                P3M1 = 0x0B;     //定義P3.0,P3,1,P3,3口為強上拉輸出,提供更多電流以驅動LED彩燈。

                }






                        io=public; //公共極賦值,否則LED就亮不了。



        while(1) { //無限循環

                        new_red_size=rand();//紅色亮度取隨機數
                        new_green_size=rand();//藍色亮度取隨機數
                        new_blue_size=rand();//綠色亮度取隨機數


                        while(new_red_size != red_size && new_green_size != green_size && new_blue_size != blue_size){ //當前顏色不等于隨機到達的顏色則循環
                                if(red_size<new_red_size) { //當前紅色亮度小于到達的紅色亮度
                                        red_size++; //紅色亮度相加
                                                } else { //否則
                                        red_size--; //紅色亮度相減
                                }

                                if(green_size<new_green_size) { //當前綠色亮度小于到達的綠色亮度
                                        green_size++; //綠色亮度相加
                                                } else { //否則
                                        green_size--; //綠色亮度相減
                                }

                                if(blue_size<new_blue_size) { //當前藍色亮度小于到達的藍色色亮度
                                        blue_size++; //藍色亮度相加
                                                } else { //否則
                                        blue_size--; //藍色亮度相減
                                }
                                       
                                        delay_led=rand()&0xF+0xF; //設置替減次數
                                        while(delay_led--){ //計數循環替減
                                                set_led_color(red_size,green_size,blue_size);  //設置輸出LED顏色


                                        }



                        }
                                       
                                        delay_led=rand()&0x7F+0x7F; //持續執行0~127個下面的指令。
                                                while(delay_led--){ //漸變完畢有1段時間保持顏色。
                                                        set_led_color(red_size,green_size,blue_size);  //設置輸出LED顏色
                                                }
                                       
                                       
                                                


                                





               


        }
}

void Timer0Interrupt(void) interrupt 1{ //1ms 定時器中斷程序
    TH0 = 0x0A2;
    TL0 = 0x40;
        if(p==0){  //延遲時間減到0
                p=md[m+1]; //設置延遲時間
                set_hz(md[m]); //設置鳴叫頻率
                m+=2; //指針加2
                if(m>=212) m=0; //指針超過212則清零避免取出其他胡亂的數據
        } else {
                p--; //延遲時間減1
               
        }
}






作者: babylu200661    時間: 2016-7-7 14:31
好東西~
作者: lb688    時間: 2016-7-7 15:23
不錯,學習了。
作者: lb688    時間: 2016-7-7 15:24
不錯,好東西。
作者: 天下第一帥    時間: 2016-7-7 17:19
挺好的
作者: nsj21n    時間: 2016-7-8 13:27
有點意思,不錯!
作者: HWL0541    時間: 2016-7-8 13:34
想看看這個
作者: DIY電子    時間: 2016-7-8 14:48
學習  謝謝分享............
作者: 黃看山    時間: 2016-7-8 20:43
看看,好東西

作者: 行云流水    時間: 2016-7-8 23:33
這個不錯,學習學習!謝謝分享
作者: xsjysm888    時間: 2016-7-13 20:41
正在學習,看下
作者: uva2015    時間: 2016-7-14 23:39
好東西,看看
作者: 1511544112    時間: 2016-7-16 22:49
不錯!
作者: hantp    時間: 2016-7-17 08:55
這個應該不錯。
作者: 仨芢    時間: 2016-7-17 10:45
好好好
作者: 騰飛的龍    時間: 2016-7-17 11:45
看看學習一下
作者: 山水qls    時間: 2016-7-20 14:47
好,非常棒,人才哈
作者: darkpirates    時間: 2016-7-20 15:57
好東西~
作者: 286458071    時間: 2016-7-20 21:37
好東西!學習啦!
作者: ztflove51    時間: 2016-7-21 08:20
好東西
作者: abc201006    時間: 2016-7-22 05:33
蜂鳴器放歌, 有意思
作者: wkuz8888    時間: 2016-7-25 00:03
好東西吧
作者: wszyg621    時間: 2016-7-25 06:25
天天在學 就是沒長進,還是年輕好啊!
作者: shitouyiyuya    時間: 2016-7-26 22:20
#在這里快速回復# 這個不錯,學習學習!謝謝分享
作者: 綠源學習者    時間: 2016-7-27 22:06
什么東西
作者: AOP    時間: 2016-7-28 23:10
這個要看看,學習學習

作者: AOP    時間: 2016-7-28 23:22
代碼好規范啊
作者: 發瘋飛    時間: 2016-8-21 18:12
我也要
作者: liumingqin    時間: 2016-8-21 22:25
向樓主學習
作者: middfat    時間: 2016-8-22 06:16
學習了
作者: nihua    時間: 2016-8-24 23:06
好強大,我是菜鳥,正在發奮中
作者: 劉海龍    時間: 2016-8-25 08:41
學習一下
作者: whengfu    時間: 2016-8-31 00:39
音樂與光色同時運行,學習了
作者: 數據總線    時間: 2016-8-31 08:43
學習了,支持樓主的精神
作者: lh3158    時間: 2016-8-31 12:25
看看,應該是好東西
作者: LH縱橫    時間: 2016-9-3 22:47
學習學習 嘿嘿
作者: 32323232    時間: 2016-9-4 10:13
謝謝你的分享
作者: workload900    時間: 2016-9-4 15:21
自己嘗試寫過,效果不好。學習下高手怎么寫的

作者: 東北那誰    時間: 2016-9-12 21:56
樓主好人,謝謝分享
作者: lids    時間: 2016-9-28 09:15
很好的資料,謝謝分享
作者: dbsjacky    時間: 2017-6-30 19:27
謝謝 樓主分享
作者: hei51com    時間: 2020-5-23 10:59
感謝分享,學習看看




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1