当前位置:网站首页>STM32 serial port sending and receiving multiple data tutorial based on gas sensor practice
STM32 serial port sending and receiving multiple data tutorial based on gas sensor practice
2022-07-19 03:41:00 【No martial arts, no understanding of the Jianghu】
Preface
I've been working on a project recently , It is necessary to detect the concentration of various gases in the cable trench , So a gas sensor is used , The sensor is RS485 signal communication , So we need to realize RS485 To serial port and STM32 signal communication ,MCU by STM32F429,485 The chip is MAX3485.
One 、 Serial port data receiving and sending
Here I want to talk about the serial port , be engaged in stm32 It has been developed for several years , Think you're right stm32 I have mastered it well , Later, I found that I was just floating on the surface , No good in-depth study stm32 The bottom of the
1. brief introduction
Serial port is MCU Critical external interface , At the same time, it is also an important debugging tool in the process of software development , Now basically everything MCU Will have a serial port .
Serial port setting steps :
Serial clock enable ,GPIO Clock enable .
Set pin multiplexer mapping : call GPIO_PinAFConfig function .
GPIO Initialize settings : To set the mode to reuse function .
Initialization of serial port parameters : set baud rate , The word is long , Parity and other parameters .
Turn on interrupt and initialize NVIC, To interrupt ( If you need to turn on interrupt, you need this step ).
Enable serial port .
Write interrupt handling functions : The function name format is USARTxIRQHandler(x Corresponding serial port number ).
About 7 Interrupt handling function in , There is one thing to note , When the serial port used is USART when , Interrupt handler name : USARTxIRQHandler(x Corresponding serial port number ), When using serial port UART when , Interrupt handler name : UARTxIRQHandler(x Corresponding serial port number ), Remember that , Otherwise, the serial port interrupt function cannot enter , and DEBUG The interrupt function cannot set a breakpoint .
2. Serial port configurator
I use serial port 5,UART5,TX by PC12,RX by PD2
void Usart5_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure; //1.GPIO Mouth initialization
USART_InitTypeDef USART_InitStructure; // Serial initialization
NVIC_InitTypeDef NVIC_InitStructure; // Interrupt initialization
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE); // Can make GPIOC The clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);// Can make USART5 The clock
// Opening a serial port 5 Corresponding IO Pin multiplexing mapping
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
//IO Port initialization configuration
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Speed 50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
//IO Port initialization configuration
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Speed 50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure);
//GPIO // RS485EN5, Code here is the same as RS485 of
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//
GPIO_Init(GPIOD, &GPIO_InitStructure);// initialization GPIOD
// Serial port initialization configuration
USART_InitStructure.USART_BaudRate = bound;// Baud rate
USART_InitStructure.USART_WordLength = USART_WordLength_8b;// Data bits
USART_InitStructure.USART_StopBits = USART_StopBits_1;// Stop bit
USART_InitStructure.USART_Parity = USART_Parity_No;// Parity bit
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Transceiver mode
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// No hardware data flow control
USART_Init(UART5,&USART_InitStructure);
USART_Cmd(UART5, ENABLE); // Enable serial port 5
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);// Turn on related interrupt
// USART5 NVIC initialization
NVIC_InitStructure.NVIC_IRQChannel= UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 3;
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
3. Serial port sending program
There are multiple senders here , But every serial port sends programs through UART5->DR Write data in the register to send data , The same goes for receiving , Are read UART5->DR Register data . When data needs to be sent , stay while Call the following functions in .
/ Send a byte of data
//input:byte, Data to be sent
void UART5_send_byte(uint8_t byte)
{
while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET);// Wait for the send to complete
//UART5->DR=byte; //byte
USART_SendData(UART5,byte);
}
// Sending multibyte data
void UART5_Send_bytes(uint8_t *Buffer, uint8_t Length)
{
uint8_t i=0;
while(i<Length)
{
UART5_send_byte(Buffer[i++]);
}
GPIO_ResetBits(GPIOD, GPIO_Pin_3); //USART5 SEND DATA switch 1:send 0;receive
}
// Sending multibyte data + The checksum
void UART5_Send(uint8_t *Buffer, uint8_t Length)
{
uint8_t i=0;
while(i<Length)
{
if(i<(Length-1))
Buffer[Length-1]+=Buffer[i];// Add up Length-1 Data before
if(i==(Length-1))
{
Buffer[Length-1]=Buffer[Length-1]&0xFF;
}
UART5_send_byte(Buffer[i++]);
}
}
4. Serial port receives data
There are two ways to receive data through serial port ,1 Polling method is adopted ,2 It adopts interrupt mode . Using interrupt to receive serial port data does not need to call the receiving function manually , Because the receiving data of the serial port is realized in the interrupt , You need to write interrupt function and receive data processing function .
void usart5_data_analyse(u8 *buf,u8 num,u8 WhichGas) // Serial port accepts data processing program
{
// Receive data processing function , Fill in according to your needs
}
void UART5_IRQHandler(void) // Interrupt handling function , When sending is interrupted MCU Call the function automatically .
{
uint8_t res; static u8 i1=0;
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)// Judge the receiving flag
{
res = UART5->DR;
UART5_RX_BUF[i1] = res;
i1++;
if(i1 > 17 )//
{
usart5_data_analyse(UART5_RX_BUF,18,WhichGas);// Receive data processing function
i1=0;// Put on hold 0
UART5_RX_STA=1;
}
}
}
There are two ways to receive data by interrupt of serial port , One is idle interrupt IDLE, One is RXNE( The read data register is not empty ), When RXNE The bit is set 1 When , It indicates that data has been received and can be read . At this time, all we have to do is read it as soon as possible USART_DR, By reading USART_DR This bit can be cleared , You can also write... To this bit 0, Direct removal .
5.USART block diagram
This block diagram clearly describes the data sending and receiving process of the serial port , The sending process is 1-->2-->3, The receiving process is :4-->5-->6

