2019-06-12 22:51:39
期末的课程设计告一段落,复习进度变慢,得赶紧进入状态!
总结一下设计中遇到的问题:
1、硬件设计
2、软件设计
总体结构图
代码:
1、Main.c
1 #include <reg52.h> 2 #include<LCD1602.h> 3 #include<stdio.h> 4 #include<DS18B20.h> 5 #include<Button.h> 6 #include<chuankou.h> 7 #include<fengshan.h> 8 9 void display_all();//温度显示 10 sbit BEEP=P3^2; 11 12 uint flag_n=0;//用于获取正确的温度0表示还未获取,1表示已经获取 13 14 15 16 void delayms(uchar i) 17 { 18 while(i--); 19 } 20 21 /*******************************************************************/ 22 /* 23 /* 主函数 24 /* 25 /*******************************************************************/ 26 27 void main() 28 { uchar i; 29 30 Init_inter(); 31 lcd_init(); //LCD初始化 32 delay(10); 33 34 i = 0; 35 lcd_wcmd(0x80); //第1行第1列 36 37 while(table2[i] != ‘\0‘) //按键1对应的字样 38 { 39 lcd_wdata(table2[i]); 40 i++; 41 } 42 43 44 lcd_wcmd(0x80+0x0d); // 设置显示位置为第二行第13个字符 45 lcd_wdata(0xdf); // 显示字符° 46 lcd_wdata(‘c‘); 47 48 i=0; 49 50 lcd_wcmd(0x80+0x40); 51 while(table4[i] != ‘\0‘) //按键1对应的字样 52 { 53 lcd_wdata(table4[i]); 54 i++; 55 } 56 57 Dis_temp(warn_h); 58 i=0; 59 lcd_wcmd(0x80+0x46); 60 while(table5[i] != ‘\0‘) //按键1对应的字样 61 { 62 lcd_wdata(table5[i]); 63 i++; 64 } 65 66 Dis_temp(warn_l); 67 68 69 70 delayms(5); 71 while(1) 72 { 73 74 75 keyscan(); 76 flag_n++; 77 if(flag_n>1000) flag_n=3; 78 79 tempchange();//实时获取温度 80 temp=get_temp(); //获取温度的变化是有一定的延时的 81 if(flag_n>68){ //使用flag_n变量的原因:当第一次获取实时温度时,有一定的延时。当代码烧录进去时会出现85这个温度,因此为了解决这个问题引入flag_n变量,让它第一次获取温度时晚点显示在LCD屏幕上 82 83 display_all();//将数据显示在LCD1602上 84 85 sprintf(MESSAGE,"%d",temp); 86 MESSAGE[3]=MESSAGE[2]; 87 MESSAGE[2]=‘.‘; 88 MESSAGE[4]=‘\0‘; 89 90 91 comm(); 92 93 if(temp>=warn_h*10||temp<=warn_l*10) //当实时温度不在设定的范围内时,蜂鸣器响 94 { 95 BEEP=1; delayms(1000); 96 97 98 BEEP=0; delayms(1000); 99 100 101 102 } 103 104 } 105 106 107 108 } 109 }
1 sbit KEY1=P1^0;//调高TH 2 sbit KEY2=P1^1;//调低TH 3 sbit KEY3=P1^2;//调高TL 4 sbit KEY4=P1^3;//调低TL 5 /********注意:这一段代码文件名字为BUTTON.H************/ 6 uchar flag=0; 7 8 uchar k=0; 9 10 uchar key_state=0; 11 12 void delay_system(unsigned int n) //延时函数 13 { 14 uint x,y; 15 for(x=n;x>0;x--) 16 for(y=110;y>0;y--); 17 } 18 void keyscan(void) 19 { 20 if(KEY1==0) 21 { 22 delay_system(1); 23 if(KEY1==0){ 24 warn_h++; 25 while(!KEY1);//等待按键释放 26 } 27 } 28 if(KEY2==0) 29 { 30 delay_system(1); 31 if(KEY2==0){ 32 warn_h--; 33 while(!KEY2);//等待按键释放 34 } 35 } 36 if(KEY3==0) 37 { 38 delay_system(1); 39 if(KEY3==0){ 40 warn_l++; 41 while(!KEY3);//等待按键释放 42 } 43 } 44 if(KEY4==0) 45 { 46 delay_system(1); 47 if(KEY4==0){ 48 warn_l--; 49 while(!KEY4);//等待按键释放 50 } 51 } 52 } 53 54 void Init_inter() 55 { 56 TMOD=0x01; //使用定时器T0的模式1 57 EA=1; //开总中断 58 ET0=1; //定时器T0中断允许 59 TR0=1; //启动定时器T0 60 TH0=(65536-1000)/256; //定时器T0赋初值,每计数200次(217微秒)发送一次中断请求 61 TL0=(65536-1000)%256; //定时器T0赋初值 62 63 } 64 65 /************************************************* 66 函数功能:定时器T0的中断服务子程序 67 **************************************************/ 68 void Time0_serve(void) interrupt 1 69 { 70 71 TH0=(65536-1000)/256; 72 TL0=(65536-1000)%256; 73 74 }
1 /*******************************************************************/ 2 /* 3 /* DS18B20温度传感器模块 4 /* 5 /*******************************************************************/ 6 sbit ds = P3^7; // 温度传感器信号线 7 /********注意这一段代码文件名为DS18B20.H************/ 8 9 void dsreset(void) //18B20复位,初始化函数 10 { 11 uint i; 12 ds=0; 13 i=103; 14 while(i>0)i--; 15 ds=1; 16 i=4; 17 while(i>0)i--; 18 } 19 20 bit tempreadbit() //读1位数据函数 21 { 22 uint i; 23 bit dat; 24 ds=0;i++; //i++ 起延时作用 25 ds=1;i++;i++; 26 dat=ds; 27 i=8;while(i>0)i--; 28 return dat; 29 } 30 31 uchar tempread() //读1个字节 32 { 33 uchar i,j,dat; 34 dat=0; 35 for(i=1;i<=8;i++) 36 { 37 j=tempreadbit(); 38 dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里 39 } 40 return dat; 41 } 42 43 void tempwritebyte(uchar dat) //向DS18B20写一个字节数据函数 44 { 45 uint i; 46 uchar j; 47 bit testb; 48 for(j=1;j<=8;j++) 49 { 50 testb=dat&0x01; 51 dat=dat>>1; 52 if(testb) //写 1 53 { 54 ds=0; 55 i++;i++; 56 ds=1; 57 i=8;while(i>0)i--; 58 } 59 else 60 { 61 ds=0; //写 0 62 i=8;while(i>0)i--; 63 ds=1; 64 i++;i++; 65 } 66 67 } 68 } 69 void tempchange(void) //DS18B20 开始获取温度并转换 70 { 71 dsreset(); 72 delay(1); 73 tempwritebyte(0xcc); // 写跳过读ROM指令 74 tempwritebyte(0x44); // 写温度转换指令 75 } 76 uint get_temp() //读取寄存器中存储的温度数据函数 77 { 78 uchar a,b; 79 80 dsreset(); 81 delay(1); 82 tempwritebyte(0xcc); 83 tempwritebyte(0xbe); 84 a=tempread(); //读低8位 85 b=tempread(); //读高8位 86 temp=b; 87 temp<<=8; //两个字节组合为1个字 88 temp=temp|a; 89 f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625° 90 temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入 91 f_temp=f_temp+0.05; 92 return temp; //temp是整型 93 } 94 95 void display_all() 96 { 97 /*一下为温度显示模块*/ 98 99 unsigned char i; 100 101 lcd_wcmd(0x80+0x09); 102 103 104 105 t[0]=temp/100; //百位 106 t[1]=temp%100/10; //十位 107 t[2]=temp%10; //个位(小数点后面的一位) 108 109 110 lcd_wdata(table3[t[0]]); //温度的十位 111 lcd_wdata(table3[t[1]]); //温度的个位 112 lcd_wdata(0x20+14); //小数点 113 lcd_wdata(table3[t[2]]); 114 115 i=0; 116 117 lcd_wcmd(0x80+0x40); 118 while(table4[i] != ‘\0‘) //按键1对应的字样 119 { 120 lcd_wdata(table4[i]); 121 i++; 122 } 123 124 Dis_temp(warn_h); 125 i=0; 126 lcd_wcmd(0x80+0x46); 127 while(table5[i] != ‘\0‘) //按键1对应的字样 128 { 129 lcd_wdata(table5[i]); 130 i++; 131 } 132 133 Dis_temp(warn_l); 134 135 }
1 /*******************************************************************/ 2 /* 3 /* 1602液晶模块 这一段代码文件名字为LCD1602.H 4 /* 5 /*******************************************************************/ 6 sbit LCD_RS = P2^6; // 数据/命令选择端(H/L) 7 sbit LCD_RW = P2^5; // 读写选择端(1/0) 8 sbit LCD_EP = P2^7; // 使能信号 9 #define uchar unsigned char 10 #define uint unsigned int 11 uchar code table2[] = {"Now temp: "}; 12 uchar code table3[] = {"0123456789"}; 13 uchar code table4[]="TH:"; 14 uchar code table5[]="TL:"; 15 uchar t[4]; //存温度的每一位 16 uint temp=0; 17 float f_temp=0; 18 uint warn_h=27;//初始的上限为30 19 uint warn_l=15;//初始下限为15 20 void delay(uint xms) 21 { // 延时函数 22 uint i,j; 23 for(i = xms;i > 0;i--) 24 for(j = 110;j > 0;j--); 25 } 26 void lcd_wcmd(uchar cmd) // 写入指令数据到LCD 27 { //RS=L,RW=L,E=高脉冲,D0-D7=指令码。 28 LCD_RS = 0; 29 LCD_RW = 0; 30 LCD_EP = 0; 31 P0 = cmd; 32 delay(1); 33 LCD_EP = 1; 34 delay(1); 35 LCD_EP = 0; 36 } 37 void lcd_wdata(uchar dat) //写入字符显示数据到LCD 38 { //RS=H,RW=L,E=高脉冲,D0-D7=数据 39 LCD_RS = 1; 40 LCD_RW = 0; 41 LCD_EP = 0; 42 P0 = dat; 43 delay(1); 44 LCD_EP = 1; 45 delay(1); 46 LCD_EP = 0; 47 } 48 void lcd_init() //LCD初始化设定初始化函数 49 { 50 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 51 delay(1); 52 lcd_wcmd(0x0c); //设置开显示,不显示光标 53 delay(1); 54 lcd_wcmd(0x06); //写一个字符后地址指针加1 55 delay(1); 56 lcd_wcmd(0x01); //显示清0,数据指针清0 57 delay(1); 58 } 59 60 /*void Dis_temp(uint t);//用于设置上下限显示*/ 61 void Dis_temp(uint t){ 62 63 lcd_wdata(table3[t/10]); 64 lcd_wdata(table3[t%10]); 65 }
1 #define key P1 2 void delay2(uchar n); 3 void delaym(unsigned int i); 4 char MESSAGE[5]="234"; 5 /*****注意这一段代码文件名字为CHUANKOU.H**********/ 6 unsigned char a; 7 unsigned char UART_buff; 8 unsigned char th[]="12H"; 9 unsigned char i=0; 10 unsigned char change=0; 11 void delay2(uchar n) 12 { 13 uchar i,j; 14 for(i=0;i<n;i++) 15 for(j=0;j<50;j++); 16 } 17 /********发送***********/ 18 void post() //发送 19 { 20 21 a=0; 22 23 while(MESSAGE[a] != ‘\0‘) { 24 25 SBUF = MESSAGE[a]; 26 while(!TI); // 等特数据传送 (TI 发送中断标志) 27 TI = 0; // 清除数据传送标志 28 a++; // 下一个字符 29 } 30 31 32 } 33 34 35 void comm() 36 { 37 38 SCON = 0x50; //REN=1 允许串行接受状态,串口工作模式1 39 TMOD|= 0x20; //定时器工作方式2 40 PCON|= 0x80; 41 TH1 = 0xF3; //baud*2 /* 波特率4800、数据位8、停止位1。校验位无 (12M) 42 TL1 = 0xF3; 43 TR1 = 1; 44 ES = 1; //开串口中断 45 EA = 1; // 开总中断 46 EX0=1; 47 post(); 48 49 50 } 51 void delaym(unsigned int i) //延时处理程序 52 { 53 unsigned char j; 54 for(i; i > 0; i--) 55 for(j = 200; j > 0; j--) ; 56 } 57 58 void ser_int (void) interrupt 4 59 { 60 if(RI == 1) { //如果收到. 61 62 RI = 0; //清除标志. 63 UART_buff = SBUF; //接收. 64 th[i]=UART_buff ; 65 i++; 66 if(i==3){ 67 i=0; 68 change=1; 69 } 70 } 71 72 if(change){ //在上位机中,为了让下位机能分别出上下限于是结尾用H表示上限,L表示下限 73 if(th[2]==‘H‘) 74 warn_h=(th[0]-‘0‘)*10+(th[1]-‘0‘); 75 else 76 warn_l=(th[0]-‘0‘)*10+(th[1]-‘0‘); 77 change=0; 78 } 79 }
1 Dim s1(60) ‘上位机代码 2 Dim sum1 As Double 3 Dim flag As Integer 4 Private Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long 5 6 7 Private Sub Command1_Click() 8 If Text1.Text = "" Then 9 MsgBox ("端口未打开!") 10 Else 11 Picture1.Cls 12 Timer4.Enabled = True 13 14 Picture1.Line (-2, 0)-(68, 0) 15 Picture1.Line (0, 38)-(0, -2) 16 Picture1.CurrentX = -2: Picture1.CurrentY = 0: Picture1.Print 0 17 Picture1.CurrentX = 63: Picture1.CurrentY = 0: Picture1.Print "时间/S" 18 Picture1.CurrentX = 0.2: Picture1.CurrentY = 38: Picture1.Print "温度/℃" 19 20 For i = 1 To 12 21 Picture1.Line (0, i * 3)-(60, i * 3), RGB(180, 180, 180) 22 Next i 23 24 For i = 1 To 20 25 Picture1.Line (i * 3, 0)-(i * 3, 36), RGB(180, 180, 180) 26 Picture1.CurrentX = i * 3 - 1.2: Picture1.CurrentY = 0: Picture1.Print i * 3 27 Next i 28 29 30 For j = 1 To 12 31 Picture1.CurrentX = -2.7: Picture1.CurrentY = j * 3 + 1: Picture1.Print j * 3 32 Next j 33 34 End If 35 End Sub 36 37 Private Sub Command2_Click() 38 If Text1.Text = "" Then 39 MsgBox ("端口暂时未接收到数据!请检查端口是否打开!") 40 41 Timer3.Enabled = True 42 43 End If 44 End Sub 45 46 Private Sub Command3_Click() 47 MSComm1.PortOpen = True 48 Timer1.Enabled = True 49 Label13.Caption = "端口通信中" 50 Shape5.FillColor = RGB(0, 255, 0) 51 Shape2.FillColor = RGB(0, 255, 0) 52 53 Timer1.Enabled = True 54 End Sub 55 56 Private Sub Command4_Click() 57 End 58 Unload Me 59 End Sub 60 61 Private Sub Command5_Click() 62 MSComm1.PortOpen = False 63 Shape5.FillColor = RGB(0, 0, 0) 64 Shape2.FillColor = RGB(0, 0, 0) 65 Timer1.Enabled = False 66 Timer4.Enabled = False 67 Label13.Caption = "端口关闭" 68 Text1.Text = "" 69 70 End Sub 71 72 Private Sub Command6_Click() ‘写文件函数 73 74 75 Timer3.Enabled = False 76 s = "D:\温度记录\text1.txt" 77 Open "D:\温度记录\text1.txt" For Append As #1 78 Print #1, Format(Now, "AMPM(hh:mm:ss)") & " " & Text1.Text 79 Close #1 80 MsgBox ("历史温度已经保存在" & s & "下,请注意查看!") 81 82 End Sub 83 84 Private Sub Command7_Click() 85 If Text1.Text = "" Then 86 MsgBox ("端口未打开!") 87 Else 88 Timer4.Enabled = False 89 End If 90 End Sub 91 92 Private Sub Command8_Click() ‘点击发送上限按钮触发事件 93 If Text1.Text = "" Then 94 MsgBox ("端口未打开!") 95 Else 96 MSComm1.InputMode = 0 ‘设置文本格式 97 MSComm1.Output = Text6.Text + "H" ‘上限值传送 98 End If 99 End Sub 100 101 Private Sub Command9_Click() ‘点击发送下限按钮触发事件 102 If Text1.Text = "" Then 103 MsgBox ("端口未打开!") 104 Else 105 MSComm1.InputMode = 0 ‘设置文本格式 106 MSComm1.Output = Text7.Text + "L" ‘下限值传送 107 End If 108 End Sub 109 110 Private Sub Dir1_Change() ‘文件驱动 111 File1.Path = Dir1.Path 112 File1.Pattern = "*.txt" 113 End Sub 114 ‘文件模块 115 Private Sub Drive1_Change() 116 Dir1.Path = Drive1.Drive 117 End Sub 118 119 Private Sub File1_DblClick() ‘鼠标双击事件(打开指定文件)函数 120 Text4.Text = "" 121 p = File1.Path & "\" & File1.FileName 122 ‘Picture1.Picture = Loadpicture(p) 123 ‘Text4.Text = LoadFile(p) 124 125 Open p For Input As #1 ‘读方式打开文件 126 Do While Not EOF(1) ‘循环,只到文件结束 127 Line Input #1, Data ‘将"*.txt"中的一行读到data 中 128 ‘Text1.Text = Text1.Text + Data 129 Text4.Text = Text4.Text & Data & Chr(13) & Chr(10) 130 Loop 131 Close #1 ‘关闭文件号 132 End Sub 133 Private Sub Form_Load() ‘端口初始化函数 134 MSComm1.Settings = "4800,n,8,1" 135 MSComm1.CommPort = 4 136 MSComm1.InputLen = 0 137 MSComm1.InBufferSize = 512 138 MSComm1.InBufferCount = 0 139 MSComm1.OutBufferSize = 512 140 MSComm1.OutBufferCount = 0 141 MSComm1.RThreshold = 1 142 MSComm1.SThreshold = 1 143 flag = 0 144 ‘MSComm1.PortOpen = True‘ 145 Timer1.Enabled = False 146 147 148 Picture1.Line (-2, 0)-(68, 0) 149 Picture1.Line (0, 38)-(0, -2) 150 Picture1.CurrentX = -2: Picture1.CurrentY = 0: Picture1.Print 0 151 Picture1.CurrentX = 63: Picture1.CurrentY = 0: Picture1.Print "时间/S" 152 Picture1.CurrentX = 0.2: Picture1.CurrentY = 38: Picture1.Print "温度/℃" 153 154 For i = 1 To 12 155 Picture1.Line (0, i * 3)-(60, i * 3), RGB(180, 180, 180) 156 Next i 157 158 For i = 1 To 20 159 Picture1.Line (i * 3, 0)-(i * 3, 36), RGB(180, 180, 180) 160 Picture1.CurrentX = i * 3 - 1.2: Picture1.CurrentY = 0: Picture1.Print i * 3 161 Next i 162 163 164 For j = 1 To 12 165 Picture1.CurrentX = -2.7: Picture1.CurrentY = j * 3 + 1: Picture1.Print j * 3 166 Next j 167 168 169 170 171 172 173 174 175 End Sub 176 177 Private Sub MSComm1_OnComm() ‘MSComm事件 178 179 Select Case MSComm1.CommEvent 180 Case comEvReceive 181 inputsignal = MSComm1.Input 182 183 Text1.Text = inputsignal 184 If flag = 0 Then 185 Open "D:\温度记录\text1.txt" For Output As #1 186 Print #1, Format(Now, "AMPM(hh:mm:ss)") & " " & Text1.Text 187 Close #1 188 flag = 1 189 Else 190 Open "D:\温度记录\text1.txt" For Append As #1 191 Print #1, Format(Now, "AMPM(hh:mm:ss)") & " " & Text1.Text 192 Close #1 193 End If 194 195 196 197 198 Case Else 199 End Select 200 End Sub 201 202 203 204 205 206 207 208 209 210 211 212 213 214 Private Sub Timer1_Timer() 215 216 217 If Val(Text1.Text) > Val(Text6.Text) Or Val(Text1.Text) < Val(Text7.Text) Then 218 219 ‘playsnd 2187, 100 220 Shape2.FillColor = RGB(255, 0, 0) 221 Else 222 Shape2.FillColor = RGB(0, 255, 0) 223 224 End If 225 End Sub 226 227 Private Sub Timer2_Timer() 228 ‘Text5.Text = Now ‘获取系统日期与时间 229 Label11.Caption = Now 230 End Sub 231 232 Private Sub Timer3_Timer() 233 234 If Text1.Text = "" Then 235 MsgBox ("端口暂时未接收到数据!") 236 237 End If 238 239 End Sub 240 241 Private Sub Timer4_Timer() 242 t = Second(Time) 243 s1(t) = Val(Text1) 244 245 246 ‘计算均值 247 sum1 = sum1 + s1(t) 248 249 ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘ 250 If t <> 0 Then 251 Text12.Text = (sum1 / (t + 1)) 252 253 Picture1.Line (t - 1, s1(t - 1))-(t, s1(t)), RGB(255, 0, 0) 254 255 End If 256 257 If t = 59 Then 258 Picture1.Cls 259 sum1 = 0: sum2 = 0: sum3 = 0 260 Picture1.Line (-2, 0)-(68, 0) 261 Picture1.Line (0, 38)-(0, -2) 262 Picture1.CurrentX = -2: Picture1.CurrentY = 0: Picture1.Print 0 263 Picture1.CurrentX = 63: Picture1.CurrentY = 0: Picture1.Print "时间/S" 264 Picture1.CurrentX = 0.2: Picture1.CurrentY = 38: Picture1.Print "温度/℃" 265 266 For i = 1 To 12 267 Picture1.Line (0, i * 3)-(60, i * 3), RGB(180, 180, 180) 268 Next i 269 270 For i = 1 To 20 271 Picture1.Line (i * 3, 0)-(i * 3, 36), RGB(180, 180, 180) 272 Picture1.CurrentX = i * 3 - 1.2: Picture1.CurrentY = 0: Picture1.Print i * 3 273 Next i 274 275 For j = 1 To 12 276 Picture1.CurrentX = -2.7: Picture1.CurrentY = j * 3 + 1: Picture1.Print j * 3 277 Next j 278 279 280 End If 281 282 283 End Sub
原文:https://www.cnblogs.com/industrial-fd-2019/p/11013408.html