STM32—项目四(LCD屏显示温湿度)

目录

一、LCD1602液晶显示屏

1.说明

2.例子(LDC显示字符)

二、DHT11温湿度传感器

三、实验(LCD屏显示温湿度)

1.接线

2.配置

3.main.c代码


一、LCD1602液晶显示屏

1.说明

        1.引脚接口说明

第 1 脚: VSS 为电源地

第 2 脚: VDD 接 5V 正电源

第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度 过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度。

第 4 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第 5 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。

                当 RS 和 R/W 共 同为低电平时可以写入指令或者显示地址,

                当 RS 为低电平 R/W 为高电平时可以读忙信号,

                当 RS 为高电平 R/W 为低电平时可以写入数据。

第 6 脚:E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。

第 7-14 脚:D0~D7 为 8 位双向数据线。

第 15 脚:背光源正极。

第 16 脚:背光源负极。

        2.模块控制指令

         3.在什么位置显示

         例如:第二行第一个字符的地址是 40H,那么是否直接写入 40H 就可以将光标定位在第二行第 一个字符的位置呢?这样不行,因为写入显示地址时要求最高位 D7 恒定为高电平 1 所以实 际写入的数据应该是 01000000B(40H) +10000000B(80H)=11000000B(C0H)。

         4.显示什么(Ascll码表)

        5.读操作时序

        6.写操作时序

2.例子(LDC显示字符)

        1.接线

        D0~D7->A0~A7        RS -> B1         RW -> B2         EN -> B10        V0 ->GND

        BLA ->VCC        BLK->GND

        2.配置

              1.SYS

        2.RCC

         3.GPIO

        3.main.c代码(显示jiayou)

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

//宏定义 为了更加简便
#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_Pin GPIO_PIN_1
#define RW_Pin GPIO_PIN_10
#define EN_Pin GPIO_PIN_0

#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET)//RS拉高
#define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_SET)//RW拉高
#define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_SET)//EN拉高
#define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET)



void Write_Cmd_Func(uint8_t cmd)//写命令
{
	RS_LOW;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = cmd;//cmd的数据按位输出给A口
	HAL_Delay(5);//5ms
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}

void Write_Data_Func(uint8_t dataShow)//写数据
{
	RS_HIGH;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = dataShow;
	HAL_Delay(5);
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}



void LCD1602_INIT(void)//初始化
{
	//(1)延时 15ms
	HAL_Delay(15);
	//(2)写指令 38H(不检测忙信号)
	Write_Cmd_Func(0x38);
	//(3)延时 5ms
	HAL_Delay(5);
	//(4)以后每次写指令,读/写数据操作均需要检测忙信号
	//(5)写指令 38H:显示模式设置
	Write_Cmd_Func(0x38);
	//(6)写指令 08H:显示关闭
	Write_Cmd_Func(0x08);
	//(7)写指令 01H:显示清屏
	Write_Cmd_Func(0x01);
	//(8)写指令 06H:显示光标移动设置
	Write_Cmd_Func(0x06);
	//(9)写指令 0CH:显示开及光标设置}
	Write_Cmd_Func(0x0c);
}

