2015年高校联盟电子制作大赛题目(数字类)技术报告队长:黄文杰学号:2014212652学院:自动化学院队员:李嘉伟学号:2014212650学院:自动化学院唐泓学号:2014212640学院:自动化学院题目名称:简易红外光数字通信装置1、设计题目:单片机应用系统设计基于单片机的——简易红外光数字通信装置2、总体要求:本次大赛设计内容从主办方所给的题目出发,参赛者应了解单片机实际的应用系统,并自学红外信号编码,弄清结构和功能,结合单片机课程知识及其他相关课程知识,充分发挥自己的想象力和创造力,实现主办方题目要求并适当发挥,团队合作完成本次比赛。
3、具体要求:1)确定应用系统功能参数2)设计合理的电路原理图3)Proteus仿真原理图4)制作电路板并检测5)设计程序6)电路板调试运行7)技术报告单片机技术报告一、项目简介单片机被广泛应用于仪器仪表、工业自动控制、家用电器、医用设备、办公自动化设备、安全监控等领域,涵盖了人类生活的方方面面。
二、系统功能描述这是一款基于STC89C52RC单片机的简易红外光数字通信装置。
它可以分为六个部分:(1)红外功能,可以红外传送数据(2)音阶功能,在发射板上按动七个音阶,在接收板上可以响出duo rai mi fa suo nai xi 七个音阶(3)温度检测,在发射板上可以检测温度,在接收板上可以显示温度,每隔0.5秒更新一次温度。
三、设计思路红外模块设计思路:1:对输入的数据进行编码。
2:对编码进行脉冲调制。
3:信号放大后,通过发射管发送38khz信号。
4:接收信号,进行解码。
5:让51 对信号进行处理(显示,统计,分析)。
音阶模块设计思路:1:计算音阶响应相应延时2:建立延时数组,按键控制取数组里的值。
3:用延时控制发出不同声音温度模块设计:1:温度测出数据,读取温度感应数据,计算成十进制数。
2:在数码管上显示十进制数3:延时控制发射更新温度数据四、程序部分1.红外部分,红外部分分为,发射和接收部分,发射部分,通过定时器0产生38k载波,通过定时器1发送信号。
接收部分,通过外部中断(下降沿触发)接收信号,通过定时器计算两个下降沿之间的时间来确定收到的是0还是1。
2.音阶部分:按键1~7,每次按键按下,发送控制数据,控制接收蜂鸣器根据不同频率发出不同声音。
3.温度部分:发射端温度传感器,测出温度,通过计算得到温度具体数值,发送数据,接收端,根据接收的数据,显示在数码管上。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar m,inform;uint temp; // variable of temperature // sign of the result positive or negativesbit DS=P0^3;sbit IR_OUT=P1^1;sbit key1=P2^4;sbit key2=P2^5;sbit key3=P2^6;sbit key4=P2^7;sbit key5=P2^0;sbit key6=P2^1;sbit key7=P2^2;sbit key8=P2^3;/*--------三个延迟函数的定义-------*/void delay_ms(uint ms){uint i,j;for(i=0;i<120;i++){for(j=0;j<ms;j++);}}void delay(uint count) //delay{uint i;while(count){i=200;while(i>0)i--;count--;}}/*——————————温度传感器函数定义——————————————————*/void dsreset(void) //send reset and initialization command {uint i;DS=0;i=103;while(i>0)i--;DS=1;i=4;while(i>0)i--;}//------------------------------------------------------------bit tmpreadbit(void) //read a bit{uint i;bit dat;DS=0;i++; //i++ for delayDS=1;i++;i++;dat=DS;i=8;while(i>0)i--;return (dat);}//--------------------------------------------------------------------- uchar tmpread(void) //read a byte date{uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tmpreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);}//---------------------------------------------------------------------------void tmpwritebyte(uchar dat) //write a byte to ds18b20{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb) //write 1{DS=0;i++;i++;DS=1;i=8;while(i>0)i--;}else{DS=0; //write 0i=8;while(i>0)i--;DS=1;i++;i++;}}}void tmpchange(void) //DS18B20 begin change{dsreset();delay(1);tmpwritebyte(0xcc); // address all drivers on bustmpwritebyte(0x44); // initiates a single temperature conversion }uint tmp() //get the temperature{float tt;.uchar a,b;dsreset();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8; //two byte compose a int variable temp=temp|a;tt=temp*0.0625;temp=tt*10+0.5;return temp;}void readrom() //read the serial{uchar sn1,sn2;dsreset();delay(1);tmpwritebyte(0x33);sn1=tmpread();sn2=tmpread();}/*--------温度传感器函数定义-----------*///T1 13us产生一次中断用于产生38K载波//T0 方式1 16位用于定时void Init_Timer(){TMOD=0x21; //T0 mode 1 T1 mode 2 TH1=256-13; //定时产生13us//特殊TL1=TH1;ET1=1;EA=1;}//发送引导码发送方:9ms高电平4.5ms低电平void Send_Start_Bit() //TR1的值=发送的电平{//9ms 1TH0=(65536-9000)/256;TL0=(65536-9000)%256;TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//4.5ms 0TH0=(65536-4500)/256; TL0=(65536-4500)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}//发送0void Send_Bit_0() {//0.565ms 1TH0=(65536-565)/256;TL0=(65536-565)%256; TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//0.565ms 0TH0=(65536-565)/256; TL0=(65536-565)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}//发送1void Send_Bit_1()//0.565ms 1TH0=(65536-565)/256; TL0=(65536-565)%256; TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//1.685ms 0TH0=(65536-1685)/256; TL0=(65536-1685)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}void Send_over() //发送一个结束码,因为最后一个位只有遇到下降沿才能读取(发射端的上升沿){//0.500ms 1 //小于0.5ms 接收端很难识别到TH0=(65536-500)/256;TL0=(65536-500)%256;TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//0.500ms 0TH0=(65536-500)/256;TL0=(65536-500)%256;TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}void keyscan(){if(key1==0){delay_ms(5);if(key1==0){m=1;while(!key1);}}if(key2==0){delay_ms(5);if(key2==0){m=2;while(!key2);}}if(key3==0){delay_ms(5);if(key3==0){m=3;while(!key3);}}if(key4==0){delay_ms(5);if(key4==0){m=4;while(!key4);}}if(key5==0){delay_ms(5);if(key5==0){m=5;while(!key1);}}if(key6==0){delay_ms(5);if(key6==0){m=6;while(!key6);}}if(key7==0){delay_ms(5);if(key7==0){m=7;while(!key7);}}if(key8==0){delay_ms(5);if(key8==0){m=8;while(!key8);}}switch(m){case 1:inform=0x7e;break;case 2:inform=0x18;break;case 3:inform=0x3c;break;case 4:inform=0x42;break;case 5:inform=0xe7;break;case 6:inform=0x5a;break;case 7:inform=0x99;break;case 8:inform=0x24;break;default:break;}}void Send_Char(uchar inform,uchar flag) //发送一字节8位{uchar i,j1,j2,j3,j4;j1=flag;j2=0x41;j3=inform;j4=0x20;Send_Start_Bit();for(i=0;i<8;i++){if(j1&0x01)Send_Bit_1();elseSend_Bit_0();j1=j1>>1;//先发射低位}for(i=0;i<8;i++) {if(j2&0x80) Send_Bit_0(); elseSend_Bit_1(); j2=j2<<1;//先发射低位}for(i=0;i<8;i++) {if(j3&0x01) Send_Bit_1(); elseSend_Bit_0(); j3=j3>>1;//先发射低位}for(i=0;i<8;i++) {if(j4&0x80)Send_Bit_0();elseSend_Bit_1();j4=j4<<1;//先发射低位}Send_over();//结束符}void T1_ISR() interrupt 3 {IR_OUT=~IR_OUT;}void delay_send() {uchar i,j;for(i=120;i>1;i--)for(j=500;j>1;j--){keyscan();if(m)Send_Char(inform,0);m=0;}}void main(){Init_Timer();while(1){m=0;IR_OUT=0;tmpchange();if(tmp()>250){inform=0x7e;Send_Char(inform,0);}delay_send();Send_Char(tmp(),0xff);}}#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit IR=P3^2; //红外接口标志sbit Beep=P2^0;sbit A1=P2^1;sbit A2=P2^2;sbit A3=P2^3;/*------------------------------------------------全局变量声明------------------------------------------------*/uchar irtime;//红外用全局变量bit irpro_ok,irok; //是否进行接收和是否接受完毕uchar IRcord[4];uchar irdata[33];uchar Th1,Tl1; //分别给TH0,TH1赋值uchar key=0;uchar code KeyCode[]={0XFF,0XFF,0xF8,0x8B,0xF9,0x5B,0xFA,0x14,0xFA,0x66,0xFB,0x03,0xFB,0x8F,0xFC,0x0B, 0xFC,0x43,0xFC,0xAB,0xFD,0x08,0xFD,0x33,0xFD,0x81,0xFD,0xC7,0xFE,0x05, 0xFE,0x21,0xFE,0x55,0xFE,0x84,0xFE,0X99,0XFE,0xC0,0xFE,0xE3,0xFF,0x02,};uchar code table[]={0x5f,0x06,0x9b,0x97,0xc6,0xd5,0xdd,0x07,0xdf,0xd7}; uchar code table1[]={0x7f,0x26,0xbb,0xb7,0xe6,0xf5,0xfd,0x27,0xff,0xf7}; /*------------------------------------------------函数声明------------------------------------------------*/void Ir_work(void);void Ircordpro(void);//音阶函数声明void PlayKey(void);void DisPlay(void);void delay_ms(uchar ms){uchar i,j;for(i=0;i<120;i++)for(j=0;j<ms;j++);}/*------------------------------------------------定时器0初始化------------------------------------------------*/void TIM0init(void)//定时器初始化{TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值,定时器1工作方式1TH0=0x00; //重载值TL0=0x00; //初始化值ET0=1; //开中断TR0=1;ET1=1;}/*------------------------------------------------外部中断0初始化------------------------------------------------*/void EX0init(void){IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)EX0 = 1; //使能外部中断EA = 1; //开总中断}/*------------------------------------------------定时器0中断处理------------------------------------------------*/void tim0_isr (void) interrupt 1 using 1{irtime++; //用于计数2个下降沿之间的时间}/*------------------------------------------------定时器1中断处理------------------------------------------------*/void time1() interrupt 3{TH1=Th1;TL1=Tl1;Beep=~Beep;}/*------------------------------------------------外部中断0中断处理------------------------------------------------*/void EX0_ISR (void) interrupt 0 //外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码TC9012的头码,9ms+4.5msi=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}/*------------------------------------------------键值处理------------------------------------------------*/void Ir_work(void)//红外键值散转程序{switch(IRcord[2])//判断第三个数码值{case 0x7e:key=1;break;//1 显示相应的按键值case 0x18:key=2;break;//2case 0x3c:key=3;break;//3case 0x42:key=4;break;//4case 0xe7:key=5;break;//5case 0x5a:key=6;break;//6case 0x99:key=7;break;//7case 0x24:key=8;break;//8default:break;}irpro_ok=0;//处理完成标志}void ledisplay()uchar bai,shi,ge;bai=IRcord[2]/100; shi=IRcord[2]%100/10; ge=IRcord[2]%10;A1=0;P0=table[bai];delay_ms(5);P0=0x00;A1=1;A2=0;P0=table1[shi]; delay_ms(5);P0=0x00;A2=1;A3=0;P0=table[ge];delay_ms(5);P0=0x00;A3=1;}/*------------------------------------------------红外码值处理------------------------------------------------*/void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差value|=0x80;if(j<8){value>>=1;}k++;}IRcord[i]=value;value=0;}irpro_ok=1;//处理完毕标志位置1}//————————————音阶处理函数————————————————————————————//void PlayKey(void) //按键播放程序{if(key==0)return;else{Th1=KeyCode[key*2];Tl1=KeyCode[key*2+1];TR1=1;delay_ms(187);TR1=0;key=0;}}/*------------------------------------------------主函数------------------------------------------------*/void main(void){EX0init(); //初始化外部中断TIM0init();//初始化定时器while(1)//主循环{if(irok) //如果接收好了进行红外处理{Ircordpro();irok=0;}if(irpro_ok){if(IRcord[0]>125){ledisplay();}else{Ir_work();PlayKey();}}}}五、Proteus仿真发射proteus图接收proteus图:六、结束语通过这个比赛,真的时对自己思维的一次很大的挑战,算法想不出来,焊接后不能实现功能。