当前位置:网站首页>Huada chip hc32f4a0 realizes RS485 communication DMA transceiver
Huada chip hc32f4a0 realizes RS485 communication DMA transceiver
2022-07-28 16:21:00 【Chop Hua】
1. Serial initialization
stc_irq_signin_config_t stcIrqSigninCfg;
const stc_usart_uart_init_t stcUartInit = {
.u32Baudrate = USART_BAUDRATE,
.u32BitDirection = USART_LSB,
.u32StopBit = USART_STOPBIT_1BIT,
.u32Parity = USART_PARITY_NONE,
.u32DataWidth = USART_DATA_LENGTH_8BIT,
.u32ClkMode = USART_INTERNCLK_OUTPUT,
.u32PclkDiv = USART_PCLK_DIV64,
.u32OversamplingBits = USART_OVERSAMPLING_8BIT,
.u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
.u32SbDetectPolarity = USART_SB_DETECT_FALLING,
};
/* Configure USART RX/TX pin. */
GPIO_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
2. A serial port to receive DMA initialization
#define DMA_RX_UNIT (M4_DMA1)
#define DMA_RX_CH (DMA_CH0)
#define DMA_RX_BTC_INT (DMA_BTC_INT_CH0)
#define DMA_RX_BTC_INT_SRC (INT_DMA1_BTC0)
#define DMA_RX_BTC_INT_IRQn (Int000_IRQn)
#define DMA_RX_FUNCTION_CLK_GATE (PWC_FCG0_DMA1)
#define DMA_RX_TRIGGER_SOURCE (EVT_USART6_RI)
/** * @brief Initialize DMA. * @param None * @retval en_result_t */
static en_result_t DMA_Rx_Config(void)
{
en_result_t enRet;
stc_dma_init_t stcDmaInit;
stc_irq_signin_config_t stcIrqSignConfig;
/* DMA&AOS FCG enable */
PWC_FCG0_Unlock();
PWC_Fcg0PeriphClockCmd((DMA_RX_FUNCTION_CLK_GATE | PWC_FCG0_AOS), Enable);
PWC_FCG0_Lock();
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_DISABLE; // interrupt
stcDmaInit.u32BlockSize = 1UL; //1block
stcDmaInit.u32TransCnt = RS485_RX_BUFF_LEN; // Transmission length
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT; //8bit
stcDmaInit.u32DestAddr = (uint32_t)(rs485_struct.rx_buff); // Destination address
stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_UNIT->DR) + 2UL);// source address A serial port DR register
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_FIX; // source address Fixed address
stcDmaInit.u32DestInc = DMA_DEST_ADDR_INC; // Destination address Address auto increment
enRet = DMA_Init(DMA_RX_UNIT, DMA_RX_CH, &stcDmaInit);
if (Ok == enRet)
{
/* DMA module enable */
DMA_Cmd(DMA_RX_UNIT, Enable);
/* DMA channel enable */
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Enable);
/* Set DMA trigger source */
DMA_SetTriggerSrc(DMA_RX_UNIT, DMA_RX_CH, DMA_RX_TRIGGER_SOURCE);
}
return enRet;
}
3. A serial port to receive DMA initialization
#define DMA_TX_UNIT (M4_DMA1)
#define DMA_TX_CH (DMA_CH1)
#define DMA_TX_BTC_INT (DMA_TC_INT_CH1)
#define DMA_TX_BTC_INT_SRC (INT_DMA1_TC1)
#define DMA_TX_BTC_INT_IRQn (Int004_IRQn)
#define DMA_TX_FUNCTION_CLK_GATE (PWC_FCG0_DMA1)
#define DMA_TX_TRIGGER_SOURCE (EVT_USART6_TI)
static en_result_t DMA_Tx_Config(void)
{
en_result_t enRet;
stc_dma_init_t stcDmaInit;
stc_irq_signin_config_t stcIrqSignConfig;
/* DMA&AOS FCG enable */
PWC_FCG0_Unlock();
PWC_Fcg0PeriphClockCmd((DMA_TX_FUNCTION_CLK_GATE | PWC_FCG0_AOS), Enable);
PWC_FCG0_Lock();
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_ENABLE; //DMA_INT_ENABLE; Interrupt enable
stcDmaInit.u32BlockSize = 1UL; // Block size
stcDmaInit.u32TransCnt = 128; // transmission 128 Time
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;// Data width 8bit
stcDmaInit.u32DestAddr = ((uint32_t)(&USART_UNIT->DR)); // Destination address TX: (&USART_UNIT->DR)
stcDmaInit.u32SrcAddr = 0; // source address empty RX: (&USART_UNIT->DR +2U)
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_INC; // The source address is incremented
stcDmaInit.u32DestInc = DMA_DEST_ADDR_FIX; // The destination address is fixed DMA_DEST_ADDR_FIX;
enRet = DMA_Init(DMA_TX_UNIT, DMA_TX_CH, &stcDmaInit); // initialization dmi
if (Ok == enRet)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_CH);
/* Register interrupt */
stcIrqSignConfig.enIntSrc = DMA_TX_BTC_INT_SRC;
stcIrqSignConfig.enIRQn = DMA_TX_BTC_INT_IRQn;
stcIrqSignConfig.pfnCallback= &dma_tx_tc_irqcallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn,DDL_IRQ_PRIORITY_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
/* DMA module enable */
DMA_Cmd(DMA_TX_UNIT, Enable);
/* DMA channel interrupt enable */
DMA_TransIntCmd(DMA_TX_UNIT, DMA_TX_BTC_INT, Enable);
/* DMA channel enable */
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Enable);
/* Set DMA trigger source */
DMA_SetTriggerSrc(DMA_TX_UNIT, DMA_TX_CH, DMA_TX_TRIGGER_SOURCE);
}
DMA_SetSrcAddr(DMA_TX_UNIT, DMA_TX_CH, (uint32_t)"pbuf");
return enRet;
}
//DMA Send completion interrupt
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); // Wait for the data to be sent
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
4. Timer initialization
/* Timer0 unit & channel definition */
#define TMR0_UNIT (M4_TMR0_2)
#define TMR0_CH (TMR0_CH_A)
#define TMR0_FUNCTION_CLK_GATE (PWC_FCG2_TMR0_2)
/** * @brief Configure TMR0. * @param None * @retval None */
static void TMR0_Config(void)
{
uint32_t u32CmpVal;
stc_tmr0_init_t stcTmr0Init;
PWC_Fcg2PeriphClockCmd(TMR0_FUNCTION_CLK_GATE, Enable);
/* Clear CNTAR register for channel A */
TMR0_SetCntVal(TMR0_UNIT, TMR0_CH, 0U);
/* TIMER0 basetimer function initialize */
(void)TMR0_StructInit(&stcTmr0Init);
stcTmr0Init.u32ClockDivision = TMR0_CLK_DIV8;
stcTmr0Init.u32ClockSource = TMR0_CLK_SRC_XTAL32;
stcTmr0Init.u32HwTrigFunc = (TMR0_BT_HWTRG_FUNC_START | TMR0_BT_HWTRG_FUNC_CLEAR);
if (TMR0_CLK_DIV1 == stcTmr0Init.u32ClockDivision)
{
u32CmpVal = (USART_BAUDRATE - 4UL);
}
else if (TMR0_CLK_DIV2 == stcTmr0Init.u32ClockDivision)
{
u32CmpVal = (USART_BAUDRATE/2UL - 2UL);
}
else
{
u32CmpVal = (USART_BAUDRATE / (1UL << (stcTmr0Init.u32ClockDivision >> TMR0_BCONR_CKDIVA_POS)) - 1UL);
}
DDL_ASSERT(u32CmpVal <= 0xFFFFUL);
stcTmr0Init.u16CmpValue = (uint16_t)(u32CmpVal);
(void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);
/* Clear compare flag */
TMR0_ClearStatus(TMR0_UNIT, TMR0_CH);
}
5. Serial port interrupt enable
RS485 The communication serial port only needs to enable the receiving timeout interrupt 
Interrupt initialization
/* Register RX timeout IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = USART_RXTO_INT_IRQn;
stcIrqSigninCfg.enIntSrc = USART_RXTO_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_RxTimeout_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSigninCfg);
NVIC_ClearPendingIRQ(stcIrqSigninCfg.enIRQn);
NVIC_SetPriority(stcIrqSigninCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_EnableIRQ(stcIrqSigninCfg.enIRQn);
/* Enable TX && RX && RX interrupt function */
USART_FuncCmd(USART_UNIT, (USART_RX | USART_INT_RX | USART_TX | \
USART_RTO | USART_INT_RTO), Enable);
6. Timeout receive interrupt
/** * @brief USART RX timeout IRQ callback. * @param None * @retval None */
static void USART_RxTimeout_IrqCallback(void)
{
TMR0_Cmd(TMR0_UNIT, TMR0_CH, Disable);
USART_ClearStatus(USART_UNIT, USART_CLEAR_FLAG_RTOF);
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Disable);
// memcpy(&data_arry[0], &uart_buf[0], sizeof(data_arry));
rs485_struct.rx_len = RS485_RX_BUFF_LEN - DMA_GetTransCnt(DMA_RX_UNIT, DMA_RX_CH);
memset(rs485_struct.rx_buff, 0, sizeof(rs485_struct.rx_buff));
//printf("\r\nble recv %d %s\r\n",BleDMARecieve.len,BleDMARecieve.data);
DMA_SetDestAddr(DMA_RX_UNIT, DMA_RX_CH, (uint32_t)(&rs485_struct.rx_buff[0]));
DMA_SetBlockSize(DMA_RX_UNIT, DMA_RX_CH, 1);
DMA_SetTransCnt(DMA_RX_UNIT, DMA_RX_CH, RS485_RX_BUFF_LEN);
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Enable);
}
7. Sending function
//DMA Send completion interrupt
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); // Wait for the data to be sent
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
void rx485_send(uint8_t *pData, uint16_t Cnt)
{
set_rx485_ctrl_pin(1);
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Disable);
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
USART_FuncCmd(USART_UNIT, USART_INT_TXE, Disable);
DMA_SetSrcAddr(DMA_TX_UNIT, DMA_TX_CH, (uint32_t)pData);
DMA_SetBlockSize(DMA_TX_UNIT, DMA_TX_CH, 1);
DMA_SetTransCnt(DMA_TX_UNIT, DMA_TX_CH, Cnt);
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Enable);
USART_FuncCmd(USART_UNIT, USART_TX, Enable);
USART_FuncCmd(USART_UNIT, USART_INT_TXE, Enable);
}
It should be noted that DMA The sending completion interrupt just throws the data into the buffer , It is not that the serial port is sent, so it needs to wait for a period of time
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); // Wait for the data to be sent
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
Not much to say, just look at the source code :
#include "bsp_rs485.h"
#include "hc32_ddl.h"
#define RS485_RX_BUFF_LEN (256)
typedef struct{
uint8_t rx_buff[RS485_RX_BUFF_LEN];
uint16_t rx_len;
}RS485_RX;
RS485_RX rs485_struct;
/* DMA Unit/Channel/Interrupt definition */
#define DMA_RX_UNIT (M4_DMA1)
#define DMA_RX_CH (DMA_CH0)
#define DMA_RX_BTC_INT (DMA_BTC_INT_CH0)
#define DMA_RX_BTC_INT_SRC (INT_DMA1_BTC0)
#define DMA_RX_BTC_INT_IRQn (Int000_IRQn)
#define DMA_RX_FUNCTION_CLK_GATE (PWC_FCG0_DMA1)
#define DMA_RX_TRIGGER_SOURCE (EVT_USART6_RI)
#define DMA_TX_UNIT (M4_DMA1)
#define DMA_TX_CH (DMA_CH1)
#define DMA_TX_BTC_INT (DMA_TC_INT_CH1)
#define DMA_TX_BTC_INT_SRC (INT_DMA1_TC1)
#define DMA_TX_BTC_INT_IRQn (Int004_IRQn)
#define DMA_TX_FUNCTION_CLK_GATE (PWC_FCG0_DMA1)
#define DMA_TX_TRIGGER_SOURCE (EVT_USART6_TI)
/* Timer0 unit & channel definition */
#define TMR0_UNIT (M4_TMR0_2)
#define TMR0_CH (TMR0_CH_A)
#define TMR0_FUNCTION_CLK_GATE (PWC_FCG2_TMR0_2)
/* UART unit definition */
#define USART_UNIT (M4_USART6)
#define USART_BAUDRATE (115200UL)
#define USART_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
/* UART unit interrupt definition */
#define USART_TC_INT_SRC (INT_USART6_TCI)
#define USART_TC_INT_IRQn (Int001_IRQn)
#define USART_RXTO_INT_SRC (INT_USART6_RTO)
#define USART_RXTO_INT_IRQn (Int002_IRQn)
/* UART RX/TX Port/Pin definition */
#define USART_RX_PORT (GPIO_PORT_H) /* PH13: USART1_RX */
#define USART_RX_PIN (GPIO_PIN_06)
#define USART_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
#define USART_TX_PORT (GPIO_PORT_H) /* PH15: USART1_TX */
#define USART_TX_PIN (GPIO_PIN_07)
#define USART_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
#define RX485_CTRL_PROT (GPIO_PORT_H)
#define RX485_CTRL_PIN (GPIO_PIN_05)
/******************************************************************************* * Global variable definitions (declared in header file with 'extern') ******************************************************************************/
/******************************************************************************* * Local function prototypes ('static') ******************************************************************************/
static en_result_t DMA_Rx_Config(void);
static void TMR0_Config(void);
static void DMA_Btc_IrqCallback(void);
static void USART_RxErr_IrqCallback(void);
static void USART_RxTimeout_IrqCallback(void);
static void dma_tx_tc_irqcallback(void);
static void set_rx485_ctrl_pin(uint8_t state);
/******************************************************************************* * Local variable definitions ('static') ******************************************************************************/
static en_functional_state_t m_enLedOn = Disable;
static en_functional_state_t m_enLedCurrentStatus = Disable;
/******************************************************************************* * Function implementation - global ('extern') and local ('static') ******************************************************************************/
/** * @brief Initialize DMA. * @param None * @retval en_result_t */
static en_result_t DMA_Rx_Config(void)
{
en_result_t enRet;
stc_dma_init_t stcDmaInit;
stc_irq_signin_config_t stcIrqSignConfig;
/* DMA&AOS FCG enable */
PWC_FCG0_Unlock();
PWC_Fcg0PeriphClockCmd((DMA_RX_FUNCTION_CLK_GATE | PWC_FCG0_AOS), Enable);
PWC_FCG0_Lock();
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_DISABLE; // interrupt
stcDmaInit.u32BlockSize = 1UL; //1block
stcDmaInit.u32TransCnt = RS485_RX_BUFF_LEN; // Transmission length
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT; //8bit
stcDmaInit.u32DestAddr = (uint32_t)(rs485_struct.rx_buff); // Destination address
stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_UNIT->DR) + 2UL);// source address A serial port DR register
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_FIX; // source address Fixed address
stcDmaInit.u32DestInc = DMA_DEST_ADDR_INC; // Destination address Address auto increment
enRet = DMA_Init(DMA_RX_UNIT, DMA_RX_CH, &stcDmaInit);
if (Ok == enRet)
{
/* DMA module enable */
DMA_Cmd(DMA_RX_UNIT, Enable);
/* DMA channel enable */
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Enable);
/* Set DMA trigger source */
DMA_SetTriggerSrc(DMA_RX_UNIT, DMA_RX_CH, DMA_RX_TRIGGER_SOURCE);
}
return enRet;
}
static en_result_t DMA_Tx_Config(void)
{
en_result_t enRet;
stc_dma_init_t stcDmaInit;
stc_irq_signin_config_t stcIrqSignConfig;
/* DMA&AOS FCG enable */
PWC_FCG0_Unlock();
PWC_Fcg0PeriphClockCmd((DMA_TX_FUNCTION_CLK_GATE | PWC_FCG0_AOS), Enable);
PWC_FCG0_Lock();
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_ENABLE; //DMA_INT_ENABLE; Interrupt enable
stcDmaInit.u32BlockSize = 1UL; // Block size
stcDmaInit.u32TransCnt = 128; // transmission 128 Time
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;// Data width 8bit
stcDmaInit.u32DestAddr = ((uint32_t)(&USART_UNIT->DR)); // Destination address TX: (&USART_UNIT->DR)
stcDmaInit.u32SrcAddr = 0; // source address empty RX: (&USART_UNIT->DR +2U)
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_INC; // The source address is incremented
stcDmaInit.u32DestInc = DMA_DEST_ADDR_FIX; // The destination address is fixed DMA_DEST_ADDR_FIX;
enRet = DMA_Init(DMA_TX_UNIT, DMA_TX_CH, &stcDmaInit); // initialization dmi
if (Ok == enRet)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_CH);
/* Register interrupt */
stcIrqSignConfig.enIntSrc = DMA_TX_BTC_INT_SRC;
stcIrqSignConfig.enIRQn = DMA_TX_BTC_INT_IRQn;
stcIrqSignConfig.pfnCallback= &dma_tx_tc_irqcallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn,DDL_IRQ_PRIORITY_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
/* DMA module enable */
DMA_Cmd(DMA_TX_UNIT, Enable);
/* DMA channel interrupt enable */
DMA_TransIntCmd(DMA_TX_UNIT, DMA_TX_BTC_INT, Enable);
/* DMA channel enable */
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Enable);
/* Set DMA trigger source */
DMA_SetTriggerSrc(DMA_TX_UNIT, DMA_TX_CH, DMA_TX_TRIGGER_SOURCE);
}
DMA_SetSrcAddr(DMA_TX_UNIT, DMA_TX_CH, (uint32_t)"pbuf");
return enRet;
}
/** * @brief Configure TMR0. * @param None * @retval None */
static void TMR0_Config(void)
{
uint32_t u32CmpVal;
stc_tmr0_init_t stcTmr0Init;
PWC_Fcg2PeriphClockCmd(TMR0_FUNCTION_CLK_GATE, Enable);
/* Clear CNTAR register for channel A */
TMR0_SetCntVal(TMR0_UNIT, TMR0_CH, 0U);
/* TIMER0 basetimer function initialize */
(void)TMR0_StructInit(&stcTmr0Init);
stcTmr0Init.u32ClockDivision = TMR0_CLK_DIV8;
stcTmr0Init.u32ClockSource = TMR0_CLK_SRC_XTAL32;
stcTmr0Init.u32HwTrigFunc = (TMR0_BT_HWTRG_FUNC_START | TMR0_BT_HWTRG_FUNC_CLEAR);
if (TMR0_CLK_DIV1 == stcTmr0Init.u32ClockDivision)
{
u32CmpVal = (USART_BAUDRATE - 4UL);
}
else if (TMR0_CLK_DIV2 == stcTmr0Init.u32ClockDivision)
{
u32CmpVal = (USART_BAUDRATE/2UL - 2UL);
}
else
{
u32CmpVal = (USART_BAUDRATE / (1UL << (stcTmr0Init.u32ClockDivision >> TMR0_BCONR_CKDIVA_POS)) - 1UL);
}
DDL_ASSERT(u32CmpVal <= 0xFFFFUL);
stcTmr0Init.u16CmpValue = (uint16_t)(u32CmpVal);
(void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);
/* Clear compare flag */
TMR0_ClearStatus(TMR0_UNIT, TMR0_CH);
}
/** * @brief DMA block transfer complete IRQ callback function. * @param None * @retval None */
static void DMA_Btc_IrqCallback(void)
{
DMA_ClearTransIntStatus(DMA_RX_UNIT, DMA_RX_BTC_INT);
}
//DMA Send completion interrupt
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); // Wait for the data to be sent
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
/** * @brief USART RX timeout IRQ callback. * @param None * @retval None */
static void USART_RxTimeout_IrqCallback(void)
{
TMR0_Cmd(TMR0_UNIT, TMR0_CH, Disable);
USART_ClearStatus(USART_UNIT, USART_CLEAR_FLAG_RTOF);
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Disable);
// memcpy(&data_arry[0], &uart_buf[0], sizeof(data_arry));
rs485_struct.rx_len = RS485_RX_BUFF_LEN - DMA_GetTransCnt(DMA_RX_UNIT, DMA_RX_CH);
memset(rs485_struct.rx_buff, 0, sizeof(rs485_struct.rx_buff));
//printf("\r\nble recv %d %s\r\n",BleDMARecieve.len,BleDMARecieve.data);
DMA_SetDestAddr(DMA_RX_UNIT, DMA_RX_CH, (uint32_t)(&rs485_struct.rx_buff[0]));
DMA_SetBlockSize(DMA_RX_UNIT, DMA_RX_CH, 1);
DMA_SetTransCnt(DMA_RX_UNIT, DMA_RX_CH, RS485_RX_BUFF_LEN);
DMA_ChannelCmd(DMA_RX_UNIT, DMA_RX_CH, Enable);
}
static void set_rx485_ctrl_pin(uint8_t state)
{
if(state)
{
GPIO_SetPins(RX485_CTRL_PROT, RX485_CTRL_PIN);
}
else
{
GPIO_ResetPins(RX485_CTRL_PROT, RX485_CTRL_PIN);
}
}
void rx485_send(uint8_t *pData, uint16_t Cnt)
{
set_rx485_ctrl_pin(1);
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Disable);
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
USART_FuncCmd(USART_UNIT, USART_INT_TXE, Disable);
DMA_SetSrcAddr(DMA_TX_UNIT, DMA_TX_CH, (uint32_t)pData);
DMA_SetBlockSize(DMA_TX_UNIT, DMA_TX_CH, 1);
DMA_SetTransCnt(DMA_TX_UNIT, DMA_TX_CH, Cnt);
DMA_ChannelCmd(DMA_TX_UNIT, DMA_TX_CH, Enable);
USART_FuncCmd(USART_UNIT, USART_TX, Enable);
USART_FuncCmd(USART_UNIT, USART_INT_TXE, Enable);
}
/** * @brief Main function of UART DMA project * @param None * @retval int32_t return value, if needed */
void rs485_init(void)
{
stc_irq_signin_config_t stcIrqSigninCfg;
const stc_usart_uart_init_t stcUartInit = {
.u32Baudrate = USART_BAUDRATE,
.u32BitDirection = USART_LSB,
.u32StopBit = USART_STOPBIT_1BIT,
.u32Parity = USART_PARITY_NONE,
.u32DataWidth = USART_DATA_LENGTH_8BIT,
.u32ClkMode = USART_INTERNCLK_OUTPUT,
.u32PclkDiv = USART_PCLK_DIV64,
.u32OversamplingBits = USART_OVERSAMPLING_8BIT,
.u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
.u32SbDetectPolarity = USART_SB_DETECT_FALLING,
};
/* Initialize DMA. */
DMA_Rx_Config();
DMA_Tx_Config();
/* Initialize TMR0. */
TMR0_Config();
/* Configure USART RX/TX pin. */
GPIO_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
stc_gpio_init_t stcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinDir = PIN_DIR_OUT;
stcGpioInit.u16PinDrv = PIN_DRV_HIGH;
(void)GPIO_Init(RX485_CTRL_PROT, RX485_CTRL_PIN, &stcGpioInit);
/* Enable peripheral clock */
PWC_Fcg3PeriphClockCmd(USART_FUNCTION_CLK_GATE, Enable);
/* Initialize UART function. */
if (Ok != USART_UartInit(USART_UNIT, &stcUartInit))
{
}
/* Register RX timeout IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = USART_RXTO_INT_IRQn;
stcIrqSigninCfg.enIntSrc = USART_RXTO_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_RxTimeout_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSigninCfg);
NVIC_ClearPendingIRQ(stcIrqSigninCfg.enIRQn);
NVIC_SetPriority(stcIrqSigninCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_EnableIRQ(stcIrqSigninCfg.enIRQn);
/* Enable TX && RX && RX interrupt function */
USART_FuncCmd(USART_UNIT, (USART_RX | USART_INT_RX | USART_TX | \
USART_RTO | USART_INT_RTO), Enable);
// Enable receive mode
set_rx485_ctrl_pin(0);
}
边栏推荐
- High speed counter to rs485modbus RTU module ibf150
- Have you seen the management area decoupling architecture? Can help customers solve big problems
- MLX90640 红外热成像仪测温传感器模块开发笔记(八)
- 资本「断供」两年,我只能把公司卖了
- 小程序中的分页查询
- Zhaoqi scientific innovation and entrepreneurship competition platform, activity roadshow, investment and financing docking
- 激光测距仪非接触式地表裂缝监测仪
- Pyqt5 rapid development and practice 5.2 container: load more controls
- 【Multisim仿真】LM339过零电路仿真
- Ethernet to RS485 serial port counter WiFi module LED light controller ibf165
猜你喜欢

