小言_互联网的博客

STM32单片机之温湿度检测系统(DTH11、OLED、LCD1602)

10082人阅读  评论(0)

LCD1602

LCD1602引脚

  • 第 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 脚:背光源负极。

LCD1602显示字符

写时序图和读时序图

读时序图

写时序图

时序图的参数

根据写时序图,封装LCD1602写入指令和写入数据的两个函数

一些宏定义

写入指令

写入数据

检测忙标志是否忙

  • 液晶显示模块是一个慢显示器件,所以在写入每条指令或数据之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。

  • 由于BF标志位为数据线的D7引脚,我们只关心D7引脚,而且BF标志位为高电平时,LCD1602表示忙,可以利用一个while(BF)循环卡住,然后不断读取数据线的D7引脚,等待LCD1602不忙时,硬件将BF标志位置0。

LCD1602初始化

8bit的LCD1602初始化

  1. 延时 15ms

  1. 写指令 38H(不检测忙信号)

  1. 延时 5ms

  1. 写指令 38H:显示模式设置

  1. 写指令 08H:显示关闭

  1. 写指令 01H:显示清屏

  1. 写指令 06H:显示光标移动设置

  1. 写指令 0CH:显示开及光标设置

封装8bit的LCD1602初始化的函数

4bit的LCD1602初始化

  1. 延时 50ms

  1. 发送 0x03(4bit)(rs=0,rw=0)

  1. 延时 4.5ms

  1. 发送 0x03(4bit)(rs=0,rw=0)

  1. 延时 4.5ms

  1. 发送 0x03(4bit)(rs=0,rw=0)

  1. 延时 150μs

  1. 发送 0x02(4bit)(rs=0,rw=0)

  1. 写指令 28H(8bit)

  1. 写指令 0CH(8bit)

  1. 写指令 01H(8bit)

  1. 延时 2ms(8bit)

  1. 写指令 06H(8bit)

在哪里显示,写入指令(地址)

LCD1602 内部显示地址

由于写入指令或数据的时候,数据线D7恒定为高电平,即如果想要在0x40显示字符,则实际写入的地址为0x40 + 0x80。

显示什么字符(写入数据)

LCD1602 模块字库表

由于字符A的ASCII码为65,即0100 0001,与LCD1602 模块字库表一致,因此在写入字符的时候,直接传入一个'A'即可。

LCD1602显示一个字符

LCD1602与STM32F103C8T6板子接线
  • PB0<->RS

  • PB1<->RW

  • PB2<->EN

  • PA0<->D0

  • PA1<->D1

  • PA2<->D2

  • PA3<->D3

  • PA4<->D4

  • PA5<->D5

  • PA6<->D6

  • PA7<->D7

STM32CubeMX相关配置
配置SYS

配置RCC

配置GPIO

main函数编写

   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "tim.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. //LCD1602相关的宏定义
  26. #define RS_GPIO_Port GPIOB
  27. #define RW_GPIO_Port GPIOB
  28. #define EN_GPIO_Port GPIOB
  29. #define RS_GPIO_PIN GPIO_PIN_0
  30. #define RW_GPIO_PIN GPIO_PIN_1
  31. #define EN_GPIO_PIN GPIO_PIN_2
  32. #define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
  33. #define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
  34. #define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
  35. #define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
  36. #define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
  37. #define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)
  38. /* USER CODE END Includes */
  39. /* Private typedef -----------------------------------------------------------*/
  40. /* USER CODE BEGIN PTD */
  41. /* USER CODE END PTD */
  42. /* Private define ------------------------------------------------------------*/
  43. /* USER CODE BEGIN PD */
  44. /* USER CODE END PD */
  45. /* Private macro -------------------------------------------------------------*/
  46. /* USER CODE BEGIN PM */
  47. /* USER CODE END PM */
  48. /* Private variables ---------------------------------------------------------*/
  49. /* USER CODE BEGIN PV */
  50. /* USER CODE END PV */
  51. /* Private function prototypes -----------------------------------------------*/
  52. void SystemClock_Config(void);
  53. /* USER CODE BEGIN PFP */
  54. /* USER CODE END PFP */
  55. /* Private user code ---------------------------------------------------------*/
  56. /* USER CODE BEGIN 0 */
  57. //LCD1602写指令
  58. void writeCmd(char cmd)
  59. {
  60. RS_LOW; //选择写指令寄存器
  61. RW_LOW;
  62. EN_LOW;
  63. GPIOA->ODR = cmd; //将指令存入LCD1602的八位数据线中
  64. HAL_Delay( 5);
  65. EN_HIGH;
  66. HAL_Delay( 5);
  67. EN_LOW;
  68. }
  69. //LCD1602写数据
  70. void writeData(char myData)
  71. {
  72. RS_HIGH; //选择写数据寄存器
  73. RW_LOW;
  74. EN_LOW;
  75. GPIOA->ODR = myData; //将数据存入LCD1602的八位数据线中
  76. HAL_Delay( 5);
  77. EN_HIGH;
  78. HAL_Delay( 5);
  79. EN_LOW;
  80. }
  81. //LCD1602初始化
  82. void lcd1602Init()
  83. {
  84. HAL_Delay( 15); //延时 15ms
  85. writeCmd( 0x38); //写指令 38H(不检测忙信号)
  86. HAL_Delay( 5); //延时 5ms
  87. writeCmd( 0x38); //写指令 38H:显示模式设置
  88. writeCmd( 0x08); //写指令 08H:显示关闭
  89. writeCmd( 0x01); //写指令 01H:显示清屏
  90. writeCmd( 0x06); //写指令 06H:显示光标移动设置
  91. writeCmd( 0x0C); //写指令 0CH:显示开及光标设置
  92. }
  93. /* USER CODE END 0 */
  94. /**
  95. * @brief The application entry point.
  96. * @retval int
  97. */
  98. int main(void)
  99. {
  100. /* USER CODE BEGIN 1 */
  101. /* USER CODE END 1 */
  102. /* MCU Configuration--------------------------------------------------------*/
  103. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  104. HAL_Init();
  105. /* USER CODE BEGIN Init */
  106. /* USER CODE END Init */
  107. /* Configure the system clock */
  108. SystemClock_Config();
  109. /* USER CODE BEGIN SysInit */
  110. /* USER CODE END SysInit */
  111. /* Initialize all configured peripherals */
  112. MX_GPIO_Init();
  113. MX_TIM2_Init();
  114. /* USER CODE BEGIN 2 */
  115. char displayAddress = 0x80 + 0x05;
  116. char dsiplayData = 'H';
  117. lcd1602Init();
  118. writeCmd(displayAddress); //字符显示的地址
  119. writeData(dsiplayData); //显示的字符
  120. /* USER CODE END 2 */
  121. /* Infinite loop */
  122. /* USER CODE BEGIN WHILE */
  123. while ( 1)
  124. {
  125. /* USER CODE END WHILE */
  126. /* USER CODE BEGIN 3 */
  127. }
  128. /* USER CODE END 3 */
  129. }
  130. /**
  131. * @brief System Clock Configuration
  132. * @retval None
  133. */
  134. void SystemClock_Config(void)
  135. {
  136. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  137. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  138. /** Initializes the RCC Oscillators according to the specified parameters
  139. * in the RCC_OscInitTypeDef structure.
  140. */
  141. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  142. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  143. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  144. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  145. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  146. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  147. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  148. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  149. {
  150. Error_Handler();
  151. }
  152. /** Initializes the CPU, AHB and APB buses clocks
  153. */
  154. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  155. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  156. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  157. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  158. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  159. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  160. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  161. {
  162. Error_Handler();
  163. }
  164. }
  165. /* USER CODE BEGIN 4 */
  166. /* USER CODE END 4 */
  167. /**
  168. * @brief This function is executed in case of error occurrence.
  169. * @retval None
  170. */
  171. void Error_Handler(void)
  172. {
  173. /* USER CODE BEGIN Error_Handler_Debug */
  174. /* User can add his own implementation to report the HAL error return state */
  175. __disable_irq();
  176. while ( 1)
  177. {
  178. }
  179. /* USER CODE END Error_Handler_Debug */
  180. }
  181. #ifdef USE_FULL_ASSERT
  182. /**
  183. * @brief Reports the name of the source file and the source line number
  184. * where the assert_param error has occurred.
  185. * @param file: pointer to the source file name
  186. * @param line: assert_param error line source number
  187. * @retval None
  188. */
  189. void assert_failed(uint8_t *file, uint32_t line)
  190. {
  191. /* USER CODE BEGIN 6 */
  192. /* User can add his own implementation to report the file name and line number,
  193. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  194. /* USER CODE END 6 */
  195. }
  196. #endif /* USE_FULL_ASSERT */

