/********************************************
文件名称:main.c
文件功能:主函数
*********************************************************/
#include \"msp430g2553.h\"
#include \"LCD12864.h\"
#include\"delay.h\"
uint minute,hour,time,one,ten;
uchar Ir_time=0; //定义一个(红外)时间
uchar start_flag; //启动接收的意思
uchar Ir_date[33]; //4*8+1=33,一个引导码*1,两个客户码*8,一个数据码*8,一个数据反码*8.
uchar bitnum;
uchar Ir_receok; //红外接收完毕
uchar Ir_code[4];
uchar Ir_prosok;
uchar disp[8]; //装载分解数据后的8个元素的数组
/**************************************************
函数名称:display(uchar row,uchar line,uchar dat)
函数功能:时钟显示位置函数
输入参数:row 列、line行、dat输入参数
输出参数:无
**************************************************/
void display(uchar row,uchar line,uchar dat)
{
uchar dec,unit;
dec=dat/10;
unit=dat%10;
LCD_P8x16Ch(row,line,dec);
LCD_P8x16Ch(row+8,line,unit);
}
/**************************************************
函数名称:Timer0_A0_init()
函数功能:定时器初始化
输入参数:无
输出参数:无
**************************************************/
void Timer0_A0_init()
{
LCD_Init();//液晶初始化
LCD_Fill(0x00);//液晶灭屛
delay(10);
DCOCTL=0;//
BCSCTL1=CALBC1_16MHZ;//设置时钟源SMCLK为1MHZ
DCOCTL=CALDCO_16MHZ;//设置时钟源SMCLK为1MHZ
CCTL0=CCIE; //使能 CCR0 中断
CCR0=4095;//设定周期为1s
TACTL=TASSEL_2+MC_1;//定时器 A 的时钟源选择ACLK,八分频,增计数模式
LCD_P8x16Str(30,4,\"00:00:00\");
}
/**************************************************
函数名称:External_interrupt()
函数功能:外部中断初始化
输入参数:无
输出参数:无
**************************************************/
void External_interrupt()
{
// P1DIR&=~BIT7; //设置P1.3为输入
P1REN|=BIT7;//设计上拉
P1OUT|=BIT7; //这一句得加
P1IE|=BIT7;//设计中断口
P1IES|=BIT7;//设计下降沿有效
P1IFG&=~BIT7;//清除中断标志
//P1OUT&=~ BIT7; //取反
}
/******************************* 数据提取处理函数 *********************************/
void Irpros() //发送的是16进制数,4组数据,需要一个4个元素的数组ircode[4]来储存
{ //比如发送的是0x1C,那应该拆成两字节1和C来显示,4组数据拆成8个,即有数据分解函数
uchar k,i,j;
uchar value;
k=1; //第一个是引导码得时间,不要,所以k初值不为0,irdate[0]不管了
for(j=0;j<4;j++) //4个码
{
for(i=0;i<8;i++) //8位一字节
{ //7,value初值为0,因为是先发低位再发高位,所以右移把低位放回右边
if(Ir_date[k]>7) //8,一个irdate元素值对应着一个时间值,irdate[k]>6即弟k个元素时间值
{ //远大于1.125ms,即证明收到的是 1 ,6是个中间数。
value=value|0x80; //将高位置为 1
}
else
{
value=value;
}
if(i<8)
{
value=value>>1;
}
k++; //每次都要判断下一次
}
Ir_code[j]=value; //将一字节的数据保存起来
value=0;
}
Ir_prosok=1; //单纯一个信号,可以理解为已经提取处理完一帧数据
}
/*0为1.125ms,1.125/0.256=4.4,即irtime=4.4收到的就是0*/
/*1为2.25ms,2.25/0.256=8.8,即irtime=8.8收到的就是1*/
/*可以取个6,即irtime>6为电平1,irtime<6为电平0*/
/**************************************************
函数名称:main()
函数功能:主函数
输入参数:无
输出参数:无
**************************************************/
void main()
{
WDTCTL = WDTPW + WDTHOLD;//关闭看门狗
External_interrupt();
Timer0_A0_init();
_EINT();//打开总中断
while(1)
{
if(Ir_receok)//如果红外接收一帧数据完毕
{
Irpros();//启动数据提取处理函数
Ir_receok=0;//清零
}
if(Ir_code[2]==7) //即数字1
{
LCD_P8x16Ch(30,0,1);
}
else if(Ir_code[2]==75) //及关机键
{
P1DIR|=BIT0;
P1OUT|=BIT0;
}
if(Ir_prosok)//如果处理一帧数据完毕
{
Ir_prosok=0;//清零
}
}
}
/**************************************************
函数名称:__interrupt void port1()
函数功能:外部中断服务函数
输入参数:无
输出参数:无
**************************************************/
#pragma vector=PORT1_VECTOR//中断
__interrupt void port1()
{
P1IFG&=~BIT7;//清除中断标志
LCD_P8x16Ch(30,0,1);
if(start_flag) //启动接收的意思
{
if(Ir_time>32) //检测引导码(9ms需要几个irtime,9/0.256=33)
{ //0.256ms*n=9ms ==== n=9/0.256
bitnum=0;
}
Ir_date[bitnum]=Ir_time;/*触发外部中断后,将自增的irtime(次数,12M晶振是1us自增一次)
赋值给irdate数组的第bitnum个元素,其实就是将两个下降沿之间的自增次数
记载在数组中,一帧数据有33个下降沿,这里记载的次数以后要用来转换成具体时间*/
Ir_time=0; //清零
bitnum++;
if(bitnum==33) //一帧数据已送完
{
bitnum=0;
Ir_receok=1; //单纯一个信号,可以理解为已经接收完一帧数据
}
}
else
{
start_flag=1;
Ir_time=0;
}
P1DIR|=BIT6;
P1OUT|=BIT6;
}
/**************************************************
函数名称:__interrupt void Timer_A (void)
函数功能:定时器A中断服务函数
输入参数:无
输出参数:无
**************************************************/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A ()
{
Ir_time++;
display(78,4,Ir_time);
}
这是我红外遥控的程序,但有那么一个问题,就是当我设计定时器时间低于1MS时,外部中断就无法触发,如果超过1MS,外部中断是触发了,但是,要接收33个下降沿的红外接收头,时间已经超出范围了,请大家帮忙看一下
本文来自论坛,点击查看完整帖子内容。