/**************************************************************************** [url=home.php?mod=space&uid=288409]@file[/url] main.c* [url=home.php?mod=space&uid=187600]@author[/url] xr* [url=home.php?mod=space&uid=212281]@date[/url] 2014年3月31日22:30:08 * [url=home.php?mod=space&uid=895143]@version[/url] V1.2.3* [url=home.php?mod=space&uid=247401]@brief[/url] 串口通信+红外通信通过串口发送红外遥控器的解码值到PC* [url=home.php?mod=space&uid=536309]@NOTE[/url] 单片机STC89C52RC MCU 晶振11.0592MHZ**************************************************************************/#include <reg52.h>void ConfigUart();void UartSend(unsigned char dat);void delayms(unsigned int xms);extern bit irflag;extern unsigned char ircode[4];extern void ConfigInfrared();void main(){ConfigUart();ConfigInfrared();while (1){if (irflag) //接收到红外数据{irflag = 0;UartSend(ircode[0]); //发送用户码delayms(100);//延时100msUartSend(ircode[2]); //发送键码}}}/*** @brief 延时xms* @param xms* @retval 无*/void delayms(unsigned int xms){unsigned int x, y;for (x = 0; x < xms; x++)for (y = 0; y < 110; y++);}/*** @brief 配置串口通信* @param 无* @retval 无*/void ConfigUart(){TMOD &= 0x0F;//清零T1控制位TMOD |= 0x20;//T1方式2,八位自动重装模式TH1 = 0xFD; //波特率= 256-1/2^SMOD*T1溢出率X=256-11059200/12/32/波特率TL1 = TH1;//波特率9600bpsTR1 = 1;ET1 = 0;//只用T1的计数SCON |= 0x50;//串口方式1 SM0 SM1 SM2 REN TB8 RB8 TI RI 0101 0000/*SM0 = 0;SM1 = 1;//方式1 SM2多机通信位REN = 1;//允许接收数据TI = 0;//发送完成中断标志RI = 0;//接收完成中断标志*/ES = 1;//开串口中断EA = 1;//开总中断}/*** @brief 串口发送一个字节数据到PC* @param 待发送数据* @retval 无*/void UartSend(unsigned char dat){SBUF = dat;//while (!TI);//等待发送完成,在中断模式下不需要等待,否则进不了中断}/*** @brief 串口中断* @param 无* @retval 无*/void Uart_ISP() interrupt 4 //串口中断标号是4{if (TI) //等待发送完成{ //发送完成TI = 0;//清零}}/***************************************************************** @file infrared.c* @author xr* @date 2014年3月31日20:51:23* @version V1.2.3* @brief 红外通信--红外遥控器NEC协议解码* @note 单片机STC89C52RC MCU 晶振11.0592MHZ***************************************************************/#include <reg52.h>sbit IRD = P3^3;//红外接收检测端口bit irflag = 0;//接收到数据的标志unsigned char ircode[4];//存放红外遥控器发送的用户码,用户码反码键码键码反码/*** @brief 红外配置* @param 无* @retval 无*/void ConfigInfrared(){TH0 = 0;TL0 = 0;//清零T0计数TMOD &= 0xF0;TMOD |= 0x01;//T0方式1TR0 = 0;//在没有红外信号之前先关闭T0ET0 = 0;//只用T0的计数//外部中断1IT1 = 1;//设置外部中断触发方式为下降沿触发EX1 = 1;//开启外部中断1}/*** @brief 获得IRD红外检测引脚的高电平时间(空闲时间)* @param 无* @retval 高电平持续的计数值*/unsigned int getHeighTime(){//在检测外部信号前,必须先将IRDIO口拉高IRD = 1;TH0 = 0;TL0 = 0;//清零T0计数TR0 = 1;//开启T0计数while (IRD) //持续高电平{//超时判断if (TH0 > 0x40) //当IRD持续高电平时间17.7ms,远远大于引导码的9ms,是误码{break;//退出}}TR0 = 0;//停止计数return (TH0*256 + TL0);//返回高电平计数值}/*** @brief 获得IRD红外检测引脚的低电平时间(载波时间)* @param 无* @retval 低电平持续的计数值*/unsigned int getLowTime(){IRD = 1;//释放IRD,检测外部信号TH0 = 0;TL0 = 0;//清零T0计数TR0 = 1;//开始计数while (!IRD) //持续低电平{if (TH0 > 0x40) //超过18ms就是误码,错误信号{break;}}TR0 = 0;//停止计数return (TH0*256 + TL0);//返回低电平计数值}/*** @brief 外部中断1服务程序,检测红外信号* @param 无* @retval 无*/void EXINT_ISP() interrupt 2 //外部中断标号2{unsigned char byte;//接收数据unsigned char i, j;unsigned int time;//时间time = getLowTime();//获得载波时间if (time < 7833 || time > 8755) //引导码载波是9ms,这里规定在8.5ms-9.5ms之间是9ms的载波{//范围之外,误码IE1 = 0;//清零外部中断1中断标志,为下一次再进入中断return;//退出中断}//否则是9ms的载波time = getHeighTime();//空闲时间if (time < 3686 || time > 4608) //引导码的空闲时间4.5ms 这里规定4ms-5ms是4.5ms的空闲{IE1 = 0;//清零中断标志return;//退出中断}//否则是4.5ms的空闲//开始接收用户码和键码等for (i = 0; i < 4; i++){for (j = 0; j < 8; j++){time = getLowTime();//载波if (time < 423 || time > 608) //560us的载波和560us的空闲是0 范围460us-660us {IE1 = 0;return;}//560us载波time = getHeighTime();if (time > 423 && time < 608) //560us空闲{//bit '0'byte >>= 1;//低位在前,移入一位0}else if (time > 1198 && time < 1658) //1.68ms的空闲是1 范围1300us-1800us {//bit '1'byte >>= 1;//移入一位byte |= 0x80;//移入的一位置1}else{//误码IE1 = 0;return;//退出中断}}ircode = byte;}//接收完成irflag = 1;//退出中断时清零中断标志IE1 = 0;}。