High speed counter to rs485modbus RTU module ibf150

头条文章_signature

LabVIEW LINX Toolkit控制Arduino设备(拓展篇—1)

JS priority queue

【微信小程序开发(七)】订阅消息

两种特殊函数(箭头函数和方法)

KubeEdge发布云原生边缘计算威胁模型及安全防护技术白皮书

Why do most people who learn programming go to Shenzhen and Beijing?

Remote serial port server (adapter) UART to 1-wire application

Food safety | these two kinds of melons and fruits should be improved, especially for pregnant women with constipation
随机推荐
js 队列
Knowledge points qwer
QT打包
百度编辑器ueditor,编辑内容过多时,工具栏不可见,不方便编辑或上传问题
Record doc
软考 系统架构设计师 简明教程 | 软件调试
Pyqt5 rapid development and practice 5.2 container: load more controls
高精度绝对角度传感器应用高速度角度监测
js中的for循环总结
CoDeSys realizes bubble sorting
STM32F103C8T6 + 0.96“ I2C OLED显示3D_Cube
el-input限制只能输入规定的数
Let's learn the game of beating hamsters
Rust 入门指南(crate 管理)
我在上海偶遇数字凤凰#坐标徐汇美罗城
2021 Yahong pen test question 2
便携式钻孔测斜仪数据采集仪测量原理与测斜探头的连接及使用方法
Numpy ndarray learning < II > miscellaneous records
李宏毅《机器学习》丨5. Tips for neural network design(神经网络设计技巧)
JS linked list 01