基于MSP430的红外遥控解码程序
MSP430红外解码程序

#include "msp430x14x.h"#define uchar unsigned char#define uint unsigned int#define Ir_Pin (P1IN & BIT7) //定义红外接收头端口static uint DISPLAY=255;unsigned char Ir_Buf[4];unsigned char Code[]={0xC0,0xF9,0xA4,0xB0,//0,1,2,30x99,0x92,0x82,0xF8,//4,5,6,70x80,0x90,0x88,0x83,//8,9,A,b0xC6,0xA1,0x86,0x8E,//C,d,E,F0xff};//-,全灭void DelayMs(uint a){uchar i;for(i = a;i>0;i--)__delay_cycles(1000);}void DelayUs(uint z){uchar i;for(i=z;i>0;i--)__delay_cycles(1);}void Init_Clk(void){uint delay;BCSCTL1 &= ~XT2OFF; // XT2OFF:控制XT2振荡器的开启(XT2OFF=0)BCSCTL2 |= SELM1 + SELS; //SELS:选择SMCLK的时钟源,0:DCOCLK;1:XT2CLK.for(delay=5000;delay>0;delay--); //SELM0~1:选择MCLK的时钟源,0,1:DCOCLK,2:XT2CLK,3:LFXT1CLKIFG1 &=~OFIFG; //晶振故障中断标志位TACCR0=0XFFFF;}void InitP1(void){P1DIR &=~BIT7;//配置为输入P1SEL &=~BIT7;//选择为功能模块P1IES |= BIT7;//选择触发方式1为下降沿触发,0上升沿P1IE |= BIT7;//使能中断P1IFG &=~BIT7;//清除标志位// P1DIR |= BIT4+BIT5+BIT6;}uchar Ir_Scan(){uchar num=15;if(DISPLAY != 255) //如果有键按下{switch(DISPLAY){case 0x16: num=0;break;case 0x0c: num=1;break;case 0x18: num=2;break;case 0x5e: num=3;break;case 0x08: num=4;break;case 0x1c: num=5;break;case 0x5a: num=6;break;case 0x42: num=7;break;case 0x52: num=8;break;case 0x4a: num=9;break;default : num=15;}}return num;}void IR(void){uchar i,j;uint temp=0;if((P1IFG&BIT7)==BIT7) //此if语句主要用于中断前的清理工作{P1IFG &=~BIT7;//清除中断标志位P1IE &=~BIT7;//关闭中断}loop: //检测引导码,检测到引导码通过后,进行客户码和数据码的读取for(i=0;i<4;i++){if(Ir_Pin==0) break; //如果P1.7检测到低电平,则退出循环if(i==3){P1IE |= BIT7; //使能P1.7中断return;}DelayUs(270); //延时270usif(Ir_Pin) //如果P1.7检测到的还是高电平,再次进入检测goto loop;while(!Ir_Pin);//等待红外信号到来for(i=0;i<4;i++) //4个字节for(j=0;j<8;j++) //每个字节8位{while(Ir_Pin)DelayUs(130); //等待低电平while(!Ir_Pin)DelayUs(130); //等待高电平while(Ir_Pin) //计算高电平时间{DelayUs(130);temp++;if(temp>=30){P1IE |= BIT7; //使能中断return;}}Ir_Buf[i]>>=1; //数据右移一位if(temp>11)Ir_Buf[i]|=0x80;//如果高电平时间大于1.69ms则高位补1,红外解码从高位读起temp = 0;}DISPLAY=Ir_Buf[2];// Ir_Scan(); //红外扫描P1IFG &=~BIT7; //清除标志位P1IE |= BIT7; //打开中断}void display(){// unsigned char i;P6OUT=Code[Ir_Scan()];/* for(i=0;i<17;i++){P6OUT=Code[i];DelayMs(200);}*/}void main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗Init_Clk(); //时钟初始化InitP1(); //P1端口初始化_EINT(); //使能全局中断P6DIR =0xFF;while(1){display();}}#pragma vector=PORT1_VECTOR__interrupt void Port1(){IR();}。
基于430单片机的红外解码程序

