基于STM32CubeMX新建了基础模板工程,实现了点灯。本次继续实现串口发送接收功能。方便打印输出和shell命令调试。
首先实现串口中断发送接收功能。通过FIFO缓存来控制发送接收。
主要代码如下:
static uint8_t uart_recv_buff[4];
static uint8_t uart_send_buff[128];
shell_uart_buffer_t g_shell_uart=
{
.tx.read_i = 0,
.tx.write_i = 0,
.rx.read_i = 0,
.rx.write_i = 0,
.tx_cpl = 0,
};
//
static void uart_get_data_send(void)
{
uint32_t i;
//
for(i=0;i<128;i++)
{
if(g_shell_uart.tx.read_i != g_shell_uart.tx.write_i)
{
uart_send_buff[i] = g_shell_uart.tx.buff[g_shell_uart.tx.read_i++];
g_shell_uart.tx.read_i &= 0x1ff; //256Byte
}else break;
}
if(i)
{
g_shell_uart.tx_cpl = 1;
HAL_UART_Transmit_IT(&UART_SHELL_PORT,uart_send_buff,i);
}
}
static void uart_send_char(uint8_t ch)
{
while(((g_shell_uart.tx.write_i+1)&0x1ff) == g_shell_uart.tx.read_i)
{
//fifo buffer full
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
g_shell_uart.tx.buff[g_shell_uart.tx.write_i++] = ch;
g_shell_uart.tx.write_i &= 0x1ff;//256Byte
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
//////////////////////////////////////////////////////////////////////////////
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == UART_PORT) //shell
{
//
if(((g_shell_uart.rx.write_i+1)&0x1ff) != g_shell_uart.rx.read_i)
{
g_shell_uart.rx.buff[g_shell_uart.rx.write_i++] = uart_recv_buff[0] & 0xff;
g_shell_uart.rx.write_i &= 0x1ff;//256Byte
}
HAL_UART_Receive_IT(huart,uart_recv_buff,1);//
}
}
//
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == UART_PORT) //shell
{
g_shell_uart.tx_cpl = 0;
uart_get_data_send();
}
}
//
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == UART_PORT) //shell
{
HAL_UART_Receive_IT(huart,uart_recv_buff,1);//
}
}
uint8_t USART_GetChar(void)
{
uint8_t ch;
while(g_shell_uart.rx.read_i == g_shell_uart.rx.write_i);
ch = g_shell_uart.rx.buff[g_shell_uart.rx.read_i++];
g_shell_uart.rx.read_i &= 0x1ff; //256Byte
return ch;
}
void USART_PutChar(uint8_t ch)
{
uart_send_char(ch);
}
下面对接printf输出。选择pack里面的软件包。
然后实现下面几个函数:
void _ttywrch (int ch) {
}
void _sys_exit (void) {
}
int stdin_getchar (void)
{
return USART_GetChar();
}
int stdout_putchar (int ch)
{
USART_PutChar(ch & 0xff);
return ch;
}
初始化启动串口中断接收后。就可以准备printf打印了。
编译下载效果:
下面移植一下nr_micro_shell功能。首先添加nr_micro_shell的代码,然后配置串口的输入和输出。
主要配置如下:
添加头文件路径:
添加初始化和主循环处理串口数据。
然后编译下载,就可以实现shell调试命令了。
|