因为stm32f042最小单片机系统外部引脚资源较少,故选取另外一款最小单片机系统stm32f103c8t6,承接前一章基于stm32的温湿度检测案例(一),加入串口通信屏幕将DHT11采集的数据在串口屏幕上显示。使用USART2向屏幕发送数据,屏幕将接收到的数据解析并显示。

DHT11温度湿度检测模块,是检测不到温湿度的小数位滴。


- #include "public.h"
-
- /*********************************************局部方法声明*********************************************/
- void DHT11_GPIO_Out(void);
- void DHT11_GPIO_In(void);
- void DHT11_StructInit(void);
- st_u8 DHT11_ReadByte ( void );
-
- /*********************************************方法定义*********************************************/
- /*********************************************初始化部分*********************************************/
- void DHT11_StructInit(void)
- {
- DHT11_Data.humi_int=0x00;
- DHT11_Data.humi_deci = 0x00;
- DHT11_Data.humi_int = 0x00;
- DHT11_Data.temp_deci=0x00;
- DHT11_Data.check_sum = 0x00;
- }
-
- void DHT11_Init(void)
- {
- DHT11_StructInit();
- DHT11_GPIO_Out();
- //GPIOSet(Debug1_DHT11_PORT, Debug1_DHT11_PIN,1);
- DHT11_H;
- }
- /*********************************************方法定义*********************************************/
- // 输出配置
- void DHT11_GPIO_Out(void)
- {
- // 时钟 端口 引脚 输出模式 通用推挽输出
- GPIOxInit(Debug1_DHT11_RCC,Debug1_DHT11_PORT,Debug1_DHT11_PIN,GPIO_Mode_Out_PP);
- }
-
- // 输入配置
- void DHT11_GPIO_In(void)
- {
- // 时钟 端口 引脚 输入模式 GPIO_Mode_IN_FLOATING
- // GPIOxInit(Debug1_DHT11_RCC,Debug1_DHT11_PORT,Debug1_DHT11_PIN,GPIO_Mode_IN_FLOATING);
-
- // GPIO_Mode_IPU
- GPIOxInit(Debug1_DHT11_RCC,Debug1_DHT11_PORT,Debug1_DHT11_PIN,GPIO_Mode_IPU);
- }
-
- /*
- * 从DHT11读取一个字节,MSB先行
- */
- st_u8 DHT11_ReadByte ( void )
- {
- st_u8 i, temp=0;
- for(i=0;i<8;i++)
- {
- /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/
- while(DHT11_Input==Bit_RESET);
- /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
- *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
- */
- delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可
- if(DHT11_Input==Bit_SET)/* x us后仍为高电平表示数据“1” */
- {
- /* 等待数据1的高电平结束 */
- while(DHT11_Input==Bit_SET);
-
- temp|=(st_u8)(0x01<<(7-i)); //把第7-i位置1,MSB先行
- }
- else // x us后为低电平表示数据“0”
- {
- temp&=(st_u8)~(0x01<<(7-i)); //把第7-i位置0,MSB先行 高位先出。 高位 1111 1111 地位 左边高位,右边地位
- }
- }
- return temp;
- }
-
- /*
- * 一次完整的数据传输为40bit,高位先出
- * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
- */
- st_u8 DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
- {
- /*输出模式*/
- DHT11_GPIO_Out();
- /*主机拉低*/
- DHT11_L;
- /*延时18ms*/
- delay_ms(18);
- /*总线拉高 主机延时30us*/
- DHT11_H;
- delay_us(30); //延时30us
- /*主机设为输入 判断从机响应信号*/
- DHT11_GPIO_In();
- /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/
- if(DHT11_Input==Bit_RESET)
- {
- /*轮询直到从机发出 的80us 低电平 响应信号结束*/
- while(DHT11_Input==Bit_RESET);
- /*轮询直到从机发出的 80us 高电平 标置信号结束*/
- while(DHT11_Input==Bit_SET);
- /*开始接收数据*/
- DHT11_Data->humi_int= DHT11_ReadByte();
- DHT11_Data->humi_deci= DHT11_ReadByte();
- DHT11_Data->temp_int= DHT11_ReadByte();
- DHT11_Data->temp_deci= DHT11_ReadByte();
- DHT11_Data->check_sum= DHT11_ReadByte();
- /*读取结束,引脚改为输出模式*/
- DHT11_GPIO_Out();
- /*主机拉高*/
- DHT11_H;
- /*检查读取的数据是否正确*/
- // 一次完整的数据传输为40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
- if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
- return SUCCESS;
- else
- return ERROR;
- }
- else
- return ERROR;
- }
- /*********************************************测试部分*********************************************/
- void DHT11_Test1(void)
- {
- //int humi_buf[3]; // 湿度
- //int temp_buf[3]; // 温度
- /*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
- if( DHT11_Read_TempAndHumidity (&DHT11_Data) == SUCCESS)
- {
- //printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",\
- // DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
- // 湿度转 十六进制转换为十进制
- //humi_buf[0]= DHT11_Data.humi_int/100+0x30;
- //humi_buf[0]= DHT11_Data.humi_int/10+0x30;
- // humi_buf[1]= DHT11_Data.humi_int%10+0x30;
- //humi_buf[2]= '0';
- printf("湿度:%d\r\n 温度:%d\r\n",DHT11_Data.humi_int,DHT11_Data.temp_int);
- // 湿度 十六进制转换为十进制
- //temp_buf[0]= DHT11_Data.humi_int/100+0x30;
- //temp_buf[1]= DHT11_Data.humi_int/10+0x30;
- //temp_buf[2]= DHT11_Data.humi_int%10+0x30;
-
- //printf("温度:%d\r\n",DHT11_Data.humi_int);
- }
- else
- {
- printf("Read DHT11 ERROR!\r\n");
- }
-
- delay_ms(20000);
- }
- /********************************************* 中断优先级配置*********************************************/
- // 中断分组配置 NVIC_PriorityGroupConfig
- void NVIC_PG_Config(st_u32 PG)
- {
- /*
- 中断分组号 抢占式优先级 子优先级配置/响应式优先级 分配位数
- 0 0 0-15 抢0bit 响4bit(1111)
- 1 0~1 0~7 抢1bit 响3bit(0111)
- 2 0~3 0~3 抢2bit 响2bit(0011)
- 3 0~7 0~1 抢3bit 响1bit(0001)
- 4 0~15 0 抢4bit 响0bit(0000)
- 特征:在抢占式优先级相同的情况下,高响应优先级的中断优先被响应。
- 抢占式优先级数值越小,优先级越高
- */
- if(PG==NVIC_PriorityGroup_0)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
- }else if(PG==NVIC_PriorityGroup_1){
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- }else if(PG==NVIC_PriorityGroup_2) {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- } else if(PG==NVIC_PriorityGroup_3){
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
- }else if(PG==NVIC_PriorityGroup_4){
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
- }else{
- printf("%s","没有使用中断分组\r\n");
- }
- }
- // 中断优先级配置
- void NVIC_Config(st_u8 IRQn,st_u8 IRQChannelPriority,st_u8 IRQChannelSubPriority)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =IRQChannelPriority; // 抢占式优先级 0~15
- NVIC_InitStructure.NVIC_IRQChannelSubPriority =IRQChannelSubPriority ; // 子优先级 0~15
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
-
- /*********************************************串口配置*********************************************/
- void USART_Config(st_u32 BaudRate,USART_TypeDef* USARTx)
- {
- USART_InitTypeDef USART_InitStructure;
- if(USARTx==USART1)RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- if(USARTx==USART2)RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
- /* USART1工作模式配置 */
- USART_InitStructure.USART_BaudRate = BaudRate; //波特率设置:
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置:1位
- USART_InitStructure.USART_Parity = USART_Parity_No ; //是否奇偶校验:无
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制模式设置:没有使能
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//接收与发送都使能
- USART_Init(USARTx, &USART_InitStructure); //初始化USART1
- // 使能串口接收中断
- USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
- // 使能中断发送
- USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);
- USART_Cmd(USARTx, ENABLE); // USART使能
- }
-