void LCD1602_showLine(char row, char col, char *string)
{
	switch(row){
		case 1:
		Write_Cmd_Func(0x80+col);//第一行
	while(*string){
		Write_Data_Func(*string);
		string++;
	}
		break;
	
		case 2:
		Write_Cmd_Func(0x80+0x40+col);//第二行
	while(*string){
		Write_Data_Func(*string);
		string++;
	}
		break;
	}
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */


	LCD1602_INIT();//初始化
	LCD1602_showLine(1,1,"jia");//横、列、字符串
	LCD1602_showLine(2,1,"you");


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

二、DHT11温湿度传感器

        详细介绍看(1条消息) STM32—项目三(温湿度在oled屏显示)_wlkq~的博客-CSDN博客

        1.总时序图(主机信号由代码设置波形,DHT信号由DHT11发出)

         2.初始化部分  检测模块是否存在(检测下图DHT响应信号有没有被拉低)

         3.接收数据部分(有效数据都是高电平,但持续时间不一样,可通过延时后是否被拉低来判断是0还是1)

                 DHT11传输0的时序分析

               DHT11传输1的时序分析  

         4.数据格式

        只有一根数据线DAT,发送序列指令给DHT11模块,模块就会传输一次完整的数据为40bit(8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验),高位先出。

三、实验(LCD屏显示温湿度)

1.接线

        D0~D7->A0~A7        RS -> B1         RW -> B2         EN -> B10        V0 ->GND

        BLA ->VCC        BLK->GND

        DAT->B3

2.配置

         1.SYS

        2.RCC

         3.GPIO

        4.B3既作为输入,也作为输出,则不能直接在CubeMX里配置,需要自己写代码。

3.main.c代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

//LCD宏定义 为了更加简便
#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_Pin GPIO_PIN_1
#define RW_Pin GPIO_PIN_10
#define EN_Pin GPIO_PIN_0

#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET)//RS拉高
#define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_SET)//RW拉高
#define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_SET)//EN拉高
#define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET)

//DH11宏定义
#define DAT_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET)
#define DAT_HIGH HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET)

#define DAT_VALUE HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)

void delay_us(uint32_t us)//微妙延时
{
    uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
    while (delay--)
    {
        ;
    }
}

void Write_Cmd_Func(uint8_t cmd)//LCD写命令
{
	RS_LOW;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = cmd;//cmd的数据按位输出给A口
	HAL_Delay(5);//5ms
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}

void Write_Data_Func(uint8_t dataShow)//LCD写数据
{
	RS_HIGH;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = dataShow;
	HAL_Delay(5);
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}



void LCD1602_INIT(void)//LCD初始化
{
	//(1)延时 15ms
	HAL_Delay(15);
	//(2)写指令 38H(不检测忙信号)
	Write_Cmd_Func(0x38);
	//(3)延时 5ms
	HAL_Delay(5);
	//(4)以后每次写指令,读/写数据操作均需要检测忙信号
	//(5)写指令 38H:显示模式设置
	Write_Cmd_Func(0x38);
	//(6)写指令 08H:显示关闭
	Write_Cmd_Func(0x08);
	//(7)写指令 01H:显示清屏
	Write_Cmd_Func(0x01);
	//(8)写指令 06H:显示光标移动设置
	Write_Cmd_Func(0x06);
	//(9)写指令 0CH:显示开及光标设置}
	Write_Cmd_Func(0x0c);
}

void LCD1602_showLine(char row, char col, char *string)//LCD行、列、字符串显示
{
	switch(row){
		case 1:
		Write_Cmd_Func(0x80+col);//第一行
	while(*string){
		Write_Data_Func(*string);
		string++;
	}
		break;
	
		case 2:
		Write_Cmd_Func(0x80+0x40+col);//第二行
	while(*string){
		Write_Data_Func(*string);
		string++;
	}
		break;
	}
}

void DHT_GPIO_Init(uint32_t Mode)//初始化GPIO口,PB3口接温度传感器DAT
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();//时钟
	GPIO_InitStruct.Pin = GPIO_PIN_3;
	GPIO_InitStruct.Mode = Mode;//输出还是输入
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_Start()//DHT11初始化开始信号
{
   //下面是主机信号
	DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);//PA5设置为输出推挽模式
	DAT_HIGH;
	DAT_LOW;
	HAL_Delay(30);//ms
	DAT_HIGH;
	
	DHT_GPIO_Init(GPIO_MODE_INPUT);//PA5设置为输入模式
  //下面是DHT信号,如果符合DHT信号时序图就进行运行
	while(DAT_VALUE);
	//dht=0
	while(!DAT_VALUE);
	//dht=1
	while(DAT_VALUE);//之后开始传输数据
	//dht=0
}

uint8_t data[5];//存放DH11数据

void DHT11_Read()//接收DH11数据
{
	int i;
	int j;
	char tmp;//移位,存放8个bit
	char flag;//标志位
	
	DHT11_Start();//重启进入高速模式之后才发送bit

	DHT_GPIO_Init(GPIO_MODE_INPUT);//PA5设置为输入模式
	for(i = 0;i < 5;i++){//取4个字节

		for(j=0;j<8;j++){//每个字节取8个bit
			while(!DAT_VALUE);//卡g点数据来会从0变成1 
			delay_us(40); //延时读取
			if(DAT_VALUE == 1){
					flag = 1;
					while(DAT_VALUE);//等待变位70us下一个bit
			}else{
					flag = 0;
			}	
			tmp = tmp << 1;//左移一位或者  tmp<<=1,为了使先出来的bit到高位
			tmp |= flag;//可以为   tmp=tmp|flag  
		}
		data[i] = tmp;//得到8个bit为一个字节,存放在数组里  
	}

}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	char SpeedMes[16];//存放显示的字符串
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
		LCD1602_INIT();//初始化
		DHT11_Read();//读取数据
		
		sprintf(SpeedMes,"H:%d.%d",data[0], data[1]);
		LCD1602_showLine(1,0,SpeedMes);//横、列、字符串
		
		sprintf(SpeedMes,"T:%d.%d",data[2], data[3]);
		LCD1602_showLine(2,0,SpeedMes);//横、列、字符串
		HAL_Delay(600);//	600毫秒
		}
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wlkq~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值