求51单片机红外摇控接收c程序,并在数码管上显示键值出来?

求51单片机红外摇控接收c程序,并在数码管上显示键值出来?,第1张

#include<reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

#define Nop() {_nop_()_nop_()_nop_()_nop_()_nop_()}

volatile ulong IRcode=0x00000000 //32位的键代码

volatile ulong Irdcode=0x00000000

volatile uint customcode=0x0000 //16位用户码

volatile uint time_us=0x0000 //两个下降沿之间的时间

volatile uchar timeH,timeL //保存TH1 TL的值

uchar Lcustomcode //低8用户码

uchar Hcustomcode//高8

uchar datacode //8位键数据码

uchar mycode

uchar Rdatacode //8位键数据反码

uchar uc1ms

uchar uc10ms

uchar uc3ms

uchar ucDispTime

uchar ucDispOrder

uchar ucDispCon

uchar ucSpeakerTime

unsigned char code LedData[16] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}

unsigned char code LedCon[2] = {0x8f,0x4f}

unsigned char ucDispData[2]// 存放显示数据

sbit led1 = P3^7

sbit led2 = P3^6

sbit power=P1^0 //电源开关

sbit BEEP= P2^1

bit NewIRcode=0 //指示当处理完了32位码后,就有了新的遥控码

bit DataRight=0 //为1时读取数据正确

bit bSampleOk

bit bSampling

bit b10msInt

bit b1msInt

bit bKeySound

bit b1msMain

bit IR_E //表示有新的遥控键控下就更新扫描数据

bit b3msint

void SendDataToDispDevice()

void Ir_process()

void display()

void beeping()

/****** 晶振为12 MHZ*******/

/**定时器1,12 MHZ最大定时为65.53ms***/

//------------------------------------------------------------------------------

void init()

{

IP=0x09 //定时器1,外部中断0优先级高

TMOD=0x11//定时器0,工作方式1 定时器1,工作方式1

TCON=0x01//外中断0下降沿触发,(包括TR1=0,TR0=0)

TH0=0xff //初始化定时器0,定时0.2ms

TL0=0x47

TH1=0x00 //初始化定时器1

TL1=0x00

EA=1 //开全中断

ET0=1 //开放T0中断

ET1=1 //开放T1中断

EX0=1 //开放INT0

TR1=0

TR0=1

}

//--------------------------------------

void TimeProg(void)

{

b1msMain = b1msInt

b1msMain=0

b10msInt = 0

if(b1msInt == 1)

{

b1msMain=1

if(++uc10ms == 10)

{

uc10ms = 0

b10msInt = 1

if(bKeySound==1)

{ beeping()

bKeySound=0

}

}

}

}//void TimeProg(void)

//-------------------------------------interrupt0-------------------------------------

void IR_ISR() interrupt 0 using 1 //遥控器中断处理函数

{

static uchar cn

TR1=0

timeH=TH1

timeL=TL1

TH1=0

TL1=0

TR1=1//开定时器中断1

time_us=(unsigned int)timeH

time_us=time_us<<8

time_us=time_us|timeL

if(time_us>12200&&time_us<13000) {cn=1IRcode=0} //遇到引导码,就把cn清0,IRcode清0

//引导码的时间长度为9ms+4.5ms

if(cn<34)

{

if(time_us>950&&time_us<1120) //0

{

IRcode=IRcode|0x00000000

if(cn<33) IRcode=IRcode>>1

}

else if(time_us>1920&&time_us<2120)//1t >1950 &&t <2150

{

IRcode=IRcode|0x80000000

if(cn<33) IRcode=IRcode>>1

}

//else if(time_us>10000&&time_us<11000) {Irdcode=IRcodecn=34} //遇到重复码

//cn用于记录接收到的数据位

}

cn++

if(cn==34)

{ NewIRcode=1

TR1=0

Irdcode= IRcode cn=0

} //读完32位码,则有新码产生

}

//--------------------------------------timer_ISR------------------------------

void Timer0_ISR() interrupt 1 using 2 //定时器0中断函数

{

TR0=0

TH0=0xff //初始化定时器0,定时0.2ms 晶振为11.0592 MHZ

TL0=0x47

TR0=1

if(++uc1ms == 5)

{

uc1ms = 0

b1msInt=1

if(++uc3ms==8)

{

uc3ms=0

b3msint=1

SendDataToDispDevice()//n* ms送一次显示

}

}

}//void Timer0IntProg() interrupt 1 using 1

void Timer1_ISR() interrupt 3 using 3 //定时器1中断函数

