记录关于电子设计
选题内容
利用焊接完的电路板完成软件的设计,本次选的题目为温度控制器与蓝牙通信,最终达到手机端能收到温度控制器测得的实时温度,其中温度控制器的核心部件是DS18B20芯片和LCD1602A液晶显示芯片,蓝牙通信的核心部件是HC-08蓝牙串口通信模块,DS18B20芯片用来实现温度测量功能;LCD1602A液晶显示芯片用来实现测量温度显示功能,HC-08蓝牙串口通信模块作为上位安卓机同52单片机通信的桥梁,达到单片机能将所测得温度发送给上位机,上位机能向单片机发送一些指令的效果。
本次所选的题目,温度控制器实现了实时显示当前温度功能,可以设置上限阈值,即温度报警值,当温度达到阈值时蜂鸣器会响起滴答滴答的声音,同时LCD显示屏右上角显示出“W”代表进入报警状态此时的温度控制器仍然正常工作,当温度低于阈值时解除报警状态。除此之外,还设计了一个APP通过蓝牙模块同单片机通信,可以达到通过手机就能查看当前单片机测得的温度,查看阈值,调整阈值的功能。此项目综合实现了多方面的功能,运用了多个芯片和组件,对单片机知识的掌握是很好的一次考察,通过此项目的实现,提高了我对单片机知识的综合掌握程度。
具体实现
温度控制器主要涉及到的硬件资源有STC89C52RC、LCD1602A显示屏芯片、DS18B20芯片、蜂鸣器、HC-08蓝牙模块。此次实验搭建的蓝牙通信APP使用的是基AppInventor2服务器的WXbit图像化编程工具,能够较为轻松的搭建出一个APP。
按照既定计划,本项目的流程为,先实现读取DS18B20模块数据,送给LCD1602模块显示,再之后就是最困难的通信模块构建,本次是基于蓝牙模块实现单片机同上位机(安卓手机)之间的通信,这就需要考虑到它们之间波特率的问题,由于此次实验通过的单片机晶振是12Mhz,12Mhz晶振通信起来误差是非常大的,这是由于其并计算初值时存在的误差。而市面上的蓝牙模块其默认波特率大都为9600,采用9600波特率,单片机根本无法同蓝牙模块建立稳定的通信,所以就要求使用AT指令调整波特率,调整到4800,并且波特率翻倍的情况下才能实现误差为0.16%的通信,较为可靠。
其中最头疼的就是数据如何存储发送了,因为串口一次只能发送八位数据,而获取的温度值是有小数的,所以我尝试了两种方案,一是将数据分为整数部分和小数部分,分两次发送,二是将数据存为字符数组,直接发送字符数组,实践证明,第二种效果较好。
蓝牙模块同51系列单片机通信
最重要的方面就是波特率设置啦,这个方面刚开始做的时候说实话踩了不少坑,因为学校电子设计提供的板子上面的晶振是12Mhz,总所周知,12Mhz的晶振通信起来误差是非常大的,这是由于其并计算初值时存在的误差。
最开始,我采用了杨文嘉老师提供的蓝牙模块,调试开始!经过一晚上的摸索,始终没能成功通信,这个时候仔细查阅发现,这个蓝牙模块波特率是固定9600的,而12Mhz的晶振产生9600的波特率,误差会达到5%左右,这是无法接受的,所以理所应当的通信不上。然后我在我的另外一个11.0592Mhz的单片机上面尝试成功。真的头很大,搞了一晚上还以为是单片机串口坏了。
之后,我购买了一个波特率可调的蓝牙模块,提供AT指令将蓝牙模块的波特率调为了4800,(经过查阅资料,发现当51单片机波特率调为4800时,波特率翻倍)这个时候误差会来到0.16%,这个误差能勉强接受,经过调试之后,通过手机上的蓝牙调试软件控制单片机P1口灯开关,成功!!!
然后就开始思考如何完成自己想做。
具体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| #include <REGX52.H> #include "DS18b20.h" #include "LCD1602.h" char RECEIVED_CMD; unsigned char flag = 0 ; extern unsigned int tvalue; extern unsigned char tflag; unsigned char disdata[7]; unsigned char chg[3]; unsigned int wrong = 30;
void UART_Init(); void UART_SendData(char dat); void UART_SendStr(char* str); void ds1820disp(); void change(); void main() { unsigned int temperature , old ; int A=5000; UART_Init(); LCD_Init(); LCD_ShowString(1,1,"Temperature"); P1_4 = 0; temperature = ReadTemperature(); old = temperature ; ds1820disp(); LCD_ShowString(2,1,disdata); LCD_ShowNum(2,13,wrong,2); while(1){ temperature=ReadTemperature(); LCD_ShowNum(2,13,wrong,2); LCD_ShowChar(2,16,'C'); if (temperature != old ) { old = temperature; ds1820disp(); LCD_ShowString(2,1,disdata); } if(temperature > wrong * 10) { P1_4 = !P1_4; while(A--); A=5000; LCD_ShowChar(1,16,'W'); } else { LCD_ShowChar(1,16,'N'); P1_4 = 0; } if(flag) flag = 0 ; if(RECEIVED_CMD == '0') { UART_SendStr(disdata); } else if(RECEIVED_CMD == '3') { change(); UART_SendStr(chg); } else if(RECEIVED_CMD == '1') { wrong ++ ; } else if(RECEIVED_CMD == '2'){ wrong -- ; } RECEIVED_CMD =' '; } } }
void UART_Init() { SCON=0x50; PCON |= 0x80; TMOD &= 0x0F; TMOD |= 0x20; TL1 = 0xF3; TH1 = 0xF3; ET1 = 0; TR1 = 1; EA=1; ES=1; IT0 = 1; IT1 = 1; EX0 = 1; EX1 = 1; } void UART_Isr() interrupt 4 using 1 { if(RI) { RI = 0 ; RECEIVED_CMD = SBUF ; flag = 1 ; } if(TI) { TI = 0 ; } }
void int0() interrupt 0 { wrong ++; }
void int1() interrupt 2 { wrong --; }
void UART_SendData(char dat) { ES = 0 ; SBUF = dat ; while(!TI) ; TI = 0 ; ES = 1 ; }
void UART_SendStr(char *str) { do{ UART_SendData(*str); }while(*str ++ != '\0' ); }
void ds1820disp(){ unsigned char flagdat; if(tflag==0) flagdat=0x2b; else flagdat=0x2d; disdata[1]=tvalue/1000+0x30; disdata[2]=tvalue%1000/100+0x30; disdata[3]=tvalue%100/10+0x30; disdata[4]= 0x2E ; disdata[5]=tvalue%10/1+0x30; if(disdata[1]==0x30) disdata[0]= 0x20; disdata[1]= flagdat; if(disdata[2]==0x30) disdata[1]=0x20; disdata[2]=flagdat; } } }
void change(){ chg[0] = wrong / 10 + 0x30; chg[1] = wrong % 10 + 0x30; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include "DS18b20.h" unsigned int tvalue; unsigned char tflag;
void delay(unsigned int i){ while(i--); }
void Init_DS18B20(void){ unsigned char x=0; DQ = 1; delay(8); DQ = 0; delay(80); DQ = 1; delay(14); x=DQ; delay(20); } unsigned char ReadOneChar(void){ unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) DQ = 0; dat>>=1; DQ = 1; if(DQ) dat|=0x80; delay(4); } return(dat);} void WriteOneChar(unsigned char dat){ unsigned char i=0; for (i=8; i>0; i--) DQ = 0; DQ = dat&0x01; delay(5); DQ = 1; dat>>=1; } } int ReadTemperature(void) { unsigned char a=0; unsigned char b=0; Init_DS18B20(); WriteOneChar(0xCC); WriteOneChar(0x44); Init_DS18B20(); WriteOneChar(0xCC); WriteOneChar(0xBE); a=ReadOneChar(); b=ReadOneChar(); tvalue = b; tvalue <<= 8; tvalue = tvalue|a; if(tvalue<0x0fff) tflag=0; else{ tvalue=~tvalue+1; tflag=1; } tvalue = tvalue*(0.625); return(tvalue); }
|
具体代码:https://github.com/KrealHtz/Studywork