/*红外遥控解码*///将遥控器的码值送至595驱动的数码管显示//P2_0为1838输入//595的驱动没有附上,大家可以自己想办法显示出来#include <msp430f2272.h>#include "hc595.h"#define uchar unsigned char#define uint unsigned int#define c(x) (x*120000/120000)uchartable[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1, 0x86,0x8E};//共阳数码管uchar table2[]={0x01,0x02,0x04,0x08};uchar Led_Buf[4];//数码显示缓冲区uchar Ir_Buf[4];//储存解码结果uchar Led_index=0;//中断函数内显示之用void delay1(){uint x,y;for(x=100;x>0;x--)for(y=100;y>0;y--);}/*获取低电平时间函数*///////////////////////unsigned int Ir_Get_Low(){uint temp0;TACTL=TASSEL_2+MC_1+ID_3;//时钟来源为SMCLK,8分频,1M,增加模式TACCR0=65500;while(!(P2IN&0X01));//条件是:低电平TACTL&=~MC_3;temp0=TAR;//读取低电平时间TACTL|=TACLR;//TACCR0清零return temp0;}/*获取高电平时间函数*///////////////////////1unsigned int Ir_Get_High(){uint temp1;TACTL=TASSEL_2+MC_1+ID_3;//时钟来源为SMCLK,8分频,1M,增加模式TACCR0=65500;while(P2IN&0X01);//条件是:高电平TACTL&=~MC_3;temp1=TAR;//读取低电平时间TACTL|=TACLR;//TACCR0清零return temp1;}/*系统时钟初始化函数*///////////////////void clock_init(){uchar i;WDTCTL=WDTPW+WDTHOLD;/* BCSCTL1&=~XT2OFF;BCSCTL2|=SELM_2+SELS;//MCLK为8M,SMCLK不分频,8M WDTCTL=WDTPW+WDTHOLD;//关闭看门狗*/BCSCTL1|=XTS;BCSCTL2|=SELM_3+SELS+DIVS_1+DIVM_1;//MCLK为16M,SMCLK8M BCSCTL3|=LFXT1S_2;do{IFG1&=~OFIFG;//清除振荡错误标志for(i=0;i<100;i++)_NOP();}while((IFG1&OFIFG)!=0);IFG1&=~OFIFG;}/*主函数*//////////////////void main(){uchar j,k;uint temp;clock_init(); //时钟初始化hc595_init();//595初始化TBCTL|=TBSSEL_2+MC_1+ID_3+TBCLR;TBCCR0=5000;TBCTL|=TBIE;//P2DIR&=0XFE;//P2_0输入//P2IE|=BIT0;//允许中断//P2IES|=BIT0;//下降沿触发中断_EINT();hc595(0XC0,0x01);while(1){restart:while(P2IN&0X01);temp=Ir_Get_Low();if(temp<c(8000) || temp>c(10000)) continue;//引导脉冲低电平9000temp=Ir_Get_High();if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500for(k=0;k<4;k++) //4个字节for(j=0;j<8;j++) //每个字节8位{temp=Ir_Get_Low();if(temp<c(200) || temp>c(800)) goto restart;temp=Ir_Get_High();if(temp<c(200) || temp>c(2000)) goto restart;Ir_Buf[k]>>=1;//高电平时间大于1120us,就认为是1,小于则是0if(temp>c(1120)) Ir_Buf[k]|=0x80;}Led_Buf[0]=Ir_Buf[2]&0xf;//显示结果Led_Buf[1]=(Ir_Buf[2]/16)&0xf;Led_Buf[2]=Ir_Buf[3]&0xf;Led_Buf[3]=(Ir_Buf[3]/16)&0xf;}}3//管脚中断函数#pragma vector=PORT2_VECTOR__interrupt void Port_2(void){P2IFG&=~BIT0;}//定时器A溢出中断函数#pragma vector=TIMERA0_VECTOR__interrupt void Timer_A(void){TACTL&=~TAIFG;}//定时器B溢出中断函数#pragma vector=TIMERB1_VECTOR__interrupt void Timer_B(void){hc595(table[Led_Buf[Led_index]],table2[Led_index]); Led_index++;if(Led_index==4)Led_index=0;TBCTL&=~TBIFG;}。
msp430 红外解码