LCD1602显示一行字符

LCD1602与STM32F103C8T6板子接线
  • PB0<->RS

  • PB1<->RW

  • PB2<->EN

  • PA0<->D0

  • PA1<->D1

  • PA2<->D2

  • PA3<->D3

  • PA4<->D4

  • PA5<->D5

  • PA6<->D6

  • PA7<->D7

STM32CubeMX相关配置
配置SYS
配置RCC
配置GPIO
main函数编写

   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "tim.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. //LCD1602相关的宏定义
  26. #define RS_GPIO_Port GPIOB
  27. #define RW_GPIO_Port GPIOB
  28. #define EN_GPIO_Port GPIOB
  29. #define RS_GPIO_PIN GPIO_PIN_0
  30. #define RW_GPIO_PIN GPIO_PIN_1
  31. #define EN_GPIO_PIN GPIO_PIN_2
  32. #define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
  33. #define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
  34. #define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
  35. #define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
  36. #define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
  37. #define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)
  38. /* USER CODE END Includes */
  39. /* Private typedef -----------------------------------------------------------*/
  40. /* USER CODE BEGIN PTD */
  41. /* USER CODE END PTD */
  42. /* Private define ------------------------------------------------------------*/
  43. /* USER CODE BEGIN PD */
  44. /* USER CODE END PD */
  45. /* Private macro -------------------------------------------------------------*/
  46. /* USER CODE BEGIN PM */
  47. /* USER CODE END PM */
  48. /* Private variables ---------------------------------------------------------*/
  49. /* USER CODE BEGIN PV */
  50. /* USER CODE END PV */
  51. /* Private function prototypes -----------------------------------------------*/
  52. void SystemClock_Config(void);
  53. /* USER CODE BEGIN PFP */
  54. /* USER CODE END PFP */
  55. /* Private user code ---------------------------------------------------------*/
  56. /* USER CODE BEGIN 0 */
  57. //LCD1602写指令
  58. void writeCmd(char cmd)
  59. {
  60. RS_LOW; //选择写指令寄存器
  61. RW_LOW;
  62. EN_LOW;
  63. GPIOA->ODR = cmd; //将指令存入LCD1602的八位数据线中
  64. HAL_Delay( 5);
  65. EN_HIGH;
  66. HAL_Delay( 5);
  67. EN_LOW;
  68. }
  69. //LCD1602写数据
  70. void writeData(char myData)
  71. {
  72. RS_HIGH; //选择写数据寄存器
  73. RW_LOW;
  74. EN_LOW;
  75. GPIOA->ODR = myData; //将数据存入LCD1602的八位数据线中
  76. HAL_Delay( 5);
  77. EN_HIGH;
  78. HAL_Delay( 5);
  79. EN_LOW;
  80. }
  81. //LCD1602初始化
  82. void lcd1602Init()
  83. {
  84. HAL_Delay( 15); //延时 15ms
  85. writeCmd( 0x38); //写指令 38H(不检测忙信号)
  86. HAL_Delay( 5); //延时 5ms
  87. writeCmd( 0x38); //写指令 38H:显示模式设置
  88. writeCmd( 0x08); //写指令 08H:显示关闭
  89. writeCmd( 0x01); //写指令 01H:显示清屏
  90. writeCmd( 0x06); //写指令 06H:显示光标移动设置
  91. writeCmd( 0x0C); //写指令 0CH:显示开及光标设置
  92. }
  93. //LCD1602显示一行字符
  94. void lcd1602ShowData(char rows,char columns,char *str)
  95. {
  96. switch (rows){ //选择行
  97. case 1:
  98. writeCmd( 0x80 + columns -1); //选择列
  99. while(*str != '\0'){
  100. writeData(*str); //显示字符
  101. str++;
  102. }
  103. break;
  104. case 2:
  105. writeCmd( 0x80 + 0x40 +columns -1); //选择列
  106. while(*str != '\0'){
  107. writeData(*str); //显示字符
  108. str++;
  109. }
  110. break;
  111. default:
  112. break;
  113. }
  114. }
  115. /* USER CODE END 0 */
  116. /**
  117. * @brief The application entry point.
  118. * @retval int
  119. */
  120. int main(void)
  121. {
  122. /* USER CODE BEGIN 1 */
  123. /* USER CODE END 1 */
  124. /* MCU Configuration--------------------------------------------------------*/
  125. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  126. HAL_Init();
  127. /* USER CODE BEGIN Init */
  128. /* USER CODE END Init */
  129. /* Configure the system clock */
  130. SystemClock_Config();
  131. /* USER CODE BEGIN SysInit */
  132. /* USER CODE END SysInit */
  133. /* Initialize all configured peripherals */
  134. MX_GPIO_Init();
  135. MX_TIM2_Init();
  136. /* USER CODE BEGIN 2 */
  137. char displayAddress = 0x80 + 0x05;
  138. char dsiplayData = 'H';
  139. lcd1602Init();
  140. lcd1602ShowData( 1, 1, "haozige");
  141. lcd1602ShowData( 2, 1, "jiangxiaoya");
  142. /* USER CODE END 2 */
  143. /* Infinite loop */
  144. /* USER CODE BEGIN WHILE */
  145. while ( 1)
  146. {
  147. /* USER CODE END WHILE */
  148. /* USER CODE BEGIN 3 */
  149. }
  150. /* USER CODE END 3 */
  151. }
  152. /**
  153. * @brief System Clock Configuration
  154. * @retval None
  155. */
  156. void SystemClock_Config(void)
  157. {
  158. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  159. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  160. /** Initializes the RCC Oscillators according to the specified parameters
  161. * in the RCC_OscInitTypeDef structure.
  162. */
  163. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  164. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  165. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  166. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  167. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  168. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  169. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  170. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  171. {
  172. Error_Handler();
  173. }
  174. /** Initializes the CPU, AHB and APB buses clocks
  175. */
  176. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  177. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  178. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  179. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  180. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  181. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  182. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  183. {
  184. Error_Handler();
  185. }
  186. }
  187. /* USER CODE BEGIN 4 */
  188. /* USER CODE END 4 */
  189. /**
  190. * @brief This function is executed in case of error occurrence.
  191. * @retval None
  192. */
  193. void Error_Handler(void)
  194. {
  195. /* USER CODE BEGIN Error_Handler_Debug */
  196. /* User can add his own implementation to report the HAL error return state */
  197. __disable_irq();
  198. while ( 1)
  199. {
  200. }
  201. /* USER CODE END Error_Handler_Debug */
  202. }
  203. #ifdef USE_FULL_ASSERT
  204. /**
  205. * @brief Reports the name of the source file and the source line number
  206. * where the assert_param error has occurred.
  207. * @param file: pointer to the source file name
  208. * @param line: assert_param error line source number
  209. * @retval None
  210. */
  211. void assert_failed(uint8_t *file, uint32_t line)
  212. {
  213. /* USER CODE BEGIN 6 */
  214. /* User can add his own implementation to report the file name and line number,
  215. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  216. /* USER CODE END 6 */
  217. }
  218. #endif /* USE_FULL_ASSERT */

DHT11

DHT11介绍

DHT11用来实时检测空气中温湿度,一次完整的数据为40bit,即5个字节

DTH11的通讯过程

用户发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。

时序图如下:

一些宏定义

将通讯过程拆分成3个过程,配置DTH11输出数据、输出数据0、输出数据1

配置DTH11输出数据

输出数据0

输出数据1

DHT11输出0或1主要取决于DHT11一段信号后的高电平持续时间

获取空气中温湿度并发送到串口

DHT11与STM32板子接线

  • PB7<->DAT

STM32CubeMX相关配置

配置SYS

配置RCC

配置串口1

配置GPIO

由于DHT11的DAT接口既需要输入也需要输出,因此需要自己在main函数中配置,无法使用STM32CubeMX配置

