1.串口初始化
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.串口接收DMA初始化
#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; //中断
stcDmaInit.u32BlockSize = 1UL; //1block
stcDmaInit.u32TransCnt = RS485_RX_BUFF_LEN; //传输长度
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT; //8bit
stcDmaInit.u32DestAddr = (uint32_t)(rs485_struct.rx_buff); //目的地址
stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_UNIT->DR) + 2UL);//源地址 串口DR寄存器
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_FIX; //源地址 固定地址
stcDmaInit.u32DestInc = DMA_DEST_ADDR_INC; //目的地址 地址自增
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.串口接收DMA初始化
#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;中断使能
stcDmaInit.u32BlockSize = 1UL; //块大小
stcDmaInit.u32TransCnt = 128; //传输128次
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;//数据宽度8bit
stcDmaInit.u32DestAddr = ((uint32_t)(&USART_UNIT->DR)); //目的地址TX: (&USART_UNIT->DR)
stcDmaInit.u32SrcAddr = 0; //源地址 空 RX: (&USART_UNIT->DR +2U)
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_INC; //源地址依次递增
stcDmaInit.u32DestInc = DMA_DEST_ADDR_FIX; //目的地址固定 DMA_DEST_ADDR_FIX;
enRet = DMA_Init(DMA_TX_UNIT, DMA_TX_CH, &stcDmaInit); //初始化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发送完成中断
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); //等待数据发送完成
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
4.定时器初始化
/* 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.串口中断使能
/* 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.超时接收中断
/**
* @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.发送函数
//DMA发送完成中断
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); //等待数据发送完成
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);
}
需要注意的是DMA发送完成中断只是将数据丢入缓冲区,并不是串口发送完成所以需要等待一段时间
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); //等待数据发送完成
USART_FuncCmd(USART_UNIT, USART_TX, Disable);
set_rx485_ctrl_pin(0);
}
不多说直接看源码:
#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; //中断
stcDmaInit.u32BlockSize = 1UL; //1block
stcDmaInit.u32TransCnt = RS485_RX_BUFF_LEN; //传输长度
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT; //8bit
stcDmaInit.u32DestAddr = (uint32_t)(rs485_struct.rx_buff); //目的地址
stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_UNIT->DR) + 2UL);//源地址 串口DR寄存器
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_FIX; //源地址 固定地址
stcDmaInit.u32DestInc = DMA_DEST_ADDR_INC; //目的地址 地址自增
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;中断使能
stcDmaInit.u32BlockSize = 1UL; //块大小
stcDmaInit.u32TransCnt = 128; //传输128次
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;//数据宽度8bit
stcDmaInit.u32DestAddr = ((uint32_t)(&USART_UNIT->DR)); //目的地址TX: (&USART_UNIT->DR)
stcDmaInit.u32SrcAddr = 0; //源地址 空 RX: (&USART_UNIT->DR +2U)
stcDmaInit.u32SrcInc = DMA_SRC_ADDR_INC; //源地址依次递增
stcDmaInit.u32DestInc = DMA_DEST_ADDR_FIX; //目的地址固定 DMA_DEST_ADDR_FIX;
enRet = DMA_Init(DMA_TX_UNIT, DMA_TX_CH, &stcDmaInit); //初始化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发送完成中断
static void dma_tx_tc_irqcallback(void)
{
DMA_ClearTransIntStatus(DMA_TX_UNIT, DMA_TX_BTC_INT);
DDL_DelayUS(210); //等待数据发送完成
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);
//使能接收模式
set_rx485_ctrl_pin(0);
}