任务描述:实现温度报警器
实验目的:
- 掌握DS18B20温度传感器的使用方法
- 掌握HC595模块的使用方法
- 掌握蜂鸣器模块的使用方法
DS18B20延时
命令
接线图:
外设 | 引脚 |
蜂鸣器 | (buzzer)I/O=PA4 |
HC595 | DIO ==> PA27 SCLK==>PA26 RCLK ==> PA13 |
DS18B20 | DQ ==> PA1 |
systools 配置
DS18B20初始化配置,读取
//DS18B20 DQ 相关定义 #define SET_DQ_OUT() do{\ DL_GPIO_initDigitalOutput(DQ_PORT_DQ_IOMUX);\ DL_GPIO_enableOutput(DQ_PORT_PORT, DQ_PORT_DQ_PIN); \ } while(0) #define SET_DQ_IN() do{\ DL_GPIO_disableOutput(DQ_PORT_PORT, DQ_PORT_DQ_PIN); \ DL_GPIO_initDigitalInput(DQ_PORT_DQ_IOMUX); \ } while(0) #define DQ(x) (x) ? (DL_GPIO_setPins(DQ_PORT_PORT, DQ_PORT_DQ_PIN)) : (DL_GPIO_clearPins(DQ_PORT_PORT, DQ_PORT_DQ_PIN)) #define GET_DQ() DL_GPIO_readPins(DQ_PORT_PORT, DQ_PORT_DQ_PIN) unsigned char tempL = 0; // 设全局变量 unsigned char tempH = 0; unsigned int sdata; // 测量到的温度的整数部分 unsigned char xiaoshu1; // 小数第一位 unsigned char xiaoshu2; // 小数第二位 unsigned char xiaoshu; //相关延时函数 void delay(uint32_t us) { delay_cycles(32*us); //delay 1us } void delay1ms(uint32_t ms) { delay(1000*ms); } void Init_DS18B20(void) { unsigned char x = 0; SET_DQ_OUT(); DQ(1); // DQ先置高 delay(8*8); // 稍延时 DQ(0); // 发送复位脉冲 delay(490); // 延时(>480us) DQ(1); // 拉高数据线 delay(60); // 等待(15~60us) SET_DQ_IN(); x=GET_DQ(); // 用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 delay(160); } /**********读一个字节************/ uint8_t ReadOneChar(void) // 主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号 { unsigned char i = 0; // 每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期 unsigned char dat = 0; for (i = 8; i > 0; i--) // 一个字节有8位 { SET_DQ_OUT(); DQ(1); delay(8); DQ(0); dat >>= 1; DQ(1); SET_DQ_IN(); if( GET_DQ()) dat |= 0x80; delay(32); } return (dat); } /*****写一个字节*****/ void WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--) { SET_DQ_OUT(); DQ(0); DQ(dat&0x01); //与1按位与运算,dat最低位为1时DQ总线为1,dat最低位为0时DQ总线为0 delay(42); DQ(1); dat>>=1; } delay(33); } // 读温度值(低位放tempL;高位放tempH;) uint8_t fg; void ReadTemperature(void) { Init_DS18B20(); // 初始化 WriteOneChar(0xcc); // 跳过读序列号的操作 WriteOneChar(0x44); // 启动温度转换 delay(800); // 转换需要一点时间,延时 Init_DS18B20(); // 初始化 WriteOneChar(0xcc); // 跳过读序列号的操作 WriteOneChar(0xbe); // 读温度寄存器(头两个值分别为温度的低位和高位) tempL = ReadOneChar(); // 读出温度的低位LSB tempH = ReadOneChar(); // 读出温度的高位MSB if (tempH > 0x7f) // 最高位为1时温度是负 { tempL = ~tempL; // 补码转换,取反加一 tempH = ~tempH + 1; fg = 0; // 读取温度为负时fg=0 } sdata = tempL / 16 + tempH * 16; // 整数部分 xiaoshu1 = (tempL & 0x0f) * 10 / 16; // 小数第一位 xiaoshu2 = (tempL & 0x0f) * 100 / 16 % 10; // 小数第二位 xiaoshu = xiaoshu1 * 10 + xiaoshu2; // 小数两位 }
实际测试结果
问题:1) HC595的显示 ,有明有暗 这个待解决(把读取函数放到定时器中断回调函数里可以解决一下 ,但还是不太亮)
2) 借用串口打印数据 ,使用printf函数过程中选择Use Micro LIB
打印不了浮点数(程序hardware default)