6.USART_SR Serial port status register

There are several registers that need to be understood .
TXE: Send data register is empty (Transmit data register empty)
When TDR When the contents of the register have been transferred to the shift register , This bit is set by hardware 1. If USART_CR1 register
in TXEIE position = 1, An interrupt is generated . Through to USART_DR The register performs a write operation to clear this bit .
0: Data not transferred to shift register
1: Data is transferred to the shift register
TC: Send complete (Transmission complete)
If the transmission of the frame containing data has been completed and TXE Set up 1, Then this bit is set by hardware 1. If USART_CR1 Deposit
In the device TCIE = 1, An interrupt is generated . This bit is cleared by the software sequence ( Read USART_SR register , And then write
USART_DR register ). TC Bit can also be written to this bit ‘0’ To clear . It is recommended to communicate only in multiple buffers
Use this zeroing sequence .
0: Transfer not completed
1: Transfer completed
RXNE: The read data register is not empty (Read data register not empty)
When RDR move position Send save device Of Inside Rong has Pass on transport To USART_DR Send save device when , The position from hard Pieces of Set up 1. Such as fruit
USART_CR1 In the register RXNEIE = 1, An interrupt is generated . Through to USART_DR Registers perform read
Operate to clear this bit . RXNE The flag can also be cleared by writing zero to this bit . It is recommended to make
Use this zeroing sequence .
0: No data received
1: Ready to read the received data
IDLE: Idle line detected (IDLE line detected)
When an idle line is detected , This bit is set by hardware 1. If USART_CR1 In the register IDLEIE = 1, Will generate
break . This bit is cleared by the software sequence ( Read in USART_SR register , Then read in USART_DR register ).
0: No idle lines detected
1: Idle line detected
ORE: Overflow error (Overrun error)
stay RXNE = 1 Under the circumstances , When the word currently being received in the shift register is ready for transmission to RDR When the register , The
The bit is set by hardware 1. If USART_CR1 In the register RXNEIE = 1, An interrupt is generated . This bit is cleared by the software sequence
zero ( Read in USART_SR register , Then read in USART_DR register ).
0: No overflow error
1: Overflow error detected
Two 、USART turn RS485
1. Serial port to RS485 Circuit design
use MAX3485 The chip realizes serial port to 485.
One thing to note is that ,RE and DE The pin is used to control the receiving and sending of data , When RE and DE For high voltage , The chip is in the sending state ,RE and DE Low power level , The chip is in the receiving state
3、 ... and 、 Realization USART Send and receive multiple data
Serial port sending and receiving multiple data is also realized on the basis of single sending and receiving , Because the project needs to read the concentration of four gases , Therefore, the serial port is required to send four data requests and accept four serial port data , Note that the data format is 16 Base number
oid Get_Gas_Density(void) // This function first delays 100s, How to send four data in turn and receive four data , Receiving data is achieved by interruption
{
if(tx_times==1)
{
for(WaitTime=0;WaitTime<100;WaitTime++) //wait 30s
{
delay_ms(1000);
}
tx_times=2;
}
if(tx_times==2)
{
UART5_RX_STA = 0;
GPIO_SetBits(GPIOD, GPIO_Pin_3); //USART5 SEND DATA switch 1:send 0;receive
delay_ms(50);
LED1=0;
WhichGas = 0;
UART5_Send_bytes( UART5_TX_BUF_1, 12);
LED1=1;
tx_times = 3;
delay_ms(1000);
}
else if((tx_times==3)&&(UART5_RX_STA))
{
UART5_RX_STA = 0;
GPIO_SetBits(GPIOD, GPIO_Pin_3); //USART5 SEND DATA switch 1:send 0;receive
delay_ms(50);
LED1=0;
WhichGas = 1;
UART5_Send_bytes( UART5_TX_BUF_2, 12);
LED1=1;
tx_times = 4;
delay_ms(1000);
}
else if((tx_times==4)&&(UART5_RX_STA))
{
UART5_RX_STA = 0;
GPIO_SetBits(GPIOD, GPIO_Pin_3); //USART5 SEND DATA switch 1:send 0;receive
delay_ms(50);
LED1=0;
WhichGas = 2;
UART5_Send_bytes( UART5_TX_BUF_3, 12);
LED1=1;
tx_times = 5;
delay_ms(1000);
}
else if((tx_times==5)&&(UART5_RX_STA))
{
UART5_RX_STA = 0;
GPIO_SetBits(GPIOD, GPIO_Pin_3); //USART5 SEND DATA switch 1:send 0;receive
delay_ms(50);
LED1=0;
WhichGas = 3;
UART5_Send_bytes( UART5_TX_BUF_4, 12);
LED1=1;
tx_times=2;
delay_ms(1000);
}
else
{
}
}
void usart5_data_analyse(u8 *buf,u8 num,u8 WhichGas) // Serial port accepts data processing program
{
CalcDedmsoty[1] = (buf[11]&0x0f) * 100;
CalcDedmsoty[0] = ((buf[11]>>4)&0x0f) * 1000;
CalcDedmsoty[2] = (buf[12]&0x0f) ;
CalcDedmsoty[3] = ((buf[12]>>4)&0x0f) * 10;
GasDensity[WhichGas] = CalcDedmsoty[0]+CalcDedmsoty[1]+CalcDedmsoty[2]+CalcDedmsoty[3];
switch(buf[13])
{
case 0x00:
GasDensity[WhichGas] = GasDensity[WhichGas];
break;
case 0x01:
GasDensity[WhichGas] = GasDensity[WhichGas]/10;
break;
case 0x02:
GasDensity[WhichGas] = GasDensity[WhichGas]/100;
break;
case 0x03:
GasDensity[WhichGas] = GasDensity[WhichGas]/1000;
break;
}
}
void UART5_IRQHandler(void)
{
uint8_t res; static u8 i1=0;
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)// Judge the receiving flag
{
res = UART5->DR;
UART5_RX_BUF[i1] = res;
i1++;
if(i1 > 17 )//
{
usart5_data_analyse(UART5_RX_BUF,18,WhichGas);
LED2=0;
i1=0;// Put on hold 0
UART5_RX_STA=1;
LED2=1;
}
}
}
边栏推荐
- Install Net prompt "cannot establish a certificate chain to trust the root authority" (simple method with download address)
- Wechat applet -- Summary of problems in the actual development of taro framework
- Game theory of catching lice
- 代理模式——B站动力节点
- Chengxin University envi_ IDL first week experiment test: simple operation of array + detailed analysis
- The installation software prompts that the program input point adddlldirectory cannot be located in the dynamic link library kernel32 DLL (download address at the end of the text)
- Theoretical basis of doubledqn and its code implementation [pytoch + pendulum-v0]
- HRNet
- Labelme starts normally, but cannot be opened
- 谷歌 Chrome 浏览器安装 PWA 应用将显示更多描述信息
猜你喜欢

