做一个基于单片机的小项目,把具体的实际应用实现了温湿度检测显示,电路图,原代码及注释,芯片引脚使用,真正的算法流程,最终实现效果。
时间: 2023-06-26 08:08:07 浏览: 108
好的,我们可以做一个基于单片机的温湿度检测显示系统。我们需要以下材料:
1. 单片机:我们选用STM32F103C8T6
2. 温湿度传感器:我们选用DHT11
3. 12864液晶屏
4. 杜邦线若干
5. 电位器一个
6. 面包板一个
接下来我们开始搭建电路,电路图如下:
![电路图](https://img-blog.csdnimg.cn/20220528145251798.png)
接下来,我们需要编写代码。代码如下:
```c
#include "stm32f10x.h"
#include "dht11.h" //DHT11驱动程序
#define LCD_RS_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_RS_GPIO_PORT GPIOB
#define LCD_RS_GPIO_PIN GPIO_Pin_0
#define LCD_RW_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_RW_GPIO_PORT GPIOB
#define LCD_RW_GPIO_PIN GPIO_Pin_1
#define LCD_EN_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_EN_GPIO_PORT GPIOB
#define LCD_EN_GPIO_PIN GPIO_Pin_2
#define LCD_D0_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D0_GPIO_PORT GPIOB
#define LCD_D0_GPIO_PIN GPIO_Pin_8
#define LCD_D1_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D1_GPIO_PORT GPIOB
#define LCD_D1_GPIO_PIN GPIO_Pin_9
#define LCD_D2_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D2_GPIO_PORT GPIOB
#define LCD_D2_GPIO_PIN GPIO_Pin_10
#define LCD_D3_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D3_GPIO_PORT GPIOB
#define LCD_D3_GPIO_PIN GPIO_Pin_11
#define LCD_D4_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D4_GPIO_PORT GPIOB
#define LCD_D4_GPIO_PIN GPIO_Pin_12
#define LCD_D5_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D5_GPIO_PORT GPIOB
#define LCD_D5_GPIO_PIN GPIO_Pin_13
#define LCD_D6_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D6_GPIO_PORT GPIOB
#define LCD_D6_GPIO_PIN GPIO_Pin_14
#define LCD_D7_GPIO_RCC RCC_APB2Periph_GPIOB
#define LCD_D7_GPIO_PORT GPIOB
#define LCD_D7_GPIO_PIN GPIO_Pin_15
void Delay_us(unsigned int nus)
{
unsigned int i=0;
for(;nus>0;nus--)
for(i=0;i<12;i++);
}
void LCD_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(LCD_RS_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_RW_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_EN_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D0_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D1_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D2_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D3_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D4_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D5_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D6_GPIO_RCC, ENABLE);
RCC_APB2PeriphClockCmd(LCD_D7_GPIO_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCD_RS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_RS_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_RW_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_RW_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_EN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_EN_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D0_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D1_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D2_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D3_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D4_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D5_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D6_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_D7_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(LCD_D7_GPIO_PORT, &GPIO_InitStructure);
}
void LCD_WriteCommand(unsigned char command)
{
GPIO_ResetBits(LCD_RS_GPIO_PORT, LCD_RS_GPIO_PIN); //RS=0,写命令
GPIO_ResetBits(LCD_RW_GPIO_PORT, LCD_RW_GPIO_PIN); //RW=0,写数据
GPIO_SetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN); //EN=1
GPIO_Write(GPIOB, command<<8); //写入命令
GPIO_ResetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN); //EN=0
}
void LCD_WriteData(unsigned char data)
{
GPIO_SetBits(LCD_RS_GPIO_PORT, LCD_RS_GPIO_PIN); //RS=1,写数据
GPIO_ResetBits(LCD_RW_GPIO_PORT, LCD_RW_GPIO_PIN); //RW=0,写数据
GPIO_SetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN); //EN=1
GPIO_Write(GPIOB, data<<8); //写入数据
GPIO_ResetBits(LCD_EN_GPIO_PORT, LCD_EN_GPIO_PIN); //EN=0
}
void LCD_Init(void)
{
LCD_GPIO_Config(); //初始化GPIO口
Delay_us(15000); //等待电源稳定
LCD_WriteCommand(0x38); //设置16×2显示,5×7点阵,8位数据口
LCD_WriteCommand(0x0C); //显示开,无光标
LCD_WriteCommand(0x06); //光标右移,字符不动
LCD_WriteCommand(0x01); //清屏
}
void LCD_ShowString(unsigned char x, unsigned char y, unsigned char* str)
{
unsigned char i;
if(x<16 && y<2) //判断字符串是否超出范围
{
if(y==0) //第一行
{
LCD_WriteCommand(0x80+x);
}
if(y==1) //第二行
{
LCD_WriteCommand(0xC0+x);
}
for(i=0; str[i]!='\0'; i++)
{
LCD_WriteData(str[i]); //写入字符
}
}
}
int main(void)
{
char buf[32];
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA时钟
DHT11_Init();// 初始化DHT11
LCD_Init();//初始化LCD
while(1)
{
if(DHT11_Read_Data()) //读取温湿度,并判断是否读取成功
{
sprintf(buf, "Temp:%d.%d C", DHT11_Data[2], DHT11_Data[3]); //将温度数据转换为字符串
LCD_ShowString(0, 0, (unsigned char*)buf); //在LCD第一行显示温度数据
sprintf(buf, "Hum:%d.%d%%", DHT11_Data[0], DHT11_Data[1]); //将湿度数据转换为字符串
LCD_ShowString(0, 1, (unsigned char*)buf); //在LCD第二行显示湿度数据
}
else
{
LCD_ShowString(0, 0, "DHT11 Error!"); //在LCD第一行显示错误信息
}
Delay_us(1000000); //延时1秒
}
}
```
代码注释已经比较详细,这里简单介绍一下。首先是LCD的初始化,然后进入无限循环,读取DHT11的温湿度数据,判断是否读取成功,将温湿度数据转换为字符串,并在LCD屏幕上显示出来。
最后,我们将代码烧录到STM32F103C8T6开发板中,连接传感器和液晶屏,就可以实现温湿度检测显示了。
效果如下:
![效果图](https://img-blog.csdnimg.cn/20220528145254737.png)
阅读全文