STM32驱动DS18B20温度传感器1602液晶显示

作者:国际小甜 | 创建时间: 2023-05-05
STM32驱动DS18B20温度传感器1602液晶显示

操作方法

/************************************************************************** *      STM32F103VET6 LCD1602液晶显示DS18B20温度 * *  实验板:火牛开发板 *  作者  :爱好单片机 * *************************************************************************/ #include "stm32f10x.h" #include "SysTick.h" #include "lcd1602.h" #include "ds18b20.h" unsigned char  value_flaoutk[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; //温度显示数组 /* *  GPIO端口配置寄存器子函数 */ void GPIO_InitStructReadtempCmd(void) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;  //开漏输出 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //输出速率 GPIO_Init(GPIOE, &GPIO_InitStruct);  //初始化指定端口管脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;  //开漏输出 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //输出速率 GPIO_Init(GPIOD, &GPIO_InitStruct);  //初始化指定端口管脚 } /* *   打开外设时钟子函数 */ void RCC_APB2PeriphReadtempyCmd(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);    //打开GPIOD外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);//打开GPIOE外设时钟 } /* *  DS18B20显示子函数 */ void DISPLAY_DS18B20_tembookeCmd(void) { if(value_flag == 1)//判断如果flag = 1 { value_flag1 = 0x2D;//显示温度 - 号 } else//否则 { value_flag1 = 0x20;//正温度什么都不显示 } value_flaoutk[0] = value_flag1;//温度符号放入数组第1位 value_flaoutk[1] = value_table[value_temp / 1000];//温度百位放入数组第2位 value_flaoutk[2] = value_table[value_temp % 1000 / 100];//温度十位放入数组第3位 value_flaoutk[3] = value_table[value_temp % 100 / 10];//温度个位放入数组第4位 value_flaoutk[4] = 0x2E;//小数点放入数组第5位 value_flaoutk[5] = value_table[value_temp % 10];//温度小数位放入数组第6位 value_flaoutk[6] = 0x20;//显示空白 value_flaoutk[7] = 0xDF;//温度标示 。 value_flaoutk[8] = 0x43;//温度标示 C if(value_flaoutk[1] == 0x30)//判断温度百位是否显示0 { if(value_flaoutk[2] == 0x30)//判断温度十位是否显示0 { value_flaoutk[2] = 0x20;//如果温度十位显示0,什么都不显示 } value_flaoutk[1] = 0x20;//如果温度百位显示0,什么都不显示 } Write_LCD1602_BOOKE_Com_Date(0, 0x80 + 2);//写入LCD1602指定地址 Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[0]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[1]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[2]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[3]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[4]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[5]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[6]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[7]); Write_LCD1602_BOOKE_Com_Date(1, value_flaoutk[8]); } /* *  程序主体 */ int main(void) { SystemInit();//系统时钟初始化为 72M主频 SYSTICK_InitStructReadTCmd();//系统滴答定时器初始化 RCC_APB2PeriphReadtempyCmd();//外设时钟初始化 GPIO_InitStructReadtempCmd();//GPIO端口配置初始化 Init_LCD1602();//LCD1602液晶指令初始化 while(1)//大循环 { Startup_DS18B20_Change();//启动温度转换 Delay_1us(300000);//延时300MS Gretemp_DS18B20_Change();//读DS18B20两个字节转换温度 DISPLAY_DS18B20_tembookeCmd();//DS18B20温度显示 } } /***********************************END*************************************/

LCD1602液晶底层驱动

