include//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #define uint unsigned int #define uchar unsigned char sbit IR=P3^2; //红外接口标志 unsigned char irtime;//红外用全局变量 unsigned char eeprom_read(unsigned int addres); bit LEDDirection=0;//LED控制方向0:渐亮1:渐灭 bit kg_flag; bit zb_flag,irprosok,irok; bit m_flag; bit s_flag; bit f_flag; bit irpro_ok,irok; sbit ledr=P1^0; sbit ledg=P1^2; sbit ledb=P1^6; sfr isp_data =0xe2; sfr isp_addrh =0xe3; sfr isp_addrl =0xe4; sfr isp_cmd =0xe5; sfr isp_trig =0xe6; sfr isp_contr =0xe7; uchar temp1,ee_temp,ee_temp1; uchar IRcord[4]; uchar irdata[33]; uchar pwm_r,pwm_g,pwm_b; uchar pwmr,pwmg,pwmb,scw; uint t; void TIM0init(void)//定时器0初始化 { TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值 TH0=0x00; //重载值 TL0=0x00; //初始化值 ET0=1; //开中断 TR0=1; } void TIM1init(void)//定时器0初始化 { TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值 TH1=(65536-10)/256; TL1=(65536-10)%256; //初始化值 EA=1; ET1=1; //开中断 TR1=1; EX1=1; } void EX0init(void) { IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2) EX0 = 1; //使能外部中断 EA = 1; //开总中断 } //eeprom擦除 //***********************************/ void eeprom_eares(unsigned int addres)//扇区擦除。 { unsigned i; isp_addrl=addres; //低位地址 isp_addrh=addres>>8; //高位地址 isp_contr=0x01; isp_contr=isp_contr|0x80; //设时间与充ISP操作。 isp_cmd=0x03; //扇区命命令 isp_trig=0x46; //触发 isp_trig=0xb9; //触发启动。 for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; } /****************************************** EEPROM写 *******************************************/ void eeprom_write(unsigned int addres,unsigned char write_data) { unsigned char i; isp_data=write_data; //要写入的数据。 isp_addrl=addres; //低位地址 isp_addrh=addres>>8; //高位地址 isp_contr=0x01; isp_contr=isp_contr|0x80; //设时间与充ISP操作。 isp_cmd=0x02; //写命令 isp_trig=0x46; //触发 isp_trig=0xb9; //触发启动。 for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; } /********************************************** EEPROM读 ***********************************************/ unsigned char eeprom_read(unsigned int addres) { unsigned char i,z; isp_addrl=addres; isp_addrh=addres>>8; isp_contr=0x01; isp_contr=isp_contr|0x80; isp_cmd=0x01; isp_trig=0x46; isp_trig=0xb9; for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; z=isp_data; return(z); } void Ircordpro(void)//红外码值处理函数 { unsigned char i, j, k; unsigned char cord,value; k=1; for(i=0;i<4;i++) //处理4个字节 { for(j=1;j<=8;j++) //处理1个字节8位 { cord=irdata[k]; if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差 value|=0x80; if(j<8) { value>>=1; } k++; } IRcord[i]=value; value=0; } irpro_ok=1;//处理完毕标志位置1 } void Ir_work(void)//红外键值散转程序 {temp1=eeprom_read(0x2000); //temp1=isp_data; //ee_temp=ee_temp1&0x0f; switch(temp1)//判断第三个数码值 { case 0x07:{kg_flag=1; f_flag=0; s_flag=0; zb_flag=0; m_flag=0; pwm_r=0; pwm_g=0; pwm_b=0; }break;//1 显示相应的按键值 case 0x06:{kg_flag=0; }break;//2 case 0x04:{if(kg_flag==1) {if((m_flag==0)&&(s_flag==0)&&(f_flag==0) &&(zb_flag==0)) { if(pwm_r<180) {pwm_r=pwm_r+20;} if(pwm_b<180) {pwm_b=pwm_b+20;} if(pwm_g<180) {pwm_g=pwm_g+20;} } } }break;//3 case 0x05:{if(kg_flag==1) {if((m_flag==0)&&(s_flag==0)&&(f_flag==0) &&(zb_flag==0)) {if((pwm_r>0)&&(pwm_r!=199)) {pwm_r=pwm_r-20;} if((pwm_b>0)&&(pwm_b!=199)) {pwm_b=pwm_b-20;} if((pwm_g>0)&&(pwm_g!=199)) {pwm_g=pwm_g-20;}} } }break;//4 case 0x09: {if(kg_flag==1) {flag(); pwm_r=0; pwm_g=199; pwm_b=199; } break;}//5 case 0x08:{if(kg_flag==1) {flag(); pwm_r=199; pwm_b=199; pwm_g=0;} break;}//6 case 0x0A:{if(kg_flag==1) {pwm_r=199; pwm_b=0; pwm_g=199; flag();} break;}//7 case 0x0B:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=0; flag();} break;}//8 case 0x0D:{if(kg_flag==1) {pwm_r=0; pwm_b=199; pwm_g=160; flag();} break;} case 0x0C:{if(kg_flag==1) {pwm_r=199; pwm_b=160; pwm_g=0; flag();} break;} case 0x0E:{if(kg_flag==1) {pwm_r=160; pwm_b=0; pwm_g=199; flag();} break;} case 0x15:{if(kg_flag==1) {pwm_r=0; pwm_b=199; pwm_g=120; flag();} break;} case 0x14:{if(kg_flag==1) {pwm_r=199; pwm_b=120; pwm_g=0; flag();} break;} case 0x16:{if(kg_flag==1) {pwm_r=120; pwm_b=0; pwm_g=199; flag();} break;} case 0x19:{if(kg_flag==1) {pwm_r=0; pwm_b=199; pwm_g=80; flag();} break;} case 0x18:{if(kg_flag==1) {pwm_r=199; pwm_b=80; pwm_g=0; flag();} break;} case 0x1A:{if(kg_flag==1) {pwm_r=80; pwm_b=0; pwm_g=199; flag();} break;} case 0x11:{if(kg_flag==1) {pwm_r=0; pwm_b=199; pwm_g=0; flag();} break;} case 0x10:{if(kg_flag==1) {pwm_r=199; pwm_b=0; pwm_g=0; flag();} break;} case 0x12:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=199; flag();} break;} case 0x13:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=0; f_flag=0; s_flag=0; zb_flag=0; m_flag=1;} break;} case 0x1B:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=0; f_flag=0; s_flag=0; zb_flag=1; m_flag=0;} break;} case 0x17:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=0; f_flag=0; s_flag=1; zb_flag=0; m_flag=0;} break;} case 0x0F:{if(kg_flag==1) {pwm_r=0; pwm_b=0; pwm_g=0; f_flag=1; s_flag=0; zb_flag=0; m_flag=0; } break;} } irpro_ok=0;//处理完成标志 } void main(void) { EX0init(); //初始化外部中断 TIM0init();//初始化定时器 TIM1init(); //取位码 第一位数码管选通,即二进制1111 1110 while(1)//主循环 { if(irok) //如果接收好了进行红外处理 { Ircordpro(); irok=0; if(IRcord [2]>=0x04) {if(IRcord [2]<=0x1b) { temp1=IRcord[2]; eeprom_eares(0x2000); //STC_EEROM_0X2000 temp1 eeprom_write(0x2000,temp1); temp1=eeprom_read(0x2000); //temp1=isp_data; // ee_temp=ee_temp1&0x0f; } else { temp1=eeprom_read(0x2000); //temp1=isp_data; //ee_temp=ee_temp1&0x0f; } } } if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等 { Ir_work(); } } } void tim0_isr (void) interrupt 1 using 1 { irtime++; //用于计数2个下降沿之间的时间 } void tim1_isr (void) interrupt 3 {TH1=(65536-10)/256; TL1=(65536-10)%256; TR1=0; scw++; if(kg_flag==1) { if(m_flag==1) { if(scw==200)//20ms时间到 { scw=0; t++; if((t>0)&&(t<400)) {rjb();} if((t>400)&&(t<800)) {gjb();} if((t>800)&&(t<1200)) {bjb();} if((t>1200)&&(t<1600)) {rjb();gjb();} if((t>1600)&&(t<2000)) {rjb();bjb();} if((t>2000)&&(t<2400)) {gjb();bjb();} if((t>2400)&&(t<2800)) {rjb();gjb();bjb();} if(t>2800){t=0;} } if(pwm_r>0){ledr=0;pwm_r--;} else{ledr=1;} if(pwm_g>0){ledg=0;pwm_g--;} else{ledg=1;} if(pwm_b>0){ledb=0;pwm_b--;} else{ledb=1;} } if(f_flag==1) { sjb(); } if(s_flag==1) { fjb(); } if(zb_flag==1) {if(scw==200)//20ms时间到 { scw=0; {rjb();bjb();gjb();} } if(pwm_r>0){ledr=0;pwm_r--;} else{ledr=1;} if(pwm_g>0){ledg=0;pwm_g--;} else{ledg=1;} if(pwm_b>0){ledb=0;pwm_b--;} else{ledb=1;} } if((m_flag==0)&&(s_flag==0)&&(f_flag==0) &&(zb_flag==0)) {if(scw==200)//20ms时间到 { scw=0; } if(scw<=pwm_r) { ledr=1; } else {ledr=0;} if(scw<=pwm_g) { ledg=1; } else {ledg=0;} if(scw<=pwm_b) { ledb=1; } else {ledb=0;} } } else{ledr=1;ledg=1;ledb=1;} TR1=1; } void EX0_ISR (void) interrupt 0 //外部中断0服务函数 { static unsigned char i; //接收红外信号处理 static bit startflag; //是否开始处理标志位 if(startflag) { if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms i=0; irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1 irtime=0; i++; if(i==33) { irok=1; i=0; } } else { irtime=0; startflag=1; } }
RGB遥控C程序
写了个遥控RGB程序分享下,随便请教下高手怎么用单片机EEPROM写断电记忆