main函数编写


   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "usart.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. #include <stdio.h>
  26. #define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)
  27. #define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
  28. #define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)
  29. /* USER CODE END Includes */
  30. /* Private typedef -----------------------------------------------------------*/
  31. /* USER CODE BEGIN PTD */
  32. /* USER CODE END PTD */
  33. /* Private define ------------------------------------------------------------*/
  34. /* USER CODE BEGIN PD */
  35. /* USER CODE END PD */
  36. /* Private macro -------------------------------------------------------------*/
  37. /* USER CODE BEGIN PM */
  38. /* USER CODE END PM */
  39. /* Private variables ---------------------------------------------------------*/
  40. /* USER CODE BEGIN PV */
  41. /* USER CODE END PV */
  42. /* Private function prototypes -----------------------------------------------*/
  43. void SystemClock_Config(void);
  44. /* USER CODE BEGIN PFP */
  45. /* USER CODE END PFP */
  46. /* Private user code ---------------------------------------------------------*/
  47. /* USER CODE BEGIN 0 */
  48. char dht11Data[ 5];
  49. char temperature[ 9];
  50. char humidity[ 9];
  51. //配置PB7为输入引脚或者输出引脚
  52. void DHT_GPIO_PB7_INIT(uint32_t mode)
  53. {
  54. //打开时钟
  55. __HAL_RCC_GPIOB_CLK_ENABLE();
  56. //配置引脚
  57. GPIO_InitTypeDef GPIO_InitStruct = { 0};
  58. GPIO_InitStruct.Pin = GPIO_PIN_7;
  59. GPIO_InitStruct.Mode = mode; //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP)
  60. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  61. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  62. }
  63. //重写stdio.h文件中的prinft()里的fputc()函数
  64. int fputc(int my_data,FILE *p)
  65. {
  66. unsigned char temp = my_data;
  67. //改写后,使用printf()函数会将数据通过串口一发送出去
  68. HAL_UART_Transmit(&huart1,&temp, 1, 0xffff); //0xfffff为最大超时时间
  69. return my_data;
  70. }
  71. //微秒延时函数
  72. void delay_us(uint16_t cnt)
  73. {
  74. uint8_t i;
  75. while(cnt){
  76. for(i= 0;i< 10;i++){}
  77. cnt--;
  78. }
  79. }
  80. //配置DHT11输出数据
  81. void dht11Start()
  82. {
  83. DHT_GPIO_PB7_INIT(GPIO_MODE_OUTPUT_PP); //配置DHT11的DAT引脚为输出引脚
  84. DHT_HIGH;
  85. DHT_LOW;
  86. HAL_Delay( 30);
  87. DHT_HIGH;
  88. DHT_GPIO_PB7_INIT(GPIO_MODE_INPUT);
  89. while(DHT_VALUE); //等待自己拉到低电平
  90. while(!DHT_VALUE); //等待自己拉到高电平
  91. while(DHT_VALUE); //等待自己拉到低电平
  92. }
  93. //获取DHT11的数据
  94. void readDht11Data()
  95. {
  96. int i,j;
  97. char tmp;
  98. char flag;
  99. dht11Start(); //开始输出数据
  100. DHT_GPIO_PB7_INIT(GPIO_MODE_INPUT);
  101. for (i = 0; i < 5; i++){ //总共获取5个字符(40bit)的数据
  102. for (j = 0; j < 8; j++){
  103. //一次获取一个bit数据
  104. while(!DHT_VALUE); //等待自己拉到高电平
  105. delay_us( 40); //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1
  106. if(DHT_VALUE == 1){ //40微秒后为高电平即输出1
  107. while(DHT_VALUE);
  108. flag = 1;
  109. } else{ //40微秒后为低电平即输出0
  110. flag = 0;
  111. }
  112. tmp = tmp << 1; //由于dht11的数据是高位先出,所以用左移的方式
  113. tmp = tmp | flag; //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值
  114. }
  115. dht11Data[i] = tmp;
  116. }
  117. }
  118. //发送数据到字符数组,用于串口显示
  119. void sendStrData()
  120. {
  121. humidity[ 0] = 'H';
  122. humidity[ 1] = ':';
  123. humidity[ 2] = dht11Data[ 0]/ 10 + 0x30;
  124. humidity[ 3] = dht11Data[ 0]% 10 + 0x30;
  125. humidity[ 4] = '.';
  126. humidity[ 5] = dht11Data[ 1]/ 10 + 0x30;
  127. humidity[ 6] = dht11Data[ 1]% 10 + 0x30;
  128. humidity[ 7] = '%';
  129. humidity[ 8] = '\0';
  130. temperature[ 0] = 'T';
  131. temperature[ 1] = ':';
  132. temperature[ 2] = dht11Data[ 2]/ 10 + 0x30;
  133. temperature[ 3] = dht11Data[ 2]% 10 + 0x30;
  134. temperature[ 4] = '.';
  135. temperature[ 5] = dht11Data[ 3]/ 10 + 0x30;
  136. temperature[ 6] = dht11Data[ 3]% 10 + 0x30;
  137. temperature[ 7] = 'C';
  138. temperature[ 8] = '\0';
  139. }
  140. /* USER CODE END 0 */
  141. /**
  142. * @brief The application entry point.
  143. * @retval int
  144. */
  145. int main(void)
  146. {
  147. /* USER CODE BEGIN 1 */
  148. /* USER CODE END 1 */
  149. /* MCU Configuration--------------------------------------------------------*/
  150. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  151. HAL_Init();
  152. /* USER CODE BEGIN Init */
  153. /* USER CODE END Init */
  154. /* Configure the system clock */
  155. SystemClock_Config();
  156. /* USER CODE BEGIN SysInit */
  157. /* USER CODE END SysInit */
  158. /* Initialize all configured peripherals */
  159. MX_GPIO_Init();
  160. MX_USART1_UART_Init();
  161. /* USER CODE BEGIN 2 */
  162. printf( "%s", "haozige\r\n");
  163. /* USER CODE END 2 */
  164. /* Infinite loop */
  165. /* USER CODE BEGIN WHILE */
  166. while ( 1)
  167. {
  168. /* USER CODE END WHILE */
  169. /* USER CODE BEGIN 3 */
  170. readDht11Data(); //获取DHT11的数据
  171. sendStrData(); //将DHT11的数据封装到字符数组
  172. printf( "%s\r\n",humidity);
  173. printf( "%s\r\n",temperature);
  174. HAL_Delay( 1000);
  175. }
  176. /* USER CODE END 3 */
  177. }
  178. /**
  179. * @brief System Clock Configuration
  180. * @retval None
  181. */
  182. void SystemClock_Config(void)
  183. {
  184. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  185. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  186. /** Initializes the RCC Oscillators according to the specified parameters
  187. * in the RCC_OscInitTypeDef structure.
  188. */
  189. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  190. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  191. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  192. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  193. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  194. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  195. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  196. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  197. {
  198. Error_Handler();
  199. }
  200. /** Initializes the CPU, AHB and APB buses clocks
  201. */
  202. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  203. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  204. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  205. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  206. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  207. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  208. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  209. {
  210. Error_Handler();
  211. }
  212. }
  213. /* USER CODE BEGIN 4 */
  214. /* USER CODE END 4 */
  215. /**
  216. * @brief This function is executed in case of error occurrence.
  217. * @retval None
  218. */
  219. void Error_Handler(void)
  220. {
  221. /* USER CODE BEGIN Error_Handler_Debug */
  222. /* User can add his own implementation to report the HAL error return state */
  223. __disable_irq();
  224. while ( 1)
  225. {
  226. }
  227. /* USER CODE END Error_Handler_Debug */
  228. }
  229. #ifdef USE_FULL_ASSERT
  230. /**
  231. * @brief Reports the name of the source file and the source line number
  232. * where the assert_param error has occurred.
  233. * @param file: pointer to the source file name
  234. * @param line: assert_param error line source number
  235. * @retval None
  236. */
  237. void assert_failed(uint8_t *file, uint32_t line)
  238. {
  239. /* USER CODE BEGIN 6 */
  240. /* User can add his own implementation to report the file name and line number,
  241. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  242. /* USER CODE END 6 */
  243. }
  244. #endif /* USE_FULL_ASSERT */

使用MicroLIB库

DTH11获取空气中温湿度,数据在LCD1602显示

DHT11、LCD1602与STM32板子接线

  • PB5<->DAT

  • PB0<->RS

  • PB1<->RW

  • PB2<->EN

  • PA0<->D0

  • PA1<->D1

  • PA2<->D2

  • PA3<->D3

  • PA4<->D4

  • PA5<->D5

  • PA6<->D6

  • PA7<->D7

STM32CubeMX相关配置

配置SYS

配置RCC

配置GPIO

由于DHT11的DAT接口既需要输入也需要输出,因此需要自己在main函数中配置,无法使用STM32CubeMX配置

main函数编写


   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "gpio.h"
  22. /* Private includes ----------------------------------------------------------*/
  23. /* USER CODE BEGIN Includes */
  24. #define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)
  25. #define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
  26. #define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5)
  27. #define PB5_INPUT GPIO_MODE_INP
  28. #define PB5_OUTPUT GPIO_MODE_OUTPUT_PP
  29. #define RS_GPIO_Port GPIOB
  30. #define RW_GPIO_Port GPIOB
  31. #define EN_GPIO_Port GPIOB
  32. #define RS_GPIO_PIN GPIO_PIN_0
  33. #define RW_GPIO_PIN GPIO_PIN_1
  34. #define EN_GPIO_PIN GPIO_PIN_2
  35. #define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
  36. #define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
  37. #define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
  38. #define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
  39. #define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
  40. #define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)
  41. /* USER CODE END Includes */
  42. /* Private typedef -----------------------------------------------------------*/
  43. /* USER CODE BEGIN PTD */
  44. /* USER CODE END PTD */
  45. /* Private define ------------------------------------------------------------*/
  46. /* USER CODE BEGIN PD */
  47. /* USER CODE END PD */
  48. /* Private macro -------------------------------------------------------------*/
  49. /* USER CODE BEGIN PM */
  50. /* USER CODE END PM */
  51. /* Private variables ---------------------------------------------------------*/
  52. /* USER CODE BEGIN PV */
  53. /* USER CODE END PV */
  54. /* Private function prototypes -----------------------------------------------*/
  55. void SystemClock_Config(void);
  56. /* USER CODE BEGIN PFP */
  57. /* USER CODE END PFP */
  58. /* Private user code ---------------------------------------------------------*/
  59. /* USER CODE BEGIN 0 */
  60. char dht11Data[ 5];
  61. char temperature[ 9];
  62. char humidity[ 9];
  63. //配置PB5为输入引脚或者输出引脚
  64. void DHT_GPIO_PB5_INIT(uint32_t mode)
  65. {
  66. //打开时钟
  67. __HAL_RCC_GPIOB_CLK_ENABLE();
  68. //配置引脚
  69. GPIO_InitTypeDef GPIO_InitStruct = { 0};
  70. GPIO_InitStruct.Pin = GPIO_PIN_5;
  71. GPIO_InitStruct.Mode = mode; //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP)
  72. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  73. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  74. }
  75. //微秒延时函数
  76. void delay_us(uint16_t cnt)
  77. {
  78. uint8_t i;
  79. while(cnt){
  80. for(i= 0;i< 10;i++){}
  81. cnt--;
  82. }
  83. }
  84. //配置DHT11输出数据
  85. void dht11Start()
  86. {
  87. DHT_GPIO_PB5_INIT(GPIO_MODE_OUTPUT_PP);
  88. DHT_HIGH;
  89. DHT_LOW;
  90. HAL_Delay( 30);
  91. DHT_HIGH;
  92. DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);
  93. while(DHT_VALUE); //等待自己拉到低电平
  94. while(!DHT_VALUE); //等待自己拉到高电平
  95. while(DHT_VALUE); //等待自己拉到低电平
  96. }
  97. //获取DHT11的数据
  98. void readDht11Data()
  99. {
  100. int i,j;
  101. char tmp;
  102. char flag;
  103. dht11Start(); //开始输出数据
  104. DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);
  105. for (i = 0; i < 5; i++){ //总共获取5个字符(40bit)的数据
  106. for (j = 0; j < 8; j++){
  107. //一次获取一个bit数据
  108. while(!DHT_VALUE); //等待自己拉到高电平
  109. delay_us( 40); //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1
  110. if(DHT_VALUE == 1){ //40微秒后为高电平即输出1
  111. while(DHT_VALUE);
  112. flag = 1;
  113. } else{ //40微秒后为低电平即输出0
  114. flag = 0;
  115. }
  116. tmp = tmp << 1; //由于dht11的数据是高位先出,所以用左移的方式
  117. tmp = tmp | flag; //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值
  118. }
  119. dht11Data[i] = tmp;
  120. }
  121. }
  122. //发送数据到字符数组,用于LCD1602显示
  123. void sendStrData()
  124. {
  125. humidity[ 0] = 'H';
  126. humidity[ 1] = ':';
  127. humidity[ 2] = dht11Data[ 0]/ 10 + 0x30;
  128. humidity[ 3] = dht11Data[ 0]% 10 + 0x30;
  129. humidity[ 4] = '.';
  130. humidity[ 5] = dht11Data[ 1]/ 10 + 0x30;
  131. humidity[ 6] = dht11Data[ 1]% 10 + 0x30;
  132. humidity[ 7] = '%';
  133. humidity[ 8] = '\0';
  134. temperature[ 0] = 'T';
  135. temperature[ 1] = ':';
  136. temperature[ 2] = dht11Data[ 2]/ 10 + 0x30;
  137. temperature[ 3] = dht11Data[ 2]% 10 + 0x30;
  138. temperature[ 4] = '.';
  139. temperature[ 5] = dht11Data[ 3]/ 10 + 0x30;
  140. temperature[ 6] = dht11Data[ 3]% 10 + 0x30;
  141. temperature[ 7] = 'C';
  142. temperature[ 8] = '\0';
  143. }
  144. //LCD1602写指令
  145. void writeCmd(char cmd)
  146. {
  147. RS_LOW; //选择写指令寄存器
  148. RW_LOW;
  149. EN_LOW;
  150. GPIOA->ODR = cmd; //将指令存入八位数据线中
  151. HAL_Delay( 5);
  152. EN_HIGH;
  153. HAL_Delay( 5);
  154. EN_LOW;
  155. }
  156. //LCD1602写数据
  157. void writeData(char myData)
  158. {
  159. RS_HIGH; //选择写数据寄存器
  160. RW_LOW;
  161. EN_LOW;
  162. GPIOA->ODR = myData; //将数据存入八位数据线中
  163. HAL_Delay( 5);
  164. EN_HIGH;
  165. HAL_Delay( 5);
  166. EN_LOW;
  167. }
  168. //LCD1602初始化
  169. void lcd1602Init()
  170. {
  171. HAL_Delay( 15); //延时 15ms
  172. writeCmd( 0x38); //写指令 38H(不检测忙信号)
  173. HAL_Delay( 5); //延时 5ms
  174. writeCmd( 0x38); //写指令 38H:显示模式设置
  175. writeCmd( 0x08); //写指令 08H:显示关闭
  176. writeCmd( 0x01); //写指令 01H:显示清屏
  177. writeCmd( 0x06); //写指令 06H:显示光标移动设置
  178. writeCmd( 0x0C); //写指令 0CH:显示开及光标设置
  179. }
  180. //LCD1602显示一行字符
  181. void lcd1602ShowData(char rows,char columns,char *str)
  182. {
  183. switch (rows){ //选择行
  184. case 1:
  185. writeCmd( 0x80 + columns -1); //选择列
  186. while(*str != '\0'){
  187. writeData(*str); //显示字符
  188. str++;
  189. }
  190. break;
  191. case 2:
  192. writeCmd( 0x80 + 0x40 +columns -1); //选择列
  193. while(*str != '\0'){
  194. writeData(*str); //显示字符
  195. str++;
  196. }
  197. break;
  198. default:
  199. break;
  200. }
  201. }
  202. /* USER CODE END 0 */
  203. /**
  204. * @brief The application entry point.
  205. * @retval int
  206. */
  207. int main(void)
  208. {
  209. /* USER CODE BEGIN 1 */
  210. /* USER CODE END 1 */
  211. /* MCU Configuration--------------------------------------------------------*/
  212. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  213. HAL_Init();
  214. /* USER CODE BEGIN Init */
  215. /* USER CODE END Init */
  216. /* Configure the system clock */
  217. SystemClock_Config();
  218. /* USER CODE BEGIN SysInit */
  219. /* USER CODE END SysInit */
  220. /* Initialize all configured peripherals */
  221. MX_GPIO_Init();
  222. /* USER CODE BEGIN 2 */
  223. lcd1602Init();
  224. /* USER CODE END 2 */
  225. /* Infinite loop */
  226. /* USER CODE BEGIN WHILE */
  227. while ( 1)
  228. {
  229. /* USER CODE END WHILE */
  230. readDht11Data();
  231. sendStrData();
  232. lcd1602ShowData( 1, 1,humidity);
  233. lcd1602ShowData( 2, 1,temperature);
  234. HAL_Delay( 1000);
  235. /* USER CODE BEGIN 3 */
  236. }
  237. /* USER CODE END 3 */
  238. }
  239. /**
  240. * @brief System Clock Configuration
  241. * @retval None
  242. */
  243. void SystemClock_Config(void)
  244. {
  245. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  246. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  247. /** Initializes the RCC Oscillators according to the specified parameters
  248. * in the RCC_OscInitTypeDef structure.
  249. */
  250. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  251. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  252. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  253. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  254. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  255. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  256. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  257. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  258. {
  259. Error_Handler();
  260. }
  261. /** Initializes the CPU, AHB and APB buses clocks
  262. */
  263. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  264. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  265. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  266. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  267. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  268. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  269. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  270. {
  271. Error_Handler();
  272. }
  273. }
  274. /* USER CODE BEGIN 4 */
  275. /* USER CODE END 4 */
  276. /**
  277. * @brief This function is executed in case of error occurrence.
  278. * @retval None
  279. */
  280. void Error_Handler(void)
  281. {
  282. /* USER CODE BEGIN Error_Handler_Debug */
  283. /* User can add his own implementation to report the HAL error return state */
  284. __disable_irq();
  285. while ( 1)
  286. {
  287. }
  288. /* USER CODE END Error_Handler_Debug */
  289. }
  290. #ifdef USE_FULL_ASSERT
  291. /**
  292. * @brief Reports the name of the source file and the source line number
  293. * where the assert_param error has occurred.
  294. * @param file: pointer to the source file name
  295. * @param line: assert_param error line source number
  296. * @retval None
  297. */
  298. void assert_failed(uint8_t *file, uint32_t line)
  299. {
  300. /* USER CODE BEGIN 6 */
  301. /* User can add his own implementation to report the file name and line number,
  302. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  303. /* USER CODE END 6 */
  304. }
  305. #endif /* USE_FULL_ASSERT */

4针OLED(IIC协议)

IIC协议

IIC全称Inter-Integrated Circuit (集成电路总线),由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双工同步通信方式。

IIC特点

  • 简单性和有效性:由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件

  • 多主控(multimastering):其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。

IIC构成

IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。其中时钟信号是由主控器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线 的SCL上。对于并联在一条总线上的每个IIC都有唯一的地址。

IIC传输数据过程的三种信号

起始信号

时序图

终止信号

时序图

应答信号

发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字 节; 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

时序图

IIC发送一个字节数据

时序图

OLED屏

OLED写入指令或数据

①选择OLED屏

写入0x78,选择第一个OLED屏,写入0x7A选择第二个OLED屏

②选择命令还是数据

选择命令写入0x00,选择数据写入0x40

③传入信息

将命令或数据传入

OLED的寻址模式(在OLED上哪里显示字符)

OLED显示屏是一个128列*64行的点阵,垂直方向由8个PAGE控制,每个PAGE控制8个点阵。

选择PAGE(在垂直方向的哪个位置显示):

向OLED写入指令0xBx,即b(1011 0xxx),例如选择Page 3时,写入指令0xB3,即b(1011 0011)。

选择列(在水平方向的哪个位置显示):

向OLED写入指令0x0x和0x1x,即b(0000 xxxx)或b(0001 xxxx)

例如

  • 选择第1列时,写入指令0x00,即b(0000 0000)和写入指令0x10即b(0001 0000)。 它由第一条指令的低四位和第二条指令的低三位组成七位来控制水平方向的128个点阵

  • 选择第64列时,写入指令0x0F,即b(0000 1111)和写入指令0x13即b(0001 0011)。

OLED的三种地址模式

页地址模式

水平地址模式
垂直地址模式

选择寻址模式(在一个PAGE上写满数据后,数据从哪里继续开始):

向OLED写入指令0x20后,继续写入指令0x0x,即b(0000 00xx),例如选择页寻址时,写入指令0x02,即b(000 0010)。

OLED初始化

写入一下命令来对4针OLED进行初始化

OLED显示一个点

OLED与STM32板子接线

在STM32F103C8T6的产品手册中找到板子上的I2C1接口,PB6作为I2C1的SCL,PB7作为I2C1的SDA

  • PB6<->SCL

  • PB7<->SDA

STM32CubeMX相关配置

配置SYS

配置RCC

启动I2C1

main函数编写

   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "i2c.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. /* USER CODE END Includes */
  26. /* Private typedef -----------------------------------------------------------*/
  27. /* USER CODE BEGIN PTD */
  28. /* USER CODE END PTD */
  29. /* Private define ------------------------------------------------------------*/
  30. /* USER CODE BEGIN PD */
  31. /* USER CODE END PD */
  32. /* Private macro -------------------------------------------------------------*/
  33. /* USER CODE BEGIN PM */
  34. /* USER CODE END PM */
  35. /* Private variables ---------------------------------------------------------*/
  36. /* USER CODE BEGIN PV */
  37. /* USER CODE END PV */
  38. /* Private function prototypes -----------------------------------------------*/
  39. void SystemClock_Config(void);
  40. /* USER CODE BEGIN PFP */
  41. /* USER CODE END PFP */
  42. /* Private user code ---------------------------------------------------------*/
  43. /* USER CODE BEGIN 0 */
  44. //OLED写入一条指令
  45. void oledWriteCmd(uint8_t writeCmd)
  46. {
  47. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd, 1, 0xff);
  48. }
  49. //OLED写入一个数据
  50. void oledWriteData(uint8_t writeData)
  51. {
  52. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40,I2C_MEMADD_SIZE_8BIT,&writeData, 1, 0xff);
  53. }
  54. //OLCD初始化
  55. void oledInit()
  56. {
  57. oledWriteCmd( 0xAE);
  58. oledWriteCmd( 0x00);
  59. oledWriteCmd( 0x10);
  60. oledWriteCmd( 0x40);
  61. oledWriteCmd( 0xB0);
  62. oledWriteCmd( 0x81);
  63. oledWriteCmd( 0xFF);
  64. oledWriteCmd( 0xA1);
  65. oledWriteCmd( 0xA6);
  66. oledWriteCmd( 0xA8);
  67. oledWriteCmd( 0x3F);
  68. oledWriteCmd( 0xC8);
  69. oledWriteCmd( 0xD3);
  70. oledWriteCmd( 0x00);
  71. oledWriteCmd( 0xD5);
  72. oledWriteCmd( 0x80);
  73. oledWriteCmd( 0xD8);
  74. oledWriteCmd( 0x05);
  75. oledWriteCmd( 0xD9);
  76. oledWriteCmd( 0xF1);
  77. oledWriteCmd( 0xDA);
  78. oledWriteCmd( 0x12);
  79. oledWriteCmd( 0xDB);
  80. oledWriteCmd( 0x30);
  81. oledWriteCmd( 0x8D);
  82. oledWriteCmd( 0x14);
  83. oledWriteCmd( 0xAF);
  84. }
  85. //OLED清屏
  86. void olceClean()
  87. {
  88. int i,j;
  89. for(i= 0;i< 8;i++){
  90. oledWriteCmd( 0xB0 + i); //选择PAGE
  91. //选择PAGE的第0列开始显示
  92. oledWriteCmd( 0x00);
  93. oledWriteCmd( 0x10);
  94. for(j = 0;j < 128; j++){
  95. oledWriteData( 0); //写入字符0
  96. }
  97. }
  98. }
  99. /* USER CODE END 0 */
  100. /**
  101. * @brief The application entry point.
  102. * @retval int
  103. */
  104. int main(void)
  105. {
  106. /* USER CODE BEGIN 1 */
  107. /* USER CODE END 1 */
  108. /* MCU Configuration--------------------------------------------------------*/
  109. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  110. HAL_Init();
  111. /* USER CODE BEGIN Init */
  112. /* USER CODE END Init */
  113. /* Configure the system clock */
  114. SystemClock_Config();
  115. /* USER CODE BEGIN SysInit */
  116. /* USER CODE END SysInit */
  117. /* Initialize all configured peripherals */
  118. MX_GPIO_Init();
  119. MX_I2C1_Init();
  120. /* USER CODE BEGIN 2 */
  121. oledInit(); //OLED初始化
  122. olceClean(); //OLED清屏函数
  123. //设置寻址模式
  124. oledWriteCmd( 0x20); //设置内存
  125. oledWriteCmd( 0x02); //选择页寻址模式
  126. olceClean(); //清屏函数
  127. //选择行,选择第4行
  128. oledWriteCmd( 0xB3);
  129. //选择列,选择第一列
  130. oledWriteCmd( 0x00);
  131. oledWriteCmd( 0x10);
  132. //显示数据
  133. oledWriteData( 0x08); //显示一个点
  134. //选择第64列
  135. oledWriteCmd( 0x0F);
  136. oledWriteCmd( 0x13);
  137. //显示一个点
  138. oledWriteData( 0x08);
  139. /* USER CODE END 2 */
  140. /* Infinite loop */
  141. /* USER CODE BEGIN WHILE */
  142. while ( 1)
  143. {
  144. /* USER CODE END WHILE */
  145. /* USER CODE BEGIN 3 */
  146. }
  147. /* USER CODE END 3 */
  148. }
  149. /**
  150. * @brief System Clock Configuration
  151. * @retval None
  152. */
  153. void SystemClock_Config(void)
  154. {
  155. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  156. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  157. /** Initializes the RCC Oscillators according to the specified parameters
  158. * in the RCC_OscInitTypeDef structure.
  159. */
  160. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  161. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  162. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  163. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  164. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  165. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  166. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  167. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  168. {
  169. Error_Handler();
  170. }
  171. /** Initializes the CPU, AHB and APB buses clocks
  172. */
  173. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  174. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  175. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  176. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  177. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  178. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  179. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  180. {
  181. Error_Handler();
  182. }
  183. }
  184. /* USER CODE BEGIN 4 */
  185. /* USER CODE END 4 */
  186. /**
  187. * @brief This function is executed in case of error occurrence.
  188. * @retval None
  189. */
  190. void Error_Handler(void)
  191. {
  192. /* USER CODE BEGIN Error_Handler_Debug */
  193. /* User can add his own implementation to report the HAL error return state */
  194. __disable_irq();
  195. while ( 1)
  196. {
  197. }
  198. /* USER CODE END Error_Handler_Debug */
  199. }
  200. #ifdef USE_FULL_ASSERT
  201. /**
  202. * @brief Reports the name of the source file and the source line number
  203. * where the assert_param error has occurred.
  204. * @param file: pointer to the source file name
  205. * @param line: assert_param error line source number
  206. * @retval None
  207. */
  208. void assert_failed(uint8_t *file, uint32_t line)
  209. {
  210. /* USER CODE BEGIN 6 */
  211. /* User can add his own implementation to report the file name and line number,
  212. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  213. /* USER CODE END 6 */
  214. }
  215. #endif /* USE_FULL_ASSERT */

OLED显示自己名字

OLED与STM32板子接线

在STM32F103C8T6的产品手册中找到板子上的I2C1接口,PB6作为I2C1的SCL,PB7作为I2C1的SDA

  • PB6<->SCL

  • PB7<->SDA

STM32CubeMX相关配置

配置SYS

配置RCC

启动I2C1

main函数编写

   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "i2c.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. /* USER CODE END Includes */
  26. /* Private typedef -----------------------------------------------------------*/
  27. /* USER CODE BEGIN PTD */
  28. /* USER CODE END PTD */
  29. /* Private define ------------------------------------------------------------*/
  30. /* USER CODE BEGIN PD */
  31. /* USER CODE END PD */
  32. /* Private macro -------------------------------------------------------------*/
  33. /* USER CODE BEGIN PM */
  34. /* USER CODE END PM */
  35. /* Private variables ---------------------------------------------------------*/
  36. /* USER CODE BEGIN PV */
  37. /* USER CODE END PV */
  38. /* Private function prototypes -----------------------------------------------*/
  39. void SystemClock_Config(void);
  40. /* USER CODE BEGIN PFP */
  41. /* USER CODE END PFP */
  42. /* Private user code ---------------------------------------------------------*/
  43. /* USER CODE BEGIN 0 */
  44. //OLED的字符构造点阵
  45. unsigned char oledFont[]=
  46. {
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  48. 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
  49. 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2
  50. 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //# 3
  51. 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4
  52. 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5
  53. 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6
  54. 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7
  55. 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8
  56. 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9
  57. 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10
  58. 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11
  59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12
  60. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13
  61. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14
  62. 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
  63. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, //0 16
  64. 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //1 17
  65. 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, //2 18
  66. 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //3 19
  67. 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, //4 20
  68. 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, //5 21
  69. 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //6 22
  70. 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //7 23
  71. 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, //8 24
  72. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, //9 25
  73. 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
  74. 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27
  75. 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28
  76. 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29
  77. 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30
  78. 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31
  79. 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32
  80. 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, //A 33
  81. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //B 34
  82. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, //C 35
  83. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //D 36
  84. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, //E 37
  85. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, //F 38
  86. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, //G 39
  87. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, //H 40
  88. 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //I 41
  89. 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, //J 42
  90. 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, //K 43
  91. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, //L 44
  92. 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, //M 45
  93. 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, //N 46
  94. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //O 47
  95. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, //P 48
  96. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, //Q 49
  97. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, //R 50
  98. 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, //S 51
  99. 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //T 52
  100. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //U 53
  101. 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, //V 54
  102. 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, //W 55
  103. 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, //X 56
  104. 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //Y 57
  105. 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, //Z 58
  106. 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59
  107. 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60
  108. 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61
  109. 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62
  110. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63
  111. 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64
  112. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, //a 65
  113. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //b 66
  114. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, //c 67
  115. 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, //d 68
  116. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, //e 69
  117. 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //f 70
  118. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, //g 71
  119. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //h 72
  120. 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //i 73
  121. 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, //j 74
  122. 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, //k 75
  123. 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //l 76
  124. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, //m 77
  125. 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //n 78
  126. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //o 79
  127. 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, //p 80
  128. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, //q 81
  129. 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, //r 82
  130. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, //s 83
  131. 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, //t 84
  132. 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, //u 85
  133. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, //v 86
  134. 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, //w 87
  135. 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, //x 88
  136. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, //y 89
  137. 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, //z 90
  138. 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91
  139. 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92
  140. 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93
  141. 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
  142. };
  143. //OLED写入一条指令
  144. void oledWriteCmd(uint8_t writeCmd)
  145. {
  146. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd, 1, 0xff);
  147. }
  148. //OLED写入一个数据
  149. void oledWriteData(uint8_t writeData)
  150. {
  151. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40,I2C_MEMADD_SIZE_8BIT,&writeData, 1, 0xff);
  152. }
  153. //OLCD初始化
  154. void oledInit()
  155. {
  156. oledWriteCmd( 0xAE);
  157. oledWriteCmd( 0x00);
  158. oledWriteCmd( 0x10);
  159. oledWriteCmd( 0x40);
  160. oledWriteCmd( 0xB0);
  161. oledWriteCmd( 0x81);
  162. oledWriteCmd( 0xFF);
  163. oledWriteCmd( 0xA1);
  164. oledWriteCmd( 0xA6);
  165. oledWriteCmd( 0xA8);
  166. oledWriteCmd( 0x3F);
  167. oledWriteCmd( 0xC8);
  168. oledWriteCmd( 0xD3);
  169. oledWriteCmd( 0x00);
  170. oledWriteCmd( 0xD5);
  171. oledWriteCmd( 0x80);
  172. oledWriteCmd( 0xD8);
  173. oledWriteCmd( 0x05);
  174. oledWriteCmd( 0xD9);
  175. oledWriteCmd( 0xF1);
  176. oledWriteCmd( 0xDA);
  177. oledWriteCmd( 0x12);
  178. oledWriteCmd( 0xDB);
  179. oledWriteCmd( 0x30);
  180. oledWriteCmd( 0x8D);
  181. oledWriteCmd( 0x14);
  182. oledWriteCmd( 0xAF);
  183. }
  184. //OLED清屏
  185. void olceClean()
  186. {
  187. int i,j;
  188. for(i= 0;i< 8;i++){
  189. oledWriteCmd( 0xB0 + i); //选择PAGE
  190. //选择PAGE的第0列开始显示
  191. oledWriteCmd( 0x00);
  192. oledWriteCmd( 0x10);
  193. for(j = 0;j < 128; j++){
  194. oledWriteData( 0); //写入字符0
  195. }
  196. }
  197. }
  198. //OLED显示一个字符
  199. void oledShowByte(char rows,char columns,char oledByte)
  200. {
  201. unsigned int i;
  202. //显示字符的上半部分
  203. oledWriteCmd( 0xb0+(rows* 2 -2)); //选择行
  204. //选择列
  205. oledWriteCmd( 0x00+(columns& 0x0f));
  206. oledWriteCmd( 0x10+(columns>> 4));
  207. //显示数据
  208. for(i=((oledByte -32)* 16);i<((oledByte -32)* 16+ 8);i++){
  209. oledWriteData(oledFont[i]);
  210. }
  211. //显示字符的上半部分
  212. oledWriteCmd( 0xb0+(rows* 2 -1)); //选择行
  213. //选择列
  214. oledWriteCmd( 0x00+(columns& 0x0f));
  215. oledWriteCmd( 0x10+(columns>> 4));
  216. //显示数据
  217. for(i=((oledByte -32)* 16+ 8);i<((oledByte -32)* 16+ 8+ 8);i++){
  218. oledWriteData(oledFont[i]);
  219. }
  220. }
  221. //OLED显示一个字符串
  222. void oledShowString(char rows,char columns,char *str)
  223. {
  224. while(*str != '\0'){
  225. oledShowByte(rows,columns,*str);
  226. str++;
  227. columns += 8;
  228. }
  229. }
  230. /* USER CODE END 0 */
  231. /**
  232. * @brief The application entry point.
  233. * @retval int
  234. */
  235. int main(void)
  236. {
  237. /* USER CODE BEGIN 1 */
  238. /* USER CODE END 1 */
  239. /* MCU Configuration--------------------------------------------------------*/
  240. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  241. HAL_Init();
  242. /* USER CODE BEGIN Init */
  243. /* USER CODE END Init */
  244. /* Configure the system clock */
  245. SystemClock_Config();
  246. /* USER CODE BEGIN SysInit */
  247. /* USER CODE END SysInit */
  248. /* Initialize all configured peripherals */
  249. MX_GPIO_Init();
  250. MX_I2C1_Init();
  251. /* USER CODE BEGIN 2 */
  252. oledInit(); //OLED初始化
  253. olceClean(); //OLED清屏函数
  254. //设置寻址模式
  255. oledWriteCmd( 0x20); //设置内存
  256. oledWriteCmd( 0x02); //选择页寻址模式
  257. olceClean(); //清屏函数
  258. oledShowString( 1, 1, "jiangxiaoya"); //在第一行第一列显示自己的名字
  259. /* USER CODE END 2 */
  260. /* Infinite loop */
  261. /* USER CODE BEGIN WHILE */
  262. while ( 1)
  263. {
  264. /* USER CODE END WHILE */
  265. /* USER CODE BEGIN 3 */
  266. }
  267. /* USER CODE END 3 */
  268. }
  269. /**
  270. * @brief System Clock Configuration
  271. * @retval None
  272. */
  273. void SystemClock_Config(void)
  274. {
  275. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  276. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  277. /** Initializes the RCC Oscillators according to the specified parameters
  278. * in the RCC_OscInitTypeDef structure.
  279. */
  280. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  281. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  282. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  283. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  284. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  285. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  286. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  287. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  288. {
  289. Error_Handler();
  290. }
  291. /** Initializes the CPU, AHB and APB buses clocks
  292. */
  293. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  294. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  295. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  296. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  297. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  298. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  299. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  300. {
  301. Error_Handler();
  302. }
  303. }
  304. /* USER CODE BEGIN 4 */
  305. /* USER CODE END 4 */
  306. /**
  307. * @brief This function is executed in case of error occurrence.
  308. * @retval None
  309. */
  310. void Error_Handler(void)
  311. {
  312. /* USER CODE BEGIN Error_Handler_Debug */
  313. /* User can add his own implementation to report the HAL error return state */
  314. __disable_irq();
  315. while ( 1)
  316. {
  317. }
  318. /* USER CODE END Error_Handler_Debug */
  319. }
  320. #ifdef USE_FULL_ASSERT
  321. /**
  322. * @brief Reports the name of the source file and the source line number
  323. * where the assert_param error has occurred.
  324. * @param file: pointer to the source file name
  325. * @param line: assert_param error line source number
  326. * @retval None
  327. */
  328. void assert_failed(uint8_t *file, uint32_t line)
  329. {
  330. /* USER CODE BEGIN 6 */
  331. /* User can add his own implementation to report the file name and line number,
  332. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  333. /* USER CODE END 6 */
  334. }
  335. #endif /* USE_FULL_ASSERT */

