📄 复件 main.txt
字号:
/***********************************************
**** AVR DSDS18B20多点测温范例 ***
**** MCU: ATmega16 ***
**** 作者: maweili ***
**** 编译器:WINAVR ***
**** ***
**** 2008.11.27 ***
***********************************************/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> //中断函数头文件
//××××××××××××引脚宏定义×××××××××××××
//DS18B20定义
#define SET_DQ (PORTA) |= (1 << (PA2)) // DS18B20 高电平
#define CLR_DQ (PORTA) &=~(1 << (PA2)) // DS18B20 低电平
#define DQ_IN (PINA) & (1<<(PA2)) // DS18B20信号输入
#define SET_OUT (DDRA)|= (1<<(PA2)) //PA2定义成输出
#define SET_IN (DDRA)&=~(1<<(PA2)) //PA2定义成输入
//常量声明
#define BAUD 9600
//ROM操作指令码
#define DS18B20_SKIP_ROM 0xCC //跳过ROM指令码
#define DS18B20_SEARCH_ROM 0xF0 //搜索ROM指令码
#define DS18B20_READ_ROM 0x33 //读ROM指令码
#define DS18B20_MATCH_ROM 0x55 //匹配ROM指令码
#define DS18B20_ALARM_ROM 0xEC //报警搜索ROM指令码
//RAM操作指令码
#define DS18B20_CONVERT_RAM 0x44 //启动温度转换指令码
#define DS18B20_READ_RAM 0xBE //读RAM指令码
#define DS18B20_WRITE_RAM 0x4E //写RAM指令码
#define DS18B20_COPY_RAM 0x48 //把RAM的TH、TL、CFG中的内容复制到EEPROM指令码
#define DS18B20_RECALL_EEPROM 0xB8 //把EEPROM的TH、TL、CFG中的内容恢复到RAM指令码
//全局变量声明
unsigned char Temp_H,Temp_L,OK_Flag,ThrH,ThrL,CFG;
//温度高位,低位,复位成功标志,报警上下限值,配置寄存器值
unsigned char ReadRAM_Buff[9],WriteRAM_Buff[3],ReadROM_Buff[8];
//读RAM的9个字节,写RAM的温度上下限报警值和配置寄存器,读取ROM序列号
unsigned char ROM_Buff1[8] = {0x28,0xc5,0x10,0xce,0x00,0x00,0x00,0x3a};
unsigned char ROM_Buff2[8] = {0x28,0x08,0xc1,0xb1,0x00,0x00,0x00,0x3e};
//函数声明
void Delayus(unsigned int lus); //us延时函数
void Delayms(unsigned int lms); //ms延时函数
void Port_DS18B20(void); //DSDS18B20端口配置
void Port_Init(void); //端口初始化配置
void Usart_Init(void); //USART寄存器设置
void Usart_PutChar(unsigned char cTXData); //字节发送函数
void Usart_PutString(unsigned char *pcString); //字符串发送函数
unsigned char DS18B20_Init(void); //DSDS18B20初始化
unsigned char Read_DS18B20(void); //读DS18B20
void Write_DS18B20(unsigned char dat); //写DS18B20
void DS18B20_StartConvert(void); //启动温度转换
void DS18B20_GetConvert(void); //获得温度转换结果
void DS18B20_ReadRAM(void); // 读取RAM内容
void DS18B20_WriteRAM(void); //写温度上下限和配置寄存器到RAM
void DS18B20_CopyEEPROM(void); //复制RAM中的温度上下线和配置寄存器到EEPROM
void DS18B20_RecallRAM(void); //把EEPROM中的温度上下线和配置寄存器恢复到RAM
void DS18B20_ReadROM(void); //读ROM,当总线上只有一个节点时,可以执行此操作
void DS18B20_SearchROM(void); //搜索ROM,确定总线上的节点数目和ROM内容
void DS18B20_SkipROM(void); // 跳过ROM,当总线上只有一个节点时,可以执行此操作
void DS18B20_MatchROM(void); //匹配ROM,此命令后紧跟64位ROM序列号,匹配的节点可以读写
void DS18B20_AlarmROM(void); //报警搜索ROM,只有温度超过设定值的才能响应
//带ROM匹配的函数
void DS18B20_StartConvert1(void); //启动温度转换
void DS18B20_GetConvert1(void); //获得温度转换结果
int main(void)
{
unsigned char i;
unsigned int tempint,tempint1,tempint2,tempint3,tempint4;
//分别存储温度整数值,整数值的千,百,十,个位
unsigned int temppoint,temppoint1,temppoint2,temppoint3,temppoint4;
//分别存储温度小数值,小数值的千,百,十,个位
Port_Init(); //端口初始化
Usart_Init(); //串口初始化
Port_DS18B20(); //DSDS18B20端口初始化
tempint = 0; //变量初始化
temppoint=0;
Temp_H = 0;
Temp_L = 0;
OK_Flag = 0;
Usart_PutString("DS18B20 温度测量实验");
Usart_PutChar(0x0D);
Usart_PutChar(0x0A); //结尾发送回车换行
/*
//这段被屏蔽的程序演示了读出ROM内容,读出的内容发送到计算机可以通过串口观察两次读到
//的值,由于发送的是16进制,所以在串口助手上要选择“HEX”显示(即16进制显示),
//才能进行观察
//注意这个时候总线上只能连接1个DS18B20
DS18B20_ReadROM();
for(i = 0;i < 8;i++)
{
Usart_PutChar(ReadROM_Buff[i]);
}
for(i=0;i<200;i++) //延时4S,再进行温度转换
{
Delayms(200);
}
*/
/*
//这段被屏蔽的程序演示了1、读出RAM内容,读出的内容发送到计算机2、写温度上下限报警值和
//配置寄存器的值到RAM 3、将这3个值保存到EEPROM中,4、将EEPROM中的值恢复到RAM,5、再
//从RAM中读取全部9个字节,并发送到计算机。可以通过串口观察两次读到的值,由于发送的是
//16进制,所以在串口助手上要选择“HEX”显示(即16进制显示),才能进行观察
DS18B20_ReadRAM(); // 读取RAM内容
for(i = 0;i < 9;i++)
{
Usart_PutChar(ReadRAM_Buff[i]);
}
ThrH = 0x50;
ThrL = 0x10;
CFG = 0x7f;
DS18B20_WriteRAM(); //写温度上下限和配置寄存器到RAM
DS18B20_CopyEEPROM(); //复制RAM中的温度上下线和配置寄存器到EEPROM
DS18B20_RecallRAM(); //把EEPROM中的温度上下线和配置寄存器恢复到RAM
DS18B20_ReadRAM(); // 读取RAM内容
for(i = 0;i < 9;i++)
{
Usart_PutChar(ReadRAM_Buff[i]);
}
for(i=0;i<200;i++) //延时4S,再进行温度转换
{
Delayms(200);
}
*/
sei(); //使能全局中断
while(1)
{
//DS18B20_StartConvert1(); //启动温度转换
//DS18B20_GetConvert1(); //获得温度转换结果
//DS18B20_StartConvert(); //启动温度转换
//DS18B20_GetConvert(); //获得温度转换结果
DS18B20_Init(); //初始化DS18B20
Write_DS18B20(0Xcc); //发送ROM指令,跳过ROM匹配
//Write_DS18B20(0X55); //发送ROM指令,跳过ROM匹配
//for(i = 0;i < 8;i++)
//{
// Write_DS18B20(ROM_Buff2[i]);
//}
Write_DS18B20(0X44); // 发送温度转换命令
for(i=0;i<50;i++) //延时1S,等转换完成
{
Delayms(20);
}
DS18B20_Init(); //初始化DS18B20
//Write_DS18B20(0Xcc); //发送ROM指令,跳过ROM匹配
Write_DS18B20(0X55); //发送ROM指令,跳过ROM匹配
for(i = 0;i < 8;i++)
{
Write_DS18B20(ROM_Buff2[i]);
}
Write_DS18B20(0Xbe); //发送读取暂存器指令
Temp_L = Read_DS18B20(); //获得温度的低位
Temp_H = Read_DS18B20(); //获得温度的高位
if(Temp_H & 0x08) //判断温度的正负
{
Temp_H = ~Temp_H; //负温度。取反加1
Temp_L = ~Temp_L; //
SREG |= ~(1 << SREG_C); //清零进位位标志
Temp_L++; //温度低字节加1
if(SREG & (1 << SREG_C)) //有进位吗?
{
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.625得出温度的小数位值,在此扩大1000
//倍,得出温度的4位小数位,显示的时候加小数点
temppoint1 = temppoint / 1000; //千位
temppoint2 = temppoint % 1000 / 100; //百位
temppoint3 = temppoint % 100 / 10; //十位
temppoint4 = temppoint % 10; //个位
Usart_PutString("当前环境温度为:"); //发送温度值到上位机
if(!(tempint1)) //高位为零,则不显示
{
Usart_PutChar(' ');
if(!(tempint2))
{
Usart_PutChar(' ');
}
else
{
Usart_PutChar(tempint2 + 0x30);
}
if(!(tempint3))
{
Usart_PutChar(' ');
}
else
{
Usart_PutChar(tempint3 + 0x30);
}
}
else
{
Usart_PutChar(tempint1 + 0x30);
Usart_PutChar(tempint2 + 0x30);
Usart_PutChar(tempint3 + 0x30);
}
Usart_PutChar(tempint4 + 0x30);
Usart_PutChar('.'); //显示小数点
Usart_PutChar(temppoint1 + 0x30); //显示小数位
Usart_PutChar(temppoint2 + 0x30);
Usart_PutChar(temppoint3 + 0x30);
Usart_PutChar(temppoint4 + 0x30);
Usart_PutChar(' '); //不显示,空一格
Usart_PutChar('o'); //显示温度的符号。由于实在找不到温度那个再上面的小o,
Usart_PutChar('C'); //只好用普通的小写o来代替了。
Usart_PutChar(0x0D);
Usart_PutChar(0x0A); //结尾发送回车换行
for(i=0;i<200;i++) //延时4S,再进行温度转换
{
Delayms(20);
}
}
}
//端口状态初始化设置函数
void Port_Init()
{
PORTD = 0X00; //USART的发送接收端口分别为PD0和PD1
DDRD |= (1 << PD1); //PD0为接收端口,置为输入口;PD1为发送端口,置为输出口
PORTB = 0x00;
DDRB = 0xff;
}
void Port_DS18B20()
{
DDRA &= ~(1 << PA2); // 输入模式(上电时为高电平)
PORTA &= ~(1 << PA2); // 输出锁存器写0,以后不再更改
}
//USART寄存器配置函数
void Usart_Init()
{
UCSRA = 0X00;
UCSRC |= (1<<URSEL) | (1 << UCSZ1) | (1 << UCSZ0); //异步,数据格式8,N,1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -