|
在某一个宝上买的公交车自动报站项目学习资料,问了店家几次也讲不明白。
这个红外线发射电路是单片机编码?
接收电路我知道是用VS1838红外接收头接收的红外信号,然后解码传送给单片机,但红外发射电路(从机)就一个单片机连接一个二极管就完成红外信号的编码和发送。不明白这个红外发射电路的原理
主机原理图
从机原理图
主机程序:
- #include <reg52.h> //调用单片机头文件
- #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
- #define uint unsigned int //无符号整型 宏定义 变量范围0~65535
- sbit rs=P2^5; //寄存器选择信号 H:数据寄存器 L:指令寄存器
- sbit rw=P2^6; //寄存器选择信号 H:数据寄存器 L:指令寄存器
- sbit e =P2^7; //片选信号 下降沿触发
- sbit hw_P32=P3^2; //红外遥控接的IO口
- uchar hw_table[4]; //红外解码的缓冲区
- bit flag_jiema_en = 1; //红外解码成功标志
- uchar geshu=2;
- uchar code gj_ming[]="直达车 ";
- uchar code table1[]="1号站 ";
- uchar code table2[]=" 2号站 ";
- /***********************语音模块控制IO口的定义************************/
- sbit VRST = P3^7;
- sbit VBUSY= P3^6;
- sbit VSDA = P3^5;
- sbit VCS = P3^4;
- sbit VSCL = P3^3;
- /********************************************************************
- * 名称 : delay_1ms()
- * 功能 : 延时1ms函数
- * 输入 : q
- * 输出 : 无
- ***********************************************************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
-
-
- /************ 延时函数 *****************/
- void delay_uint(uint z)
- {
- while(z--);
- }
- /***************交换函数 高位变低位 低位变高位*****************/
- uchar change_dat(uchar dat)
- {
- uchar i,value;
- for(i=0;i<8;i++)
- {
- value <<= 1;
- if((dat & 0x01) == 0x01)
- value |= 0x01;
- dat >>= 1;
- }
- return value;
- }
- /************ 写命令函数 *****************/
- void write_com(uchar com)
- {
- P0=change_dat(com);
- rw=0;
- rs=0;
- delay_uint(25);
- e=1;
- delay_uint(50);
- e=0;
- }
- /************ 写数据函数 *****************/
- void write_dat(uchar dat)
- {
- P0=change_dat(dat);
- rw=0;
- rs=1;
- delay_uint(25);
- e=1;
- delay_uint(50);
- e=0;
- }
- /**********************************************************
- *函数名: addr_12864
- *功能:写地址
- *说明:写汉字时要写个地址
- *输入:无
- *返回:无
- **********************************************************/
- void addr_12864(uchar hang,uchar lie) //地址转换
- {
- uchar address;
- switch(hang)
- {
- case 1: address=0x80 + lie ;
- break;
- case 2: address=0x90 + lie ;
- break;
- case 3: address=0x88 + lie ;
- break;
- case 4: address=0x98 + lie ;
- break;
- default :
- break;
- }
- write_com(address);
- }
- /**********************************************************
- *函数名: write_string
- *功能:在12864上显示字符数据
- *说明:
- *输入:无
- *返回:无
- **********************************************************/
- void write_string(uchar hang,uchar lie,uchar *p)
- {
- addr_12864(hang,lie); //地址转换
- while(*p != '\0')
- {
- write_dat(*p);
- p++;
- delay_uint(50);
- }
- }
- /************12864液晶初始化函数*****************/
- void init_12864()
- {
- write_com(0x30);
- write_com(0x0c);
- write_com(0x01);
- delay_1ms(100);
- }
- /************初始化显示*****************/
- void init_12864_dis()
- {
- write_string(1,0," 欢迎乘坐 ");
- write_string(2,0,gj_ming);
- write_string(3,0," ");
- write_string(4,0," ");
- }
- /***********************语音子程序************************/
- void Send_threelines(unsigned char addr,uchar dat)
- {
- unsigned char i;
- VRST=0;
- VRST=1;
- VCS=0;
- for(i=0;i<8;i++)
- {
- VSCL=0;
- if(addr&0x01)
- {
- VSDA=1;
- }
- else
- VSDA=0;
- addr>>=1;
- VSCL=1;
- }
- VCS=1;
- if(dat == 1)
- while(VBUSY == 0); //忙等待
- }
- /***************100us的延时函数***12M晶振*****************/
- void delay_100us(uchar z)
- { //12M
- uchar x,y;
- for(x=0;x<z;x++)
- for(y=0;y<20;y++);
- }
- /********************独立按键程序*****************/
- uchar key_can; //按键值
- void key() //独立按键程序
- {
- if((P1 & 0x0f) != 0x0f) //按键按下
- {
- delay_1ms(1); //按键消抖动
- if((P1 & 0x0f) != 0x0f)
- { //确认是按键按下
- switch(P1 & 0x0f)
- {
- case 0x0e: key_can = 2; break; //得到按键值
- case 0x0d: key_can = 1; break; //得到按键值
- }
- }
- }
- }
- /***********外部中断0初始化程序****************/
- void init_int0()
- {
- EX0=1; //允许外部中断0中断
- EA=1; //开总中断
- IT0 = 1; //外部中断0负跳变中断
- }
- /***************主函数*****************/
- void main()
- {
- uchar num;
- P0 = P1 = P2 = P3 = 0XFF;
- init_12864();
- init_12864_dis();
- Send_threelines(0,0); //语音播报
- init_int0(); //外部中断初始化
- while(1)
- {
- if(flag_jiema_en == 1)
- {
- flag_jiema_en = 0;
- if(hw_table[2] == 0x45)
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table1);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(1,1); //语音播报
- }
- if(hw_table[2] == 0x47)
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table2);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(2,1); //语音播报
- }
- hw_table[2] = 0;
- }
- key(); //独立按键程序
- if(key_can == 1)
- {
- if(num < 2)
- {
- num ++;
- if(num == 1) //报第1个站
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table1);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(1,0); //语音播报
- }
- if(num == 2) //报第2个站
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table2);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(2,0); //语音播报
- }
- }
- }
- if(key_can == 2)
- {
- if(num != 0)
- num--;
- if(num == 1) //报第1个站
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table1);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(1,0); //语音播报
- }
- if(num == 2) //报第2个站
- {
- write_string(1,0,gj_ming);
- write_string(2,0,table2);
- write_string(3,0," ");
- write_string(4,0," ");
- Send_threelines(2,0); //语音播报
- }
- }
- }
- }
- /*****************红外解码程序********************/
- void int0() interrupt 0
- {
- unsigned char i,j;
- delay_100us(20); //防止干扰
- if(hw_P32 == 0)
- { //引导码
- while(hw_P32 == 0); //等待低电平过完
- delay_100us(20);
- if(hw_P32 == 1) //引码结束
- {
- delay_100us(20); // 说明高电平已经过完 引导码已经结束
- for(i=0;i<4;i++)
- for(j=0;j<8;j++)
- {
- while(hw_P32 == 0); //等待过完
- delay_100us(5);
- if(hw_P32 == 0) //数据0的时间
- { //数据1的时间
- hw_table[i] >>= 1; //低位在前
- }
- else
- {
- delay_100us(5); // 高电平的时间过完
- hw_table[i] >>= 1; //低位在前
- hw_table[i] |= 0x80; //数据值1
- }
- }
- flag_jiema_en = 1; //红外解码成功
- }
- }
- }
- 从机程序:
- #include"reg52.h"
- #define uint unsigned int
- #define uchar unsigned char
- sbit P35=P2^7; // 定义控制红外发射管的控制引脚
- uchar fa_value;
- /*********** 延时函数 ***********/
- void delay_1ms(uint z) // 延时 z 毫秒
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--) ;
- }
- /***************100us的延时函数***12M晶振*****************/
- void delay_100us(uchar z)
- { //12M
- uchar x,y;
- for(x=0;x<z;x++)
- for(y=0;y<20;y++);
- }
- /*********** 红外发射子程序 ***********/
- void hongwaifase(uchar dat) // 发射dat
- {
- uchar i,j,str[4]; // str[4]存放等待发射的四个数据
- str[0]=0xff;str[1]=0x00;
- str[2]=dat;str[3]=~dat;
- TR1=1;
- delay_100us(90); //起始信号 9毫秒
- TR1=0;
- delay_100us(45);
- for(j=0;j<4;j++) //发射四个数据
- {
- for(i=0;i<8;i++) // 发射八个位
- {
- TR1=1;
- delay_100us(5); // 0.56毫秒
- TR1=0;
- if(str[j]&0x01==0x01)
- delay_100us(11); //11.2毫秒 代表发送1
- else
- delay_100us(5); //0.56毫秒 代表发送0
- str[j]>>=1;
- }
- }
- }
- void init()
- {
- EA=1;
- ET1=1;
- TR1 = 1;
- TMOD=0X20;
- TH1=0XF0;
- TL1=0XF0; // 用定时器中断产生38khz的方波
- }
- void main()
- {
- init();
- while(1)
- {
- hongwaifase(0x45);
- delay_1ms(1000);
- }
- }
- void time1() interrupt 3 using 1
- {
- P35=~P35; //取反产生方波
- }
复制代码
|
|