本帖最后由 kktron 于 2023-2-10 18:09 编辑
这是测试170FAUA TIM6配合DMA串口0,超时4ms 接收不定长的代码。
共享出来大家 看看指出还有什么问题
//myuart.h文件里如下#define UART0_TX_MAX_LEN 128
#define UART0_RX_MAX_LEN (128+512)
void uart0_init(void);
void uart0_GpioCfg(void);
void uart0_BaseCfg(void);
void uart0_DmaCfg(void);
void uart0_Time6Cfg(uint16_t tPeriod);
void Uart0_SendData(uint8_t *tx_pBuf, uint16_t tx_len);
//uart0状态结构体
typedef struct
{
__IO uint8_t RxFinished;
__IO uint8_t TxData[UART0_TX_MAX_LEN];
__IO uint8_t RxData[UART0_RX_MAX_LEN];
__IO uint8_t RxCopy[UART0_RX_MAX_LEN];
__IO uint16_t TxCnt;
__IO uint16_t RxCnt;
__IO uint16_t RxNow;
}my_stc_uart_t;
extern my_stc_uart_t g_uart0_obj;
//myuart.c文件里如下
my_stc_uart_t g_uart0_obj;
/**
******************************************************************************
** \brief uart0_init
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_init(void)
{
uart0_GpioCfg();
uart0_BaseCfg();
uart0_DmaCfg();
uart0_Time6Cfg(3000); //3000*(1/48M)*64分频 = 0.004s =4ms) 24MHz外接晶振倍频到最高48MHz
}
/**
******************************************************************************
** \brief uart0_GpioCfg
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_GpioCfg(void)
{
stc_gpio_cfg_t stcGpioCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(GpioPortA, GpioPin9, &stcGpioCfg);
Gpio_SetAfMode(GpioPortA, GpioPin9, GpioAf1); //配置PA09 端口为URART1_TX
///<RX
stcGpioCfg.enDir = GpioDirIn;
Gpio_Init(GpioPortA, GpioPin10, &stcGpioCfg);
Gpio_SetAfMode(GpioPortA, GpioPin10, GpioAf1);//配置PA10 端口为URART1_RX
}
/**
******************************************************************************
** \brief uart0_BaseCfg
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_BaseCfg(void)
{
///< 串口参数配置
stc_uart_cfg_t stcCfg;
stc_uart_multimode_t stcMulti;
stc_uart_baud_t stcBaud;
DDL_ZERO_STRUCT(stcCfg);
DDL_ZERO_STRUCT(stcMulti);
DDL_ZERO_STRUCT(stcBaud);
///< 开启外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);///<使能uart0模块时钟
///<UART Init
stcCfg.enRunMode = UartMskMode1; ///<模式1
stcCfg.enStopBit = UartMsk1bit; ///<1bit停止位
stcCfg.enMmdorCk = UartMskDataOrAddr; ///<无校验
stcCfg.stcBaud.u32Baud = 115200; ///<波特率115200, @48MHz 下0.16%误差
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<通道采样分频配置
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
Uart_Init(M0P_UART0, &stcCfg); ///<串口初始化
M0P_UART0->SCON_f.DMARXEN = 1; //DMA_RX使能允许
///<UART中断使能
Uart_ClrStatus(M0P_UART0,UartRC); ///<清接收请求
Uart_ClrStatus(M0P_UART0,UartTC); ///<清发送请求
Uart_DisableIrq(M0P_UART0,UartTxIrq); ///<禁止串口发送中断
Uart_EnableIrq(M0P_UART0,UartRxIrq); ///<使能串口接收中断
Uart_EnableIrq(M0P_UART0,UartFEIrq); ///<帧错误中断使能
EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE); ///<系统中断使能
}
/**
******************************************************************************
** \brief uart0_DmaCfg
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_DmaCfg(void)
{
stc_dma_cfg_t stcDmaCfg;
DDL_ZERO_STRUCT(stcDmaCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralDma, TRUE); //ADT外设时钟使能
//DMA_Ch0_RX
stcDmaCfg.enMode = DmaMskBlock; //选择块传输
stcDmaCfg.u16BlockSize = 0x01u; //块传输个数
stcDmaCfg.u16TransferCnt = UART0_RX_MAX_LEN; //Block模式,一次传输数据大小为 8(BlockSize),传输1次
stcDmaCfg.enTransferWidth = DmaMsk8Bit; //传输数据的宽度,此处选择字(8Bit)宽度
stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix; //源地址固定
stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc; //目的地址自增
stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadDisable; //禁止重新加载传输目的地址
stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadDisable; //禁止重新加载传输源地址
stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadDisable; //禁止能重新加载BC/TC值
stcDmaCfg.u32SrcAddress = (uint32_t)&(M0P_UART0->SBUF); //指定传输源地址
stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_obj.RxData[0]; //指定传输目的地址
stcDmaCfg.enTransferMode = DmaMskContinuousTransfer; //DMAC 在传输完成时清除 CONFA:ENS 位。
stcDmaCfg.enRequestNum = DmaUart0RxTrig; //设置为Uart0Rx触发
stcDmaCfg.enPriority = DmaMskPriorityFix; //DMA 各通道优先级固定 (CH0>CH1)
Dma_InitChannel(DmaCh0,&stcDmaCfg); //初始化DMA通道0
Dma_Enable();
Dma_EnableChannel(DmaCh0);
Uart_ClrStatus(M0P_UART0,UartRC);
}
/**
******************************************************************************
** \brief uart0_Time6Cfg
** \param tPeriod
** \retval 无
** \retval 无
******************************************************************************/
void uart0_Time6Cfg(uint16_t tPeriod)
{
stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
stc_adt_aos_trig_cfg_t stcAdtAosTrigCfg;
DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
DDL_ZERO_STRUCT(stcAdtAosTrigCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdvTim, TRUE); //ADT外设时钟使能
stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;
stcAdtBaseCntCfg.enCntDir = AdtCntUp;
stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div64;
Adt_Init(M0P_ADTIM6, &stcAdtBaseCntCfg); //ADT载波、计数模式、时钟配置
Adt_SetPeriod(M0P_ADTIM6, tPeriod); //周期设置
stcAdtAosTrigCfg.enAos0TrigSrc = AdtAosxTrigSelUart0Int; //AOS0选择UART0中断
Adt_AosTrigCfg(&stcAdtAosTrigCfg);
Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos0); //AOS0事件触发TIM6启动
Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos0); //AOS0事件 清零TIM6
Adt_EnableHwStart(M0P_ADTIM6); //硬件启动使能
Adt_EnableHwClear(M0P_ADTIM6); //硬件清零使能
Adt_ClearAllIrqFlag(M0P_ADTIM6);
Adt_CfgIrq(M0P_ADTIM6, AdtOVFIrq, TRUE); //配置TIM6 上溢中断
EnableNvic(ADTIM6_IRQn, IrqLevel0, TRUE);
}
/**
******************************************************************************
** \brief UART0 数据发送
** \param tx_pBuf,tx_len
** \retval 无
** \retval 无
******************************************************************************/
void Uart0_SendData(uint8_t *tx_pBuf, uint16_t tx_len)
{
while(tx_len--)
{
Uart_SendDataPoll(M0P_UART0, *tx_pBuf);
tx_pBuf++;
}
}
/**
******************************************************************************
** \brief Uart0_IRQHandler
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void Uart0_IRQHandler(void)
{
if(Uart_GetStatus(M0P_UART0, UartRC))
{
Uart_ClrStatus(M0P_UART0, UartRC);
}
if(Uart_GetStatus(M0P_UART0, UartFE))
{
Uart_ClrStatus(M0P_UART0, UartFE);
}
}
/**
******************************************************************************
** \brief Tim6_IRQHandler
** \param 无
** \retval 无
** \retval 无
******************************************************************************/
void Tim6_IRQHandler(void)
{
Adt_StopCount(M0P_ADTIM6);
if(TRUE == Adt_GetIrqFlag(M0P_ADTIM6, AdtOVFIrq))
{
Dma_DisableChannel(DmaCh0);
g_uart0_obj.RxNow = (UART0_RX_MAX_LEN - 1) - M0P_DMAC->CONFA0_f.TC;
if(g_uart0_obj.RxNow>=UART0_RX_MAX_LEN)
{
g_uart0_obj.RxNow=0;
}
g_uart0_obj.RxCnt = g_uart0_obj.RxNow;
for(uint16_t i = 0; i < g_uart0_obj.RxCnt; i++)
{
g_uart0_obj.RxCopy =g_uart0_obj.RxData;
}
Dma_SetTransferCnt(DmaCh0, UART0_RX_MAX_LEN);
Dma_SetDestinationAddress(DmaCh0, (uint32_t)&g_uart0_obj.RxData[0]);
Dma_EnableChannel(DmaCh0);
Uart_ClrStatus(M0P_UART0,UartRC);
g_uart0_obj.RxFinished = 1;
Adt_ClearIrqFlag(M0P_ADTIM6, AdtOVFIrq);
}
}
/******************************************************************************
* EOF (not truncated)
******************************************************************************/
//主函数.C里例如下
int main (void)
{
;略初始化
while(1)
{
if(1 == g_uart0_obj.RxFinished) {
if(g_uart0_obj.RxCnt>0)
{
g_uart0_obj.TxCnt = g_uart0_obj.RxCnt;
g_uart0_obj.RxCnt = 0;
Uart0_SendData((uint8_t *)&g_uart0_obj.RxCopy[0],g_uart0_obj.TxCnt);
}
g_uart0_obj.RxFinished = 0;
}
}
}
|