{

TR1=0

TH1=0x00 //初始化定时器1

TL1=0x00

TR1=1

}

//--------------------SendDataToDispDevice----------

void SendDataToDispDevice()

{

unsigned char n

//watchdog()

if(++ucDispOrder >= 2) ucDispOrder = 0// 下一显示巡回

// 下面为发送控制数据 位控

if(ucDispOrder==0)

{led1=0

led2=1

Nop()

Nop()

}

if(b3msint==1)

{if(ucDispOrder==1)

{led2=0

led1=1

Nop()

Nop()

}

}

// 下面为发送显示数据

n = LedData[ucDispData[ucDispOrder]]

P0=n

} //void SendDataToDispDevice()

//------------------------------------main()----------------------------------------------

void main()

{

init()

beeping()

while(1)

{

TimeProg()

Ir_process()

display()

}

}

void Ir_process()

{

if(NewIRcode==1)//如果有新的遥控码就读

{

NewIRcode=0//读完之后清零,表示新码已读

customcode=(Irdcode>>16) //取红外码中的按码键

//取低8位用户码

Lcustomcode=customcode>>8//取低8位按码键

datacode=(unsigned char)(customcode&0x00ff) //取高8位按码键

Rdatacode=Lcustomcode //取低8位按码键的反码

if(~Rdatacode!=datacode)

{ DataRight=0

Irdcode=0

datacode=Rdatacode=0

} //校验用户码,反码

else

{ DataRight=1

IR_E=1

mycode=datacode}

if(DataRight==1) { bKeySound = 1DataRight=0 }

}

}

void display()

{

/* unsigned char a[2]

a[0] = mycode &0x0f

mycode = mycode >>4

a[1] = mycode &0x0f

ET0 = 0

ucDispData[0] = a[0]

ucDispData[1] = a[1]

ET0 = 1*/

if(IR_E==1)

{

ET0 = 0

ucDispData[0] = mycode &0x0f

mycode = mycode >>4

ucDispData[1] = mycode &0x0f

IR_E=0

ET0 = 1

}

}

/**********************************************************/

void delay(unsigned char x)//x*0.14MS

{

unsigned char a

while(x--)

{

for (a = 0a<13a++) {}

}

}

/**********************************************************/

void beeping()

{

unsigned char i

for (i=0i<100i++)

{

delay(4)

BEEP=!BEEP//BEEP取反

}

BEEP=1

//关闭蜂鸣器

}

双轴按键摇杆主要由两个10K的电位器和一个按键开关组成,两个电位器随着摇杆扭转角度分别输出X、Y轴上对应的电压值,在Z轴方向上按下摇杆可触发轻触按键。在配套机械结构的作用下,无外力扭动的摇杆初始状态下,两个电位器都处在量程的中间位置。

2.2 电路原理图

这里单片机主控学长选择arduino,可选其他模块,如stm32

双轴按键摇杆模块的VCC、GND分别连接开发板的5V、GND,模块的X轴输出、Y轴输出分别连接开发板的模拟引脚A0、A1,模块的Z轴输出连接开发板数字引脚2。

3 实现效果

4 测试代码

/*

* JoyStick

* 双轴按键摇杆

*/

#define pinX A0

#define pinY A1

#define pinK 2

int value = 0

void setup()

{

pinMode(pinK, INPUT)

Serial.begin(9600)

}

void loop()

{

value = analogRead(pinX)

Serial.print("X: ")

Serial.print(value)

value = analogRead(pinY)

Serial.print(" Y: ")

Serial.print(value)

value = digitalRead(pinK)

Serial.print(" Z: ")

Serial.println(value)

delay(1000)

}

登录后复制

烧录代码后,打开串口监视器,波特率设置成与程序中相一致的9600,扭动摇杆,监视器将显示X、Y轴对应的电压对应的AD数值。

#include\x0d\x0a#include\x0d\x0a#define uchar unsigned char\x0d\x0a#define uint unsigned int\x0d\x0asbit lcden = P2^7\x0d\x0asbit lcdrs = P2^6\x0d\x0asbit lcdwr = P2^5\x0d\x0asbit IR = P3^2\x0d\x0auchar IRCOM[6]//数组,用于存储红外编码\x0d\x0auchar code table1[] = "remote control"\x0d\x0auchar code table2[] = "CODE:"\x0d\x0avoid delayms(uchar x)// 延时x*0.14ms\x0d\x0a{\x0d\x0auchar i\x0d\x0awhile(x--)\x0d\x0afor(i=0i//延时xms\x0d\x0a{\x0d\x0auchar i,j\x0d\x0afor(i=xi>0i--)\x0d\x0afor(j=110j>0j--)\x0d\x0a}\x0d\x0a/****************************LCD部分***********************************************/\x0d\x0avoid write_com(uchar com)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 0\x0d\x0alcdwr = 0\x0d\x0aP0 = com\x0d\x0adelay(5)\x0d\x0alcden = 1\x0d\x0adelay(5)\x0d\x0alcden = 0//别忘了lcden拉低\x0d\x0a}\x0d\x0avoid write_date(uchar date)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 1\x0d\x0alcdwr = 0\x0d\x0aP0 = date\x0d\x0adelay(5)\x0d\x0alcden = 1\x0d\x0adelay(5)\x0d\x0alcden = 0\x0d\x0a}\x0d\x0avoid lcd_init(void)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 0\x0d\x0alcdwr = 0\x0d\x0adelay(5)\x0d\x0awrite_com(0x38)\x0d\x0awrite_com(0x0c)\x0d\x0awrite_com(0x06)\x0d\x0awrite_com(0x01)\x0d\x0a}\x0d\x0a/*****************main()************************/\x0d\x0avoid main(void)\x0d\x0a{\x0d\x0auchar count=0\x0d\x0aIR = 1\x0d\x0alcd_init()\x0d\x0awrite_com(0x80)\x0d\x0awhile(table1[count]!='\0')\x0d\x0a{\x0d\x0awrite_date(table1[count])\x0d\x0acount++\x0d\x0adelay(5)\x0d\x0a}\x0d\x0acount = 0\x0d\x0awrite_com(0x80+0x40)\x0d\x0awhile(table2[count]!='\0')\x0d\x0a{\x0d\x0awrite_date(table2[count])\x0d\x0acount++\x0d\x0adelay(5)\x0d\x0a}\x0d\x0a\x0d\x0aIE = 0x81//开中断\x0d\x0aTCON = 0x01//脉冲负边沿触发\x0d\x0awhile(1)\x0d\x0a\x0d\x0a}\x0d\x0a/*********************红外中断**************************/\x0d\x0avoid IR_time() interrupt 0 \x0d\x0a{\x0d\x0auchar i,j,TimeNum=0//TimeNum用来计IR高电平次数 从而判断是0还是1\x0d\x0aEX0 = 0//关闭中断\x0d\x0adelayms(5)\x0d\x0aif(1 == IR)\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0awhile(!IR) //跳过9ms前导低电平\x0d\x0adelayms(1)\x0d\x0afor(i=0i{\x0d\x0afor(j=0j{\x0d\x0awhile(IR) //跳过4.5ms的前导高电平\x0d\x0adelayms(1)\x0d\x0awhile(!IR) //跳过0.56ms的低电平\x0d\x0adelayms(1)\x0d\x0a\x0d\x0awhile(IR) \x0d\x0a{\x0d\x0aTimeNum++//计时高电平时间从而判断读取的是0还是1\x0d\x0adelayms(1)\x0d\x0a}\x0d\x0aif(TimeNum>=30)//按键按下时间过长 跳过\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0aIRCOM[i] = IRCOM[i]>>1\x0d\x0aif(TimeNum >= 8) //8*0.14ms 这时读取的是1;\x0d\x0a{\x0d\x0aIRCOM[i] = IRCOM[i]|0x80\x0d\x0a}\x0d\x0aTimeNum = 0\x0d\x0a}\x0d\x0a}\x0d\x0aif(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0aIRCOM[4] = IRCOM[2]&0x0f//取低四位\x0d\x0aIRCOM[5] = IRCOM[2]>>4//IRCOM[5]取IRCOM[2]高四位\x0d\x0aif(IRCOM[4] >9) //转换成字符\x0d\x0a{\x0d\x0aIRCOM[4] = IRCOM[4] + 0x37\x0d\x0a}\x0d\x0aelse\x0d\x0aIRCOM[4] = IRCOM[4] + 0x30\x0d\x0aif(IRCOM[5] >9)\x0d\x0a{\x0d\x0aIRCOM[5] = IRCOM[5] + 0x37\x0d\x0a}\x0d\x0aelse\x0d\x0aIRCOM[5] = IRCOM[5] + 0x30\x0d\x0adelay(5)\x0d\x0awrite_com(0x80 + 0x40 + 5)\x0d\x0awrite_date(IRCOM[5])\x0d\x0awrite_date(IRCOM[4])\x0d\x0aEX0 = 1//重新开启外部中断\x0d\x0a}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7873482.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存