我叫蛮吉 发表于 2021-10-9 15:02

用芯圣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;            //清除发送标志位
}

weifeng90 发表于 2021-10-9 20:03

正好用上,感谢楼主分享。

6552918 发表于 2021-10-10 10:42

可以借鉴一下

carpsnow 发表于 2021-10-12 18:14

这一堆代码,没有原理图么

我叫蛮吉 发表于 2021-10-13 08:28

carpsnow 发表于 2021-10-12 18:14
这一堆代码,没有原理图么

网上一搜一大把

yangxiaor520 发表于 2021-10-14 07:55

谢谢分享代码

单片小菜 发表于 2021-10-19 09:56

感谢楼主的分享,不错的东东,很棒的。很好的。

cehuafan 发表于 2021-11-10 21:31

这个用的是定时器吗?      

wengh2016 发表于 2021-11-10 21:31

捕获时钟长度吗   

qiufengsd 发表于 2021-11-10 21:31

可以做nec发送吗   

kmzuaz 发表于 2021-11-10 21:31

芯圣mcu效果怎么样   

plsbackup 发表于 2021-11-10 21:31

这个3.8khz调试的信号吗   

mnynt121 发表于 2021-11-10 21:31

地址位不需要取反吗   

soodesyt 发表于 2021-11-10 21:32

求工程源文件吧。   

ghuca 发表于 2021-11-10 21:32

HC89F003是多大频率的呢      

aspoke 发表于 2021-11-10 21:32

TM1650有原理图吗      

232321122 发表于 2021-11-10 21:32

这个解析速度怎么样   

yangxiaor520 发表于 2021-11-11 07:53

可以搞个自适应红外编码解码

yinwuqing110 发表于 2021-11-12 08:32

万能解码器是这样弄出来吗

我叫蛮吉 发表于 2021-11-16 11:07

yinwuqing110 发表于 2021-11-12 08:32
万能解码器是这样弄出来吗

不是吧这个只是简单的适用芯圣的NEC协议遥控器
页: [1] 2 3 4
查看完整版本: 用芯圣mcu实现NEC红外遥控解码-源码