[HAL library] Quick use of HAL library STM32cubemx

overall block diagram

image-20230409094054766

Software: keil5, STM32Cubemx
Hardware: Taobao's STM32F103C8T6 minimum system

1. Basic engineering

1 new construction

image-20230403143250580

image-20230403143526045

2 Configure RCC

Select external clock source.

image-20230403144245550

Set the input value of the external crystal oscillator, my board is 8M.
Then manually enter the maximum clock frequency, and press Enter to let him automatically configure the clock tree. My board is 72M.

image-20230403144558704

3 Configure SYS

My downloader is SWD two wires, so I choose this. (Be sure to configure the download mode before downloading the program, otherwise the MCU will be bricked and needs to be downloaded from the serial port for recovery)

image-20230403144726224

4 Project settings

image-20230403145108357

img

5 Generate code

Click to generate code

img

Open the keil project

image-20230403145259140

6 Keil settings download & reset

Select the downloader type, I use DAP. Click on the following Settings.

image-20230403145424797

After entering, check the automatic reset, which means that the single-chip microcomputer will automatically reset and run the program after each program download.
Click OK after setting.

image-20230403145616759

2. Necessary peripherals

1 Directory specification

Under the project directory, create a new ICODE folder to store various peripheral files written by yourself.

image-20230403145833040

2 LED

1 Import the .ch file (that is, import the .ch file into the keil project, and this link will not be described later)

Copy the previously written LED folder to the ICODE directory of this project.
There are led.c led.h folder inside.

image-20230403150423937

In the project, create the ICODE folder and add the led.c file.

image-20230403150845428

In the project, add the led.h file.

image-20230403151117553

image-20230403151200248

2 Cubemx configuration

Configure the board LED pins, push-pull output mode. My board is PC13.
Regenerate the code.

image-20230403151836114

3 Modify the .h file

To change to other pins, just change the LED port number and pin PIN. My board is PC13.

image-20230403152111448

4 tests

Add #include "led.h" in main.c
and add the following code in while. LED light blinks.

LED_Contrary();
HAL_Delay(500);//500ms

2 RTC

1 Import the .ch file (no more details, see the LED section for details)

none

2 Cubemx configuration

Conflict with PC13, the core board PC13 is an LED, so disable RTC OUT.

3 Modify the .c file

In the interrupt.c, add the led header file, and in the RTC interrupt function, add the 500ms, LED level inversion function.

#include "led.h"

static uint16_t rtccnt=0;
rtccnt++;
if(rtccnt>500) rtccnt=0,LED_Contrary();

image-20230404190141584

4 tests

The LEDs blink.

3 USE

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

image-20230404190406936

Tick ​​to use

image-20230408220340280

2 Cubemx configuration

Use serial port 1, default baud rate, asynchronous communication.

image-20230404185429185
enable interrupt
image-20230404093133924

3 Modify the .h file

The code uses serial port 1 by default. Adding other serial ports can be done in .h, copied and renamed.

image-20230404183337374

4 tests

Serial send/receive function:

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收

Serial interrupt function:

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();串口接收错误函数

The commonly used sending function is: HAL_UART_Transmit();

The commonly used receiving function is: HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

HAL library serial port interrupt call process:

image-20230404105922320

send:

1 printf remapping:

/* printf重映射 */
#include <stdio.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    //具体哪个串口可以更改huart1为其它串口
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1 , 0xffff);
    return ch;
}

2 printf sends:

printf("hello \r\n"); //发送字符串

float Data=1.11;
printf("Data=%.2f \r\n",Data);	//发送变量

3 Hal library comes with sending function:

#include <stdio.h>

HAL_UART_Transmit(&huart1,"hello\r\n",sizeof("hello\r\n"),0xffff);//发送字符串

uint8_t Data1[]={
    
    "hello\r\n"};
HAL_UART_Transmit(&huart1,Data1,sizeof(Data1),0xffff);//发送字符串

uint8_t Databuffer[20]={
    
    0};
float Data=1.11;
sprintf(Databuffer,"Data=%.2f \r\n",Data);
HAL_UART_Transmit(&huart1,Databuffer,strlen(Databuffer),0xffff);//发送变量 用strlen

Interrupt reception:

1 fixed length

 /*	
		串口接收中断
		定长接收	
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
		if(huart == &huart1)
		{
			HAL_UART_Transmit(&huart1,(uint8_t *)&Uart1_RxData,1,0xffff);//原样返回
			while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
			HAL_UART_Receive_IT(&huart1,(uint8_t *)&Uart1_RxData, 1); //&取地址
		}
}

2 variable length

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
	
	if(huart == &huart1)
	{
		if(Uart1_Rx_Cnt >= 255)  //溢出判断
		{
			Uart1_Rx_Cnt = 0;
			memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer));
			HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
		}
		else
		{
			Uart1_RxBuffer[Uart1_Rx_Cnt++] = Uart1_RxData;   //接收数据转存
		
			if((Uart1_RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位\r\n。0x0D是\r,0x0A是\n
			{
				/*	此处添加用户代码	*/

				HAL_UART_Transmit(&huart1, (uint8_t *)&Uart1_RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
				while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束

				/*	此处添加用户代码	*/
				Uart1_Rx_Cnt = 0;
				memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer)); //清空数组
			}
		}
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&Uart1_RxData, 1);   //再开启接收中断
	}
}

4 KEY

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

2 Cubemx configuration

3 Modify the .h file

4 tests

3. Other peripherals

1 OLED (analog IIC, analog SPI)

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project. Choose IIC or SPI. (analog IIC and analog SPI)

image-20230404190842999

image-20230404191104861

2 Cubemx configuration

Choose the GPIO corresponding to the number of OLED pins and set it as push-pull output. Set to high speed.

image-20230404192656241

3 Modify the .h file

To change to other pins, just change OLED port number and pin PIN

image-20230404191352126

4 tests

OLED display font size 16*16 is the most suitable. Can put 4 lines: 0 16 32 48.

add header file

#include "oled.h"

add initialization

OLED_Init();
OLED_ColorTurn(0);			//0正常显示,1 反色显示
OLED_DisplayTurn(0);		//0正常显示 1 屏幕翻转显示

1 Display characters:

OLED_ShowString(0,0,"hello",16,1); 
OLED_Refresh();//更新0

2 Display variables:

uint8_t Databuffer[20]={
    
    0};
float Data=1.11;
sprintf(Databuffer,"Data=%.2f \r\n",Data);//sprintf
OLED_ShowString(0,16,Databuffer,16,1);  
OLED_Refresh();

3 Display Chinese:


1

2 BH1750 light intensity detection

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

2 Cubemx configuration

3 Modify the .h file

4 tests

add header file

add initialization

3 MQ2 smoke detection

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

image-20230404202319711

2 Cubemx configuration

Pick an ADC pin at will. Initialize ADC pins.

3 Modify the .h file

4 tests

add header file

#include "mq2.h"

collection

uint16_t MQ2_DATA=0;
MQ2_DATA = GetMQ4Value();

3 MQ4 formaldehyde detection

Same as MQ2, read AD.

Concentration conversion function:

uint16_t GetMQ4Value(void)
{
    
    
			uint16_t ADCVal;
			float Voltage;
			uint16_t ppm;
			HAL_ADC_Start(&hadc1);//开始ADC采集
			HAL_ADC_PollForConversion(&hadc1,500);//等待采集结束
			if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))//读取ADC完成标志位
			{
    
    
				ADCVal =  HAL_ADC_GetValue(&hadc1);//读出ADC数值
			}
			Voltage = ADCVal * 3.3 / 4096;
	//无天然气的环境下,实测AOUT端的电压为0.5V,当检测到天然气时,电压每升高0.1V,实际被测气体浓度增加200ppm
			ppm = (Voltage - 0.5) / 0.1 * 200;
			return ppm;
			//return ADCVal;
}

4 DHT11 temperature and humidity

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-4kFUCvSv-1681004471418)(null)]

2 Cubemx configuration

Choose an IO port and configure it as high-speed, push-pull output.

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

image-20230404202744976

2 Cubemx configuration

Choose an IO port at will. Configured as a push-pull output, high speed.

3 Modify the .h file

To define the GPIO port connected to the DHT11 bus, you only need to modify the following 2 lines of code to change the DATA pin arbitrarily

image-20230404194855017

4 tests

add header file

#include "dht11.h"

add initialization

DHT11_Init();						//DHT11温湿模块初始化

