工具与软件:
您好!
我目前正在实现基于中断的 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 函数时存在任何错误、我将不胜感激。
谢谢!
李京宰