在使用460 做串口Modbus通信时,发送几包数据就会有一包接收的数据不对,各位给看看我的串口配置有问题么?
void UART_Init(devCom_t *com, uint32_t baudRate, char parity)
{
uint64_t tmpreg = 0x00;
float DIV = 0.0;
uint32_t DIV_Integer, DIV_Fraction = 0x00;
USART_TypeDef *USARTx = com->comPort;
M4_SYSREG->PWR_FPRC_f.FPRCB1 = 1;
ENABLE_FCG0_REG_WRITE();
M4_MSTP->FCG0_f.AOS = 0;
DISABLE_FCG0_REG_WRITE();
{
// PORT RX3 PB5,TX3 PB7 RTS3 PB6
PORT_Unlock();
M4_PORT->PFSRB5 = 33;
M4_PORT->PFSRB7 = 32;
M4_PORT->PCRB5_f.DDIS = 0;
M4_PORT->PCRB5_f.PUU = 1;
M4_PORT->PCRB7_f.DDIS = 0;
M4_PORT->PCRB7_f.PUU = 1;
M4_PORT->PCRB6_f.DDIS = 0;
M4_PORT->PCRB6_f.PUU = 0; // 上拉无效
M4_PORT->PCRB6_f.DRV = 0b10; // 高驱动模式
M4_PORT->PCRB6_f.POUTE = 1;
PORT_Lock();
M4_MSTP->FCG1_f.USART3 = 0;
}
M4_SYSREG->PWR_FPRC_f.FPRCB1 = 0;
/* Set default value */
USARTx->CR1 = (uint32_t)0x801B0000ul;
USARTx->CR2 = (uint32_t)0x00000000ul;
USARTx->CR3 = (uint32_t)0x00000000ul;
USARTx->BRR = (uint32_t)0x0000FFFFul;
USARTx->PR = (uint32_t)0x00000000ul;
stc_usart_cr1_field_t CR1 = USARTx->CR1_f;
/* Set USART mode */
USARTx->CR3_f.SCEN = (uint32_t)0ul; // disable sc mode
CR1.MS = (uint32_t)0ul; // uart mode
USARTx->PR_f.PSC = 0b10;
CR1.M = 0u;
CR1.ML = 0u;
USARTx->CR2_f.STOP = 0u; // 1 stop bit
USARTx->CR2_f.CLKC = 0u; // pclk1
switch (parity)
{
case 'n':
CR1.PCE = (uint32_t)0ul;
break;
case 'e':
CR1.PS = (uint32_t)0ul;
CR1.PCE = (uint32_t)1ul;
break;
case 'o':
CR1.PS = (uint32_t)1ul;
CR1.PCE = (uint32_t)1ul;
break;
default:
break;
}
USARTx->CR3_f.CTSE = 0u; // rts enable
CR1.SBS = 0u;
CR1.OVER8 = 0u; // 16bit
uint32_t C = 100000000 / 16; //6.250M
DIV = ((float)C / ((float)baudRate * 16)) - 1.0f;
DIV_Integer = (uint32_t)DIV;
if (!((DIV < 0.0f) || (DIV_Integer > 0xFFul)))
{
if ((DIV - (float)DIV_Integer) > 0.00001f)
{
tmpreg = (uint64_t)(((uint64_t)DIV_Integer + 1ul) * (uint64_t)baudRate) * 2;
DIV_Fraction = (uint32_t)(2048ul * tmpreg / C - 128ul);
}
CR1.FBME = (DIV_Fraction > 0x7Ful) ? 0ul : 1ul;
USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
}
if (USARTx == M4_USART3)
{
USART3_DMA_Init();
M4_MSTP->FCG2_f.TIMER0_2 = 0;
M4_TMR02->CNTAR_f.CNTA = 0; // 计数值清零
M4_TMR02->CMPAR_f.CMPA = 150; // 比较器
M4_TMR02->BCONR_f.CKDIVA = 0; // 计数器分频器
M4_TMR02->BCONR_f.HCLEA = 1; //硬件触发清除
M4_TMR02->BCONR_f.HSTAA = 1; // 硬件触发启动
M4_TMR02->BCONR_f.ASYNCLKA = 0; //异步技术时钟选择:XTAL32
M4_TMR02->BCONR_f.SYNCLKA = 0; // 同步计数时钟源选择 内部硬件触发事件
M4_TMR02->BCONR_f.SYNSA = 1;
M4_INTC->SEL6_f.INTSEL = INT_USART3_TCI;
M4_INTC->SEL7_f.INTSEL = INT_USART3_EI;
M4_INTC->SEL8_f.INTSEL = INT_USART3_RTO;
NVIC_EnableIRQ(Int006_IRQn);
NVIC_EnableIRQ(Int007_IRQn);
NVIC_EnableIRQ(Int008_IRQn);
}
CR1.RIE = 1;
CR1.RTOE = 1;
CR1.RTOIE = 1;
CR1.TE = 1;
CR1.RE = 1;
USARTx->CR1_f.CRTOF = 1ul;
USARTx->CR1 = *(__IO uint32_t *)(&CR1);
}
static void USART3_DMA_Init(void)
{
/* Enable peripheral clock */
ENABLE_FCG0_REG_WRITE();
M4_MSTP->FCG0_f.DMA2 = 0;
DISABLE_FCG0_REG_WRITE();
/* Enable DMA. */
M4_DMA2->EN_f.EN = 1;
/* Initialize DMA. */
M4_DMA2->DTCTL0_f.BLKSIZE = 1; // 1 block
M4_DMA2->DTCTL0_f.CNT = 10; // 传输字节数
M4_DMA2->SAR0 = ((uint32_t)(COM3_TX_BUFF + 1)); // 源地址
M4_DMA2->DAR0 = ((uint32_t)(&M4_USART3->DR)); // 目标地址
M4_DMA2->CH0CTL_f.SINC = 1; // 源地址递增
M4_DMA2->CH0CTL_f.DINC = 0; // 目标地址固定
M4_DMA2->CH0CTL_f.HSIZE = 0; // 传输数据宽度 8bit
M4_DMA2->CH0CTL_f.SRPTEN = 1; // 源地址重置
M4_DMA2->CH0CTL_f.IE = 0; // 禁止中断
M4_DMA2->DTCTL1_f.BLKSIZE = 1; // 1 block
M4_DMA2->DTCTL1_f.CNT = UART_BUFF_SIZE; // 传输字节数
M4_DMA2->SAR1 = ((uint32_t)(&M4_USART3->DR) + 2ul); // 源地址
M4_DMA2->DAR1 = ((uint32_t)(COM3_RX_BUFF)); // 目标地址
M4_DMA2->CH1CTL_f.SINC = 0; // 源地址固定
M4_DMA2->CH1CTL_f.DINC = 1; // 目标地址递增
M4_DMA2->CH1CTL_f.HSIZE = 0; // 传输数据宽度 8bit
M4_DMA2->CH1CTL_f.DRPTEN = 1; // 目标址重置
M4_DMA2->CH1CTL_f.IE = 0; // 禁止中断
M4_DMA2->CHEN |= 2;
M4_DMA2->INTCLR1 |= 3; // 清空 0,1 通道IT
M4_AOS->DMA2_TRGSEL0 = EVT_USART3_TI;
M4_AOS->DMA2_TRGSEL1 = EVT_USART3_RI;
}
void UART3_Send(uint16_t length)
{
com3.lock = true;
com3.buff.txOK = false;
USART3_RTS_HIGHT;
vTaskDelay(1);
length -= 1;
M4_DMA2->DTCTL0_f.CNT = length;
M4_DMA2->RPT0_f.SRPT = length;
M4_DMA2->CHEN |= 1;
M4_USART3->DR_f.TDR = COM3_TX_BUFF[0];
M4_USART3->CR1_f.TCIE = 1;
}
void IRQ006_Handler(void) // USART1 DMA 1 CH0
{
portDISABLE_INTERRUPTS();
M4_USART3->CR1_f.TCIE = 0;
M4_DMA2->INTCLR1 |= 0x10001; // reset DMA 中断
com3.buff.txOK = true;
com3.lock = false;
USART3_RTS_LOW;
portENABLE_INTERRUPTS();
}
void IRQ007_Handler(void) // USART DMA 1 CH1
{
M4_USART3->CR1_f.CFE = 1u;
M4_USART3->CR1_f.CPE = 1u;
}
void IRQ008_Handler(void) // USART3 RXOT
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
portDISABLE_INTERRUPTS();
M4_TMR02->BCONR_f.CSTA = 0;
M4_TMR02->STFLR_f.CMAF = 0;
M4_USART3->CR1_f.CRTOF = 1ul;
M4_DMA2->CHEN &= 0x0D;
com3.lock = false;
com3.buff.rxOK = true;
com3.buff.rxLength = UART_BUFF_SIZE - M4_DMA2->MONDTCTL1_f.CNT;
M4_DMA2->DTCTL1_f.CNT = UART_BUFF_SIZE;
M4_DMA2->DAR1 = ((uint32_t)(COM3_RX_BUFF));
M4_DMA2->CHEN |= 2;
portENABLE_INTERRUPTS();
vTaskNotifyGiveFromISR(mbMasterReviceHandle, &xHigherPriorityTaskWoken);
}
|