项目描述:
单片机(STC89C52RCA)通过1-wire总线协议控制DS18B20测量当前环境的温度,并将采集回的温度数据实时显示在LCD1602上。测温范围:-55°C ~ 125°C。超过温度范围时会蜂鸣器响起,LED灯闪烁报警。
C语言代码如下:
/*----------------------------
FileName:TempratureMeasure.h
Function: 头文件
Author: Zhang Kaizhou
Date: 2019-6-21 16:21:00
----------------------------*/
#include #include #include #define uchar unsigned char #define uint unsigned int /*主模块端口定义*/ sbit start = P3^4; // 启动温度测量 sbit buzzer = P2^3; sbit led = P1^7; /*DS18B20测温模块端口定义*/ sbit DQ = P2^2; /*LCD1602显示模块端口定义*/ sbit lcdrs = P1^0; sbit lcdrw = P1^1; sbit lcden = P2^5; /*主模块函数声明*/ void start18B20(); void getTemprature(); void setAlarmTemprature(uchar tHigh, uchar tLow); void tempratureAlarming(); void timer0Init(); /*1-wire总线模块函数声明*/ void initResetBus(); void writeByte18B20(uchar dat); void writeLogic1(); void writeLogic0(); void readByte18B20(uchar * dat); bit readBit(); /*LCD1602显示模块函数声明*/ void LCDInit(); void display(float dat); void writeCommand(uchar command); void writeData(uchar dat); void delay(uint xms); /*--------------------------------------------------------------- FileName: main.c Function: 单片机通过1-wire总线协议控制DS18B20测量当前环境的温度, 并将采集回的温度数据实时显示在LCD1602上。 Description: 测温范围:-55°C ~ 125°C。超过温度范围时会蜂鸣器响起, LED灯闪烁报警。 Author: Zhang Kaizhou Date: 2019-6-21 11:26:22 ----------------------------------------------------------------*/ #include "TempratureMeasure.h" /*定义全局变量*/ float temprature = 25; // 存放从18B20温度暂存器中读取的温度数据 /*主函数*/ void main(){ LCDInit(); timer0Init(); // setAlarmTemprature(0x28, 0x14); // 温度上下限设置为20~30摄氏度 start18B20(); while(1){ getTemprature(); display(temprature); tempratureAlarming(); } } ///*设置18B20报警温度的上下限*/ //void setAlarmTemprature(uchar tHigh, uchar tLow){ // initResetBus(); // delay(1); // writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测 // writeByte18B20(0x4e); // 写暂存器指令 // writeByte18B20(tHigh); // 报警温度上限30摄氏度 // writeByte18B20(tLow); // 报警温度下限20摄氏度 //} /*温度报警函数*/ void tempratureAlarming(){ if(temprature < 20 || temprature > 30){ // 温度上下限为20~30摄氏度 buzzer = 0; // 开启蜂鸣器报警 TR0 = 1; // 启动timer0,LED闪烁报警 }else{ buzzer = 1; TR0 = 0; } } /*timer0用于LED灯闪烁计时*/ void timer0Init(){ TMOD = 0x01; // timer0 定时模式 16位定时器 非门控启动 TH0 = (65536 - 50000) / 256; // 定时50ms TL0 = (65536 - 50000) % 256; ET0 = 1; // 开timer0溢出中断 EA = 1; // 开全局中断 } /*timer0溢出中断服务程序*/ void timer0Service() interrupt 1{ TH0 = (65536 - 50000) / 256; // 定时50ms TL0 = (65536 - 50000) % 256; led = ~led; } /*启动18B20开始从环境中获取温度*/ void start18B20(){ initResetBus(); delay(1); writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测 writeByte18B20(0x44); // 启动18B20开始温度转换 } /*MCU从18B20的温度暂存器中读取温度*/ void getTemprature(){ uchar tLow, tHigh; uint result; initResetBus(); // 复位总线 delay(1); writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测 writeByte18B20(0xbe); // 启动18B20开始温度转换 readByte18B20(&tLow); // 读取温度暂存器中的低字节 readByte18B20(&tHigh); // 读取温度暂存器中的低字节 result = tHigh; // 高低字节合并成一个双字节数据 result <<= 8; result |= tLow; temprature = result * 0.0625; // 温度寄存器为12bit, 温度分辨率为0.0625 } /*----------------------------- FileName: 1-wireBus.c Function: 单总线操作相关的函数 Author: Zhang Kaizhou Date: 2019-6-21 16:23:34 -----------------------------*/ #include "TempratureMeasure.h" /*定义全局变量*/ uint i; // 延时变量 /*1-wire总线初始化(复位)函数*/ void initResetBus(){ DQ = 0; // 主控设备将总线拉低(480us~960us), 使得总线处于初始化状态 i = 103; while(i) i--; // 将总线拉低870us DQ = 1; // 释放总线并等待(15~60us)接收18B20的应答信号 i = 4; while(i) i--; // 延时等待45us /* 若总线上存在18B20设备, 在检测到总线上引第8行释放总线而产生的上升沿信号后, 等待15~60us之后会将总线拉低60~240us */ // ack = DQ; // 读取18B20的应答信号(若ack = 0, 则总线上存在18B20, 否则无) // return ack; } /*向DS18B20写一个字节数据的函数*/ void writeByte18B20(uchar dat){ bit bitFlag; uchar i; for(i = 0; i < 8; i++){ bitFlag = dat & 0x01; dat >>= 1; if(bitFlag){ // 写1 writeLogic1(); }else{ // 写0 writeLogic0(); } } } /*向1-wire总线写逻辑1*/ void writeLogic1(){ DQ = 0; // 将总线拉低至少1us声明要进行写操作(产生写时隙) _nop_(); _nop_(); // 延时2 * 1.09us = 2.18us DQ = 1; // 从产生写时隙开始在15us之内释放总线 i = 8; while(i) i--; // 延时71us } /*向1-wire总线写逻辑0*/ void writeLogic0(){ DQ = 0; // 将总线拉低至少1us声明要进行写操作(产生写时隙) i = 8; while(i) i--; // 延时71us DQ = 1; // 从产生写时隙开始要将总线持续拉低至少60us _nop_(); _nop_(); } /*从1-wire总线上读取1byte数据*/ void readByte18B20(uchar * dat){ uchar i, temp; for(i = 0; i < 8; i++){ temp = readBit(); * dat = (temp << 7) | ((* dat) >> 1); } } /*从1-wire总线上读取1bit数据*/ bit readBit(){ bit dat; DQ = 0; // 将总线拉低大于1us开始进入读总线时段 _nop_(); DQ = 1; // 释放总线 _nop_(); _nop_(); dat = DQ; i = 8; while(i) i--; // 延时71us return dat; } /*----------------------------- FileName:display.c Function: LCD1602显示函数 Author: Zhang Kaizhou Date: 2019-6-21 16:21:40 ------------------------------*/ #include "TempratureMeasure.h" uchar code table0[] = {"Welcome here"}; uchar code table1[] = {"T:"}; uchar code table2[] = {"0123456789"}; uchar code table3[] = {"'C"}; uchar num = 0; /*初始化LCD1602的设置*/ void LCDInit(){ uchar i; lcden = 0; // 拉低使能端,准备产生使能高脉冲信号 writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口) writeCommand(0x0c); // 开显示,不显示光标 writeCommand(0x06); // 写一个字符后地址指针自动加1 writeCommand(0x01); // 显示清零,数据指针清零 /*LCD上电界面*/ writeCommand(0x80); // 将数据指针定位到第一行首 for(i = 0; i < strlen(table0); i++){ writeData(table0[i]); delay(5); } writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首 for(i = 0; i < strlen(table1); i++){ writeData(table1[i]); delay(5); } } /*LCD显示函数*/ void display(float dat){ uchar i; writeCommand(0x80 + 0x40 + strlen(table1)); writeData(table2[(uchar)((uchar)(dat / 100))]); // 显示温度的百位 delay(5); writeData(table2[(uchar)dat % 100 / 10]); // 显示温度的十位 delay(5); writeData(table2[(uchar)dat % 10]); // 显示温度的个位 delay(5); writeData('.'); // 显示小数点 delay(5); writeData(table2[(uchar)(dat * 10) % 10]); // 显示温度的十分位 delay(5); writeData(table2[(uchar)(dat * 100) % 10]); // 显示温度的百分位 delay(5); for(i = 0; i < strlen(table3); i++){ writeData(table3[i]); delay(5); } } /*写指令函数*/ void writeCommand(uchar command){ lcdrs = 0; // 命令选择 lcdrw = 0; P0 = command; delay(5); lcden = 1; // 产生一个正脉冲使能信号 delay(5); lcden = 0; } /*写数据函数*/ void writeData(uchar dat){ lcdrs = 1; // 数据选择 lcdrw = 0; P0 = dat; delay(5); lcden = 1; delay(5); lcden = 0; } /*延时xms函数*/ void delay(uint xms){ uint i, j; for(i = xms; i > 0; i--) for(j = 110; j > 0; j--); }
上一篇:单片机PWM调光
下一篇:DA转换(IIC总线)
推荐阅读最新更新时间:2024-11-10 09:44
设计资源 培训 开发板 精华推荐
- 使用 LTC6905CS5-133 振荡器驱动 50 欧姆电缆的典型应用电路
- LTC4001-1 的典型应用 - 2A 同步降压锂离子充电器
- GI_Dice_Charger_V1.0_Rel
- ADCLK854/PCBZ,ADCLK954 时钟扇出缓冲器评估板
- AVR481、DB101为图形液晶模块应用电路
- AD8047-EB,AD8047 评估板,用作 AD872(12 位、10 MSPS A/D 转换器)的驱动器
- TJA1100HN 100BASE-T1汽车以太网PHY - 客户评估板
- DC1525A-K,基于 LTC2171-12、12 位、40Msps、1.8V 四路串行 ADC 的演示板
- LTC2288IUP 演示板,DeMUX 双路 ADC,+3.0V,65Msps 10 位 1MHz
- ADR443B 3 Vout 超低噪声、LDO XFET 电压基准的典型应用,具有电流吸收器和电流源