标题:
这个单片机红外自收自发代码怎么改?我把发送和接受放在一个while循环里只能接受
[打印本页]
作者:
yangshuo9264
时间:
2021-7-8 17:59
标题:
这个单片机红外自收自发代码怎么改?我把发送和接受放在一个while循环里只能接受
有谁能教教我这个代码怎么改吗
内容在附件里,谢谢
//适用于市场上用量最大的HT6121/6122及其兼容的IC编码。
//使用外部中断0接收P3.2
//发射引脚(接PNP三极管b极)
//PNP三极管e极接2Ω电阻,c极接红外发射管
#include<reg52.h>
#include "lcd1602.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_DATA P0
#define SBM 0x80 //识别码
#define m9 (65536-9000) //约9mS
#define m4_5 (65536-4500) //约4.5mS
#define m1_6 (65536-1630) //约1.65mS
#define m_65 (65536-580) //约0.65mS
#define m_56 (65536-560) //约0.56mS
#define m40 (65536-40000) //约40mS
#define m56 (65536-56000) //56mS
#define m2_25 (65536-2250) //约2.25mS
sbit IRR = P3^6; //定义发射引脚(接PNP三极管基极)
sbit LED = P2^3;
uchar KEY(void);//按键
void SanZhuan(void);//键值和ASCII码值的转换
void ZZ(uchar x);//
void Z0(uchar temp);
void TT0(bit BT,uint x);
void YS(uchar time);
uchar code tab[] = {0X30,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X38,0X39};
uchar code set[] = {0X30,0X31,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30};
uchar code tab1[] = {0X4F,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X4F,0X39};
uchar code tab2[] = {0X46,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X4E,0X39};
sbit IR = P3^3; //接收引脚
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
uchar N[4]; //识别码,操作码存放
uchar X1,X2,X3,X4;
void XSQ(void);
typedef unsigned int u16; //???????????
typedef unsigned char u8;
sbit IRIN=P3^2; //????
u8 IrValue[4] = {'\0'};
u8 Time;
/*????,i=1?,????10us*/
void delay(u16 i)
{
while(i--);
}
/*????*/
void DigDisplay()
{
u8 i;
write_com(0x83);
for(i=0;i<4;i++)
{
if(IrValue[i]/16<10)
{
write_data(IrValue[i]/16 + 0x30);
}
else
{
write_data(IrValue[i]/16 + 0x37);
}
if(IrValue[i]%16<10)
{
write_data(IrValue[i]%16 + 0x30);
}
else
{
write_data(IrValue[i]%16 + 0x37);
}
}
}
/*??????0(????????)*/
void IrInit()
{
IT0=1;//?????
EX0=1;//????0??
EA=1; //?????
IRIN=1;//?????
}
/*???*
/*???????????*/
void ReadIr() interrupt 0
{
u8 j,k;
u16 err;
Time=0;
delay(700); //7ms
if(IRIN==0) //??????????????
{
err=1000; //1000*10us=10ms,????????????
/*???????????,????????????????,????????
?,??????*/
while((IRIN==0)&&(err>0)) //????9ms??????
{
delay(1);
err--;
}
if(IRIN==1) //??????9ms???
{
err=500;
while((IRIN==1)&&(err>0)) //??4.5ms????????
{
delay(1);
err--;
}
for(k=0;k<4;k++) //??4???
{
for(j=0;j<8;j++) //??????
{
err=60;
while((IRIN==0)&&(err>0))//???????560us?????
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //???????????
{
delay(10); //0.1ms
Time++;
err--;
if(Time>30) //??3ms ????
{
return;
}
}
IrValue[k]>>=1; //k???????
if(Time>=8) //?????????0.8ms,???1
{
IrValue[k]|=0x80;
}
Time=0; //?????????
}
}
}
if(IrValue[2]!=~IrValue[3]) //?? ??? ????? ???? ?????
{
return;
}
}
}
/***************************************************************
函数功能: 4×4矩阵键盘
***************************************************************/
uchar KEY(void)
{
uchar H,L; //行值,列值
H=0;
L=0;
P1 = 0xf0; //将键盘端口行值设为1,列值设为0
if(P1!= 0xf0) //检测是否有按键按下,如果有则hangval必不为0x0f
{
YS(10); //按键去抖动,延时10毫秒
if(P1!=0xf0) //确实有按键按下
{
H = P1&0xf0; //按键后得到按键的行标志位,将行标志位赋值给hangval
P1 = 0x0f; //翻转键盘接口输出
L = P1&0x0f; //得到列标志位
}
return (H+L);
}
return 0;
}
/***************************************************************
函数功能:散转程序
入口参数:v
// 13 14 15 16
// 9 10 11 12
// 5 6 7 8
// 1 2 3 4
***************************************************************/
void SanZhuan(void)
{
uchar v;
v =KEY();
switch(v)
{
case 0x77:ZZ(0x00);v=0;break; //"0"
case 0xb7:ZZ(0x01);v=0;break; //"1 "
case 0xd7:ZZ(0x02);v=0;break; //"2 "
case 0xe7:ZZ(0x03);v=0;break; //"3"
case 0x7b:ZZ(0x04);v=0;break; //"4 "
case 0xbb:ZZ(0x05);v=0;break; //"5"
case 0xdb:ZZ(0x06);v=0;break; //"6"
case 0xeb:ZZ(0x07);v=0;break; //"7"
case 0x7d:ZZ(0x08);v=0;break; //"8"
case 0xbd:ZZ(0x09);v=0;break; //"9"
case 0xdd:ZZ(0x0a);v=0;break; //"a"
case 0xed:ZZ(0x0b);v=0;break; //"b"
case 0x7e:ZZ(0x0c);v=0;break; //"c"
case 0xbe:ZZ(0x0d);v=0;break; //"d"
case 0xde:ZZ(0x1e);v=0;break; //"e"
case 0xee:ZZ(0x1f);v=0;break; //"f"
default:v=0;break;
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:发送主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uchar x)
{
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS引导
/*┈ 发送4帧数据 ┈*/
Z0(SBM); //识别码
Z0(~SBM);
Z0(x); //数据码
Z0(~x);
/*┈┈ 结束码 ┈┈*/
TT0(1,m_65);
TT0(0,m40);
/*┈┈ 重复码 ┈┈*/
while(KEY())
{
TT0(1,m9);
TT0(0,m2_25);
TT0(1,m_56); //38khz
TT0(0,m40);
TT0(0,m56);
LED = !LED; //指示灯
}
LED = 1;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:单帧发送程序
入口参数:1帧数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uchar temp)
{
uchar v;
for (v=0;v<8;v++) //循环8次移位
{
TT0(1,m_65); //高电平0.65mS
if(temp&0x01==1) TT0(0,m1_6); //发送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:38KHz脉冲发射 + 延时程序
入口参数:(是否发射脉冲,延时约 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint x)
{
TH0 = x/256; //输入T0初始值
TL0 =x%256;
TF0=0; //清0
TR0=1; //启动定时器0
if(BT == 0)
while(!TF0); //BT=0时不发射38KHz脉冲只延时;BT=1发射38KHz脉冲且延时;
else while(1) //38KHz脉冲,占空比5:26
{
IRR = 0;
if(TF0)break;
if(TF0)break;
IRR = 1;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
}
TR0=0; //关闭定时器0
TF0=0; //标志位溢出则清0
IRR =1; //脉冲停止后,发射端口常态为高电平
}
/***************************************************************
函数功能:按键消抖 延时程序
入口参数:1ms×time (晶振=12MHz)
***************************************************************/
void YS(uchar time)
{
uchar i,j;
for(i=0; i<time; i++)
for(j=0; j<247; j++)_nop_();
}
/*******************************接收*********************************************/
void delay1(unsigned char t) {
unsigned char i;
while(t--)
for(i = 200; i > 0; i--);
}
void LCD_write_instruction(unsigned char LCD_instruction) { //写指令到LCD
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA = LCD_instruction;
LCD_EN = 1;
_nop_();
LCD_EN = 0;
delay(1);
}
void LCD_write_data(unsigned char LCD_data) { //输出一个字节数据到LCD
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA = LCD_data;
LCD_EN = 1;
_nop_();
LCD_EN = 0;
delay(1);
}
void LCD_set_position(unsigned char x) { //LCD光标定位到x处
LCD_write_instruction(0x80|x);
}
void LCD_printc(unsigned char lcd_data) { //输出一个字符到LCD
LCD_write_data(lcd_data);
}
void LCD_prints(unsigned char *lcd_string) { //输出一个字符串到 LCD
unsigned char i = 0;
while(lcd_string[i] != 0x00) {
LCD_write_data(lcd_string[i]);
i++;
}
}
void LCD_initial(void) { //初始化 LCD
LCD_write_instruction(0x38);
LCD_write_instruction(0x0c);
LCD_write_instruction(0x06);
LCD_write_instruction(0x01);
}
/**********************LCD显示函数************************/
void XSQ(void)
{
while(1) {
uchar temp1,temp2,temp3,temp4;
temp1=tab[X4];
temp2=set[X3];
temp3=tab1[X1];
temp4=tab2[X1];
LCD_set_position(0x88); //LCD换行显示
LCD_printc(temp3);
LCD_set_position(0x89); //LCD换行显示
LCD_printc(temp4);
LCD_set_position(0xC8); //LCD换行显示
LCD_printc(temp2);
LCD_set_position(0xC9); //LCD换行显示
LCD_printc(temp1);
SanZhuan();
}
}
/********************** 外部中断函数************************/
void exint0() interrupt 1
{
uint cnt;
uchar i;
EX0 =0;
cnt = 0;
while(!IR) cnt++; //记录引导码时间
if(cnt < 1000){EX0=1;return;} //9ms的计数值(12MHz:1000< cnt <1500)
cnt =0;
while(IR) if(cnt++ > 400){EX0=1;return;} //防卡死,超时保护(12MHz: > 300)
if(cnt < 200){EX0=1;return;} //(12MHz不分频: <260)
for(i=0; i<32; i++) //读取32位位码
{
cnt =0;
while(!IR);
while(IR) if(cnt++ > 200){EX0=1;return;} //超时保护(12MHz:>=200)
N[i/8] >>= 1;
if(cnt>60) N[i/8] |= 0x80; //0和1的计数界线(12MHz:< 109)
}
if(N[0] == ~N[1] && N[2] == ~N[3]) //校验识别码,操作码
{
X1 =N[0]/16;
X2 =N[0]%16;
X3 = N[2]/16;
X4 = N[2]%16;
}
EX0 =1;
}
/****************** 主函数 *******************/
void main(void)
{
TMOD = 0x01; //T0 16位工作方式 //发射端口常态为高电平
IRR=1; //发射端口常态为高电平
IrInit(); //????0(?????)
init_lcd(); //???1602
while(1)
{
DigDisplay(); //??
SanZhuan();
}
}
复制代码
代码.rar
(45.91 KB, 下载次数: 5)
2021-7-8 17:58 上传
点击文件名下载附件
里面是代码
作者:
man1234567
时间:
2021-7-14 08:27
自收自发是啥东东 ?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1