read temperature and humidity

uint8_t DHT11_DATA[2]={0};		//用于存放DHT11温湿度数据
DHT11_ReadData(DHT11_BUF);		//读出DHT11传感器数据(参数是存放数据的数组指针)
printf("湿度:%2d% 温度:%2d℃\r\n",DHT11_BUF[0],DHT11_BUF[1]);//串口打印湿度温度

5 SIM900A GSM module

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

2 Cubemx configuration

3 Modify the .h file

4 tests

add header file

add initialization

6 BMP180 air pressure sensor

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

image-20230409090534520

2 Cubemx configuration

Using analog IIC, choose any two io ports to set as push-pull output mode. I choose B7 B6 here.

Configure serial port 1 and remap printf.

Cubemx basic project and configuration see: [HAL library] HAL library STM32cubemx quick use

3 Modify the .h file

You only need to modify the following 2 lines of code to change the pins arbitrarily

image-20230409090442577

4 tests

add header file

#include "bmp1801.h"

add initialization

BMP_Init();				  //BMP180初始化
BMP_ReadCalibrationData();//BMP180初始化

read

uint8_t ID = 0;		//BMP180器件号
ID = BMP_ReadOneByte(0xd0);	//读取设备ID
BMP_UncompemstatedToTrue();	//读取气压值
printf("ID = %d\t  temp = %d.%dC\t   Pressure = %.2fkPa\t   Altitude = %.5fm\r\n",ID,bmp180.Temp/10,bmp180.Temp%10,(float)bmp180.p/1000.0,bmp180.altitude);
HAL_Delay(500);

image-20230409092351354

7 ESP8266+Onenet+HTTP

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

2 Cubemx configuration

3 Modify the .h file

4 tests

add header file

add initialization

8 ESP8266+Onenet+MQTT

1 Import the .ch file (no more details, see the LED section for details)

Import the previously written .ch file into the keil project.

image-20230408211617282

2 Cubemx configuration

Serial port 1 is used for debugging, serial port 3 is used for ESP8266 communication, and the interrupt is enabled.

I will not configure the basic ones, you can see the detailed explanation above.

3 Modify the .ch file

Things to modify when transplanting:

1 Change the serial port used

Sending part: In esp8266.c, replace all huart3 with the serial port number to be modified, such as serial port 2.

image-20230408212731847

Receiving part: Use the serial port interrupt to receive the message from esp8266. Add the serial port callback function in any folder. I personally created a uart.c file to put all the codes related to the serial port.

Add the following code (serial port number is modified according to personal circumstances)

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    
    
    if(huart == &huart3)//esp8266接收云平台数据
		{
    
    
			if(esp8266_cnt >= sizeof(esp8266_buf))
			{
    
                
				esp8266_cnt = 0; //防止串口被刷爆
			}
			esp8266_buf[esp8266_cnt++] = Uart3_RxData;

			HAL_UART_Receive_IT(&huart3,(uint8_t *)&Uart3_RxData, 1); //&取地址
		}
}

2 Change wifi name and password

image-20230408211926168

3 Change the product ID, device ID, and authentication information.

image-20230408212601399

4 tests

add header file

#include "onenet.h"
#include "esp8266.h"

add initialization

Don't forget to open the serial interrupt.

HAL_UART_Receive_IT(&huart3,(uint8_t *)&Uart3_RxData, 1);//开启串口中断
/* esp8266连接wifi+连接Onenet */
HAL_Delay(2000);
ESP8266_Init();					//初始化ESP8266,连接wifi
HAL_Delay(2000);
while(OneNet_DevLink())			//连接OneNET
HAL_Delay(2000);

If the connection is successful, onenet will display that the device is online. The serial port will also print successfully.

image-20230408213614618

image-20230408220823254

send data

OneNet_SendData();	//发送数据
ESP8266_Clear();	//清空数据缓存区
HAL_Delay(3000);	//3s发送一次

image-20230408220926312

What data to send, change here:

image-20230408214852054

Receive data

dataPtr = ESP8266_GetIPD(0);//获取平台返回的数据
if(dataPtr != NULL)//如果返回数据不为空
	OneNet_RevPro(dataPtr);//平台返回数据检测

Guess you like

Origin blog.csdn.net/weixin_44029896/article/details/129960982