while(TAR<=1000); TACTL=0; TAR=0; } #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void) { char m,n,k,CodeTemp; int j; P1IE&=HONGWAI_0;//禁止 P1.0 中断 if((P1IFG&HONGWAI_1)==HONGWAI_1) { P1IFG=0;//清中断标志 //停止计数器
BCSCTL2|=SELM1+SELS+DIVS_2+DIVS_1;//MCLK and SMCLK 1M 8 分频 do { IFG1 &= ~OFIFG; 误标志 for(i = 0; i < 100; i++) _NOP(); //延时等待
// 清除振荡错
} while ((IFG1 & OFIFG) != 0); //如果标志为 1 继续循环等 待 IFG1&=~OFIFG; }
for(k=0;k<10;k++) { delay_07ms(1); if (HONGWAI_IN) HONGWAI_IN=1,说明不是引导码 { k=10;break; } // 如 果 0.7ms 后
else if(k==9) 明是引导码 { while(HONGWAI_IN==0); delay_07ms(5); //跳过持续 4.5ms 的高电平 // 如果持续了 10×0.7ms=7ms 的低电平,说
基于msp430g2553的红外遥控小车解码控制程序

基于msp430g2553的红外遥控小车解码控制程序//遥控小车最终程序#include#define CPU_F ((double)12000000)//数字控制震荡器1MHZ#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/12000000.0))//延时X微秒#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/12000.0))//延时X毫秒char const redled[8]={0x07,0x00,0x01,0x02,0x03,0x04,0x05,0x06};//led测试版对应的八个灯unsigned char receive[2]={0x00,0x00};//数据码,数据反码unsigned char j=0,k=0,f=0,led=0;//中断次数,receive的元素,,找到按键地址数组的第f个元素int flag=1;//***************************主程序********************//void main(void){WDTCTL=WDTPW+WDTHOLD; //关闭看门狗BCSCTL1=CALBC1_1MHZ; //这两句的作用,基本时钟系统控制,数控震荡控制,将时钟校准1MHZDCOCTL=CALDCO_1MHZ;P1DIR|=BIT0+BIT6+BIT2+BIT3+BIT4;//P1端口的P1.0、P1.6设置为输出方向P2DIR|=0x0f; //P2的0,1,2,3设置为输出口P1OUT|=BIT0+BIT6; //P1.0、P1.6输出高电平,次单片机的VCC为3.56VP1IE|=0X02; //P1.1中断使能P1IES|=BIT1; //P1.1中断边沿选择,下降沿触发P1IFG=0; //清P1.1中断标志_BIS_SR(GIE); //开总中断while(1) //{if(receive[0]==0xa2){flag=1;}if(receive[0]==0xe2){flag=-1;}if(flag==1) //正转P1.0{P1OUT&=~BIT3;P1OUT&=~BIT4;switch(receive[0]){case 0x68:{P1OUT&=~BIT0;P1OUT&=~BIT2;break;} //0键case0x30:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(1);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(9);}break;}//1键case0x18:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(2);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(8);}break;}//2键case0x7a:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(3);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(7);}break;}//3键case0x10:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(4);P1OUT&=~BIT0;P1OUT&=~BIT2;delay_m s(6);}break;}//4键case0x38:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(5);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(5);}break;}//5键case0x5a:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(6);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(4);}break;}//6键case0x42:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(7);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(3);}break;}//7键case0x4a:{{P1OUT|=BIT0;P1OUT|=BIT2;delay_ms(8);P1OUT&=~B IT0;P1OUT&=~BIT2;delay_m s(2);}break;}//8键case 0x52:{P1OUT|=BIT0;P1OUT|=BIT2;break;} //9键}}else if(flag==-1) //反转P1.2{P1OUT&=~BIT0;P1OUT&=~BIT2;switch(receive[0]){case 0x68:{P1OUT&=~BIT3;P1OUT&=~BIT4;break;} //0键case0x30:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(1);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(9);}break;}//1键case0x18:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(2);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(8);}break;}//2键case0x7a:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(3);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(7);}break;}//3键case0x10:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(4);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(6);}break;}//4键case0x38:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(5);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(5);}break;}//5键case0x5a:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(6);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(4);}break;}//6键case0x42:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(7);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(3);}break;}//7键case0x4a:{{P1OUT|=BIT3;P1OUT|=BIT4;delay_ms(8);P1OUT&=~B IT3;P1OUT&=~BIT4;delay_m s(2);}break;}//8键case 0x52:{P1OUT|=BIT3;P1OUT|=BIT4;break;} //9键}}}}//*********************红外遥控器中断程序*******************//#pragma vector=PORT1_VECTOR //中断程序的格式:#pragma vector=中断矢量__interrupt void port1(void)//格式:__interrupt void 函数名(void){P1IFG=0X00; //清P1中断标志int count=0; //高电平持续时间计数值while(!(P1IN&BIT1)); //等电平变为高电平while(P1IN&BIT1) //计算高电平持续时间{count++;if(count>8000)return;//如果高电平持续时间过长则推出中断程序}if(j>16) //一体化红外接收头一接收遥控器信号,就会输出32位的脉冲序列波,其中后16位{ //决定遥控器的按键地址,16位由8位数据码和数据反码组成,我们需要将其解码//time[j-17]=count; //将记得的高电平持续时间放入时间数组中if(j==25)k++; //到数据反码的起始位的时候,我让receive数组元素下标+1receive[k]<<=1; //接收数据码左移一位,比如:xxxx xxxx 左移一位后xxxx xxx0if(count>80)receive[k]|=0x01;//高电平持续时间超过80,则将左移一位后的最低位变1,} //结果变为,xxxx xxx1,如果没超过80则保持不变,xxxx xxx0 j++;if(j>32){j=0;k=0; //解码结束,j,k值清零delay_ms(150);}}。
基于MSP430红外遥控小车的设计与开发(开发文档,源代码,电路图)

方案二:采用 L298N 芯片驱动电机,只需通过单片机产生 PWM 波即可驱动电 机,而且可以同时驱动两个直流电机同时工作,最大输入电压可达 50V,驱动能 力较大。并且可以通过四个输入端口对电机的正反转进行控制,符合遥控小车的 要求,选用方案二。
3.5 显示模块方案选择:
2.6.3 外形尺寸图:
2.7 基本方案论证:
本设计以单片机 MSP430F149 为控制核心,电路主要分为红外发送电路和 红外接收控制电路,红外发送电路包括方向按键电路和红外管发射电路;接收及 控制电路包括红外接收电路,lcd 显示电路,电机驱动电路和计程模块。PC838 一体化红外接收头接收遥控器发射的红外型号,并传送给单片机,单片机根据已 定的协议对车体运行进行控制,并通过计程模块对小车行使的路程进行实时的采 集,通过 LCD 显示。
3.6 计程模块方案选择:
方案一:采用 ST151 计程,ST151 由发光管和光敏元件构成,发光管发 光可导通光敏元件,输出端口输出高电平。在发光管和光敏元件间加一挡板,阻 止光敏元件导通,输出端输出低电平。可以在车轮侧面加挡板,通过 ST151 进
行测距离。 方案二:采用 ON2171 计程,ON2171 原理与 ST151 相同,但其体积小,
3.7.3 红外接收模块 红外接收模块采用一体化红外接收头 PC838,用 3.3V 供电,在电源和地
之间加 104 的滤波电容,消除电源波纹对接受效果的影响。其输出引脚直接接 单片机的 P13 口。电路图如下:
3.7.4 LCD 显示模块 LCD 显示模块用来显示小车的运行状态和行程,Nokia5110lcd 显示屏体
考虑到遥控小车在实际运行中要的灵活性和快速性的要求,最终选择方案二。
基于MSP430实现的红外传输系统

//将寄存器的内容清零
U1TCTL = 0X00;
//波特率发生器选择SMCLK
U1TCTL += SSEL1;
//波特率为57600
UBR0_1 = 0X8B;
UBR1_1 = 0X00;
//调整寄存器
UMCTL_1 = 0X00;
// 初始化时钟
Init_CLK();
// 初始化端口
Init_Port();
// 初始化串口1
Init_UART1();
// 打开中断
_EINT();
// 先发送数据
UART1_TX_BUF[0] = 'O';
UART1_TX_BUF[1] = 'K';
void main(void)
{
int nRes_UART1;
int nRes = 0;
char UART1_RX_Temp[60];
int i;
// 关闭看门狗
WDTCTL = WDTPW + WDTHOLD;
// 关闭中断
_DINT();
//将所有的管脚设置为一般I/O口
P3SEL = 0;
return;
}
void Init_CLK(void)
{
unsigned int i;
//将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1
nSend_TX1 += 1;
if(nSend_TX1 >= nTX1_Len)
{
nSend_TX1 = 0;
msp430红外解码

#include <msp430x14x.h>#define uchar unsigned char#define uint unsigned intuint count=0;uchar value = 0;uint ifclr = 0;long LastTime;/*********发送的码都是高位在后,低位在前********/long preamble_code; //引导码长int address_code[16]; //地址码,先是低位地址码,再是高位地址码int data_code[16]; //数据码,先是8位数据,再是8位数据反码uchar infrared_address_high = 0;uchar infrared_address_low = 0;uchar infrared_data = 0;uchar infrared_back_data = 0;/*******************************************函数名称:Delay_1ms功能:延时约1ms的时间参数:无返回值:无********************************************/void Delay_1s(){long a,i;for(a=200;a>0;a--){for(i = 10000;i > 0;i--) _NOP();}}/*******************************************函数名称:Infrared_decoding()功能:红外解码参数:无返回值:无********************************************/void Infrared_decoding(){uint count1;if(count>32){_DINT();count = 0;value = 0;ifclr = 0;if(preamble_code>13000 && preamble_code<14000){for(count1=0;count1<8;count1++){infrared_address_low = infrared_address_low>>1;if(address_code[count1]<2500 && address_code[count1]>1500) infrared_address_low |= 0x80;elseinfrared_address_low |= 0x00;}for(count1=8;count1<16;count1++){infrared_address_high = infrared_address_high>>1;if(address_code[count1]<2500 && address_code[count1]>1500) infrared_address_high |= 0x80;elseinfrared_address_high |= 0x00;}for(count1=0;count1<8;count1++){infrared_data = infrared_data>>1;if(data_code[count1]<2500 && data_code[count1]>1500){infrared_data |= 0x80;}elseinfrared_data |= 0x00;}for(count1=8;count1<16;count1++){infrared_back_data = infrared_back_data>>1;if(data_code[count1]<2500 && data_code[count1]>1500)infrared_back_data |= 0x80;elseinfrared_back_data |= 0x00;}}/* P1OUT = infrared_address_low; //实验测得为0x00Delay_1s();P1OUT = infrared_address_high; //实验测得为0xffDelay_1s();P1OUT = infrared_data;/**************************************************************** 实验测得为01 2 3 ** 4 5 6 ** 7 8 9 **OXA2 0X62 0XE2 0X22 0X02 0XC2 0XE0 0XA8 0X9010 11 12 ** 13 14 15 ** 16 17 18 **OX68 0X98 0XB0 0X30 0X18 0X7A0X10 0X31 0X5A19 20 210X42 0X4A0X52******************************************************************/ Delay_1s();P1OUT = infrared_back_data; //实验测得为0xff*//* if((infrared_data & infrared_back_data)==0X00)P1OUT = 0X00;else P1OUT = 0XFF;*/P1OUT = infrared_data;_EINT();}}/*******************************************函数名称:init_clk()功能:时钟初始化参数:无返回值:无********************************************/void init_clk(){uchar i;BCSCTL1&=~XT2OFF; //打开XT振荡器do{IFG1 &= ~OFIFG; //清除振荡错误标志for(i = 0; i < 100; i++)_NOP(); //延时等待}while ((IFG1 & OFIFG) != 0); //如果标志为1继续循环等待BCSCTL2 |= SELM_2 + SELS + DIVS_3; //MCLK SMCLK 选择外部高频时钟}/***********************主函数*************************************/int main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;/*下面六行程序关闭所有的IO口*/P1DIR = 0XFF;P1OUT = 0XFF;P2DIR = 0XFF;P2OUT = 0XFF;P3DIR = 0XFF;P3OUT = 0XFF;P4DIR = 0XFF;P4OUT = 0XFF;P5DIR = 0XFF;P5OUT = 0XFF;P6DIR = 0XFF;P6OUT = 0XFF;init_clk();P4DIR&=~BIT0;P4SEL|=BIT0;TBCCTL0 |= CM_2 + CCIS_0 + SCS + CAP + CCIE; //设置捕获模式,下降沿捕获,同步,开中断TBCTL |= TBSSEL_2 + MC_2 + TBCLR; //选择SMCLK 连续计数模式1us 1MHZ//TBCLR 清零_EINT();while(1){Infrared_decoding();}// LPM1;}/**********************捕获中断函数******************************/#pragma vector=TIMERB0_VECTOR__interrupt void TIMERB0(){if(ifclr==0){TBCTL |= TBCLR;ifclr=1;}else if(ifclr==1){LastTime = TBCCR0;TBCTL |= TBCLR;if(count==0){preamble_code = LastTime;}else if(count>=1 && count<=16){address_code[count-1] = LastTime;}else if(count>16 && count<=32){data_code[count-17] = LastTime;}if(preamble_code>13000 && preamble_code<14000) count++;}}。
基于MSP430F149为主芯片下的红外线解码资料源程序

头文件<InfraredRX.h>/***MODU+********************************************************************/ /* Copyright (c) 2009.04 WH, All Rights Reserved. *//* FileName : DS18B20.h *//* Description : The Led define *//* History : *//* [Author] [Date] [Version] [Description] *//* [1] dragonhzw 2009/04/09 Ver 1.0.0 Initial file. *//***MODU-********************************************************************/ #ifndef __MSP430_TEST_INFRAREDRX_H__#define __MSP430_TEST_INFRAREDRX_H__//--------------------------------------------------------------------------------//6种接收状态#define IR_Idle 0//空闲#define IR_WaitStart 1//接收引导代码#define IR_GetAddress 2//接收地址#define IR_GetAddressInv 3//接收地址反码#define IR_GetData 4//接收数据#define IR_GetDataInv 5//接收数据反码#define ms_168 0x0690#define ms_9 0x2328#define ms_125 0x30D4#define ms_15 0x3A98//--------------------------------------------------------------------------------void delay_ms(unsigned long ms);#endif/* __MSP430_TEST_INFRAREDRX_H__ */InfraredRX.c//***************************************************************************** *// MSP430P149 Demo - InfraredRX, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK//// Description: Echo a received character, RX ISR used. Normal mode is LPM3,// USART1 RX interrupt triggers TX Echo.// ACLK = UCLK1 = LFXT1 = 32768, MCLK = SMCLK = DCO~ 800k// Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 3.41 (0003h 4Ah )// //* An external watch crystal is required on XIN XOUT for ACLK *//////// MSP430F149// -----------------// /|\| XIN|-// | | | 32kHz// --|RST XOUT|-// | |// | |// | P2.7 |<----INR_RXD// | |//// Copyright (c) 2009.04 WH, All Rights Reserved.// WebSite:// Description : The InfraredRX module// History :// [Author] [Date] [Version] [Description]// [1] dragonhzw 2009/04/09 Ver 1.0.0 Initial file.//// Built with IAR Assembler for MSP430V3.20A/W32 (3.20.1.9)//***************************************************************************** *#include <msp430x14x.h>#include "InfraredRX.h"//-------------------------------------------------------------------------------unsigned char dis_code[18] = {0x3f,0x06,0x5b,0x4f,0x66, //段码表// 0 1 2 3 4 对应内容0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5e,0x79,0x71,0xff};// 5 6 7 8 9 A B C D E Funsigned char dis_0 = 0; // 个位值unsigned char dis_1 = 0; // 十位值unsigned char dis_2 = 0; // 百位值unsigned char dis_3 = 0; // 千位值unsigned char IR_State=IR_Idle;//接收状态变量,初值为空闲unsigned char IR_Ready=0;//数据接收完标志unsigned char IR_Repeat=0;//连发标志unsigned char IR_Data[4]={0,0,0,0};//接收到的4字节数据unsigned char Tmp;unsigned char IRtimer=0;//--------------------------------------------------------------------------------/***FUNC+*********************************************************************/ /* Name : Port2INT */ /* Descrp : 端口1中断处理程序*/ /* Input : num. */ /* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ #pragma vector=PORT2_VECTOR__interrupt void Port2INT(void){unsigned int Count;//红外线接收头中断if(P2IFG&BIT7){Count= TAR;//读取计数值TACTL|=MC0+TACLR;//定时器B重新开始计数switch(IR_State){case IR_Idle:{IR_State = IR_WaitStart;IRtimer = 11;break;}case IR_WaitStart:{if((Count>ms_125)&&(Count<ms_15)){//接收到引导码IR_Data[0]=0;IR_Data[1]=0;IR_Data[2]=0;IR_Data[3]=0;Tmp=1;IR_Repeat=0;IR_State=IR_GetAddress;}else if((Count>ms_9)&&(Count<ms_125)){//接收连发代码IR_Repeat=1;IR_State=IR_Idle;}else{IR_State=IR_Idle;}break;}case IR_GetAddress:{if(Count>ms_168){//接收到1IR_Data[0]|=Tmp;}Tmp<<=1;if(!Tmp){IR_State=IR_GetAddressInv;Tmp=1;}break;}case IR_GetAddressInv:{if(Count>ms_168){//接收到1IR_Data[1]|=Tmp;}Tmp<<=1;if(!Tmp){IR_State=IR_GetData;Tmp=1;}break;}case IR_GetData:{if(Count>ms_168){//接收到1IR_Data[2]|=Tmp;}Tmp<<=1;if(!Tmp){IR_State=IR_GetDataInv;Tmp=1;}break;}case IR_GetDataInv:{if(Count>ms_168){//接收到1IR_Data[3]|=Tmp;}Tmp<<=1;if(!Tmp){if(((IR_Data[0]^IR_Data[1])==0xFF)&&((IR_Data[2]^IR_Data[3])==0xFF))IR_Ready=1;//校验数据IR_State=IR_Idle;}break;}default:{IR_State=IR_Idle;break;}}}P2IFG=0x00;//清除中断标志位}/***FUNC+*********************************************************************/ /* Name : InitTimerA */ /* Descrp : 定时器A初始化*/ /* Input : num. */ /* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ void InitTimerA(void){TACTL=TASSEL1+ID1+ID0+MC0+TACLR;//选择1/8SMCLK 增计数清除TARTACCR0=65535;//时间间隔10ms}/***FUNC+*********************************************************************/ /* Name : InitTimerB *//* Descrp : 定时器B初始化*/ /* Input : num. */ /* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ void InitTimerB(void){TBCTL=TBSSEL1+ID1+ID0+MC0+TBCLR;//选择1/8SMCLK 增计数清除TBRTBCCTL0=CCIE;//CCR0中断允许比较模式TBCCR0=10000;//时间间隔10ms}/***FUNC+*********************************************************************/ /* Name : TimerBINT */ /* Descrp : 定时器B中断*/ /* Input : num. */ /* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ #pragma vector=TIMERB0_VECTOR__interrupt void TimerBINT(void){if(IRtimer){IRtimer--;}else{IR_State = IR_Idle;//解码超时}}/***FUNC+*********************************************************************/ /* Name : Init_CLK */ /* Descrp : Set PLL Clock. *//* Input : None. *//* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ void Init_CLK(void){int index;BCSCTL1&=~0X00; //打开XT2振荡器do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (index = 0xFF; index > 0; index--)// 延时,等待XT2起振{;}} while ((IFG1 & OFIFG) != 0);// 判断XT2是否起振BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2}/******* 红外遥控器键值表******45 46 4744 40 4307 15 0916 19 0d0c 18 5e08 1c 5a42 52 4a**********************************//***FUNC+*********************************************************************/ /* Name : main */ /* Descrp : 主程序*//* Input : num. *//* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ void main( void ){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗Init_CLK();//时钟初始化//Init_UART1();InitTimerA();//定时器A初始化InitTimerB();//定时器B初始化/****************************************************************************/ /* 1、初始化数码管引脚*//****************************************************************************/ // 将P4设置为I/O口P4SEL = 0x00;// 将P4设置为输出方向P4DIR = 0xFF;// 将P4口输出全高P4OUT = 0xFF;// 将P3设置为I/O口P3SEL = 0x00;// 将P3设置为输出方向P3DIR |= 0x0F;P3OUT = 0x0F;/****************************************************************************/ /* 2、初始化红外线接收引脚*//****************************************************************************/P2DIR&=~BIT7;//P2.7设置为输入方向P2IES|=BIT7;//P2.7下降沿触发中断P2IE|=BIT7;//P2.7中断允许_EINT();//打开中断while(1){if(IR_Ready==1){ //计算要显示的每位数字while(1){ //计算要显示的每位数字IR_Ready=0;dis_0 = (IR_Data[2]&0xF0)>>4;//数码管后2位显示数据P4OUT = dis_code[dis_0];P3OUT &= ~BIT1; // 开第一个显示(P2.2口控制个位数码管)delay_ms(5);P3OUT |= BIT1; // 关第一个显示(P2.2口控制个位数码管)dis_1 = (IR_Data[2]&0x0F);P4OUT = dis_code[dis_1];P3OUT &= ~BIT2; // 开第一个显示(P2.2口控制个位数码管)delay_ms(5);P3OUT |= BIT2; // 关第一个显示(P2.2口控制个位数码管)P4OUT =0x76;//'H'P3OUT &= ~BIT3; // 开第一个显示(P2.2口控制个位数码管)delay_ms(5);P3OUT |= BIT3; // 关第一个显示(P2.2口控制个位数码管) }}}}/***FUNC+*********************************************************************/ /* Name : delay_ms */ /* Descrp : delay time *//* Input : num. */ /* Output : None. *//* Return : None. *//***FUNC-*********************************************************************/ void delay_ms(unsigned long ms) // 延时毫秒@12M,ms最大值255{unsigned char i;while(ms--)for(i = 0; i < 124; i++);}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<msp430x14x.h>
//*************************************************
//***********基于MSP430的红外遥控器解码程序
//***********利用I/O口的中断功能结合定时间器,捕捉周期时间确定数值//***********每16位编码表示一个按键
//***********只检测了1-6号键盘,其他的按照同样方式进行解码,相信你能做得到
//***********注意起始条件的判断
int count=0;//接受脉冲计数,16个信号
int overflow=0;//定时器A溢出次数计数
int biao=0;//起始标志位
unsigned int ki;//键值
unsigned int temp2=0;//定时器计数值
int
d[33]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0};//脉冲时间保存
void Init_System(void)
{
Init_CLK();
Init_TimerA();
P2IE|=BIT3;
P2IES|=BIT3;
}
void Init_TimerA(void)
{
TACTL=TACLR+TASSEL1+ID1; //时钟源=ACLK,8分频,清TAR
TACCTL0=CCIE; //CCR0中断允许
TACCR0=60000; //定时125ms
TACTL|=MC0; //开始计数,增计数模式
}
//***************系统时钟设置****************//
// 主时钟
MCLK=SMCLK=4M //
// 辅助时钟
ACLK=32768 //
//*******************************************//
void Init_CLK(void)
{
unsigned int i;
BCSCTL1&=~(XT2OFF+XTS);
// XT2on,ACLK为32768
//BCSCTL1&=~(XTS);
BCSCTL2 |=
SELM1+SELS; // MCLK = SMCLK = XT2
do
{
IFG1 &=
~OFIFG; // Clear OSCFault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) != 0); // fail?
}
////============主函数==============////
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
Init_System(); //系统初始化
_EINT(); //开总中断
while(1); //等待中断
}
////===============定时中断=============////
#pragma vector=TIMERA0_VECTOR
__interrupt void Lamp_Drive(void)
{
overflow++;
}
#pragma vector=PORT2_VECTOR
__interrupt void yaokong(void)
{
int i;
unsigned int temp1;
temp1=TAR;
P1OUT|=Light1;
P2IFG=0x00;
P2IE&=~BIT3;
_EINT();
for(i=0;i<=50;i++);//调试的过程中发现一干扰信号,此延时用来屏蔽干扰 if ((P2IN&BIT3)!=0x00)
{
P2IFG=0x00;
P2IE|=BIT3;
P1OUT&=~Light1;
return;
}
if(biao==0)
{
for(i=0;i<1000;i++)//起始位,注意起始位的判断
{
if((P2IN&BIT3)!=0x00)
break;
}
if(i==1000)
{
biao=1;
count=0;
overflow=0;
}
}
else
{
if(count<=16)
{
if(overflow==0)
{
d[count]=temp1-temp2;
}
else
{
d[count]=temp1+60000-temp2;
overflow=0; //时间保存数组D[j]
}
if(count==16)
{
unsigned int tempui;
ki=0;
tempui=1;
for(i=1;i<=16;i++)
{
if(d[i]>=1500)
ki |= tempui;
tempui=tempui<<1;//计数大于1500则表示数据位1 }
biao=0;
if
(ki==0x2102||ki==0x2302||ki==0x2502||ki==0x2702||ki==0x2902||ki==0x2B 02)
{ if(ki==0x2102)
ki=1;
if(ki==0x2302)
ki=2;
if(ki==0x2502)
ki=3;
if(ki==0x2702)
ki=4;
if(ki==0x2902)
ki=5;
if(ki==0x2B02)
ki=6;
Concentr=(unsigned int)ki;
Disp_Current(Concentr,Temp);
}
}
}
count++;
}
temp2=temp1;
P2IFG=0x00;
P2IE|=BIT3;
//P1OUT&=~Light1;
}
//需要说明的是,由于其是一个整体程序的一部分,我把译码部分整理到这里,里面对子函数的定义很不规范(没有声明),呵呵,大家不要学~
//一定要严谨。