基于MSP430的红外遥控解码程序
#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;
}
//需要说明的是,由于其是一个整体程序的一部分,我把译码部分整理到这里,里面对子函数的定义很不规范(没有声明),呵呵,大家不要学~
//一定要严谨。
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++);}。
msp430单片机红外遥控小车设计程序_1
/*************************************************************************原理:根据高电平持续时间判断信号传输的是0还是1进行解码方法:采用定时器这里用width=end-start,width的长度来判断解码信号为1还是0 功能:按一个键,单片机数码管上显示按键的用户码、数据码和数据反码**************************************************************************/#include <msp430f5438a.h>#include "PIN_DEF.H"#define uchar unsigned char#define uint unsigned intuint start = 0,end = 0; //计数开始和结束标志uint width = 0; //用于存放脉宽uint en = 0,n = 0; // en用于保存是否有引导码进入,n表示保存信号的数组IR[]下标uchar IR[32]; //先用数组将接收到的数据保存起来uchar IR_buf[4]={0x00,0x00,0x00,0x00};//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区// IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区uchar disp_buf[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //显示缓冲单元,初值为0x00,指向显示码的8个"0"uchar seg_data[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//0~F和"-"符的显示码(字形码)/* 50us的延迟函数*/void delay_50us(unsigned int t){unsigned int j;for(;t>0;t--)for(j=10;j>0;j--);}/********以下是显示函数********/void Display(){P8DIR = 0XFF; //段选方向打开P8OUT = seg_data[disp_buf[0]]; //用户码低P9DIR = 0x01; //选位P9OUT = ~0x01; //数码管第一位输出delay_50us(1); //延迟50usP8OUT = seg_data[disp_buf[1]]; //用户码低P9DIR = 0x02;P9OUT = ~0x02;delay_50us(1);P8OUT = seg_data[disp_buf[2]]; //用户码高P9DIR = 0x04;P9OUT = ~0x04;delay_50us(1);P8OUT = seg_data[disp_buf[3]]; //用户码高P9DIR = 0x08;P9OUT = ~0x08;delay_50us(1);P9DIR = 0x00;P8OUT = seg_data[disp_buf[4]]; //数据码P1DIR = 0x10;P1OUT = ~0x10;delay_50us(1);P8OUT = seg_data[disp_buf[5]]; //数据码P1DIR = 0x20;P1OUT = ~0x20;delay_50us(1);P8OUT = seg_data[disp_buf[6]]; //数据反码P1DIR = 0x40;P1OUT = ~0x40;delay_50us(1);P8OUT = seg_data[disp_buf[7]]; //数据反码P1DIR = 0x80;P1OUT = ~0x80;delay_50us(1);P1DIR = 0x00;}//***************************************************************************// // // // Init_Port(void): 设置IO端口//// // //***************************************************************************// void Init_Port(void){P5DIR |= POWER ; // 主电源MAIN_POWER_ON ;}//***************************************************************************//// // //函数:Init_CLK(void) ////功能:初始化主时钟: MCLK = XT2=16MHZ // // // //***************************************************************************// void Init_CLK(void){P5SEL |= 0x0c; //选择内部16MHZ晶振,将引脚作为第二功能使用P5DIR |= 0x0c;UCSCTL6 &= ~XT2OFF; //EN XT2//因为XT1未开启,所以给默认为XT1的时钟重新选择时钟来源UCSCTL4 |= SELA_1; //先将ACLK配置为VLOCLKUCSCTL3 |= SELREF_2; //将FLLREFCLK配置为REFCLKwhile (SFRIFG1 & OFIFG){UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // 清除时钟标志位SFRIFG1 &= ~OFIFG; // 清除时钟错误标志位}UCSCTL4 |=SELS_5; //将SMCLK时钟源配置为XT2}//***************************************************************************// // // // Init_IRUART(void): 设置红外端口//// // //***************************************************************************// void Init_IRUART(void){P1SEL |= (0x01<<2); //捕获的输入引脚P1.2P1DIR &= ~(0x01<<2);}/********以下是解码函数********/void Decode(void){if(width > 8600) //如果高电平时间大于4.3ms,则判断为引导码并将解码标志en置为1{en = 1;n = 0;}if(en == 1) //判断是否执行解码操作{if(width >=1700&&width <=4000) //当高电平时间>=0.85ms,<=2ms时判断为1 {IR[n] = 1;n++;width = 0;}if(width > 600&&width<1700) //当高电平时间<0.85ms,>0.3ms时判断为0{IR[n] = 0;n++;width = 0;}if(n >= 32) //当数组存满32位时,n清零,en使能标志位清零{en = 0;n = 0;}}}/*将IR[]里的值八位一组分开并转换到IR_buf[]里面,并将IR_buf的值转换成数码管显示的缓存*/void Process(void){if(n == 0){ //如果n == 0将IR[]的值转存到IR_buf[]里IR_buf[0]=IR[8*0]*128+IR[8*0+1]*64+IR[8*0+2]*32+IR[8*0+3]*16+IR[8*0+4]*8+IR[8*0+5]*4+IR[ 8*0+6]*2+IR[8*0+7];IR_buf[1]=IR[8*1]*128+IR[8*1+1]*64+IR[8*1+2]*32+IR[8*1+3]*16+IR[8*1+4]*8+IR[8*1+5]*4+IR[ 8*1+6]*2+IR[8*1+7];IR_buf[2]=IR[8*2]*128+IR[8*2+1]*64+IR[8*2+2]*32+IR[8*2+3]*16+IR[8*2+4]*8+IR[8*2+5]*4+IR[ 8*2+6]*2+IR[8*2+7];IR_buf[3]=IR[8*3]*128+IR[8*3+1]*64+IR[8*3+2]*32+IR[8*3+3]*16+IR[8*3+4]*8+IR[8*3+5]*4+IR[ 8*3+6]*2+IR[8*3+7];//if(IR_buf[2] == ~IR_buf[3]) //校验{disp_buf[0]=IR_buf[0]>>4; //取键码的低四位送显示缓冲disp_buf[1]=IR_buf[0]&0x0f; //右移4次,高四位变为低四位送显示缓冲disp_buf[2]=IR_buf[1]>>4;disp_buf[3]=IR_buf[1]&0x0f;disp_buf[4]=IR_buf[2]>>4;disp_buf[5]=IR_buf[2]&0x0f;disp_buf[6]=IR_buf[3]>>4;disp_buf[7]=IR_buf[3]&0x0f;}}}/********以下是主函数********/void main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗Init_Port(); // 电源初始化Init_IRUART(); //红外端口初始化Init_CLK() ; //初始化时钟TA0CTL = TASSEL_2+ID_3+TACLR+TAIE+MC_1; //定时器A时钟信号选择SMCLK,8分频,//同时设置定时器A计数模式为增计模式TA0CCTL1 = CM0+SCS+CAP+CCIE; //输入上升沿捕获,CCI0A为捕获信号源TA0CCR0 = 20000; //设置计数器溢出时间为10ms_EINT() ; //开启全局中断while(1){Process(); //将IR[]数组缓存转换为数码管显示缓存函数Display(); //数码管显示函数}}#pragma vector=TIMER0_A1_VECTOR //定时器A中断处理__interrupt void Timer0_A1(void){switch(TA0IV) //向量查询{ case 2: //捕获中断if(TA0CCTL1&CM0) //捕获到上升沿{TA0CCTL1=(TA0CCTL1&(~CM0))|CM1; //更变设置为下降沿触发start=TA0R; //记录初始时间}else if (TA0CCTL1&CM1) //捕获到下降沿{TA0CCTL1=(TA0CCTL1&(~CM1))|CM0; //==更变设置为上升沿触发end=TA0R; //用start,end,overflow计算脉冲宽度if(end>start)width = end - start; //实际高电平宽度Decode(); //解码end = 0;start = 0;TA0R=0;}break;default:break;}}。
基于MSP430单片机的学习型遥控器设计
基于MSP430单片机的学习型遥控器设计MSP430单片机是德州仪器(TI)推出的一种低功耗、高性能的微控制器系列。
它在嵌入式系统中应用广泛,具有低功耗、高集成度、高性能和易于使用的特点。
在本文中,我将介绍基于MSP430单片机的学习型遥控器设计。
学习型遥控器是一种可以学习其他遥控器信号的设备,可以用来控制各种电器、设备和机器。
它通常包含一个红外发射器和一个红外接收器,可以通过学习其他遥控器的红外信号来实现对其他设备的控制。
首先,我们需要选择适合的硬件平台。
MSP430单片机系列中有许多型号可供选择,我们可以根据具体要求选择合适的型号。
同时,我们还需要一些外围设备,如红外发射器、红外接收器、按键和显示屏等。
接下来,我们需要进行硬件设计。
首先,我们需要将MSP430单片机与外围设备进行连接。
MSP430单片机具有多个通用输入输出引脚,我们可以使用这些引脚来连接外围设备。
例如,我们可以将红外接收器的输出引脚连接到MSP430单片机的一个输入引脚,以接收红外信号;同时,我们可以将红外发射器的输入引脚连接到MSP430单片机的一个输出引脚,以发送红外信号。
在硬件设计完成后,我们需要进行软件编程。
MSP430单片机通常使用C语言进行编程,我们可以使用MSP430单片机的软件开发工具包(MSP430SDK)进行软件开发。
首先,我们需要编写程序来接收和解码红外信号。
MSP430单片机提供了一些硬件辅助模块,如计时器和比较器,可以用来实现红外信号的接收和解码。
我们可以使用MSP430SDK提供的相关函数和库来简化这些操作。
然后,我们需要编写程序来发送红外信号。
MSP430单片机的输出引脚可以通过改变电平来发送红外信号,我们可以使用MSP430SDK提供的相关函数和库来控制输出引脚的电平。
最后,我们需要编写程序来控制其他设备。
我们可以使用MSP430单片机的输入引脚来读取按键的状态,然后根据按键的状态来发送相应的红外信号。
