原创
ATmega16_App_V1.0开发板范例7:LCD1602+USART+DS18B20正负测温实
一、
程序结构
二、
仿真效果
三、main.c主函数
- /*******************************************************************************
- Platform : ATmega16_App_V1.0开发板(http://bbs.armavr.com)
- Project : 范例7:LCD1602+USART+DS18B20正负测温实验(GCC)
- Clock F : 外部3.6864M
- Software : WinAVR-20090313+Proteus7.5
- Author : 林夕依然
- study bss: http://bbs.armavr.com/
- Version : 09.11.03
- Updata :
- comments :
- 1、DS18B20测量环境温度,将温度显示在LCD1602上,并实时发给PC,在串口助手中显示
- LCD和发PC均显示温度符号+/-
- 2、DS18B20接口函数参考马伟力的“基于DS18B20的温度测量实验”
- 3、DS18B20数据接口接4.7K上接电阻到VCC.(电阻焊接在ATmega16_App_V1.0开发板背面),也可去掉此上拉电阻,程序需作相应的改动。
- 4、延时函数使用GCC自带函数
- 5、DS18B20数据线接单片机的PA3端口,进行此实验,需装上JP6短节帽和LCD1602液晶屏。
- 6、可测量负温度,马伟力程序负温度测量错误
- 7、修正三位温度时,十位为零时,在PC/LCD均不显示的问题。如:109时,三者均显示"1 9",中间缺少"0"
- *******************************************************************************/
- #include <avr/io.h>
- #include <util/delay.h>
- #include <avr/interrupt.h>
- #include "main.h"
- #include "ds18b20.h"
- #include "usart.h"
- #include "LCD1602.h"
- //端口初始化
- void Port_Init(void)
- {
- DDRA = 0x00; //PA口上拉
- PORTA = 0xff;
- PORTB = 0x00; //PB口上拉
- DDRB = 0xff;
- PORTC|=0X7F; //LCD点亮背光,不影响DS18B20,固用"|"
- DDRC |=0X80;
- PORTD = 0X00; //USART的发送接收端口分别为PD0和PD1
- DDRD |= (1 << PD1); //PD0为接收端口,置为输入口;PD1为发送端口,置为输出口
- }
- int main(void)
- {
- unsigned int tempint,tempint1,tempint2,tempint3,tempint4;//分别存储温度整数值,整数值的千,百,十,个位
- unsigned int temppoint,temppoint1,temppoint2,temppoint3,temppoint4; //分别存储温度小数值,小数值的1,2,3,4位
- tempint = 0; //变量初始化
- temppoint=0;
- Temp_H = 0;
- Temp_L = 0;
- OK_Flag = 0;
- Port_Init(); //端口初始化
- Usart_Init(); //串口初始化
- LCD_init(); //LCD初始化
- Port_DS18b20(); //DS18B20端口初始化
- LCD_write_str(0,0,"Temperature Test"); //LCD显示测试日期信息
- LCD_write_str(0,1,"Data:2009-11-03");
- Usart_PutString("DS18B20 Temperature Test");//PC串口助手显示测试日期信息
- newline(); //换行
- Usart_PutString("Test data:2009-11-03");
- newline(); //换行
- _delay_ms(3000); //提示信息显示3S
- sei(); //使能全局中断
- while(1)
- {
- cli(); //关中断
- DS18B20_Init(); //初始化DS18B20
- Write_18b20(0Xcc); //发送ROM指令,跳过ROM匹配
- Write_18b20(0X44); //发送温度转换命令
- _delay_ms(1000); //转换需要时间
- DS18B20_Init(); //初始化DS18B20
- Write_18b20(0Xcc); //发送ROM指令,跳过ROM匹配
- Write_18b20(0Xbe); //发送读取暂存器指令
- Temp_L = Read_18b20(); //获得温度的低位
- Temp_H = Read_18b20(); //获得温度的高位
- temp_flag=1; //温度为正时,其值为1;温度为负时,其值为0
- if(Temp_H & 0x08) //判断温度的正负
- {
- temp_flag=0; //温度为负,置0
- Temp_H = ~Temp_H; //负温度。取反加1
- Temp_L = ~Temp_L;
- asm("clc"); //清零进位位标志
- Temp_L++; //温度低字节加1
- if((SREG&0x01)!=0x01)//有进位吗?
- {
- Temp_H++; //有进位,则温度高字节加1
- }
- }
- tempint = ((Temp_H << 4) & 0x70) | (Temp_L >> 4); //获得温度的整数位
- tempint1 = tempint / 1000; //千位
- tempint2 = tempint % 1000 / 100; //百位
- tempint3 = tempint % 100 / 10; //十位
- tempint4 = tempint % 10; //个位
- temppoint = Temp_L & 0x0f; //取出温度的小数位
- temppoint = (temppoint * 625); //小数位乘以0.0625得出温度的小数位值,在此扩大10000
- //倍,得出温度的4位小数位,显示的时候加小数点
- temppoint1 = temppoint / 1000; //千位
- temppoint2 = temppoint % 1000 / 100; //百位
- temppoint3 = temppoint % 100 / 10; //十位
- temppoint4 = temppoint % 10; //个位
- Usart_PutString("Current temperature:"); //显示当前温度提示
- LCD_clear(); //清屏
- LCD_write_str(0,0,"Temperature is:"); //显示温度提示
- if(temp_flag) //温度为正时,显示+
- {
- Usart_PutChar('+'); //发给PC空格
- LCD_write_char(0,1,'+'); //LCD第1行第1位显示+
- }
- else //温度为负时显示负
- {
- Usart_PutChar('-'); //发给PC空格
- LCD_write_char(0,1,'-'); //LCD第1行第1位显示-
- }
- if(!(tempint1)) //高位为零,则不显示
- {
- Usart_PutChar(' '); //发给PC空格
- LCD_write_char(1,1,' '); //LCD第1行第2位显示空白
- if(!(tempint2))
- {
- Usart_PutChar(' '); //发给PC空格
- LCD_write_char(2,1,' '); //LCD第1行第3位显示空白
- }
- else
- {
- Usart_PutChar(tempint2 + 0x30); //发给PC百位
- LCD_write_char(2,1,tempint2+'0');//LCD第1行第3位显示百位
- }
- if(!(tempint3)) //十位为0时,需特殊处理,以此解决温度为3位时,且十位为0时,十位不显示的问题。
- {
- Usart_PutChar('0'); //发给PC字符"0"
- LCD_write_char(3,1,0+'0'); //LCD第1行第4位显示"0"
- }
- else
- {
- Usart_PutChar(tempint3 + 0x30); //发给PC十位
- LCD_write_char(3,1,tempint3+'0');//LCD第1行第4位显示十位
- }
- }
- else
- {
- Usart_PutChar(tempint1 + 0x30); //发给PC千位
- LCD_write_char(1,1,tempint1+'0'); //LCD第1行第2位显示千位
- Usart_PutChar(tempint2 + 0x30); //发给PC百位
- LCD_write_char(2,1,tempint2+'0'); //LCD第1行第3位显示百位
- Usart_PutChar(tempint3 + 0x30); //发给PC十位
- LCD_write_char(3,1,tempint3+'0'); //LCD第1行第4位显示十位
- }
- Usart_PutChar(tempint4 + 0x30); //发给PC个位
- Usart_PutChar('.'); //发给PC小数点
- LCD_write_char(4,1,tempint4+'0'); //LCD第1行第5位显示个位
- LCD_write_char(5,1,'.'); //LCD第1行第6位显示小数点
- Usart_PutChar(temppoint1 + 0x30); //发给PC第1小数位
- LCD_write_char(6,1,temppoint1+'0'); //LCD第1行第7位显实第1小数点
- Usart_PutChar(temppoint2 + 0x30); //发给PC第2小数位
- LCD_write_char(7,1,temppoint2+'0'); //LCD第1行第8位显实第2小数点
- Usart_PutChar(temppoint3 + 0x30); //发给PC第3小数位
- LCD_write_char(8,1,temppoint3+'0'); //LCD第1行第9位显实第3小数点
- Usart_PutChar(temppoint4 + 0x30); //发给PC第4小数位
- LCD_write_char(9,1,temppoint4+'0'); //LCD第1行第10位显实第4小数点
- Usart_PutChar(' '); //不显示,空一格
- Usart_PutChar('o'); //显示温度的符号
- Usart_PutChar('C');
- LCD_write_str(10,1," oC"); //LCD第1行第11/12/13位显实温度单位
- newline(); //换行
- sei(); //开中断
- _delay_ms(3000);//3S更新一次温度测量值
- }
- }
四、完整项目文件
https://static.assets-stash.eet-china.com/album/old-resources/2009/11/9/5778c2ba-59fc-43bc-a7df-e309404e4929.rar
文章评论(0条评论)
登录后参与讨论