DHT11获取空气中温湿度,在OLED上显示

DHT11、OLED与STM32板子接线

在STM32F103C8T6的产品手册中找到板子上的I2C1接口,PB6作为I2C1的SCL,PB7作为I2C1的SDA

  • PB6<->SCL

  • PB7<->SDA

  • PB5<->DAT

STM32CubeMX相关配置

配置SYS

配置RCC

配置GPIO

由于DHT11的DAT接口既需要输入也需要输出,因此需要自己在main函数中配置,无法使用STM32CubeMX配置

启动I2C1

main函数编写

   
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "i2c.h"
  22. #include "gpio.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. #define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)
  26. #define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
  27. #define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5)
  28. #define PB5_INPUT GPIO_MODE_INP
  29. #define PB5_OUTPUT GPIO_MODE_OUTPUT_PP
  30. /* USER CODE END Includes */
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* USER CODE BEGIN PTD */
  33. /* USER CODE END PTD */
  34. /* Private define ------------------------------------------------------------*/
  35. /* USER CODE BEGIN PD */
  36. /* USER CODE END PD */
  37. /* Private macro -------------------------------------------------------------*/
  38. /* USER CODE BEGIN PM */
  39. /* USER CODE END PM */
  40. /* Private variables ---------------------------------------------------------*/
  41. /* USER CODE BEGIN PV */
  42. /* USER CODE END PV */
  43. /* Private function prototypes -----------------------------------------------*/
  44. void SystemClock_Config(void);
  45. /* USER CODE BEGIN PFP */
  46. /* USER CODE END PFP */
  47. /* Private user code ---------------------------------------------------------*/
  48. /* USER CODE BEGIN 0 */
  49. char dht11Data[ 5];
  50. char temperature[ 9];
  51. char humidity[ 9];
  52. //配置PB5为输入引脚或者输出引脚
  53. void DHT_GPIO_PB5_INIT(uint32_t mode)
  54. {
  55. //打开时钟
  56. __HAL_RCC_GPIOB_CLK_ENABLE();
  57. //配置引脚
  58. GPIO_InitTypeDef GPIO_InitStruct = { 0};
  59. GPIO_InitStruct.Pin = GPIO_PIN_5;
  60. GPIO_InitStruct.Mode = mode; //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP)
  61. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  62. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  63. }
  64. //微秒延时函数
  65. void delay_us(uint16_t cnt)
  66. {
  67. uint8_t i;
  68. while(cnt){
  69. for(i= 0;i< 10;i++){}
  70. cnt--;
  71. }
  72. }
  73. //配置DHT11输出数据
  74. void dht11Start()
  75. {
  76. DHT_GPIO_PB5_INIT(GPIO_MODE_OUTPUT_PP);
  77. DHT_HIGH;
  78. DHT_LOW;
  79. HAL_Delay( 30);
  80. DHT_HIGH;
  81. DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);
  82. while(DHT_VALUE); //等待自己拉到低电平
  83. while(!DHT_VALUE); //等待自己拉到高电平
  84. while(DHT_VALUE); //等待自己拉到低电平
  85. }
  86. //获取DHT11的数据
  87. void readDht11Data()
  88. {
  89. int i,j;
  90. char tmp;
  91. char flag;
  92. dht11Start(); //开始输出数据
  93. DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);
  94. for (i = 0; i < 5; i++){ //总共获取5个字符(40bit)的数据
  95. for (j = 0; j < 8; j++){
  96. //一次获取一个bit数据
  97. while(!DHT_VALUE); //等待自己拉到高电平
  98. delay_us( 40); //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1
  99. if(DHT_VALUE == 1){ //40微秒后为高电平即输出1
  100. while(DHT_VALUE);
  101. flag = 1;
  102. } else{ //40微秒后为低电平即输出0
  103. flag = 0;
  104. }
  105. tmp = tmp << 1; //由于dht11的数据是高位先出,所以用左移的方式
  106. tmp = tmp | flag; //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值
  107. }
  108. dht11Data[i] = tmp;
  109. }
  110. }
  111. //发送数据到字符数组,用于LCD1602显示
  112. void sendStrData()
  113. {
  114. humidity[ 0] = 'H';
  115. humidity[ 1] = ':';
  116. humidity[ 2] = dht11Data[ 0]/ 10 + 0x30;
  117. humidity[ 3] = dht11Data[ 0]% 10 + 0x30;
  118. humidity[ 4] = '.';
  119. humidity[ 5] = dht11Data[ 1]/ 10 + 0x30;
  120. humidity[ 6] = dht11Data[ 1]% 10 + 0x30;
  121. humidity[ 7] = '%';
  122. humidity[ 8] = '\0';
  123. temperature[ 0] = 'T';
  124. temperature[ 1] = ':';
  125. temperature[ 2] = dht11Data[ 2]/ 10 + 0x30;
  126. temperature[ 3] = dht11Data[ 2]% 10 + 0x30;
  127. temperature[ 4] = '.';
  128. temperature[ 5] = dht11Data[ 3]/ 10 + 0x30;
  129. temperature[ 6] = dht11Data[ 3]% 10 + 0x30;
  130. temperature[ 7] = 'C';
  131. temperature[ 8] = '\0';
  132. }
  133. //OLED的字符构造点阵
  134. unsigned char oledFont[]=
  135. {
  136. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  137. 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
  138. 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2
  139. 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //# 3
  140. 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4
  141. 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5
  142. 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6
  143. 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7
  144. 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8
  145. 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9
  146. 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10
  147. 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11
  148. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12
  149. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13
  150. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14
  151. 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
  152. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, //0 16
  153. 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //1 17
  154. 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, //2 18
  155. 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //3 19
  156. 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, //4 20
  157. 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, //5 21
  158. 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //6 22
  159. 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //7 23
  160. 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, //8 24
  161. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, //9 25
  162. 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
  163. 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27
  164. 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28
  165. 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29
  166. 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30
  167. 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31
  168. 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32
  169. 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, //A 33
  170. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //B 34
  171. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, //C 35
  172. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //D 36
  173. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, //E 37
  174. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, //F 38
  175. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, //G 39
  176. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, //H 40
  177. 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //I 41
  178. 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, //J 42
  179. 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, //K 43
  180. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, //L 44
  181. 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, //M 45
  182. 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, //N 46
  183. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //O 47
  184. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, //P 48
  185. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, //Q 49
  186. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, //R 50
  187. 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, //S 51
  188. 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //T 52
  189. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //U 53
  190. 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, //V 54
  191. 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, //W 55
  192. 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, //X 56
  193. 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //Y 57
  194. 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, //Z 58
  195. 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59
  196. 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60
  197. 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61
  198. 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62
  199. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63
  200. 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64
  201. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, //a 65
  202. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //b 66
  203. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, //c 67
  204. 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, //d 68
  205. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, //e 69
  206. 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //f 70
  207. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, //g 71
  208. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //h 72
  209. 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //i 73
  210. 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, //j 74
  211. 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, //k 75
  212. 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //l 76
  213. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, //m 77
  214. 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //n 78
  215. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //o 79
  216. 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, //p 80
  217. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, //q 81
  218. 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, //r 82
  219. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, //s 83
  220. 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, //t 84
  221. 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, //u 85
  222. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, //v 86
  223. 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, //w 87
  224. 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, //x 88
  225. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, //y 89
  226. 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, //z 90
  227. 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91
  228. 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92
  229. 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93
  230. 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
  231. };
  232. //OLED写入一条指令
  233. void oledWriteCmd(uint8_t writeCmd)
  234. {
  235. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd, 1, 0xff);
  236. }
  237. //OLED写入一个数据
  238. void oledWriteData(uint8_t writeData)
  239. {
  240. HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40,I2C_MEMADD_SIZE_8BIT,&writeData, 1, 0xff);
  241. }
  242. //OLCD初始化
  243. void oledInit()
  244. {
  245. oledWriteCmd( 0xAE);
  246. oledWriteCmd( 0x00);
  247. oledWriteCmd( 0x10);
  248. oledWriteCmd( 0x40);
  249. oledWriteCmd( 0xB0);
  250. oledWriteCmd( 0x81);
  251. oledWriteCmd( 0xFF);
  252. oledWriteCmd( 0xA1);
  253. oledWriteCmd( 0xA6);
  254. oledWriteCmd( 0xA8);
  255. oledWriteCmd( 0x3F);
  256. oledWriteCmd( 0xC8);
  257. oledWriteCmd( 0xD3);
  258. oledWriteCmd( 0x00);
  259. oledWriteCmd( 0xD5);
  260. oledWriteCmd( 0x80);
  261. oledWriteCmd( 0xD8);
  262. oledWriteCmd( 0x05);
  263. oledWriteCmd( 0xD9);
  264. oledWriteCmd( 0xF1);
  265. oledWriteCmd( 0xDA);
  266. oledWriteCmd( 0x12);
  267. oledWriteCmd( 0xDB);
  268. oledWriteCmd( 0x30);
  269. oledWriteCmd( 0x8D);
  270. oledWriteCmd( 0x14);
  271. oledWriteCmd( 0xAF);
  272. }
  273. //OLED清屏
  274. void oledClean()
  275. {
  276. int i,j;
  277. for(i= 0;i< 8;i++){
  278. oledWriteCmd( 0xB0 + i); //选择PAGE
  279. //选择PAGE的第0列开始显示
  280. oledWriteCmd( 0x00);
  281. oledWriteCmd( 0x10);
  282. for(j = 0;j < 128; j++){
  283. oledWriteData( 0); //写入字符0
  284. }
  285. }
  286. }
  287. //OLED显示一个字符
  288. void oledShowByte(char rows,char columns,char oledByte)
  289. {
  290. unsigned int i;
  291. //显示字符的上半部分
  292. oledWriteCmd( 0xb0+(rows* 2 -2)); //选择行
  293. //选择列
  294. oledWriteCmd( 0x00+(columns& 0x0f));
  295. oledWriteCmd( 0x10+(columns>> 4));
  296. //显示数据
  297. for(i=((oledByte -32)* 16);i<((oledByte -32)* 16+ 8);i++){
  298. oledWriteData(oledFont[i]);
  299. }
  300. //显示字符的上半部分
  301. oledWriteCmd( 0xb0+(rows* 2 -1)); //选择行
  302. //选择列
  303. oledWriteCmd( 0x00+(columns& 0x0f));
  304. oledWriteCmd( 0x10+(columns>> 4));
  305. //显示数据
  306. for(i=((oledByte -32)* 16+ 8);i<((oledByte -32)* 16+ 8+ 8);i++){
  307. oledWriteData(oledFont[i]);
  308. }
  309. }
  310. //OLED显示一个字符串
  311. void oledShowString(char rows,char columns,char *str)
  312. {
  313. while(*str != '\0'){
  314. oledShowByte(rows,columns,*str);
  315. str++;
  316. columns += 8;
  317. }
  318. }
  319. /* USER CODE END 0 */
  320. /**
  321. * @brief The application entry point.
  322. * @retval int
  323. */
  324. int main(void)
  325. {
  326. /* USER CODE BEGIN 1 */
  327. /* USER CODE END 1 */
  328. /* MCU Configuration--------------------------------------------------------*/
  329. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  330. HAL_Init();
  331. /* USER CODE BEGIN Init */
  332. /* USER CODE END Init */
  333. /* Configure the system clock */
  334. SystemClock_Config();
  335. /* USER CODE BEGIN SysInit */
  336. /* USER CODE END SysInit */
  337. /* Initialize all configured peripherals */
  338. MX_GPIO_Init();
  339. MX_I2C1_Init();
  340. /* USER CODE BEGIN 2 */
  341. oledInit(); //OLED初始化
  342. oledClean(); //OLED清屏函数
  343. //设置寻址模式
  344. oledWriteCmd( 0x20); //设置内存
  345. oledWriteCmd( 0x02); //选择页寻址模式
  346. /* USER CODE END 2 */
  347. /* Infinite loop */
  348. /* USER CODE BEGIN WHILE */
  349. while ( 1)
  350. {
  351. /* USER CODE END WHILE */
  352. /* USER CODE BEGIN 3 */
  353. readDht11Data();
  354. sendStrData();
  355. oledClean(); //清屏函数
  356. oledShowString( 1, 1,humidity);
  357. oledShowString( 3, 1,temperature);
  358. HAL_Delay( 1000);
  359. }
  360. /* USER CODE END 3 */
  361. }
  362. /**
  363. * @brief System Clock Configuration
  364. * @retval None
  365. */
  366. void SystemClock_Config(void)
  367. {
  368. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  369. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  370. /** Initializes the RCC Oscillators according to the specified parameters
  371. * in the RCC_OscInitTypeDef structure.
  372. */
  373. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  374. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  375. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  376. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  377. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  378. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  379. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  380. if ( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  381. {
  382. Error_Handler();
  383. }
  384. /** Initializes the CPU, AHB and APB buses clocks
  385. */
  386. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  387. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  388. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  389. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  390. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  391. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  392. if ( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  393. {
  394. Error_Handler();
  395. }
  396. }
  397. /* USER CODE BEGIN 4 */
  398. /* USER CODE END 4 */
  399. /**
  400. * @brief This function is executed in case of error occurrence.
  401. * @retval None
  402. */
  403. void Error_Handler(void)
  404. {
  405. /* USER CODE BEGIN Error_Handler_Debug */
  406. /* User can add his own implementation to report the HAL error return state */
  407. __disable_irq();
  408. while ( 1)
  409. {
  410. }
  411. /* USER CODE END Error_Handler_Debug */
  412. }
  413. #ifdef USE_FULL_ASSERT
  414. /**
  415. * @brief Reports the name of the source file and the source line number
  416. * where the assert_param error has occurred.
  417. * @param file: pointer to the source file name
  418. * @param line: assert_param error line source number
  419. * @retval None
  420. */
  421. void assert_failed(uint8_t *file, uint32_t line)
  422. {
  423. /* USER CODE BEGIN 6 */
  424. /* User can add his own implementation to report the file name and line number,
  425. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  426. /* USER CODE END 6 */
  427. }
  428. #endif /* USE_FULL_ASSERT */

转载:https://blog.csdn.net/weixin_54076783/article/details/129228660
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场