- // 清屏背景颜色
- void LCD_CLR(void)
- {
- st_u8 LCDDIR[]={"CLR(15);"};
- LCDUSART2_TX(LCDDIR);
- delay_ms(100);
- }
-
- // 背景颜色
- void LCD_SBC(void)
- {
- st_u8 LCDSBC[] = {"SBC(15);"};
- LCDUSART2_TX(LCDSBC);
- delay_ms(100);
- }
-
- // 设置背景灯光的亮度
- void LCDBL(void)
- {
- // 0~255 0亮度最高 255 关闭显示
- st_u8 LCDBL[]={"BL(30);"};
- LCDUSART2_TX(LCDBL);
- delay_ms(100);
- }
- // 静态数据
- void TempHumi_static(void)
- {
- //unsigned char i;
- // 指令设置 清除背景内容 竖向布局 白色背景颜色
- unsigned char PreInit[] = {"CLR(15);DIR(0);SBC(15)"};
- unsigned char PreInit1[] = {"CLR(15);DIR(0);SBC(15)"};
-
- LCDUSART2_TX(PreInit);
- delay_ms(100);
-
- LCDUSART2_TX(PreInit1);
- delay_ms(100);
-
-
- // TempHumi_STPE(0x09);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0A);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0B);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0C);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0D);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0E);
- // delay_ms(100);
- //
- // TempHumi_STPE(0x0F);
- // delay_ms(100);
- for(unsigned char i=0x09;i<=0x0F;i++)
- {
- TempHumi_STPE(i);
- delay_ms(100);
- }
- }
- // 温湿度界面 静态
- void TempHumi_STPE(st_u8 TempHumi_SINFO)
- {
- unsigned char Style[] = {"PL(0,62,127,62,1);PL(60,0,60,128,1)"};
- unsigned char HD_V[] = {"DC16(0,0,'HD_V:',1)"};
- unsigned char SF_V[] = {"DC16(64,0,'SF_V:',1)"};
- unsigned char Temp[] = {"DC16(0,64,'温度:',1)"};
- unsigned char Temp_unit[] ={"DC16(20,84,'℃',1)"};
- unsigned char Humi[] = {"DC16(64,64,'湿度:',1)"};
- unsigned char Humi_unit[] = {"DC16(100,84,'%',1)"};
-
- switch(TempHumi_SINFO)
- {
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x08:
- case 0x09: // 湿度单位
- LCDUSART2_TX(Humi_unit);
- TempHumi_SINFO++;
- break;
-
- case 0x0A: // 温度单位
- LCDUSART2_TX(Temp_unit);
- TempHumi_SINFO++;
- break;
-
- case 0x0B: // 样式
- LCDUSART2_TX(Style);
- TempHumi_SINFO++;
- break;
-
-
- case 0x0C: // 硬件版本
- //LCDUSART2_TX("DC16(0,0,'HD_V:',1);");
- LCDUSART2_TX(HD_V);
- TempHumi_SINFO++;
- break;
-
- case 0x0D: // 软件版本
- LCDUSART2_TX(SF_V);
- TempHumi_SINFO++;
- break;
-
- case 0x0E: // 温度
- LCDUSART2_TX(Temp);
- TempHumi_SINFO++;
- break;
-
- case 0x0F: // 湿度
- LCDUSART2_TX(Humi);
- TempHumi_SINFO++;
- break;
-
- default:
- //LCD_Show=TempHumi_State;
- break;
-
- }
- }
- // 动态数据
- void TempHumi_Dynamic_Step(st_u8 Debug_Data)
- {
- switch(Debug_Data)
- {
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
-
- case 0x07:
- case 0x08:
- case 0x09:
- case 0x0A:
- case 0x0B:
- case 0x0C: // 硬件版本显示
-
- GetHD_ID(ChipUniqueID[0],0,20);
- break;
-
- case 0x0D: // 软件版本
- LCDDisSfVersion();
- break;
-
- case 0x0E: // 温度显示
- // TempHumi_Value(0,84,DHT11_Data.temp_int);
- // TempHumi_Data_DC16Boxf(DHT11_Data.temp_int,0,84);
- TempHumi_Data_DC16Boxf(Thic.Temp,0,84);
- break;
-
- case 0x0F: // 湿度显示
- // TempHumi_Data_DC16Boxf(Thic.Humi,64,84);
- // TempHumi_Data_DC16Boxf(Thic.Humi,64,84);
- // TempHumi_Value(64,84,DHT11_Data.humi_int);
- Data_Show_Position(Thic.Humi,64,84);
- break;
-
-
- default:
- break;
- }
- }
- // 动态数据
- void TempHumi_Dynamic(void)
- {
- TempHumi_Dynamic_Step(0x0C); // 硬件版本号
- delay_ms(100);
-
- TempHumi_Dynamic_Step(0x0D); // 软件件版本号
- delay_ms(100);
-
- TempHumi_Dynamic_Step(0x0E); // 温度显示
- delay_ms(1000); // 延时太短只上一个数据
-
- TempHumi_Dynamic_Step(0x0F); // 湿度显示
- delay_ms(1000);
-
-
-
- // for(unsigned char i=0x0C;i<=0x0F;i++)
- // {
- // TempHumi_Dynamic_Step(i);
- // delay_ms(100);
- // }
-
-
-
- }