/*************************************************************************** *STM32F103VET6LCD1602液晶驱动程序 * * * ***************************************************************************/ #ifndef                  _LCD1602_H #define                  _LCD1602_H #include "lcd1602.h" #include "SysTick.h" #define       LCD1602_RS0     GPIOE->BRR  = 0x00000004//RS=0 #define       LCD1602_RW0     GPIOE->BRR  = 0x00000010//RW=0 #define       LCD1602_EN0     GPIOE->BRR  = 0x00000040//EN=0 #define       LCD1602_RS1     GPIOE->BSRR = 0x00000004//RS=1 #define       LCD1602_RW1     GPIOE->BSRR = 0x00000010//RW=1 #define       LCD1602_EN1     GPIOE->BSRR = 0x00000040//EN=1 #define       DATA_OUT        GPIOD->ODR//定义DB0-DB7数据口 /* *  LCD1602液晶写指令子函数 */ void Write_LCD1602_BOOKE_Com(unsigned char Com) { LCD1602_RS0; LCD1602_RW0; LCD1602_EN0; DATA_OUT = Com; Delay_1us(1000);//延时1ms LCD1602_EN1; Delay_1us(1000); LCD1602_EN0; } /* *  LCD1602液晶写数据子函数 */ void Write_LCD1602_BOOKE_Data(unsigned char Date) { LCD1602_RS1; LCD1602_RW0; LCD1602_EN0; DATA_OUT = Date; Delay_1us(1000); LCD1602_EN1; Delay_1us(1000); LCD1602_EN0; } /* *  LCD1602液晶写指令写数据子函数 */ void Write_LCD1602_BOOKE_Com_Date(unsigned char CountLine, unsigned char Date) { if(CountLine == 0) { Write_LCD1602_BOOKE_Com(Date); } else { Write_LCD1602_BOOKE_Data(Date); } } /* *  LCD1602液晶初始化子函数 */ void Init_LCD1602(void) { Write_LCD1602_BOOKE_Com_Date(0, 0x38); Write_LCD1602_BOOKE_Com_Date(0, 0x0C); Write_LCD1602_BOOKE_Com_Date(0, 0x06); Write_LCD1602_BOOKE_Com_Date(0, 0x01); } #endif /**********************************END****************************************/

DS18B20底层驱动

/**************************************************************************** *STM32F103VET6 DS18B20温度驱动程序 * * * ***************************************************************************/ #ifndef                  _DS18B20_H #define                  _DS18B20_H #include "ds18b20.h" #include "SysTick.h" #define       DS18B20_DQ0     GPIOE->BRR  = 0x00000008 //DS18B20数据脚低电平 #define       DS18B20_DQ1     GPIOE->BSRR = 0x00000008 //DS18B20数据脚高电平 #define       DS18B20_DQX     GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) //读取DS18B20数据脚状态 unsigned char value_LSB;  //温度低8位 unsigned char value_MSB;  //温度高8位 unsigned char value_flag;  //温度正负标志 unsigned char value_flag1;  //温度判断标志 unsigned int  value_temp = 180; unsigned char value_table[]={0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};//BCD码0-9 /* *  DS18B20复位子函数 */ unsigned char RESET_DS18B20() { unsigned char Countlook; //定义DS18B20存在脉冲返回变量 DS18B20_DQ1; //DS18B20保持高电平 Delay_1us(1); //延时1us DS18B20_DQ0; //然后拉低 Delay_1us(500); //保持500us DS18B20_DQ1; //在拉高 Delay_1us(45); //保持45us Countlook = DS18B20_DQX; //Countlook读DS18B20是否发出存在脉冲 Delay_1us(200); //延时200us Delay_1us(1); //DS18B20释放总线 return (Countlook); //变量返回 } /* *  DS18B20写操作子函数 */ void Write_DS18B20_BOOKE_Byte(unsigned char Byte) { unsigned char i;//定义变量 for(i = 8; i > 0; i--)//i变量循环--8次一帧数据 { DS18B20_DQ1;//DS18B20保持高电平 Delay_1us(1);//延时1us DS18B20_DQ0;//DS18B20拉低 Delay_1us(2);//延时2us if(Byte & 0x01)//如果变量Byte & 0x01 { DS18B20_DQ1;//DS18B20拉高 } else//否则 { DS18B20_DQ0;//DS18B20拉低 } Delay_1us(20);//延时20us Byte = Byte >> 1;//Byte右移一位 } DS18B20_DQ1;//DS18B20释放总线 } /* *  DS18B20读操作子函数 */ unsigned char Read_DS18B20_BOOKE_Byte() { unsigned char i; //定义变量 unsigned char Byte; //i变量循环--8次一帧数据 for(i = 8 ; i > 0; i--) { DS18B20_DQ1; //DS18B20保持高电平 Delay_1us(1); //延时1us DS18B20_DQ0; //DS18B20拉低 Delay_1us(4); //延时4us DS18B20_DQ1; //DS18B20拉高 Byte = Byte >> 1; //Byte右移一位 if(DS18B20_DQX) //判断变量Byte { Byte = Byte | 0x80; //变量Byte 与上 0x80 } Delay_1us(20); //延时20us } return (Byte); //返回读出来Byte变量 } /* *  DS18B20启动转换子函数 */ void Startup_DS18B20_Change(void) { RESET_DS18B20();  //复位DS18B20 Delay_1us(1000);  //延时1ms Write_DS18B20_BOOKE_Byte(0xCC);  //发出写操作 Skip ROM命令检测地址好 Write_DS18B20_BOOKE_Byte(0x44);  //发出转换Convert T命令 } /* *  DS18B20读两个字节子函数 */ unsigned int Gretemp_DS18B20_Change() { float Tkaddress;//定义浮点型变量 RESET_DS18B20();//复位DS18B20 Delay_1us(1000);//延时1ms Write_DS18B20_BOOKE_Byte(0xCC);//发出写操作 Skip ROM命令检测地址好 Write_DS18B20_BOOKE_Byte(0xBE);//发出读数据命令BEH value_LSB = Read_DS18B20_BOOKE_Byte();//度温度低8位 value_MSB = Read_DS18B20_BOOKE_Byte();//度温度高8位 value_temp = value_MSB;//把读出来高八位温度赋值给value_temp变量 value_temp <<= 8;//value_temp 左移8位 value_temp = value_temp | value_LSB;//把value_temp变量和读出来的温度低8位进行或运算 Tkaddress = value_temp * 0.0625;//把value_temp变量*0.0.0625度赋值给浮点变量 value_temp = Tkaddress * 10 + 0.5;//把浮点变量放大10倍然后四舍五入在赋值给value_temp if(value_temp > 0xFFF)//判断温度是否大于125度 { value_temp = ((~value_temp) +1);//如果大于125度取反加1 value_flag = 1;//-号标志 } else//否则 { value_flag = 0;//正温度什么都不显示 } return (value_temp);//返回温度变量 } #endif /*****************************EDN*****************************************/

