[feat] add rs485(UART3) baseic driver

This commit is contained in:
zhji 2024-06-23 21:50:41 +08:00
parent 787f8d20ad
commit 283685ff35
4 changed files with 187 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#include "stm32f4xx_rcc.h"
#include "led.h"
#include "lcd.h"
// #include "lcd.h"
#include "rs485.h"
volatile uint32_t system_tick_cnt;
@ -28,7 +29,8 @@ void system_init(void)
{
led_init();
system_tick_init();
lcd_init();
// lcd_init();
rs485_init();
}
int main(void)
@ -39,7 +41,8 @@ int main(void)
__enable_irq();
while (1) {
led_loop();
lcd_loop();
// lcd_loop();
rs485_loop();
}
return 0;
}

View File

@ -1,6 +1,7 @@
file(GLOB FILELIST
led.c
lcd.c
# lcd.c
rs485.c
)
add_library(src STATIC ${FILELIST})

153
stm32f4/src/rs485.c Normal file
View File

@ -0,0 +1,153 @@
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
#include "rs485.h"
#define RS485_TX_STREAM DMA1_Stream3
#define RS485_RX_STREAM DMA1_Stream1
#define RS485_BUFF_TX_LEN (4096)
#define RS485_BUFF_RX_LEN (1024)
uint8_t rs485_buff_tx[RS485_BUFF_TX_LEN] __attribute__((aligned(16)));
uint8_t rs485_buff_rx[RS485_BUFF_RX_LEN] __attribute__((aligned(16)));
extern uint32_t system_tick_cnt;
static void rs485_mode_tx(void)
{
GPIO_SetBits(RS485_PORT, RS485_PIN_DIR);
}
static void rs485_mode_rx(void)
{
GPIO_ResetBits(RS485_PORT, RS485_PIN_DIR);
}
void rs485_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Pin = RS485_PIN_DIR,
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT,
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP,
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz,
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL,
GPIO_Init(RS485_PORT, &GPIO_InitStructure);
rs485_mode_tx();
GPIO_PinAFConfig(RS485_PORT, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(RS485_PORT, GPIO_PinSource11, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin = RS485_PIN_TX | RS485_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(RS485_PORT, &GPIO_InitStructure);
USART_DeInit(USART3);
USART_OverSampling8Cmd(USART3, ENABLE);
USART_InitStructure.USART_BaudRate = RS485_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
USART_Cmd(USART3, ENABLE);
DMA_InitStructure.DMA_BufferSize = RS485_BUFF_TX_LEN;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&(USART3->DR));
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rs485_buff_tx;
DMA_Init(RS485_TX_STREAM, &DMA_InitStructure);
/* Configure DMA controller to manage USART RX request */
DMA_InitStructure.DMA_BufferSize = RS485_BUFF_RX_LEN;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rs485_buff_rx;
DMA_Init(RS485_RX_STREAM, &DMA_InitStructure);
/* Configure interrupt for USART3 RX */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 12;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_ITConfig(USART3, USART_IT_TC, ENABLE);
/* clear IT flag */
USART_GetITStatus(USART3, USART_IT_IDLE);
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
USART_ClearITPendingBit(USART3, USART_IT_TC);
rs485_send(15);
}
void rs485_send(uint16_t len)
{
rs485_mode_tx();
DMA_SetCurrDataCounter(RS485_TX_STREAM, len);
DMA_Cmd(RS485_TX_STREAM, ENABLE);
}
void rs485_loop(void)
{
static uint32_t ms = 0;
if (system_tick_cnt < (ms + 500)) {
return;
}
ms = system_tick_cnt;
// rs485_send(15);
}
void USART3_IRQHandler(void)
{
uint16_t len;
if (USART_GetITStatus(USART3, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART3, USART_IT_TC);
DMA_ClearFlag(RS485_TX_STREAM, DMA_FLAG_TCIF3 | DMA_FLAG_HTIF3 | DMA_FLAG_TEIF3 | DMA_FLAG_DMEIF3 | DMA_FLAG_FEIF3);
DMA_Cmd(RS485_TX_STREAM, DISABLE);
/* after tx complete, config rx */
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
DMA_SetCurrDataCounter(RS485_RX_STREAM, RS485_BUFF_RX_LEN);
DMA_Cmd(RS485_RX_STREAM, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
rs485_mode_rx();
}
if (USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) {
USART_ITConfig(USART3, USART_IT_IDLE, DISABLE);
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
DMA_Cmd(RS485_RX_STREAM, DISABLE);
DMA_ClearFlag(RS485_RX_STREAM, DMA_FLAG_TCIF1 | DMA_FLAG_HTIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_FEIF1);
len = DMA_GetCurrDataCounter(RS485_RX_STREAM);
len = RS485_BUFF_RX_LEN - len;
for (uint16_t i = 0; i < len; i++) {
rs485_buff_tx[i] = rs485_buff_rx[i] + 2;
}
rs485_send(len);
}
}

26
stm32f4/src/rs485.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef __RS485_H__
#define __RS485_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx.h"
#define RS485_PORT (GPIOB)
#define RS485_PIN_TX (GPIO_Pin_10)
#define RS485_PIN_RX (GPIO_Pin_11)
#define RS485_PIN_DIR (GPIO_Pin_1)
#define RS485_BAUDRATE (115200)
#define RS485_MB_ADDR (9)
void rs485_init(void);
void rs485_send(uint16_t len);
void rs485_loop(void);
#ifdef __cplusplus
}
#endif
#endif /* __RS485_H__ */