你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C031 评测】串口移植nr_micro_shell测试

[复制链接]
落花又见流水 发布时间:2024-3-15 17:33

本次移植一个串口shell,用于交互命令。串口shell目前有好几个开源的,像nr_micro_shell和letter_shell。本次选择nr_micro_shell移植。

下面首先下载nr_micro_shell源码,然后加入到工程内。

image.png

下面修改串口使用中断发送和接收。

c95d06aae0dca39ea91de9b9852f6b5.png

生成工程后修改串口发送接收接口。使用fifo缓存方式发送接收数据。

代码如下:

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DRV_UART_H
#define __DRV_UART_H



#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "nr_micro_shell.h"

/* Private includes ----------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

typedef struct fifo_buffer_t
{
    volatile uint32_t    read_i;
    volatile uint32_t    write_i;
    uint8_t              buff[512];
}fifo_buffer_t;

typedef struct shell_uart_buffer_t
{
    fifo_buffer_t       tx;
    fifo_buffer_t       rx;
    volatile uint32_t    tx_cpl  :   1;

}shell_uart_buffer_t;

extern shell_uart_buffer_t  g_shell_uart;

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
/* USER CODE BEGIN EFP */

void shell_usart_init(void);
int stdout_putchar (int ch);
void shell_usart_loop(void);

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __DRV_UART_H */
/******************************************************************************
 * Include files
 ******************************************************************************/
#include "main.h"
#include "drv_uart.h"


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,
};

//缓存发送
//发送FIFO缓存还有数据就继续发送
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(&huart2,uart_send_buff,i);
    }
}


static void uart_send_char(uint8_t ch)
{
    //检查缓存是否满,压入发送缓存
    if(((g_shell_uart.tx.write_i+1)&0x1ff) != g_shell_uart.tx.read_i)
    {
        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();
    }
}

int stdout_putchar (int ch)
{
    uart_send_char(ch & 0xff);
    return ch;
}

int fputc(int ch,FILE *f)
{
    return stdout_putchar(ch);
}



void shell_usart_init(void)
{
    shell_init();   //shell初始化
    HAL_UART_Receive_IT(&huart2,uart_recv_buff,1);//开始接收回应数据
}

void shell_usart_loop(void)
{
    //从缓存取出接收数据
    if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
    {
        shell(g_shell_uart.rx.buff[g_shell_uart.rx.read_i++]);
        g_shell_uart.rx.read_i &= 0x1ff; //缓存256Byte
    }

    if(g_shell_uart.tx_cpl == 0)
    {
        uart_get_data_send();
    }
}



//////////////////////////////////////////////////////////////////////////////
//串口接收中断完成回掉
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2)   //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 == USART2)   //shell
    {
        g_shell_uart.tx_cpl = 0;
        uart_get_data_send();
    }
}

//出错
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2)   //shell
    {
        HAL_UART_Receive_IT(huart,uart_recv_buff,1);//开始接收回应数据
    }
}

然后在main中调用初始化和循环接收串口数据,然后解析命令。

image.png

添加头文件路径。

image.png

编译下载之后就可以实现串口命令解析执行了。

下面就是串口测试效果。

image.png

收藏 评论0 发布时间:2024-3-15 17:33

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版