#include "SPCE061A.H"
#define LED_SEG 0x00ff //IOB0~IOB7
#define LED_DIG 0x3f00 //IOB8~IOB13
unsigned int Time=0,Code[40]={0},CodeNum=0//计数器,32位码,码字计数
//extern unsigned int Time,CodeNum,Code[40]
unsigned int Star_Flag,First_IRQ
//====================================================================================
//函数名称:unsigned getkey(void)
//函数功能:获得红外遥控器键值
//入口参数:无
//出口参数:无
//说明:适用于32位码字红外接收头及宏科万能遥控器
//====================================================================================
unsigned getkey(void)
{
unsigned int j=0
unsigned int DateCode,key=0
if(Code[0]==5) //判断头部是否是5;防止误接收
{ for(j=9j<=14j++)
{
*P_Watchdog_Clear = 0x01
if(Code[j]==1&&Code[j+1]==1&&Code[j+2]==1&&Code[j+3]==1&&Code[j+4]==1&&Code[j+5]==1&&Code[j+6]==0&&Code[j+7]==1)
{ //判断用户识别码是不是1111 1101
for(DateCode=0DateCode<8DateCode++)//若是,则开始接收八位数据码
{
Code[j+8+DateCode]<<=8
key|=Code[j+8+DateCode]
key>>=1 //将八位二进制数倒序转成16进制
}
break
}
}
Code[0]=0//将头部清零
return key//返回键值
}
else return(0)
}
//====================================================================
//函数名称:void IO_Init()
//函数功能:IO口初始化,主要是设置IOB2口,用于外中断
//入口参数:无
//出口参数:无
//====================================================================
void IO_Init()
{
*P_IOB_Attrib&=0xfffb //IOB2端口上拉电阻输入 外中断
*P_IOB_Dir&=0xfffb
*P_TimerA_Ctrl=C_SourceA_32768Hz+C_SourceB_1//TimerA:32768Hz
*P_TimerA_Data=0xfffe
*P_INT_Ctrl=C_IRQ3_EXT1|C_IRQ1_TMA// 外中断1,时基中断,定时中断
__asm("INT IRQ")
}
//做档=====================================================================
//函数并厅名称:
//函数功能绝胡隐:中断函数
//入口参数:无
//出口参数:无
//=====================================================================
void IRQ3(void) __attribute__ ((ISR))
void IRQ3(void)
{
if(*P_INT_Ctrl&C_IRQ3_EXT2)
{ //IRQ3_Ext1
*P_INT_Clear=C_IRQ3_EXT2
}
else if(*P_INT_Ctrl&C_IRQ3_EXT1)
{//外中断1用于判断脉冲个数
if(!First_IRQ) {Time=0First_IRQ=1}//第一次外中断来时设置
else
{
if(Time>180&&Time<240)//判断起始码
{Star_Flag=1CodeNum=0Code[0]=5CodeNum=1Time=0}//起始码来时设置
if(Star_Flag)//开始接收
{
if((Time>=10)&&(Time<25))Code[CodeNum]=0//计数值设置
else if((Time>25)&&(Time<40))Code[CodeNum]=1
CodeNum++//码字计数器加1
Time=0//计数值清零,以对下一个脉冲宽度进行计时
if(CodeNum>40) {CodeNum=0Star_Flag=0First_IRQ=0}//脉冲个数判断,共32个,此处设为40,是为防止漏接收
}
}
*P_INT_Clear=C_IRQ3_EXT1
}
else
{
*P_INT_Clear=C_IRQ3_KEY//IRQ3_KeyWakeUp
}
}
void IRQ1(void) __attribute__ ((ISR))
void IRQ1(void)
{ Time++//计数以获得脉冲宽度
*P_INT_Clear=C_IRQ1_TMA//clear INT flag
}
红外解码程序!/*-----------------------------------------------
名称:遥控器红外解码液晶显示
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include<intrins.h>
#define TURE 1
#define FALSE 0
sbit IR=P3^2 //红外局如接口标志
sbit RS = P2^4//Pin4
sbit RW = P2^5//胡洞Pin5
sbit E = P2^6//Pin6
#define Data P0//数据端口
unsigned int hour,minute,second,count
char code Tab[16]="0123456789ABCDEF"
char data TimeNum[]=""
char data Test1[]=" "
/******************************************************************/
/*变量声明*/
/******************************************************************/
unsigned char irtime//红外用全局变量
bit irpro_ok,irok
unsigned char IRcord[4] //处理后的红外码,分别是 客户码,客户码,数据码,数据码反码
unsigned char irdata[33]//33个高低电平的时间数据
/******************************************************************/
/*函数声明*/
/******************************************************************/
void Ir_work(void)
void Ircordpro(void)
void ShowString (unsigned char line,char *ptr)
/******************************************************************/
/裤腊枯*定时器0中断服务函数 */
/******************************************************************/
void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
{
irtime++//用于计数2个下降沿之间的时间
}
/******************************************************************/
/*外部中断0函数 */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
static unsigned char i//接收红外信号处理
static bit startflag //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0
irdata[i]=irtime//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0
i++
if(i==33)
{
irok=1
i=0
}
}
else
{irtime=0startflag=1}
}
/******************************************************************/
/* 定时器0初始化*/
/******************************************************************/
void TIM0init(void)//定时器0初始化
{
TMOD=0x02//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00//重载值
TL0=0x00//初始化值
ET0=1 //开中断
TR0=1
}
/******************************************************************/
/* 外部中断初始化 */
/******************************************************************/
void EX0init(void)
{
IT0 = 1 //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1 //使能外部中断
EA = 1 //开总中断
}
/******************************************************************/
/*红外键值处理*/
/******************************************************************/
void Ir_work(void)//红外键值散转程序
{
TimeNum[5] = Tab[IRcord[0]/16] //处理客户码并显示
TimeNum[6] = Tab[IRcord[0]%16]
TimeNum[8] = Tab[IRcord[1]/16] //处理客户码并显示
TimeNum[9] = Tab[IRcord[1]%16]
TimeNum[11] = Tab[IRcord[2]/16] //处理数据码并显示
TimeNum[12] = Tab[IRcord[2]%16]
TimeNum[14] = Tab[IRcord[3]/16] //处理数据反码并显示
TimeNum[15] = Tab[IRcord[3]%16]
ShowString(1,TimeNum)//显示处理过后的码值
irpro_ok=0 //处理完成后清楚标志位
}
/******************************************************************/
/*红外解码函数处理*/
/******************************************************************/
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k
unsigned char cord,value
k=1
for(i=0i<4i++) //处理4个字节
{
for(j=1j<=8j++) //处理1个字节8位
{
cord=irdata[k]
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
{
value=value|0x80
}
else
{
value=value
}
if(j<8)
{
value=value>>1
}
k++
}
IRcord[i]=value
value=0
} irpro_ok=1//处理完毕标志位置1
}
/******************************************************************/
/*微秒延时函数*/
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt
uscnt=us>>1/* Crystal frequency in 12MHz*/
while(--uscnt)
}
/******************************************************************/
/*毫秒函数声明*/
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
while(--ms)
{
DelayUs(250)
DelayUs(250)
DelayUs(250)
DelayUs(250)
}
}
/******************************************************************/
/* 写入命令函数 */
/******************************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(5)// *** 作前短暂延时,保证信号稳定
E=0
RS=0
RW=0
_nop_()
E=1
Data=c
E=0
}
/******************************************************************/
/* 写入数据函数 */
/******************************************************************/
void WriteData(unsigned char c)
{
DelayMs(5) // *** 作前短暂延时,保证信号稳定
E=0
RS=1
RW=0
_nop_()
E=1
Data=c
E=0
RS=0
}
/******************************************************************/
/* 写入字节函数 */
/******************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p
if (pos>=0x10)
p=pos+0xb0//是第二行则命令代码高4位为0xc
else
p=pos+0x80//是第二行则命令代码高4位为0x8
WriteCommand (p)//写命令
WriteData (c) //写数据
}
/******************************************************************/
/* 写入字符串函数 */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
{
unsigned char l,i
l=line<<4
for (i=0i<16i++)
ShowChar (l++,*(ptr+i))//循环显示16个字符
}
/******************************************************************/
/* 初始化函数 */
/******************************************************************/
void InitLcd()
{
DelayMs(15)
WriteCommand(0x38)//display mode
WriteCommand(0x38)//display mode
WriteCommand(0x38)//display mode
WriteCommand(0x06)//显示光标移动位置
WriteCommand(0x0c)//显示开及光标设置
WriteCommand(0x01)//显示清屏
}
/******************************************************************/
/* 主函数 */
/******************************************************************/
void main(void)
{
EX0init()//初始化外部中断
TIM0init()//初始化定时器
InitLcd()//初始化液晶
DelayMs(15)
sprintf(Test1," haixiang MCU ") //显示第一行固定信息
ShowString(0,Test1)
sprintf(TimeNum,"Code")//显示第二行固定信息
ShowString(1,TimeNum)
while(1)//主循环
{
if(irok)//如果接收好了进行红外处理
{
Ircordpro()
irok=0
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work()
}
}
}
(1)发送程序#include <reg52.h>
static bit OP //红外发射管的亮灭
static unsigned int count //延时计数器
static unsigned int endcount//终止延时计数
static unsigned int temp//按键
static unsigned char flag //红外发送标志
static unsigned char num
sbit ir_in=P3^4
char iraddr1 //十六位地址的第一个字节
char iraddr2 /脊贺/十六位地址的第二个字节
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 2009-8-11 <br>4 <br>红外数据传输 <br>0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e} //共阳数码管 0~~f
void SendIRdata(char p_irdata)
void delay(unsigned int)
void keyscan()
/******************主函数**************************/
void main(void)
{
num=0
P2=0x3f
count = 0
flag = 0
OP = 0
ir_in= 0
EA = 1//允许CPU中断
TMOD = 0x11//设定时器0和1为16位模式1
ET0 = 1//定时器0中断允许
TH0 = 0xFF
TL0 = 0xE6//设定时值0为38K 也就是每隔26us中断一次
TR0 = 1//开始芦腊计数
iraddr1=3//00000011
iraddr2=252//11111100
do{keyscan()<br>}while(1)
}
/***********************定时器0中断处理 **********************/
void timeint(void) interrupt 1
{
TH0=0xFF
TL0=0xE6//设定时值为38K 也就是每隔26us中断一次
count++
if (flag==1)
{
OP=~OP
}
else
{
OP = 0
}
ir_in= OP
}
void SendIRdata(char p_irdata)
{ 2009-8-11
5
红外数据传输
int i
char irdata=p_irdata
//发送9ms的起始码
endcount=223
flag=1
count=0
do{}while(count<endcount)
/**********************发送4.5ms的结果码***********************/
endcount=117
flag=0
count=0
do{}while(count<endcount)
/********************发送十六位地址的前樱哗派八位*******************/
irdata=iraddr1
for(i=0i<8i++)
{
/*****先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)*****/
endcount=10
flag=1
count=0
do{}while(count<endcount)
/***********停止发送红外信号(即编码中的高电平)*************/
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=41//1为宽的高电平
}
else
{
endcount=15 //0为窄的高电平
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
/**********************发送十六位地址的后八位******************/
irdata=iraddr2
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{ 2009-8-11
6
红外数据传输
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
/******************发送八位数据********************************/
irdata=p_irdata
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
/***********************发送八位数据的反码**********************/
irdata=~p_irdata
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
2009-8-11
7
红外数据传输
endcount=10
flag=1
count=0
do{}while(count<endcount)
flag=0
}
void delay(unsigned int z)
{
unsigned char x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
/*********************4×4键盘扫描按下按键发射数据************************/
void keyscan()
{
P1=0xfe
temp=P1
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P1
switch(temp)
{
case 0xee:num=1
break
case 0xde:num=2
break
case 0xbe:num=3
break
case 0x7e:num=4
break
}
while(temp!=0xf0)
{
temp=P1
temp=temp&0xf0
}
P2=table[num-1]
SendIRdata(table[num-1])
}
P1=0xfd
temp=P1
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P1
switch(temp)
{
case 0xed:num=5
break
case 0xdd:num=6
break
case 0xbd:num=7
break
case 0x7d:num=82009-8-11
8
红外数据传输
break
}
while(temp!=0xf0)
{
temp=P1
temp=temp&0xf0
}
P2=table[num-1]
SendIRdata(table[num-1])
}
P1=0xfb
temp=P1
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P1
switch(temp)
{
case 0xeb:num=9
break
case 0xdb:num=10
break
case 0xbb:num=11
break
case 0x7b:num=12
break
}
while(temp!=0xf0)
{
temp=P1
temp=temp&0xf0
}
P2=table[num-1]
SendIRdata(table[num-1])
}
P1=0xf7
temp=P1
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P1
switch(temp)
{
case 0xe7:num=13
break
case 0xd7:num=14
break
case 0xb7:num=15
break
case 0x77:num=16
break
}
while(temp!=0xf0)
{
temp=P1
temp=temp&0xf0
} 2009-8-11
9
红外数据传输
P2=table[num-1]
SendIRdata(table[num-1])
}
}
(2)接收程序
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
uchar dis_num,num,num1,num2,num3
sbit led=P1^0
unsigned char code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e} //共阳数码管 0~~f
sbit prem =P3^2 //定义遥控头的接收脚
uchar ram[4]={0,0,0,0}//存放接受到的4个数据 地址码16位+按键码8位+按键码取反的8位
void delaytime(uint time) //延迟90uS
{
uchar a,b
for(a=timea>0a--)
{
for(b=40b>0b--)
}
}
void rem()interrupt 0 //中断函数
{
uchar ramc=0 //定义接收了4个字节的变量
uchar count=0 //定义现在接收第几位变量
uint i=0 //此处变量用来在下面配合连续监测9MS 内是否有高电平
prem=1
for(i=0i<1100i++) //以下FOR语句执行时间为8MS左右
{
if(prem) //进入遥控接收程序首先进入引导码的前半部判断,即:是否有9MS左右的低电平
return //引导码错误则退出
}
while(prem!=1) //等待引导码的后半部 4.5 MS 高电平开始的到来。
delaytime(50) //延时大于4.5MS时间,跨过引导码的后半部分,来到真正遥控数据32位中
//第一位数据的0.56MS开始脉冲
for(ramc=0ramc<4ramc++)//循环4次接收4个字节
{for(count=0count<8count++) //循环8次接收8位(一个字节)
{
while(prem!=1) //开始判断现在接收到的数据是0或者1 ,首先在这行本句话时,
//保已经进入数据的0.56MS 低电平阶段
//等待本次接受数据的高电平的到来。
delaytime(9)//高电平到来后,数据0 高电平最多延续0.56MS,而数据1,高电平可 2009-8-11
10
红外数据传输
//延续1.66MS大于0.8MS 后我们可以再判断遥控接收脚的电平,
if(prem) //如果这时高电平仍然在继续那么接收到的数据是1的编码
{
ram[ramc]=(ram[ramc]<<1)+1//将目前接收到的数据位1放到对应的字节中
delaytime(11)//如果本次接受到的数据是1,那么要继续延迟1MS,这样才能跨入
//下个位编码的低电平中(即是开始的0.56MS中)
}
else //否则目前接收到的是数据0的编码
ram[ramc]=ram[ramc]<<1 //将目前接收到的数据位0放到对应的字节中
} //本次接收结束,进行下次位接收,此接收动作进行32次,正好完成4个字节的接收
}
if(ram[2]!=(~(ram[3]&0x7f)))//本次接收码的判断
{
for(i=0i<4i++) //没有此对应关系则表明接收失败,清除接受到的数据
ram[i]=0
return
}
dis_num=ram[2] //将接收到的按键数据赋给显示变量
}
main()
{
IT0=1 //设定INT0为边沿触发
EX0=1 //打开外部中断0
EA=1 //全局中断开关打开
while(1)
{
switch(dis_num)
{
case 0x81: num=0break
case 0xcf: num=1break
case 0x92: num=2break
case 0x86: num=3break
case 0xcc: num=4break
case 0xa4: num=5break
case 0xa0: num=6break
case 0x8f: num=7break
case 0x80: num=8break
case 0x84: num=9break
case 0x88: num=10break
case 0xe0: num=11break
case 0xb1: num=12break
case 0xc2: num=13break
case 0xb0: num=14break
case 0xb8: num=15break
}
P2=table[num]
P1=0x01
delaytime(5)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)