该项目有四项要求:
(1)检测温度
(2)检测温度超出限定温度,启动报警装置
(3)报警装置启动时,跑马灯进行工作,闪烁起来
(4)利用串口,实时传输温度数据
下面是源代码,运行是完全没有问题的,若读者有更佳的方式,希望可以交流一下.
delay.c
- /*
- *参数 :t(0 - 255)
- *延时时间 :约2 * t + 12
- */
- void delay_us(unsigned char t)
- {
- while(--t);
- }
- void delay_ms(unsigned char t)
- {
- while(t--)
- {
- delay_us(245);
- delay_us(245);
- }
- }
- // void delay_s(unsigned char t)
- // {
- // while(t--)
- // {
- // delay_ms(200);
- // delay_ms(200);
- // delay_ms(200);
- // delay_ms(200);
- // delay_ms(200);
- // }
- // }
delay.h
- #ifndef _DELAY_H_
- #define _DELAY_H_
- extern void delay_us(unsigned char t);
- extern void delay_ms(unsigned char t);
- // extern void delay_s(unsigned char t);
- #endif
lcd.c
- #include "./lcd/lcd.h"
- #define LCDPORT P0
- #define LCD_WRITE_DATA 1
- #define LCD_WRITE_COM 0
- sbit RS = P2^4;
- sbit RW = P2^5;
- sbit E = P2^6;
- void lcd_init()
- {
- delay_ms(15);
- lcd1602_write(0x38,LCD_WRITE_COM); //设置8位数据接口,两行显示,5x7点阵字符
- delay_ms(5);
- lcd1602_write(0x38,LCD_WRITE_COM); //设置8位数据接口,两行显示,5x7点阵字符
- delay_ms(5);
- lcd1602_write(0x38,LCD_WRITE_COM); //设置8位数据接口,两行显示,5x7点阵字符
- delay_ms(5);
- lcd1602_write(0x38,LCD_WRITE_COM); //设置8位数据接口,两行显示,5x7点阵字符
- delay_ms(5);
- lcd1602_write(0x08,LCD_WRITE_COM); //关闭显示,关闭光标和闪烁
- delay_ms(5);
- lcd1602_write(0x01,LCD_WRITE_COM); //清屏
- delay_ms(5);
- lcd1602_write(0x06,LCD_WRITE_COM); //设置指针方式,画面不平移
- delay_ms(5);
- lcd1602_write(0x0c,LCD_WRITE_COM); //设置指针方式,画面不平移
- delay_ms(5);
- }
- void lcd1602_write(unsigned char byte,unsigned char flag)
- {
- if(flag)
- {
- RS = 1;
- }
- else
- {
- RS = 0; //选择输入数据为数据
- }
- RW = 0; //写
- E = 1; //选中LCD
- LCDPORT = byte;
- delay_us(5);
- E = 0; //失能LCD
- }
- void lcd_dis_char(unsigned char x, unsigned char y, unsigned char byte)
- {
- if((x > 15) || (y > 1))
- {
- return ;
- }
- if(0 == y)
- {
- lcd1602_write(0x80 + x,LCD_WRITE_COM);
- }
- else
- {
- lcd1602_write(0x80 + 0x40 + x,LCD_WRITE_COM);
- }
- lcd1602_write(byte,LCD_WRITE_DATA);
- }
- /*显示字符串*/
- void lcd1602_dis_str(unsigned char x, unsigned char y, unsigned char *str)
- {
- if((x > 15) || (y > 1))
- {
- return ;
- }
- if(0 == y)
- {
- lcd1602_write(0x80 + x,LCD_WRITE_COM);
- }
- else
- {
- lcd1602_write(0x80 + 0x40 + x,LCD_WRITE_COM);
- }
- while(*str != '\0')
- {
- lcd1602_write(*str,LCD_WRITE_DATA);
- str++;
- }
- }
- void lcd_dis_self()
- {
- lcd1602_write(0x40,LCD_WRITE_COM);
- lcd1602_write(0x07,LCD_WRITE_DATA);
- lcd1602_write(0x05,LCD_WRITE_DATA);
- lcd1602_write(0x07,LCD_WRITE_DATA);
- lcd1602_write(0x0,LCD_WRITE_DATA);
- lcd1602_write(0x0,LCD_WRITE_DATA);
- lcd1602_write(0x0,LCD_WRITE_DATA);
- lcd1602_write(0x0,LCD_WRITE_DATA);
- lcd1602_write(0x0,LCD_WRITE_DATA);
- lcd1602_write(0x80 + 0x40 + 13,LCD_WRITE_COM);
- lcd1602_write(0x0,LCD_WRITE_DATA);
lcd.h
- <span style="font-size:18px;"><strong>#ifndef __LCD1602_H__
- #define __LCD1602_H__
- #include "./delay/delay.h"
- #include <reg52.h>
- extern void lcd_init();
- extern void lcd1602_write(unsigned char byte,unsigned char flag);
- extern void lcd_dis_char(unsigned char x, unsigned char y, unsigned char byte);
- extern void lcd1602_dis_str(unsigned char x, unsigned char y, unsigned char *str);
- extern void lcd_dis_self();
- #endif</strong></span>
uart.c
- #include <reg52.h>
- #include <stdio.h>
- #include "./delay/delay.h"
- void uart_init()
- {
- SCON = 0x50;
- TMOD |= 0x20;
- TH1 = 0xfd;
- TR1 = 1;
- }
uart.h
- #ifndef _UART_H_
- #define _UART_H_
- extern void uart_init();
- // extern void uart_send_byte(unsigned char byte);
- // extern void uart_send_str(unsigned char *s);
- #endif
主函数:ds18b20.c
- #include <reg52.h>
- #include <intrins.h>
- #include <stdio.h>
- #include "./lcd/lcd.h"
- #include "./delay/delay.h"
- #include "./uart/uart.h"
- #define LEDPORT P1
- sbit ds = P2^3;
- sbit beep = P2^7;
- bit ack = 0;
- void ds_reset()
- {
- ds = 1; //总线拉高
- ds = 0;
- delay_us(200);
- delay_us(200);
- ds = 1; //释放总线
- delay_us(30);
- if(0 == ds) //检测是否被拉低
- {
- ack = 1;
- }
- else
- {
- ack = 0;
- }
- delay_us(200);
- delay_us(100);
- }
- void ds_send_byte(unsigned char byte)
- {
- unsigned char i;
- for(i = 0; i < 8; i++)
- {
- ds = 0;
- _nop_();
- _nop_(); //1us
- ds = byte & 0x01; //最低位开始赋值
- byte >>= 1;
- delay_us(30);
- ds = 1;
- }
- delay_us(30);
- }
- bit ds_read_bit()
- {
- bit tmp;
- ds = 1;
- ds = 0;
- _nop_();
- _nop_();
- ds = 1;
- tmp = ds;
- delay_us(30);
- return tmp;
- }
- unsigned char ds_read_byte()
- {
- unsigned char i,j,k;
- for(i = 0; i < 8; i++)
- {
- j = ds_read_bit();
- k = (j << 7) | (k >> 1);
- }
- return k;
- }
- void main()
- {
- unsigned char a;
- unsigned int b;
- unsigned char i;
- unsigned int temp;
- unsigned char num = 0x7f;
- unsigned char disbuf[20];
- float wendu;
- lcd_init();
- uart_init();
- while(1)
- {
- ds_reset();
- ds_send_byte(0xcc);
- ds_send_byte(0x44);
- ds_reset();
- ds_send_byte(0xcc);
- ds_send_byte(0xbe);
- a = ds_read_byte();
- b = ds_read_byte();
- temp = (b << 8) | a;
- wendu = (float)temp * 0.0625;
- sprintf(disbuf,"%6.2f",wendu);
- lcd1602_dis_str(4,0,"WELCOME!");
- lcd1602_dis_str(1,1,"wendu:");
- lcd1602_dis_str(7,1,disbuf);
- lcd_dis_self();
- lcd_dis_char(14,1,'C');
- if(wendu > 30)
- {
- LEDPORT = _crol_(num,1);
- num = LEDPORT;
- delay_us(50);
- for(i = 0; i < 100; i++)
- {
- beep = ~beep;
- delay_us(100);
- }
- }
- TI = 1; //发送中断标志位
- printf("temperature is : %f\n",wendu);
- }
- }