2324|0

2015

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

分享msp430单片机红外遥控 编码 解码源程序 [复制链接]

主程序预览:
  • /***************************红外编解码.c***************************************/
  • //  * NAME          : 红外编解码.c
  • //  * FUNCTION      : 红外的编码与解码
  • //  * PROGRAMMED    : 刘中原
  • //  * DATE(ORG)     : 2010.10.12
  • //  * PROJECT       : 430红外遥控,数据传输
  • //  * OS            : 所使用的操作系统
  • //  * HISTORY       :
  • //  * ID --- DATE -----------NOTE--------------------------
  • //  * 00 94.04.14 初期完成
  • //  * 01 94.05.14 第二版 XX机能修改(追加)
  • //
  • //编解码波形(NEC)
  • //________________         __  __   __
  • //                |        | | | |  |
  • //                |        | | | |  |
  • //                |        | | | |  |
  • //                |        | | | |  |
  • //                |        | | | |  |.....................................
  • //                |        | | | |  |
  • //                |        | | | |  |
  • //                |________| |_| |__|   "0"高:0.56ms+低:0.565ms=1.125ms
  • //|<-    9ms    ->|<-4.5ms>|"0"| "1"|   "1"高:0.56ms+低:1.69ms =2.25ms
  • //|<-  引导码   ->|<-起始码|<-8位地址->|<-8位地址->|8位数据->|<-数据反码->|
  • //
  • //可以完成编码 解码  注释掉#define DECODE移去解码部分 #define ENCODE移去编码
  • //sendFlg是发送完成标志,完成后置1  未完成时连发数据无效
  • //
  • //占用资源:TB CCR0中断 CCR4 CCR5中断  CCR0赋值为1125 时钟1MHz
  • //红外输出端P2.0 32768Hz
  • //P2.1为红外输入端口
  • //
  • /******************************************************************************/
  • //
  • #define DECODE      //解码
  • #define ENCODE      //编码
  • #include "msp430x16x.h"
  • #include "红外编解码.h"
  • /**********************************宏定义**************************************/
  • #ifdef ENCODE                        /*=======编码=======*/
  • #define BIT_0     P2SEL&=~BIT0                //红外编码后的低电平
  • #define BIT_1     P2SEL|=BIT0                 //红外编码后的高电平
  • #define SENDDAT   TBCCTL0|=CCIE           //启动数据发送 发送已存入addr0和dat0的数据
  • //发送数据位高位部分 开始发数据位
  • #define SENDBIT   TBCCR4=565-1;TBCCTL4|=CCIE
  • #define SEND_END  TBCCTL0&=~CCIE;TBCCTL4&=~CCIE         //发送结束 关中断
  • #endif                                        /*=======编码=======*/
  • #ifdef DECODE                        /*=======解码=======*/
  • #define DATIN   ((P2IN&BIT1)>>1)              //数据输入
  • #endif                                        /*=======解码=======*/
  • /******************************************************************************/
  • #ifdef DECODE                        /*=======解码=======*/
  • //解码后保存数据
  • char addr1;
  • char dat1;
  • char readFlg = 0;                //成功读红外数据标志
  • #endif                                        /*=======解码=======*/
  • #ifdef  ENCODE                        /*=======编码=======*/
  • //要编码的数据  发送缓存
  • char addr0;
  • char dat0;
  • char sendFlg = 1;                //发送完成标志
  • #endif                                        /*=======编码=======*/
  • //初始化TB
  • void int_TB()
  • {
  •         TBCTL = TBSSEL_2 + TBCLR + MC_1;      //TB时钟源:SMCLK 增模式
  •         TBCCR0 = 1125 - 1;
  •         TBCCTL5 |= CCIE;
  •         TBCCR5 = 450;
  • }
  • //有关端口初始化
  • void int_io()
  • {
  • #ifdef  ENCODE                        /*=======编码=======*/
  •   //ACLK输出作为编码的载波
  •         P2OUT &=~ BIT0;
  •         P2DIR |= BIT0;
  • #endif                                        /*=======编码=======*/
  • #ifdef DECODE                        /*=======解码=======*/
  •   //解码输入端口P2.1
  •         /*P2IES |= BIT1;
  •         P2IFG &=~ BIT1;
  •         P2IE |=BIT1;*/
  • #endif                                        /*=======解码=======*/
  • }
  • //初始化红外相关资源
  • void int_hw()
  • {
  •         int_TB();
  •         int_io();
  • }
  • #ifdef ENCODE                        /*=======编码=======*/
  • //编码发送数据,eos标志最后数据一般为1,发送多字节数据时,最后一字节是1
  • void sendDat(char addr,char dat)
  • {
  •         if(sendFlg)                //上次发送完成
  •         {
  •                 //数据存入发送缓存
  •                 addr0 = addr;
  •                 dat0  = dat;
  •                 //开始发送
  •                 SENDDAT;
  •         }
  • }
  • #endif                                        /*=======编码=======*/
  • #ifdef DECODE
  • //红外数据解码函数
  • void datDecode(unsigned int tAddr, unsigned int tDat)
  • {
  •         if(((tAddr>>8)&0xff)==(tAddr&0xff))                //地址高位低位相等 地址位数据正确
  •         {
  •                 addr1 = tAddr&0xff;
  •                 if(((tDat>>8)&0xff)==((~tDat)&0xff))                //数据高位低位反 数据位数据正确
  •                 {
  •                         dat1 = ~(tDat&0xff);
  •                         readFlg = 1;
  •                 }
  •                 else
  •                 {
  •                         readFlg = 2;
  •                 }
  •         }
  •         else
  •         {
  •                 readFlg = 2;
  •         }
  • }
  • #endif
  • //中断
  • #ifdef ENCODE                        /*=======编码=======*/
  • //TB0中断 编码
  • #pragma vector=TIMERB0_VECTOR
  • __interrupt void Timer_B (void)
  • {
  •     static char i = 0;    //计数 起始
  •     static char state = 0;    //状态 起始:0  数据:1
  •     static char cnt = 0;      //发送计数
  •     if(state==0)
  •     {
  •         if(i==0)
  •         {
  •             BIT_1;
  •                         //完成标志置0 开始发送
  •                         sendFlg = 0;
  •         }
  •         else if(i==8)
  •         {
  •             BIT_0;
  •         }
  •         else if(i==11)
  •         {
  •             SENDBIT;
  •             state = 1;
  •                         i = 255;
  •         }
  •     }
  •     else if(state==1)
  •     {
  •         BIT_0;
  •         if(cnt<8)               //地址高位
  •         {
  •             if(addr0&(1<<(7-cnt)))       //从高位到低位 是1延时+2:2.25ms
  •             {
  •                 if(i==1)
  •                 {
  •                     SENDBIT;
  •                     i = 255;
  •                                 cnt++;    //发送加1
  •                 }
  •             }
  •             else
  •             {
  •                 SENDBIT;
  •                 i = 255;
  •                         cnt++;    //发送加1
  •             }
  •         }
  •         else if(cnt<16)                //地址低位
  •         {
  •             if(addr0&(1<<(15-cnt)))       //从高位到低位 是1延时+2:2.25ms
  •             {
  •                 if(i==1)
  •                 {
  •                         SENDBIT;
  •                     i = 255;
  •                                 cnt++;    //发送加1
  •                 }
  •             }
  •             else
  •             {
  •                 SENDBIT;
  •                 i = 255;
  •                         cnt++;    //发送加1
  •             }
  •         }
  •                 else if(cnt<24)                //数据
  •                 {
  •                         if(dat0&(1<<(23-cnt)))       //从高位到低位 是1延时+2:2.25ms
  •                 {
  •                 if(i==1)
  •                 {
  •                         SENDBIT;
  •                     i = 255;
  •                                 cnt++;    //发送加1
  •                 }
  •                         }
  •                         else                          //是0延时+1:1.125ms
  •                         {
  •                 SENDBIT;
  •                 i = 255;
  •                         cnt++;    //发送加1
  •                         }
  •                 }
  •                 else if(cnt<32)                //数据反码
  •                 {
  •                         if((~dat0)&(1<<(31-cnt)))       //从高位到低位 反码是1延时+2:2.25ms
  •                         {
  •                 if(i==1)
  •                 {
  •                         SENDBIT;
  •                     i = 255;
  •                                 cnt++;    //发送加1
  •                 }
  •                         }
  •                         else                          //是0延时+1:1.125ms
  •                         {
  •                 SENDBIT;
  •                 i = 255;
  •                         cnt++;    //发送加1
  •                         }
  •                 }
  •                 /*else if(cnt==32)        //最后多发一位0,否则无法识别最后一位
  •                 {
  •                 SENDBIT;
  •                 i = 255;
  •                         cnt++;    //发送加1
  •                 }*/
  •                 else
  •                 {
  •                         //完成标志置1
  •                         sendFlg = 1;
  •                         //变量归零
  •                         state = 0;
  •                         cnt = 0;
  •                         i = 255;
  •                         SEND_END;                //停止发送
  •                         BIT_0;
  •                 }
  •     }
  •     i++;      //计数加1
  •         TBCCTL4 &=~ CCIFG;                //中断标志清除
  • }
  • #endif                                        /*=======编码=======*/
  • //TB1中断
  • #pragma vector=TIMERB1_VECTOR
  • __interrupt void Timer_B1(void)
  • {
  •   static int i = 0;         //计数变量 接收用
  •   static char state = 0;   //代表接收状态的变量
  •   static char cnt = 0;                //读取位数计数
  •   switch( TBIV )
  • {
  •         case  0x08:                          // TBCCR4 编码发送数据位部分
  • #ifdef ENCODE                        /*=======编码=======*/
  •                 BIT_1;
  •                 TBCCTL4 &=~ CCIE;
  • #endif                                        /*=======编码=======*/
  •                 break;
  •     case  0x0a:                          // TBCCR5 解码用
  • #ifdef DECODE                        /*=======解码=======*/
  •                 TBCCR5 = (TBR+440>1124)?(TBR+440-1124):(TBR+440);
  •                 if(TBCCR5>1124) TBCCR5 = 1124;                                                //防止TBCCR5出界
  •                 i++;
  •                 if(DATIN==0&&readFlg>0)                //上次读取完成(可能有错误 readFlg=2 错误数据) 又有数据到来
  •                 {
  •                         readFlg = 0;
  •                         i = 0;
  •                 }
  •                 if(state==0&&readFlg == 0)                        //起始码
  •                 {
  •                         if(i<15&&DATIN)                //引导码有高电平 错误数据帧
  •                         {
  •                                 readFlg = 2;
  •                         }
  •                         else if(i>26&&DATIN==0X01)                //引导码正确 准备读数据
  •                         {
  •                                 state = 1;                //1状态 读数据
  •                                 i = 0;
  •                         }
  •                 }
  •                 else if(state==1)                //数据
  •                 {
  •                         static unsigned int tAddr = 0;                //地址位临时变量
  •                         static unsigned int tDat = 0;                //数据位临时变量
  •                         static char datFlg = 0;
  •                         if(cnt<16)                        // 地址 位
  •                         {
  •                                 if(DATIN==0x00&&datFlg==0)
  •                                 {
  •                                         datFlg = 1;                        //有数据
  •                                         i = 0;
  •                                 }
  •                                 if((i==2||i==3)&&datFlg&&DATIN==0X00)
  •                                 {
  •                                         tAddr |= (0X00)<<(15-cnt);
  •                                         i = 0;
  •                                         datFlg = 1;
  •                                         cnt++;
  •                                         return;
  •                                 }
  •                                 else if((i==3)&&DATIN==0X01&&datFlg)
  •                                 {
  •                                         tAddr |= (0X01)<<(15-cnt);
  •                                         i = 0;
  •                                         datFlg = 0;
  •                                         cnt++;
  •                                 }
  •                                 else if(i>3)
  •                                 {
  •                                         readFlg = 2;
  •                                         cnt = 0;
  •                                         datFlg = 0;
  •                                         tAddr = 0;
  •                                         tDat = 0;
  •                                         state = 0;
  •                                 }
  •                         }
  •                         else if(cnt<32)                        //数据位接收
  •                         {
  •                                 if(DATIN==0x00&&datFlg==0)
  •                                 {
  •                                         datFlg = 1;                        //有数据
  •                                         i = 0;
  •                                 }
  •                                 if((i==2||i==3)&&datFlg&&DATIN==0X00)
  •                                 {
  •                                         tDat |= (0X00)<<(31-cnt);
  •                                         i = 0;
  •                                         datFlg = 1;
  •                                         cnt++;
  •                                         return;
  •                                 }
  •                                 else if((i==3)&&DATIN==0X01&&datFlg)
  •                                 {
  •                                         tDat |= (0X01)<<(31-cnt);
  •                                         i = 0;
  •                                         datFlg = 0;
  •                                         cnt++;
  •                                 }
  •                                 else if(i>3)
  •                                 {
  •                                         readFlg = 2;
  •                                         cnt = 0;
  •                                         datFlg = 0;
  •                                         tAddr = 0;
  •                                         tDat = 0;
  •                                         state = 0;
  •                                 }
  •                         }
  •                         else
  •                         {
  •                                 datDecode(tAddr, tDat);
  •                                 //解码结束
  •                                 i = 0;
  •                                 cnt = 0;
  •                                 state = 0;
  •                                 datFlg = 0;
  •                                 tAddr = 0;
  •                                 tDat = 0;
  •                         }
  •                 }
  • #endif                                        /*=======解码=======*/
  •                 break;
  •     case  0x0e:                       //overflow 溢出,未用
  •                 break;
  •   }
  • }
  • /*
  • #ifdef DECODE                        =======解码=======*/
  • //PORT2中断 此中断仅解码接收数据用
  • /*#pragma vector=PORT2_VECTOR
  • __interrupt void PORT2_ISR(void)
  • {
  •         switch(DATIFG&BIT1)
  •         {
  •         case 2:
  •                 //开始接收数据
  •                 DATREAD;
  •                 break;
  •         }
  •         DATIFG = 0;                        //清除标志位
  • }
  • #endif                                        =======解码=======*/



 
点赞 关注(1)

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表