系统滴答定时器

/********************************************************************************** *STM32F103VET6 系统滴答定时器驱动程序 * * * ***********************************************************************************/ #ifndef                  _SYSTICK_H #define                  _SYSTICK_H #include "SysTick.h" #define   SYSTICK_CSR   (*((volatile unsigned long *) 0xE000E010)) //控制寄存器 #define   SYSTICK_LOAD  (*((volatile unsigned long *) 0xE000E014)) //重载寄存器 #define   SYSTICK_VAL   (*((volatile unsigned long *) 0xE000E018)) //当前值寄存器 #define   SYSTICK_CALRB (*((volatile unsigned long *) 0xE000E01C)) //校准值寄存器 unsigned long SYSTICK_Delay;  //定义延时变量 /* *  SysTick配置寄存器子函数 */ void SYSTICK_InitStructReadTCmd(void) { if(SysTick_Config(SystemCoreClock / 1000000))  //72000000 / 1000000 = 1us { while(1);  //循环 } SYSTICK_CSR |= 0X06;  //关闭使能计数器需要时在打开 } /* *  SysTick中断服务程序 */ void SysTick_Handler(void) { SYSTICK_VAL = 0;//当前值寄存器清零 if(SYSTICK_Delay != 0x00)//判断延时变量是否等于0 { SYSTICK_Delay--;//延时变量减减 } } /* *  软件延时子函数 */ void Delay_1us(unsigned long CountLing) //带参数的延时子函数 { SYSTICK_CSR |= 0X07; //开启使能计数器 SYSTICK_Delay = CountLing; //延时变量赋值 while(SYSTICK_Delay != 0); //等到延时变量等于0跳出循环 SYSTICK_CSR |= 0X06; //关闭使能计数器 } #endif /****************************************END*********************************************/

点击展开全文

更多推荐