当前位置: 首页 > news >正文

麦包包在网站建设方面谷歌海外推广怎么做

麦包包在网站建设方面,谷歌海外推广怎么做,网站开发网络公司,h5网址LCD1602LCD1602引脚第 1 脚: VSS 为电源地 第 2 脚: VDD 接 5V 正电源 第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度。 第 4 脚&…

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函数编写
/* 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 "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *///LCD1602相关的宏定义
#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_GPIO_PIN GPIO_PIN_0
#define RW_GPIO_PIN GPIO_PIN_1
#define EN_GPIO_PIN GPIO_PIN_2#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
#define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
#define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
#define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)/* 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 *///LCD1602写指令
void writeCmd(char cmd)
{RS_LOW; //选择写指令寄存器RW_LOW;EN_LOW;GPIOA->ODR = cmd;  //将指令存入LCD1602的八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5);EN_LOW;
}//LCD1602写数据
void writeData(char myData)
{RS_HIGH;  //选择写数据寄存器RW_LOW;EN_LOW;GPIOA->ODR = myData;  //将数据存入LCD1602的八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5); EN_LOW;
}//LCD1602初始化
void lcd1602Init()
{HAL_Delay(15);   //延时 15mswriteCmd(0x38);  //写指令 38H(不检测忙信号) HAL_Delay(5);    //延时 5mswriteCmd(0x38);  //写指令 38H:显示模式设置writeCmd(0x08);  //写指令 08H:显示关闭writeCmd(0x01);  //写指令 01H:显示清屏writeCmd(0x06);  //写指令 06H:显示光标移动设置writeCmd(0x0C);  //写指令 0CH:显示开及光标设置
}/* 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();MX_TIM2_Init();/* USER CODE BEGIN 2 */char displayAddress = 0x80 + 0x05;  char dsiplayData = 'H';  lcd1602Init();writeCmd(displayAddress);  //字符显示的地址writeData(dsiplayData);  //显示的字符/* 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 */

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函数编写
/* 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 "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *///LCD1602相关的宏定义
#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_GPIO_PIN GPIO_PIN_0
#define RW_GPIO_PIN GPIO_PIN_1
#define EN_GPIO_PIN GPIO_PIN_2#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
#define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
#define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
#define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)/* 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 *///LCD1602写指令
void writeCmd(char cmd)
{RS_LOW; //选择写指令寄存器RW_LOW;EN_LOW;GPIOA->ODR = cmd;  //将指令存入LCD1602的八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5);EN_LOW;
}//LCD1602写数据
void writeData(char myData)
{RS_HIGH;  //选择写数据寄存器RW_LOW;EN_LOW;GPIOA->ODR = myData;  //将数据存入LCD1602的八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5); EN_LOW;
}//LCD1602初始化
void lcd1602Init()
{HAL_Delay(15);   //延时 15mswriteCmd(0x38);  //写指令 38H(不检测忙信号) HAL_Delay(5);    //延时 5mswriteCmd(0x38);  //写指令 38H:显示模式设置writeCmd(0x08);  //写指令 08H:显示关闭writeCmd(0x01);  //写指令 01H:显示清屏writeCmd(0x06);  //写指令 06H:显示光标移动设置writeCmd(0x0C);  //写指令 0CH:显示开及光标设置
}//LCD1602显示一行字符
void lcd1602ShowData(char rows,char columns,char *str)
{switch (rows){  //选择行case 1:writeCmd(0x80 + columns-1);  //选择列while(*str != '\0'){writeData(*str);  //显示字符str++;}break;case 2:writeCmd(0x80 + 0x40 +columns-1);  //选择列while(*str != '\0'){writeData(*str);  //显示字符str++;}break;default: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();MX_TIM2_Init();/* USER CODE BEGIN 2 */char displayAddress = 0x80 + 0x05;  char dsiplayData = 'H';  lcd1602Init();lcd1602ShowData(1,1,"haozige");lcd1602ShowData(2,1,"jiangxiaoya");/* 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

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函数编写

/* 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 "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */#include <stdio.h>#define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)
#define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
#define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)/* 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 */char dht11Data[5];
char temperature[9];
char humidity[9];//配置PB7为输入引脚或者输出引脚
void DHT_GPIO_PB7_INIT(uint32_t mode)
{//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//配置引脚GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = mode;  //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}//重写stdio.h文件中的prinft()里的fputc()函数
int fputc(int my_data,FILE *p)
{unsigned char temp = my_data;//改写后,使用printf()函数会将数据通过串口一发送出去HAL_UART_Transmit(&huart1,&temp,1,0xffff);  //0xfffff为最大超时时间return my_data;
}//微秒延时函数
void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for(i=0;i<10;i++){}cnt--;}
}//配置DHT11输出数据
void dht11Start()
{DHT_GPIO_PB7_INIT(GPIO_MODE_OUTPUT_PP);  //配置DHT11的DAT引脚为输出引脚DHT_HIGH;DHT_LOW;HAL_Delay(30);DHT_HIGH;DHT_GPIO_PB7_INIT(GPIO_MODE_INPUT);while(DHT_VALUE);  //等待自己拉到低电平while(!DHT_VALUE);  //等待自己拉到高电平while(DHT_VALUE);  //等待自己拉到低电平
}//获取DHT11的数据
void readDht11Data()
{int i,j;char tmp;char flag;dht11Start();  //开始输出数据DHT_GPIO_PB7_INIT(GPIO_MODE_INPUT);for (i = 0; i < 5; i++){  //总共获取5个字符(40bit)的数据for (j = 0; j < 8; j++){  //一次获取一个bit数据while(!DHT_VALUE);   //等待自己拉到高电平delay_us(40);  //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1if(DHT_VALUE == 1){  //40微秒后为高电平即输出1while(DHT_VALUE);flag = 1;}else{  //40微秒后为低电平即输出0flag = 0;}tmp = tmp << 1;  //由于dht11的数据是高位先出,所以用左移的方式tmp = tmp | flag;  //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值}dht11Data[i] = tmp;}
}//发送数据到字符数组,用于串口显示
void sendStrData()
{humidity[0] = 'H';humidity[1] = ':';humidity[2] = dht11Data[0]/10 + 0x30;humidity[3] = dht11Data[0]%10 + 0x30;humidity[4] = '.';humidity[5] = dht11Data[1]/10 + 0x30;humidity[6] = dht11Data[1]%10 + 0x30;humidity[7] = '%'; humidity[8] = '\0'; temperature[0] = 'T';temperature[1] = ':';temperature[2] = dht11Data[2]/10 + 0x30;temperature[3] = dht11Data[2]%10 + 0x30;temperature[4] = '.';temperature[5] = dht11Data[3]/10 + 0x30;temperature[6] = dht11Data[3]%10 + 0x30;temperature[7] = 'C';temperature[8] = '\0'; 
}/* 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();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */printf("%s","haozige\r\n");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */readDht11Data();  //获取DHT11的数据sendStrData();  //将DHT11的数据封装到字符数组printf("%s\r\n",humidity);printf("%s\r\n",temperature);HAL_Delay(1000);}/* 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 */

使用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函数编写

/* 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 */#define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)
#define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
#define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5)#define PB5_INPUT GPIO_MODE_INP
#define PB5_OUTPUT GPIO_MODE_OUTPUT_PP#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_GPIO_PIN GPIO_PIN_0
#define RW_GPIO_PIN GPIO_PIN_1
#define EN_GPIO_PIN GPIO_PIN_2#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
#define RS_LOW HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
#define RW_LOW HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
#define EN_LOW HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)/* 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 */char dht11Data[5];
char temperature[9];
char humidity[9];//配置PB5为输入引脚或者输出引脚
void DHT_GPIO_PB5_INIT(uint32_t mode)
{//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//配置引脚GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_5;GPIO_InitStruct.Mode = mode;  //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}//微秒延时函数
void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for(i=0;i<10;i++){}cnt--;}
}//配置DHT11输出数据
void dht11Start()
{DHT_GPIO_PB5_INIT(GPIO_MODE_OUTPUT_PP);DHT_HIGH;DHT_LOW;HAL_Delay(30);DHT_HIGH;DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);while(DHT_VALUE);  //等待自己拉到低电平while(!DHT_VALUE);  //等待自己拉到高电平while(DHT_VALUE);  //等待自己拉到低电平
}//获取DHT11的数据
void readDht11Data()
{int i,j;char tmp;char flag;dht11Start();  //开始输出数据DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);for (i = 0; i < 5; i++){  //总共获取5个字符(40bit)的数据for (j = 0; j < 8; j++){  //一次获取一个bit数据while(!DHT_VALUE);   //等待自己拉到高电平delay_us(40);  //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1if(DHT_VALUE == 1){  //40微秒后为高电平即输出1while(DHT_VALUE);flag = 1;}else{  //40微秒后为低电平即输出0flag = 0;}tmp = tmp << 1;  //由于dht11的数据是高位先出,所以用左移的方式tmp = tmp | flag;  //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值}dht11Data[i] = tmp;}
}//发送数据到字符数组,用于LCD1602显示
void sendStrData()
{humidity[0] = 'H';humidity[1] = ':';humidity[2] = dht11Data[0]/10 + 0x30;humidity[3] = dht11Data[0]%10 + 0x30;humidity[4] = '.';humidity[5] = dht11Data[1]/10 + 0x30;humidity[6] = dht11Data[1]%10 + 0x30;humidity[7] = '%'; humidity[8] = '\0'; temperature[0] = 'T';temperature[1] = ':';temperature[2] = dht11Data[2]/10 + 0x30;temperature[3] = dht11Data[2]%10 + 0x30;temperature[4] = '.';temperature[5] = dht11Data[3]/10 + 0x30;temperature[6] = dht11Data[3]%10 + 0x30;temperature[7] = 'C';temperature[8] = '\0'; 
}//LCD1602写指令
void writeCmd(char cmd)
{RS_LOW; //选择写指令寄存器RW_LOW;EN_LOW;GPIOA->ODR = cmd;  //将指令存入八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5);EN_LOW;
}//LCD1602写数据
void writeData(char myData)
{RS_HIGH;  //选择写数据寄存器RW_LOW;EN_LOW;GPIOA->ODR = myData;  //将数据存入八位数据线中HAL_Delay(5); EN_HIGH;HAL_Delay(5); EN_LOW;
}//LCD1602初始化
void lcd1602Init()
{HAL_Delay(15);  //延时 15mswriteCmd(0x38);  //写指令 38H(不检测忙信号) HAL_Delay(5);   //延时 5mswriteCmd(0x38);  //写指令 38H:显示模式设置writeCmd(0x08);  //写指令 08H:显示关闭writeCmd(0x01);  //写指令 01H:显示清屏writeCmd(0x06);  //写指令 06H:显示光标移动设置writeCmd(0x0C);  //写指令 0CH:显示开及光标设置
}//LCD1602显示一行字符
void lcd1602ShowData(char rows,char columns,char *str)
{switch (rows){  //选择行case 1:writeCmd(0x80 + columns-1);  //选择列while(*str != '\0'){writeData(*str);  //显示字符str++;}break;case 2:writeCmd(0x80 + 0x40 +columns-1);  //选择列while(*str != '\0'){writeData(*str);  //显示字符str++;}break;default: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 */lcd1602Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */readDht11Data();sendStrData();lcd1602ShowData(1,1,humidity);lcd1602ShowData(2,1,temperature);HAL_Delay(1000);/* 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 */

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函数编写
/* 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 "i2c.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 *///OLED写入一条指令
void oledWriteCmd(uint8_t writeCmd)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd,1,0xff);
}//OLED写入一个数据
void oledWriteData(uint8_t writeData)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&writeData,1,0xff);
}    //OLCD初始化
void oledInit()
{oledWriteCmd(0xAE);oledWriteCmd(0x00);oledWriteCmd(0x10);oledWriteCmd(0x40);oledWriteCmd(0xB0);oledWriteCmd(0x81);oledWriteCmd(0xFF);oledWriteCmd(0xA1);oledWriteCmd(0xA6);oledWriteCmd(0xA8);oledWriteCmd(0x3F);oledWriteCmd(0xC8);oledWriteCmd(0xD3);oledWriteCmd(0x00);oledWriteCmd(0xD5);oledWriteCmd(0x80);oledWriteCmd(0xD8);oledWriteCmd(0x05);oledWriteCmd(0xD9);oledWriteCmd(0xF1);oledWriteCmd(0xDA);oledWriteCmd(0x12);oledWriteCmd(0xDB);oledWriteCmd(0x30);oledWriteCmd(0x8D);oledWriteCmd(0x14);oledWriteCmd(0xAF);
}//OLED清屏
void olceClean()
{int i,j;for(i=0;i<8;i++){oledWriteCmd(0xB0 + i);  //选择PAGE//选择PAGE的第0列开始显示oledWriteCmd(0x00);  oledWriteCmd(0x10);for(j = 0;j < 128; j++){oledWriteData(0);  //写入字符0}}
}/* 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();MX_I2C1_Init();/* USER CODE BEGIN 2 */oledInit();  //OLED初始化olceClean();  //OLED清屏函数//设置寻址模式oledWriteCmd(0x20);  //设置内存oledWriteCmd(0x02);  //选择页寻址模式olceClean();  //清屏函数//选择行,选择第4行oledWriteCmd(0xB3);  //选择列,选择第一列oledWriteCmd(0x00);  oledWriteCmd(0x10);  //显示数据oledWriteData(0x08);  //显示一个点//选择第64列oledWriteCmd(0x0F);  oledWriteCmd(0x13);//显示一个点oledWriteData(0x08);/* 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 */

OLED显示自己名字

OLED与STM32板子接线

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

  • PB6<->SCL

  • PB7<->SDA

STM32CubeMX相关配置

配置SYS

配置RCC

启动I2C1

main函数编写
/* 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 "i2c.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 *///OLED的字符构造点阵
unsigned char oledFont[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};//OLED写入一条指令
void oledWriteCmd(uint8_t writeCmd)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd,1,0xff);
}//OLED写入一个数据
void oledWriteData(uint8_t writeData)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&writeData,1,0xff);
}    //OLCD初始化
void oledInit()
{oledWriteCmd(0xAE);oledWriteCmd(0x00);oledWriteCmd(0x10);oledWriteCmd(0x40);oledWriteCmd(0xB0);oledWriteCmd(0x81);oledWriteCmd(0xFF);oledWriteCmd(0xA1);oledWriteCmd(0xA6);oledWriteCmd(0xA8);oledWriteCmd(0x3F);oledWriteCmd(0xC8);oledWriteCmd(0xD3);oledWriteCmd(0x00);oledWriteCmd(0xD5);oledWriteCmd(0x80);oledWriteCmd(0xD8);oledWriteCmd(0x05);oledWriteCmd(0xD9);oledWriteCmd(0xF1);oledWriteCmd(0xDA);oledWriteCmd(0x12);oledWriteCmd(0xDB);oledWriteCmd(0x30);oledWriteCmd(0x8D);oledWriteCmd(0x14);oledWriteCmd(0xAF);
}//OLED清屏
void olceClean()
{int i,j;for(i=0;i<8;i++){oledWriteCmd(0xB0 + i);  //选择PAGE//选择PAGE的第0列开始显示oledWriteCmd(0x00);  oledWriteCmd(0x10);for(j = 0;j < 128; j++){oledWriteData(0);  //写入字符0}}
}//OLED显示一个字符
void oledShowByte(char rows,char columns,char oledByte)
{ unsigned int i;//显示字符的上半部分oledWriteCmd(0xb0+(rows*2-2));  //选择行//选择列                        oledWriteCmd(0x00+(columns&0x0f));                          oledWriteCmd(0x10+(columns>>4));      //显示数据                       for(i=((oledByte-32)*16);i<((oledByte-32)*16+8);i++){oledWriteData(oledFont[i]);                            }//显示字符的上半部分oledWriteCmd(0xb0+(rows*2-1));  //选择行  //选择列                    oledWriteCmd(0x00+(columns&0x0f));                          oledWriteCmd(0x10+(columns>>4)); //显示数据                           for(i=((oledByte-32)*16+8);i<((oledByte-32)*16+8+8);i++){oledWriteData(oledFont[i]);                            }       
}//OLED显示一个字符串
void oledShowString(char rows,char columns,char *str)
{while(*str != '\0'){oledShowByte(rows,columns,*str);str++;columns += 8;   }       
}/* 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();MX_I2C1_Init();/* USER CODE BEGIN 2 */oledInit();  //OLED初始化olceClean();  //OLED清屏函数//设置寻址模式oledWriteCmd(0x20);  //设置内存oledWriteCmd(0x02);  //选择页寻址模式olceClean();  //清屏函数oledShowString(1,1,"jiangxiaoya");  //在第一行第一列显示自己的名字/* 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获取空气中温湿度,在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函数编写
/* 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 "i2c.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */#define DHT_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)
#define DHT_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
#define DHT_VALUE HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5)#define PB5_INPUT GPIO_MODE_INP
#define PB5_OUTPUT GPIO_MODE_OUTPUT_PP/* 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 */char dht11Data[5];
char temperature[9];
char humidity[9];//配置PB5为输入引脚或者输出引脚
void DHT_GPIO_PB5_INIT(uint32_t mode)
{//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//配置引脚GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_5;GPIO_InitStruct.Mode = mode;  //配置为输入(GPIO_MODE_INPUT)或输出(GPIO_MODE_OUTPUT_PP) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}//微秒延时函数
void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for(i=0;i<10;i++){}cnt--;}
}//配置DHT11输出数据
void dht11Start()
{DHT_GPIO_PB5_INIT(GPIO_MODE_OUTPUT_PP);DHT_HIGH;DHT_LOW;HAL_Delay(30);DHT_HIGH;DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);while(DHT_VALUE);  //等待自己拉到低电平while(!DHT_VALUE);  //等待自己拉到高电平while(DHT_VALUE);  //等待自己拉到低电平
}//获取DHT11的数据
void readDht11Data()
{int i,j;char tmp;char flag;dht11Start();  //开始输出数据DHT_GPIO_PB5_INIT(GPIO_MODE_INPUT);for (i = 0; i < 5; i++){  //总共获取5个字符(40bit)的数据for (j = 0; j < 8; j++){  //一次获取一个bit数据while(!DHT_VALUE);   //等待自己拉到高电平delay_us(40);  //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1if(DHT_VALUE == 1){  //40微秒后为高电平即输出1while(DHT_VALUE);flag = 1;}else{  //40微秒后为低电平即输出0flag = 0;}tmp = tmp << 1;  //由于dht11的数据是高位先出,所以用左移的方式tmp = tmp | flag;  //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值}dht11Data[i] = tmp;}
}//发送数据到字符数组,用于LCD1602显示
void sendStrData()
{humidity[0] = 'H';humidity[1] = ':';humidity[2] = dht11Data[0]/10 + 0x30;humidity[3] = dht11Data[0]%10 + 0x30;humidity[4] = '.';humidity[5] = dht11Data[1]/10 + 0x30;humidity[6] = dht11Data[1]%10 + 0x30;humidity[7] = '%'; humidity[8] = '\0'; temperature[0] = 'T';temperature[1] = ':';temperature[2] = dht11Data[2]/10 + 0x30;temperature[3] = dht11Data[2]%10 + 0x30;temperature[4] = '.';temperature[5] = dht11Data[3]/10 + 0x30;temperature[6] = dht11Data[3]%10 + 0x30;temperature[7] = 'C';temperature[8] = '\0'; 
}//OLED的字符构造点阵
unsigned char oledFont[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};//OLED写入一条指令
void oledWriteCmd(uint8_t writeCmd)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&writeCmd,1,0xff);
}//OLED写入一个数据
void oledWriteData(uint8_t writeData)
{HAL_I2C_Mem_Write(&hi2c1,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&writeData,1,0xff);
}    //OLCD初始化
void oledInit()
{oledWriteCmd(0xAE);oledWriteCmd(0x00);oledWriteCmd(0x10);oledWriteCmd(0x40);oledWriteCmd(0xB0);oledWriteCmd(0x81);oledWriteCmd(0xFF);oledWriteCmd(0xA1);oledWriteCmd(0xA6);oledWriteCmd(0xA8);oledWriteCmd(0x3F);oledWriteCmd(0xC8);oledWriteCmd(0xD3);oledWriteCmd(0x00);oledWriteCmd(0xD5);oledWriteCmd(0x80);oledWriteCmd(0xD8);oledWriteCmd(0x05);oledWriteCmd(0xD9);oledWriteCmd(0xF1);oledWriteCmd(0xDA);oledWriteCmd(0x12);oledWriteCmd(0xDB);oledWriteCmd(0x30);oledWriteCmd(0x8D);oledWriteCmd(0x14);oledWriteCmd(0xAF);
}//OLED清屏
void oledClean()
{int i,j;for(i=0;i<8;i++){oledWriteCmd(0xB0 + i);  //选择PAGE//选择PAGE的第0列开始显示oledWriteCmd(0x00);  oledWriteCmd(0x10);for(j = 0;j < 128; j++){oledWriteData(0);  //写入字符0}}
}//OLED显示一个字符
void oledShowByte(char rows,char columns,char oledByte)
{ unsigned int i;//显示字符的上半部分oledWriteCmd(0xb0+(rows*2-2));  //选择行//选择列                        oledWriteCmd(0x00+(columns&0x0f));                          oledWriteCmd(0x10+(columns>>4));      //显示数据                       for(i=((oledByte-32)*16);i<((oledByte-32)*16+8);i++){oledWriteData(oledFont[i]);                            }//显示字符的上半部分oledWriteCmd(0xb0+(rows*2-1));  //选择行  //选择列                    oledWriteCmd(0x00+(columns&0x0f));                          oledWriteCmd(0x10+(columns>>4)); //显示数据                           for(i=((oledByte-32)*16+8);i<((oledByte-32)*16+8+8);i++){oledWriteData(oledFont[i]);                            }       
}//OLED显示一个字符串
void oledShowString(char rows,char columns,char *str)
{while(*str != '\0'){oledShowByte(rows,columns,*str);str++;columns += 8;   }       
}/* 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();MX_I2C1_Init();/* USER CODE BEGIN 2 */oledInit();  //OLED初始化oledClean();  //OLED清屏函数//设置寻址模式oledWriteCmd(0x20);  //设置内存oledWriteCmd(0x02);  //选择页寻址模式/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */readDht11Data();sendStrData();oledClean();  //清屏函数oledShowString(1,1,humidity);oledShowString(3,1,temperature);HAL_Delay(1000);}/* 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 */
http://www.dinnco.com/news/16724.html

相关文章:

  • 电子商务网站建设论文摘要鄂尔多斯seo
  • 哪家公司建气调库400平米冷库转让学seo推广
  • 网站建设捌金手指下拉七免费涨粉工具
  • 个人域名备案麻烦吗东莞网站seo推广
  • 网络项目设计方案网站怎样优化seo
  • 织梦如何做几种语言的网站网页百度网盘
  • 长沙网站开发微联推广文案
  • 目前市面上做网站的程序seo兼职工资一般多少
  • 网站制作 牛商网 岳阳 公司东莞网站制作推广公司
  • 靠谱的网站开发百度小说排行榜第一名
  • wordpress草稿定时发布惠州seo外包
  • 云南网站做的好的公司提高工作效率的方法有哪些
  • 安卓编程软件app石家庄网络seo推广
  • 安徽省建设工程专业技术资格评审标准条件seo团队管理系统
  • 人民政府 网站建设11月将现新冠感染高峰
  • 深圳网站建设专家网络运营培训班多少钱
  • 品牌建设网站百度地图轨迹导航
  • 环艺毕业设计代做网站新闻源软文发布平台
  • 手机web网站模板十堰seo排名公司
  • 去国外做赌钱网站整站优化网站
  • 网站建设的相关问题什么叫口碑营销
  • 装饰网站建设公司常熟网络推广
  • 做网站哪个好网页设计与网站建设教程
  • wordpress 博客实例seo网站排名优化公司哪家
  • 制作企业网站页面实训报告网站权重查询接口
  • 视频网站开发背景bt磁力搜索
  • 网站积分方案2022年新闻大事
  • 做网站 给源代码合肥网站排名提升
  • 兰州网站制作公司东莞百度seo推广公司
  • 有哪些做批发出口的网站广告联盟接单赚钱平台