工具与软件:
您好!
我目前正在实现基于中断的 UART API、以使用 DriverLib 函数处理发送和接收字符串。
由于某种原因,当我使用uart_puts()
函数后uart_putc()
,我正在传输的字符串的第一个字符uart_puts()
丢失。(当我打印多个字符串时uart_puts()
没有前面的uart_putc()
,所以我怀疑中的一些操作uart_putc()
可能会影响中的后续操作 uart_puts().)
请查找下面介绍的测试代码、API 实现和结果:
这里是 main ()中的测试代码。
#include "ti_msp_dl_config.h" #include "uart.h" static void sys_init(void); int main(void) { sys_init(); uart_putc('c'); uart_puts("123\r\n"); uart_puts("456\r\n"); while (1) { /* Do nothing. */ } } /* main() */ /*! * @brief Initializes the system. */ void sys_init(void) { SYSCFG_DL_init(); uart_init(); } /* sys_init() */
以下是自定义'uart_putc ()'和'uart_puts ()'函数的实现方式:
#include "uart.h" #include "ti_msp_dl_config.h" static volatile const char * g_p_char = NULL; static volatile uart_comm_status_t g_uart_comm_status = UART_STATUS_INIT; static volatile char g_rx_char = 0; /*! * @brief Performs any additional initializations necessary for the UART * peripheral. * * @par * The UART peripheral initialization is performed by the initialization * functions automatically generated by the sysconfig tool. See * 'ti_msp_dl_config.c' for more details. */ void uart_init(void) { /* Disable interrupts and clear interrupt statuses until necessary. */ DL_UART_Main_disableInterrupt(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_TX); DL_UART_clearInterruptStatus(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_TX); DL_UART_Main_disableInterrupt(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_RX); DL_UART_clearInterruptStatus(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_RX); /* To prevent any unexpected pending IRQ from triggering an interrupt when * enabling the IRQ, clear the pending IRQ before enabling it. */ NVIC_ClearPendingIRQ(UART_COMM_INST_INT_IRQN); NVIC_EnableIRQ(UART_COMM_INST_INT_IRQN); } /* uart_init() */ /*! * @brief Sends a character over UART. * * @par * This function by itself does not trigger the UART TX interrupt. */ void uart_putc(const char c) { /* Wait until the TXDATA register is empty and there is no ongoing data * reception before proceeding with transmission. */ while (DL_UART_Main_isBusy(UART_COMM_INST)) { /* Do nothing. */ } DL_UART_Main_transmitData(UART_COMM_INST, c); } /* uart_putc() */ /*! * @brief Sends a null-terminated string over UART. * @param[in] p_str A pointer to a null-terminated string to be transmitted over * UART. */ void uart_puts(const char * p_str) { /* Enable the interrupt to perform data transmission over UART using * interrupts. */ DL_UART_Main_enableInterrupt(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_TX); /* NOTE: Ensure that the 'g_p_char' setting is performed after enabling the * TX interrupt. This is because, when the TX interrupt is enabled while * the TXDATA register of the UART peripheral is empty, the TXINT bit will * be set and trigger the interrupt immediately. For the interrupt handler * to handle this case 'g_p_char' must be a null pointer. */ g_p_char = p_str; g_uart_comm_status = UART_STATUS_TX_STARTED; /* Wait until the TXDATA register is empty and there is no ongoing data * reception before proceeding with transmission. */ while (DL_UART_Main_isBusy(UART_COMM_INST)) { /* Do nothing. */ } /* Initiate data transmission. */ DL_UART_Main_transmitData(UART_COMM_INST, *g_p_char); /* Wait for the entire transmission to complete. */ while (g_uart_comm_status != UART_STATUS_TX_COMPLETE) { /* Do nothing. */ } } /* uart_puts() */ /*! * @brief Interrupt handler for UART_COMM instance. * * @par * This handler processes UART interrupts based on the type of interrupt pending * (RX or TX). For TX interrupts, it handles the transmission of the next * character or completes the transmission when the end of the string is * reached. */ void UART_COMM_INST_IRQHandler(void) { /* Check the pending interrupt type for the UART instance. */ switch (DL_UART_Main_getPendingInterrupt(UART_COMM_INST)) { case DL_UART_MAIN_IIDX_RX: { if (UART_STATUS_RX_STARTED != g_uart_comm_status) { /* Interrupt or user input(s) uncalled for. Ignore. */ return; } g_rx_char = DL_UART_Main_receiveData(UART_COMM_INST); DL_UART_Main_disableInterrupt(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_RX); g_uart_comm_status = UART_STATUS_RX_COMPLETE; break; } case DL_UART_MAIN_IIDX_TX: { if (NULL == g_p_char) { /* No character is pending to be transmitted, return. */ return; } g_uart_comm_status = UART_STATUS_TX_INPROGRESS; /* Proceed to the next character to send. */ g_p_char++; if (*g_p_char != '\0') { /* Wait until the TXDATA register is empty and there is no ongoing data * reception before proceeding with transmission. */ while (DL_UART_Main_isBusy(UART_COMM_INST)) { /* Do nothing. */ } /* There are more characters to send, transmit the next one. */ DL_UART_Main_transmitData(UART_COMM_INST, *g_p_char); } else { /* If the string is finished, disable TX interrupt and update * status. */ DL_UART_Main_disableInterrupt(UART_COMM_INST, DL_UART_MAIN_INTERRUPT_TX); g_p_char = NULL; g_uart_comm_status = UART_STATUS_TX_COMPLETE; } break; } default: break; } } /* UART_COMM_INST_IRQHandler() */
结果如下:
1和4缺失。
c23 56
当我在看:
c123 456
如果有人能帮助我理解我在使用 DriverLib 函数时存在任何错误、我将不胜感激。
谢谢!
李京宰