HC32L170FAUA-TIM6关联串口超时问题
本帖最后由 kktron 于 2023-2-13 07:56 编辑这里看不懂 u16Period = 0xF000;u16GCMAValue = 0x0F00;配置各种值
都会出现断包分包。
我理解是不是应该配置后,数据字节与字节 超过比如5ms, 就定时器中断?
现在我值了后发现发的数据长比如300字节,收到200多字节就定时器超时了,
但设置的慢超时,又会不及时返回上位机,
170FAUA 也没看到空闲中断,这个DMA 配合TIM6高级定时器 什么原理呢?
void Time6_init(void)
{
uint16_t u16Period,u16GCMAValue;
stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
stc_adt_aos_trig_cfg_tstcAdtAosTrigCfg;
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载波、计数模式、时钟配置
u16Period = 0xF000;
Adt_SetPeriod(M0P_ADTIM6, u16Period); //周期设置
u16GCMAValue = 0x0F00;
Adt_SetCompareValue(M0P_ADTIM6, AdtCompareA, u16GCMAValue);//通用比较基准值寄存器A设置
stcAdtAosTrigCfg.enAos0TrigSrc = AdtAosxTrigSelUart0Int; //AOS0选择UART0中断
stcAdtAosTrigCfg.enAos1TrigSrc = AdtAosxTrigSelUart0Int; //AOS1选择UART0中断
Adt_AosTrigCfg(&stcAdtAosTrigCfg);
Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos0); //AOS0事件 清零TIM6
Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos0); //AOS0事件触发TIM6启动
Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos1); //AOS1事件 清零TIM6
Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos1); //AOS1事件触发TIM6启动
Adt_EnableHwStart(M0P_ADTIM6); //硬件启动使能
Adt_EnableHwClear(M0P_ADTIM6); //硬件清零使能
Adt_EnableHwStop(M0P_ADTIM6); //硬件停止使能
Adt_ClearAllIrqFlag(M0P_ADTIM6);
Adt_CfgIrq(M0P_ADTIM6, AdtCMAIrq, TRUE); //配置TIM6比较中断
EnableNvic(ADTIM6_IRQn, IrqLevel0, TRUE);
}
/**
******************************************************************************
** \briefTim6_IRQHandler
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void Tim6_IRQHandler(void)
{
volatile uint16_t len = 0;
stc_adt_sw_sync_t stcAdtSwSync;
stcAdtSwSync.bAdTim4 = TRUE;
if(TRUE == Adt_GetIrqFlag(M0P_ADTIM6, AdtCMAIrq))
{
Adt_ClearIrqFlag(M0P_ADTIM6, AdtCMAIrq);
Adt_ClearAllIrqFlag(M0P_ADTIM6);
Adt_StopCount(M0P_ADTIM6);
M0P_UART0->ICR_f.RCCF = 0; //清中断状态位
Dma_DisableChannel(DmaCh1);
Dma_ClrStat(DmaCh1); //清除通道1状态值
len = (M0P_DMAC->CONFA1)&0x0000FFFF;
if(len == 0xFFFF) len = 1;
else len = 0xFFFF - (M0P_DMAC->CONFA1)&0x0000FFFF - 1;
g_uart0_cfg.rx_len=len;
Uart0_DMA_SendData(g_uart0_cfg.uart0RxBuf,g_uart0_cfg.rx_len);
memset(&g_uart0_cfg.uart0RxBuf,0,sizeof(g_uart0_cfg.uart0RxBuf));
Dma_SetBlockSize(DmaCh1,1); //BC = 0 配置 DMA 通道待传输的数据块的大小为
Dma_SetTransferCnt(DmaCh1,65535); //TC = 0 配置 DMA 通道待传输的数据块的大小为
Dma_SetSourceAddress(DmaCh1,0x40000000);
Dma_SetDestinationAddress(DmaCh1,(uint32_t)&g_uart0_cfg.uart0RxBuf);
Dma_EnableChannel(DmaCh1);
Dma_ClrStat(DmaCh1); //清除通道0状态值
}
}
/**
******************************************************************************
** \briefuart0_DmaCfg
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_DmaCfg(void)
{
stc_dma_cfg_t stcDmaCfg;
DDL_ZERO_STRUCT(stcDmaCfg); //初始化变量
Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE); //使能DMAC外设时钟门控开关
//rx dma配置
stcDmaCfg.u32SrcAddress = 0x40000000; //接收数据寄存器地址,uart0的基地址
stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_cfg.uart0RxBuf; //接收缓冲
stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable;//使能DMA源地址重载
stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable; //使能BC和CONFA:TC的重载功能
stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //使能DMA目的地址重载
stcDmaCfg.enTransferMode = DmaMskContinuousTransfer; //连续传输,DMAC传输完成时不清除CONFA:ENS位
stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc; //目的地址自增
stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix; //源地址固定
stcDmaCfg.u16BlockSize = 1; //块传输个数,串口寄存器只能有一个数据 ,含义:数据块大小
stcDmaCfg.u16TransferCnt = 65535; //块传输次数,此处设置为最大65535
stcDmaCfg.enMode = DmaMskBlock; //块(Block)传输
stcDmaCfg.enTransferWidth = DmaMsk8Bit; // 8 bit字节传输
stcDmaCfg.enRequestNum = DmaUart0RxTrig; //DMA硬件触发源位Uart0Rx
stcDmaCfg.enPriority = DmaMskPriorityFix; //DMA 各通道优先级固定 (CH0>CH1)
Dma_Enable(); //DMA模块使能
Dma_InitChannel(DmaCh1, &stcDmaCfg); //DMA通道1初始化
Dma_EnableChannel(DmaCh1); //使能通道1
}
本帖最后由 kktron 于 2023-2-9 17:14 编辑
还有个问题就是 需要一般普通的1152008/none/1模式,不要什么多机,校验花, 是这样配置校验UartMskDataOrAddr , 模式1吗?
///<UART Init
stcCfg.enRunMode = UartMskMode1; ///<模式1
stcCfg.enStopBit = UartMsk1bit; ///<1bit停止位
stcCfg.enMmdorCk = UartMskDataOrAddr; ///<无校验
stcCfg.stcBaud.u32Baud= 115200; ///<波特率115200
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<通道采样分频配置
stcCfg.stcBaud.u32Pclk= Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
Uart_Init(M0P_UART0, &stcCfg); ///<串口初始化 kktron 发表于 2023-2-9 17:12
还有个问题就是 需要一般普通的1152008/none/1模式,不要什么多机,校验花, 是这样配置校验U ...
///< HC32L170 串口0模块配置 N - 8 - 1
void App_UartCfg(void)
{
stc_uart_cfg_tstcCfg;
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外设模块时钟使能
stcCfg.enRunMode = UartMskMode1; //模式1
stcCfg.enStopBit = UartMsk1bit; //1位停止位
stcCfg.enMmdorCk = UartMskDataOrAddr; //无校验
stcCfg.stcBaud.u32Baud = 9600; //波特率9600
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; //通道采样分频配置
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); //获得外设时钟(PCLK)频率值
Uart_Init(M0P_UART0, &stcCfg); //串口初始化
Uart_ClrStatus(M0P_UART0,UartRC); //清接收请求
Uart_ClrStatus(M0P_UART0,UartTC); //清发送请求
Uart_EnableIrq(M0P_UART0,UartRxIrq); //使能串口接收中断
Uart_EnableIrq(M0P_UART0,UartTxIrq); //使能串口发送中断
}
原理就是软件方式去模拟了硬件的串口接收超时功能,在ST 中也叫做串口空闲功能,超时时间的配置需要与当前波特率去匹配的,也就是一位所占的时间。 yang377156216 发表于 2023-2-9 18:24
谢谢,配置串口那OK的 你可以看看这个例子,虽然是在L136上的,但是对于高级定时器的使用是一样的。
yang377156216 发表于 2023-2-9 18:27
原理就是软件方式去模拟了硬件的串口接收超时功能,在ST 中也叫做串口空闲功能,超时时间的配置需要与当前 ...
像ST的普通定时器,定义1ms超时,每收到一字节超时清0定时器,比如配合115200bps
4ms 每byte进来,就空闲解析了
但这个TIM6 我试了各种值超时 都无法做到10~300字节各种不定长一包的稳定超时空闲。
感觉TIM6是从开始接收到结束接收的溢出定时,所以不定长就各种分包,
不是字节&字节的定时超时,不知道理解对否 kktron 发表于 2023-2-10 09:28
像ST的普通定时器,定义1ms超时,每收到一字节超时清0定时器,比如配合115200bps
4ms 每byte进来,就空闲 ...
如果是F460或者F4A0的timer6,可能处理起来简单一点,如果是L17x,接收数据之后,需要(UART_RX)中断信号输出到timer6的硬件清零寄存器,把timer6的计数器清零。
而如果UART_Rx如果没有使能中断,那么要想办法在每次接收之后将RX中断标志清零,否则下次不会触发DMA或者触发timer6的硬件清零。
而F460或者F4A0,UART_RX可以是触发事件,可以不用每次必须清零标志。 martinhu 发表于 2023-2-10 16:29
如果是F460或者F4A0的timer6,可能处理起来简单一点,如果是L17x,接收数据之后,需要(UART_RX)中断信 ...
谢谢!
TIM6配合DMA_UART0, 在170FAUA下可以了,定义了TIM6 4ms超时,现在没问题了
新的问题又出现2个,
1.PC1ms间隔 压力测试发300字节数据发现溢出Hardfault进入了。
stcDmaCfg.enMode =DmaMskBlock;
stcDmaCfg.u16BlockSize = 0x01u;
stcDmaCfg.u16TransferCnt = 800;
stcDmaCfg.enTransferWidth = DmaMsk8Bit;
stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_obj.RxData;//RXData开的1024字节
我理解不是800字节DMA 怎么也不会超过1024 数组吧?
还有一个就是 收到数据后,我串口就非DMA的去返回,抓包看断开严重
while(tx_len--)
{
Uart_SendDataPoll(M0P_UART0, *tx_pBuf);
tx_pBuf++;
}
Uart_SendDataPoll(M0P_UART0, *tx_pBuf);为什么抓包看会断包的? 这是库函数,里面没动它。
en_result_t Uart_SendDataPoll(M0P_UART_TypeDef* UARTx, uint8_t u8Data)
{
while(FALSE == Uart_GetStatus(UARTx,UartTxe))
{}
UARTx->SBUF_f.DATA = u8Data;
while(FALSE == Uart_GetStatus(UARTx,UartTC))
{}
Uart_ClrStatus(UARTx,UartTC);
return Ok;
}
本帖最后由 kktron 于 2023-2-10 18:09 编辑
这是测试170FAUA TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题
//myuart.h文件里如下#defineUART0_TX_MAX_LEN128
#defineUART0_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_tRxFinished;
__IO uint8_tTxData;
__IO uint8_tRxData;
__IO uint8_tRxCopy;
__IO uint16_t TxCnt;
__IO uint16_t RxCnt;
__IO uint16_t RxNow;
}my_stc_uart_t;
extern my_stc_uart_tg_uart0_obj;
//myuart.c文件里如下
my_stc_uart_tg_uart0_obj;
/**
******************************************************************************
** \briefuart0_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
}
/**
******************************************************************************
** \briefuart0_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
}
/**
******************************************************************************
** \briefuart0_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); ///<系统中断使能
}
/**
******************************************************************************
** \briefuart0_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; //指定传输目的地址
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);
}
/**
******************************************************************************
** \briefuart0_Time6Cfg
** \paramtPeriod
** \retval 无
** \retval 无
******************************************************************************/
void uart0_Time6Cfg(uint16_t tPeriod)
{
stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
stc_adt_aos_trig_cfg_tstcAdtAosTrigCfg;
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);
}
/**
******************************************************************************
** \briefUART0 数据发送
** \paramtx_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++;
}
}
/**
******************************************************************************
** \briefUart0_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);
}
}
/**
******************************************************************************
** \briefTim6_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);
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,g_uart0_obj.TxCnt);
}
g_uart0_obj.RxFinished = 0;
}
}
}
kktron 发表于 2023-2-10 17:56
谢谢!
TIM6配合DMA_UART0, 在170FAUA下可以了,定义了TIM6 4ms超时,现在没问题了
收到数据后,最好用中断返回,不要用查询的方式 感觉这个超时的时间配置的不要过长太长了也没有用 kktron 发表于 2023-2-10 18:00
这是测试170FAUA TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题
...
用查询模式太浪费资源了而且实时性也不太好 martinhu 发表于 2023-2-16 09:25
收到数据后,最好用中断返回,不要用查询的方式
使用中断模式一定要注意中断函数的处理要干净 kktron 发表于 2023-2-10 18:00
这是测试170FAUA TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题
...
数据量不大的话感觉完全没有问题主函数轮序里边还发送了数据 请问在楼主的代码注释中,有一个是ADT载波这个是什么意思呢 磨砂 发表于 2023-3-4 16:21
请问在楼主的代码注释中,有一个是ADT载波这个是什么意思呢
ADT和数据类型实质上是一个概念.其区别是: ADT的范畴更广,它不再局限于系统已定义并实现的数据类型,还包括用户自己定义的数据类型
页:
[1]