评估板的UART1连接在板载调试器的虚拟串口上,不过这个虚拟串口应该有缺陷,MCU发送数据时,虚拟串口不会实时上传数据,而是发送足够数量数据才会发送。
本次测试使用UART2,板子上的CN4接口,外接串口连接PC调试。
移植modbus主要是编写串口收发程序,定时器使用软件定时,方面多路MODBUS实现。
MM32F3277的外设管脚配置比起F103有些变化,需要选择AF,方式如下:
// UART2 AFIOGPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7);
复制代码void mb_port_Init(mb_mode_type mbMode, uint32_t ulBaudRate, mb_parity_type eParity) { UART_InitTypeDef cfg; mb_port_hal_cfg(); mbObjInit(mbMode); cfg.BaudRate = ulBaudRate; cfg.Mode = UART_Mode_Rx | UART_Mode_Tx; cfg.HWFlowControl = UART_HardwareFlowControl_None; mb_byte_send = mb_rtu_byte_send; if(mbMode == MB_RTU_MASTER || mbMode == MB_RTU_SLAVE) { // rtu mode if (MB_PAR_NONE == eParity) { cfg.Parity = UART_Parity_No; cfg.StopBits = UART_StopBits_2; cfg.WordLength = UART_WordLength_8b; } else if (MB_PAR_NONE_1S == eParity) { cfg.Parity = UART_Parity_No; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_8b; } else if (MB_PAR_ODD == eParity) { cfg.Parity = UART_Parity_Odd; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_8b; } else { cfg.Parity = UART_Parity_Even; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_8b; } mbObj.run_st.bits.rtu_mode = 1; } else { // asc mode if (MB_PAR_NONE == eParity) { cfg.Parity = UART_Parity_No; cfg.StopBits = UART_StopBits_2; cfg.WordLength = UART_WordLength_7b; } else if (MB_PAR_NONE_1S == eParity) { cfg.Parity = UART_Parity_No; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_7b; } else if (MB_PAR_ODD == eParity) { cfg.Parity = UART_Parity_Odd; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_7b; } else { cfg.Parity = UART_Parity_Even; cfg.StopBits = UART_StopBits_1; cfg.WordLength = UART_WordLength_7b; } mbObj.run_st.bits.rtu_mode = 0; } // rtu timer if(mbObj.run_st.bits.rtu_mode == 0) { mbObj.rtu_timer_sv = 240; mbObj.timeout_set = 500; } else { if (ulBaudRate > 19200) { mbObj.rtu_timer_sv = 3; } else { mbObj.rtu_timer_sv = (com_timer_cal(ulBaudRate, (35*11+9)/10, 300, 12000) + 99)/100; } } UART_Init(mbPORT, &cfg); UART_Cmd(mbPORT, ENABLE); nvic_irq_set(mbURT_IRQn,0x0F,1); mbPortTx1Rx0Enable(0); }
复制代码void mbPortTx1Rx0Enable(uint8_t mode) { volatile uint8_t u8Temp; if(0 == mode) { mbRxEnable(); mbPORT->IER = 0; mbPORT->GCR |= UART_GCR_RX | UART_GCR_UART; u8Temp = mbPORT->RDR; while((mbPORT->ISR & (UART_ISR_RXOERR | UART_ISR_RXPERR)) != 0) { u8Temp = mbPORT->RDR; mbPORT->ICR = UART_ICR_RXOERR | UART_ICR_RXPERR; __DSB(); } mbPORT->IER = UART_IER_RX; } else { mbTxEnable(); mbPORT->IER = 0; mbPORT->GCR |= UART_GCR_TX | UART_GCR_UART; mbPORT->IER = UART_IER_TX; } }
复制代码中断处理:
void mbISR() { volatile uint32_t IntSt; volatile uint8_t Data; mbObj.timeout_cnt = 0; IntSt = mbPORT->ISR; if(IntSt & UART_ISR_RX_INTF) { Data = mbPORT->RDR; if((IntSt & (UART_ISR_RXOERR | UART_ISR_RXPERR) ) != 0) { if(mbObj.rcv_cnt >= 1) { mbObj.err_st.bits.hal = 1; } mbPORT->ICR = UART_ICR_RXOERR | UART_ICR_RXPERR; } mb_data_rcv(&mbObj, Data); } else if( (mbObj.snd_size <= mbObj.snd_cnt) && (IntSt & UART_ISR_TXC)) { mb_send_end(&mbObj); mbPortTx1Rx0Enable(0); } else if( IntSt & UART_ISR_TX) { if(mb_data_send(&mbObj, mb_byte_send, 1)) { mbPORT->IER = UART_IER_TXC; } } else { } }
复制代码测试结果:
附上测试工程:
全部回复 0
暂无评论,快来抢沙发吧