leetcode162. 寻找峰值

波士顿房价分析作业总结

箭头函数与this指向详解

Laravel's problem

Configure high availability using virtual ip+kept

神经网络学习笔记2.2 ——用Matlab写一个简单的卷积神将网络图像分类器

代理模式——B站动力节点

Thinkphp5.0模型操作使用page进行分页

GNOME-BOXES虚拟机创建安装

Chengxin University envi_ The second week of IDL experiment content: extract aod+ in all MODIS aerosol products for detailed analysis
随机推荐
Shell script receives and returns parameters
Wdog and power mode of fs32k148 commissioning
GoogLeNet
Neural network learning notes 2.2 -- write a simple convolution neural network image classifier with MATLAB
10. Redis 面试常见问答
oracle 查询 主机名和对应的IP地址
Thinkphp5.0 model operation uses page for paging
STM32串口发送和接收多个数据教程基于气体传感器实战
The fourth day of the third question of daily Luogu
MySQL log management and full backup incremental backup and recovery
ES6学习笔记——B站小马哥
KubeCon + CloudNativeCon Europe 2022
mysqldump: [Warning] Using a password on the command line interface can be insecure.
Reptile learning (5): teach you reptile requests practice hand in hand
ResNet
GNOME-BOXES虚拟机创建安装
Receiver operating curve
Monte Carlo based reinforcement learning method [with code implementation]
Fisher linear discriminant analysis
Theoretical basis of double Q-learning and its code implementation [pendulum-v0]