#include #include #include #include "at89x51.h" #define TRUE 1 #define FALSE 0 #define MSG_SIZE 8 //定义系统消息队列长度 #define LED_DP1 P2_7 //显示7段LED1 #define LED_DP2 P2_6 //显示7段LED2 #define _NOP _nop_();_nop_();_nop_();_nop_();_nop_() #define SDA P2_2 #define SCL P2_3 #define MISO P1_6 #define SCK P1_7 #define M_OUT P2_4 #define BUT1_DOWN !P2_1 #define BUT2_DOWN !P2_0 #define BUT3_DOWN !P3_6 #define BUT4_DOWN !P3_7 #define BUT1_UP P2_1 #define BUT2_UP P2_0 #define BUT3_UP P3_6 #define BUT4_UP P3_7 #define RCODE_NUM 0x15 //红外编码个数 #define HEX 0 //十六进制 #define DEC 1 //十进制 #define WM_AUTO 1 #define WM_RAND 2 #define WM_LOOP 3 #define WM_STOP 4 #define M_C 0x36 //3000/f //========= // MESSAGE 消息预定义 #define M_EXIT 0x01 #define M_INIT 0x02 #define M_USER 0x70 // #define REMOTE_1 M_USER +0 #define REMOTE_2 M_USER +1 #define REMOTE_3 M_USER +2 #define REMOTE_4 M_USER +3 #define REMOTE_5 M_USER +4 #define REMOTE_6 M_USER +5 #define REMOTE_7 M_USER +6 #define REMOTE_8 M_USER +7 #define REMOTE_9 M_USER +8 #define REMOTE_10 M_USER +9 #define REMOTE_11 M_USER +10 #define REMOTE_12 M_USER +11 #define REMOTE_13 M_USER +12 #define REMOTE_14 M_USER +13 #define REMOTE_15 M_USER +14 #define REMOTE_16 M_USER +15 #define REMOTE_17 M_USER +16 #define REMOTE_18 M_USER +17 #define REMOTE_19 M_USER +18 #define REMOTE_20 M_USER +19 #define REMOTE_21 M_USER +20 //========================================= unsigned char count,runing_msg,message,_ms; unsigned char rec[2],_hbuf,_lbuf,ex0_delay; unsigned char m_count,m_tl,m_th,m_strong,work_state,ledn,stop_count,il_count,save_th; unsigned int wm_t,rand_val; unsigned char bdata system,Byte; sbit _exit_msg = system^0; sbit m_working = system^2; sbit _quit_msg = system^1; sbit event_100ms = system^4; sbit _led_show = system^5; sbit m_enable = system^6; //================== sbit Byte_7 = Byte^7; sbit Byte_0 = Byte^0; //红外遥控识别码 unsigned char code remote_code[RCODE_NUM]={ 0xD0,0x68,0x48, 0x80,0x40,0xc0, 0x20,0xa0,0x60, 0xe0,0x10,0x90, 0x50,0x00,0x58, 0x18, 0xd8, 0x28,0xc8,0x08, 0xe8 }; //LED8段码显示控制码 unsigned char code led_code[16]={ 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e }; //发光二极管流水灯效果控制码 unsigned char code led_mode4[14]={ 0x7e,0x7c,0x7a,0x76, 0x6e,0x5e,0x3e,0x7e, 0x3e,0x5e,0x6e,0x76, 0x7a,0x7c }; //系统消息结构(队列) typedef struct _msg { unsigned char message[MSG_SIZE]; unsigned char in_p; unsigned char out_p; }MESSAGE; static MESSAGE data _msg; //============================================= unsigned char post_message(unsigned char); unsigned char get_message(); void pro_call_back(unsigned char *); void display_led(unsigned char,bit); void int0_ser(); void timer1_ser(); void led_mode(unsigned char); void delay(unsigned char); void set_m_strong(unsigned char); void work_mode(unsigned char); //======== void start_I2C(); void stop_I2C(); void ack_I2C(); void no_ack_I2C(); void send_byte(unsigned char); unsigned char receive_byte(); void read_EEPROM(unsigned char,unsigned char*); void write_EEPROM(unsigned char,unsigned char); //===================================================================== //启动I2C总线 void start_I2C() { SDA = 1; SCL = 1; _nop_(); SDA = 0; _NOP; SCL = 0; _nop_(); } //结束I2C总线 void stop_I2C() { SDA = 0; _nop_();_nop_(); SCL = 1; _NOP; SDA = 1; } //总线应答函数 void ack_I2C() { SDA = 0; _nop_();_nop_(); SCL = 1; _NOP; SCL = 0; } //总线应答函数 void no_ack_I2C() { SDA = 1; _nop_();_nop_(); SCL = 1; _NOP; SCL = 0; } //I2C发送一个字节 void send_byte(unsigned char dat) { unsigned char bitn; Byte = dat; for(bitn=0;bitn<0x08;bitn++) { SDA = Byte_7; Byte <<= 1; _nop_();_nop_(); SCL = 1; _NOP; SCL = 0; } SCL = 0; } //I2C接收一个字节 unsigned char receive_byte() { unsigned char I2C_rec=0x00; unsigned char bitn; SDA = 1; for(bitn=0;bitn<0x08;bitn++) { _nop_(); SCL=0; _NOP; SCL = 1; _nop_();_nop_(); Byte<<=1; Byte_0 = SDA; _nop_();_nop_(); } SCL = 0; return I2C_rec; } //向EEPROM写数据 void write_EEPROM(unsigned char address,unsigned char dat) { unsigned int i; start_I2C(); send_byte(0xa0); ack_I2C(); send_byte(address); ack_I2C(); send_byte(dat); ack_I2C(); stop_I2C(); for(i=0;i<0xff0;i++){} } //从EEPROM中读取数据 void read_EEPROM(unsigned char address,unsigned char *dat) { start_I2C(); send_byte(0xa0); ack_I2C(); send_byte(address); ack_I2C(); start_I2C(); send_byte(0xa1); ack_I2C(); *dat=receive_byte(); SCL = 0; no_ack_I2C(); stop_I2C(); } //================================================= //系统时间服务函数 void timer1_ser() interrupt 3 { TR1 = FALSE; TH1 = save_th; //TH1=0xDC; TL1=0x27; TF1 = FALSE; TR1 = TRUE; //=================================控制LED八段码显示刷新 _led_show = !_led_show; if(_led_show) P0 = _lbuf; else P0 = _hbuf; LED_DP1 = !(LED_DP2 = _led_show); //=========================== if(!EX0) //延时开红外中断,忽略多余红外编码 if(++ex0_delay > 0x32) EX0=TRUE; if(++_ms > 0x0a) //产生100MS消息 { _ms=0x00; event_100ms=TRUE; } if(m_working && m_enable) { m_count++; if(M_OUT) { if(m_count > m_th) { m_count = 0x00; M_OUT = 0; il_count = 0x00; } } else { if(m_count > m_tl) { M_OUT = 1; if(il_count < (m_tl/2)) stop_count++; else stop_count = 0x00; m_count = 0x00; } if(!INT1) il_count++; } } else M_OUT = 1; } //===================================================== //名称:int0_ser //功能:红外接收解码 //参数:无 //返回:无 //备注: //===================================================== void int0_ser() interrupt 0 { EX0=FALSE; //P2_6=P2_7=TRUE; rec[1]=0x00; rec[0]=0x00; //=============================接收固定码=============== count=0x00; do{ TH0 = 0x00; TL0 = 0x00; TF0 =FALSE; TR0=TRUE; while(!INT0); while(INT0) { if(TF0) goto end; } TR0=FALSE; if(TH0 == 0x53) goto end; if(TH0 < 0x10) count++; }while(count < 0x1A); //==============================接收识别码============== count = 0x00; do{ TH0 = 0x00; TL0 = 0x00; TF0 =FALSE; TR0=TRUE; while(!INT0); while(INT0) { if(TF0) goto end; } TR0=FALSE; rec[1] <<= 0x01; if(TH0>0x04 && TH0<0x08) rec[1]++; }while(++count < 0x08); //==============================接收校验字节============= count = 0x00; do{ TH0 = 0x00; TL0 = 0x00; TF0 =FALSE; TR0=TRUE; while(!INT0); while(INT0) { if(TF0) goto end; } TR0=FALSE; rec[0] <<= 0x01; if(TH0>0x04 && TH0<0x08) rec[0]++; }while(++count < 0x08); //================================译码================== count=0x00; if((~rec[1]) == rec[0]) { do{ if(remote_code[count]==rec[1]) { message=M_USER +count; if(message != runing_msg) //当前执行消息是否等于收到消息 { //循环退出置位 _quit_msg=TRUE; post_message(message); ex0_delay=0x00; break; } else break; } }while(++count < RCODE_NUM); } end: //P2_6 = FALSE; return; } //===================================================== //名称:post_message //功能:将消息寄出到系统消息队列中,如果队列已满,函数 // 返回0,否则函数返回1。 //参数:unsigned char msg //返回:成功返回1,失败返回0。 //备注: //===================================================== unsigned char post_message(unsigned char msg) { unsigned char tmp; tmp = _msg.in_p + 1; if(tmp >= MSG_SIZE) tmp = 0; if(tmp == _msg.out_p) return 0; _msg.message[_msg.in_p] = msg; _msg.in_p = tmp; return 1; } //===================================================== //名称:get_message //功能:从系统消息队列中取出最前面的消息并返回。 //参数:无 //返回:队列中有消息,函数返回消息值,否则返回0。 //备注: //===================================================== static unsigned char get_message() { unsigned char ruc; if(_msg.out_p == _msg.in_p) return 0; ruc = _msg.message[_msg.out_p]; _msg.message[_msg.out_p] = 0; _msg.out_p++; if(_msg.out_p >= MSG_SIZE) _msg.out_p = 0; return ruc; } //===================================================== //名称:display_led //功能:将数据写到LED八段码显示缓冲区。 //参数:val 要显示的数据,mode 已十进制或十六进制显示。 //返回:无 //备注:mode = DEC时为十进制显示,mode = HEX时为十六进制 // 显示 //===================================================== void display_led(unsigned char data val, bit mode) { if(mode == DEC) { _lbuf = led_code[val%0x0a]; _hbuf = led_code[val/0x0a]; } else { _lbuf = led_code[val & 0x0f]; _hbuf = led_code[val>>0x04]; } } //===================================================== //名称:delay //功能:毫秒级延时 //参数:timer 要延时的时间长度。 //返回:无 //备注: //===================================================== void delay(unsigned char time) { unsigned char t1,t2; t1 = 0x00; do{ t1++; t2 = 0x00; do{ t2++; }while(t2<0x90); }while(t10x01) set_m_strong(--m_strong); break; case REMOTE_20: save_th += 1; write_EEPROM(1,save_th); break; case REMOTE_21: if(m_strong < 0x0a) set_m_strong(++m_strong); break; case M_EXIT: //_exit_msg=TRUE; //退出程序 break; default : break; } return; } //工作模式 void work_mode(unsigned char mode) { unsigned int rand_num; static unsigned char sec=0x00; switch(mode) { case WM_AUTO: if(event_100ms) { event_100ms = FALSE; if(++wm_t>0x0708) //每3分钟改变一次 { wm_t = 0x0000; m_strong++; if(m_strong == 0x0a) { post_message(REMOTE_3); } set_m_strong(m_strong); } if(++sec>0x0a) { sec = 0x00; P1_5 = !P1_5; } } break; case WM_RAND: if(event_100ms) { event_100ms = FALSE; if(++wm_t > rand_val) { wm_t = 0x0000; if(m_enable = !m_enable) { RXD = 1; rand_num=rand()%0x08+0x01; //换算到1至9之间的数值 set_m_strong(rand_num); } rand_val=rand()%0x0960+0x0258; //换算到600至1800之间的数值 } if(++sec>0x0a) { sec = 0x00; P1_6 = !P1_6; if(!m_enable) RXD=P1_6; } } break; case WM_LOOP: if(event_100ms) { event_100ms = FALSE; if(++sec>0x0a) { sec = 0x00; P1_7 = !P1_7; } } break; case WM_STOP: if(event_100ms) { event_100ms=FALSE; if(ledn > 0x0d) ledn = 0x00; P1 = led_mode4[ledn++]; } break; default : break; } } //===================================================== //名称:system_init //功能:程序运行时对系统进行初始化,并发送M_INIT消息。 //参数:无 //返回:无 //===================================================== void system_init() { IP = 0x08; //设置红外接收中断级别为最高 TMOD = 0x19; //初始化T0,T1为16位定时器 TH1 = 0xDC; TL1 = 0x27; IE =0x89; TR1 =TRUE; ex0_delay=0x00; _exit_msg = FALSE; display_led(0x00,HEX); //LED显示00 post_message(M_INIT); //发送程序初始化消息 } //===================================================== //名称:main //功能:程序主函数 //参数:无 //返回:无 //备注: //===================================================== void main() { delay(100); save_th = 0xDC; system_init(); while(!_exit_msg) { message = get_message(); if(message) { runing_msg = message; //标志当前执行消息 pro_call_back(&message); } runing_msg = 0xff; //////////////////////////////// work_mode(work_state); if(stop_count > 0x1a) { post_message(REMOTE_3); stop_count = 0x00; } } }