用芯圣mcu实现NEC红外遥控解码-源码
/********************************测试源码如下*************************************/#include "HC89F003.h"
#include "TM1650.h" //引入数码管用作代码调试
//定义键码
#define IR_KEY_A 0XFFA25D
#define IR_KEY_B 0XFF629D
#define IR_KEY_C 0XFFE21D
#define IR_KEY_D 0XFF22DD
#define IR_KEY_E 0XFFC23D
#define IR_KEY_F 0XFFB04F
#define IR_KEY_OK 0XFFA857
#define IR_KEY_S 0XFF02FD
#define IR_KEY_X 0XFF9867
#define IR_KEY_Z 0XFFE01F
#define IR_KEY_Y 0XFF906F
#define IR_KEY_0 0XFF6897
#define IR_KEY_1 0XFF30CF
#define IR_KEY_2 0XFF18E7
#define IR_KEY_3 0XFF7A85
#define IR_KEY_4 0XFF10EF
#define IR_KEY_5 0XFF38C7
#define IR_KEY_6 0XFF5AA5
#define IR_KEY_7 0XFF42BD
#define IR_KEY_8 0XFF4AB5
#define IR_KEY_9 0XFF52AD
//定义引脚
#define IN2 P0_6 //之前是P2_7 外部中断6
//定义变量、引脚
volatile unsigned long timerCount=0;//定时器计数
unsigned charirdataCount=0; //自加变量
volatile unsigned int xdata ircode; //红外代码接收缓冲区
volatile unsigned char xdata hexData={0}; //红外代码接收缓冲区
//unsigned int testArr={0};
bit readStart = 0;
bit isEnd = 0;
unsigned long longZero = 0x00000000;
//定义函数
void System_init(void);
void Timer3Init(void);
void GPIO_init();
void Int6Init(void);
void parseRevdata();
void Uart1_init(unsigned long BaudRate);
void UART1_SendByte(unsigned char temp);
//void Delay_1ms(unsigned short ms);
void main(){
System_init();
GPIO_init();
Timer3Init();
Int6Init();
Uart1_init(9600);
EA=1;
//Delay_1ms(1000);
//UART1_SendByte('a');
while(1){
if(isEnd){ //数据读取完成 开始解析数据
unsigned long parseResData;
unsigned char result;
isEnd=0;
parseRevdata();
parseResData=(unsigned long) ((longZero|hexData)<<24)+((longZero|hexData)<<16)+((longZero|hexData)<<8)+((longZero|hexData));
switch(parseResData){
case IR_KEY_A:
UART1_SendByte('A');
result= 'A';
break;
case IR_KEY_B:
UART1_SendByte('B');
result= 'B';
break;
case IR_KEY_C:
UART1_SendByte('C');
result= 'C';
break;
case IR_KEY_D:
UART1_SendByte('D');
result= 'D';
break;
case IR_KEY_E:
UART1_SendByte('E');
result= 'E';
break;
case IR_KEY_F:
UART1_SendByte('F');
result= 'F';
break;
case IR_KEY_S:
UART1_SendByte('S');
result= 'S';
break;
case IR_KEY_X:
UART1_SendByte('X');
result= 'X';
break;
case IR_KEY_Z:
UART1_SendByte('Z');
result= 'Z';
break;
case IR_KEY_Y:
UART1_SendByte('Y');
result= 'Y';
break;
case IR_KEY_OK:
UART1_SendByte('K');
result= 'K';
break;
case IR_KEY_0:
UART1_SendByte('0');
result= '0';
break;
case IR_KEY_1:
UART1_SendByte('1');
result= '1';
break;
case IR_KEY_2:
UART1_SendByte('2');
result= '2';
break;
case IR_KEY_3:
UART1_SendByte('3');
result= '3';
break;
case IR_KEY_4:
UART1_SendByte('4');
result= '4';
break;
case IR_KEY_5:
UART1_SendByte('5');
result= '5';
break;
case IR_KEY_6:
UART1_SendByte('6');
result= '6';
break;
case IR_KEY_7:
UART1_SendByte('7');
result= '7';
break;
case IR_KEY_8:
UART1_SendByte('8');
result= '8';
break;
case IR_KEY_9:
UART1_SendByte('9');
result= '9';
break;
default:
UART1_SendByte(0);
result=0;
break;
}
}
}
}
//引脚初始化
void GPIO_init()
{
P1M0=(P1M0&0XFF)|0X88; //OUT3P11 推挽输出//OUT4P10 推挽输出
}
//系统初始化
void System_init(void)
{
WDTCCR = 0x00; //关闭看门狗
while((CLKCON&0x20)!=0x20); //等待内部高频晶振起振
CLKDIV = 0x02; //CPU时钟2分频,确保在进行RC32分频时CPU时钟小于20M
CLKSWR = 0x51; //选择内部高频时钟为主时钟,且内部高频RC2分频,
while((CLKSWR&0xC0)!=0x40); //等待内部高频切换完成
CLKDIV = 0x01; //CPU时钟1分频
BORC=0xc2;
BORDBC=0x06; //V3.0版本加入
}
//定时器3初始化
//时钟频率:16.000MHz
//定时长度:50微秒
void Timer3Init(void)
{
T3CON &= 0xCF;//1分频
T3CON &= 0xFC;//系统时钟Fosc
TH3 = 0xFC;//初值高8位
TL3 = 0xE0;//初值低8位
T3CON &= 0x7F;//清除中断标志
ET3 = 1;//使能中断
T3CON |= 0x04; //开启定时器
}
//外部中断6初始化
void Int6Init(void)
{
P0M3 = P0M3&0xF0|0x02; // IN2P06上拉输入(非施密特)
PITS1 = (PITS1&0xCF)|0x10; //INT6下降沿
PINTE0 |=0x40; //允许该INT6中断
IE1 |=0x40;//允许 INT2~INT7 中断
}
//T3中断服务函数
void Timer3Interrupt (void) interrupt T3_VECTOR
{
//具体代码
timerCount++;
T3CON &= 0x7F;//清除中断标志
}
//INT1中断服务函数
void INT6Interrupt(void) interrupt INT2_7_VECTOR//外部中断时无法实时读取定时器的值 读到定时器的是一个固定值
{
if(timerCount>300){ //如果时间大于15ms 检测引导码起始段
readStart = 1; //读数据标识
irdataCount = 0; //将数据读取标识位值0
}
else{
if(readStart){
ircode = timerCount; //当前中断为上一个信号的结束,下一个信号的开始
showNumberDec(ircode);
irdataCount++;
if(irdataCount>=33){ //数据的终止码
readStart=0;
irdataCount =0;
isEnd=1; //数据接收完成标志
}
else if(irdataCount==1&&timerCount>225&&timerCount<230){ //重复码的终止码
readStart=0;
irdataCount =0;
isEnd=1;
}
}
}
timerCount=0;
PINTF0 &= ~0x40;//清除中断标志
}
void parseRevdata(){
unsigned char i;
unsigned char revdata=0x00;
if(ircode>272&&ircode<278){ //判断是数据引导头
for(i=1;i<33;i++){
if(ircode>18&&ircode<24){
// UART1_SendByte(0);
revdata<<=1;
}
else if(ircode>40&&ircode<45){
// UART1_SendByte(1);
revdata<<=1;
revdata |=0x01;
}
if(i%8==0){
hexData=revdata;
revdata = 0x00;
}
}
}
else if(ircode>225&&ircode<230){//判断第一位是重复码
for(i=1;i<33;i++){
if(ircode>18&&ircode<24){
// UART1_SendByte(0);
revdata<<=1;
}
else if(ircode>40&&ircode<45){
// UART1_SendByte(1);
revdata<<=1;
revdata |=0x01;
}
if(i%8==0){
hexData=revdata;
revdata = 0x00;
}
}
}
}
//void Delay_1ms(unsigned short ms) //2mhz时钟
//{
// unsigned short i,j;
// for(i=ms;i>0;i--)
// for(j=1600;j>0;j--);
//}
/********************************************--串口函数--********************************************************/
void Uart1_init(unsigned long BaudRate)
{
unsigned short temp;
unsigned char ch,cl;
T4CON = 0x06; //T4工作模式:UART1波特率发生器 分频比一直在调整,以实际为准
if(BaudRate==115200)
temp=65536-(1000000/BaudRate)-1; //分频系数为16的计算公式 -1是为了减少当波特率为115200时的误差
else
temp=65536-(1000000/BaudRate); //分频系数为16的计算公式
ch=(temp>>8)&0xff;
cl=temp&0xff;
TH4 = ch;
TL4 = cl; //波特率9600
P2M0=(P2M0&0X0F)|0X80; //P21推挽输出 TX1
P0M1=(P0M1&0X0F)|0X20; //P03上拉输入 RX1
TXD_MAP = 0x21; //TXD1映射P21
RXD_MAP = 0x03; //RXD1映射P03
SCON2 = 0x02; //8位UART,波特率可变
SCON = 0x10; //允许串行接收
}
void UART1_SendByte(unsigned char temp)
{
SBUF=temp; //串口1发送
while(!(SCON & 0X02)); //等待发送完成
SCON &=0XFD; //清除发送标志位
}
正好用上,感谢楼主分享。 可以借鉴一下 这一堆代码,没有原理图么 carpsnow 发表于 2021-10-12 18:14
这一堆代码,没有原理图么
网上一搜一大把 谢谢分享代码 感谢楼主的分享,不错的东东,很棒的。很好的。 这个用的是定时器吗? 捕获时钟长度吗 可以做nec发送吗 芯圣mcu效果怎么样 这个3.8khz调试的信号吗 地址位不需要取反吗 求工程源文件吧。 HC89F003是多大频率的呢 TM1650有原理图吗 这个解析速度怎么样 可以搞个自适应红外编码解码 万能解码器是这样弄出来吗 yinwuqing110 发表于 2021-11-12 08:32
万能解码器是这样弄出来吗
不是吧这个只是简单的适用芯圣的NEC协议遥控器