历史上的今天
返回首页

历史上的今天

今天是:2024年10月09日(星期三)

正在发生

2021年10月09日 | STM32 f103 实现命令终端

2021-10-09 来源:eefocus

文件说明


uart.c 


实现输入反显及命令识别


cmd.c


实现命令函数及命令查找


main.c


进入shell模式


uart.c


#include "usart.h"

 

/****************************************************************************

* 名    称:void USART1_Configuration(void)

* 功    能:配置USART1参数

* 入口参数:

* 出口参数:无

* 说    明:

* 调用方法:无 

****************************************************************************/

void USART1_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //USART1 TX

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出

GPIO_Init(GPIOA, &GPIO_InitStructure);     //A端口 

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;           //USART1 RX

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //复用开漏输入

GPIO_Init(GPIOA, &GPIO_InitStructure);           //A端口 

 

USART_InitStructure.USART_BaudRate = USART_BAUDRATE; //波特率250000bps

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位

USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位

USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件流控

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 

 

USART_Init(USART1, &USART_InitStructure); //配置串口参数函数    

 

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                    //使能接收中断

//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //使能发送缓冲空中断

 

USART_Cmd(USART1, ENABLE); //使能 USART1

}

/****************************************************************************

* 名    称:void USART1_SendByte(uint8_t TxData)

* 功    能:串口1发送函数

* 入口参数:TxData

* 出口参数:无

* 说    明:

* 调用方法:无 

****************************************************************************/

void USART1_SendByte(uint8_t TxData)

{  

   USART_SendData(USART1, TxData);

   while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);     

}

/****************************************************************************

* 名    称:int fputc(int ch, FILE *f)

* 功    能:重定向c库函数printf到串口,重定向后可使用printf函数

* 入口参数:int ch, FILE *f

* 出口参数:int

* 说    明:

* 调用方法:无 

****************************************************************************/

int fputc(int ch, FILE *f)

{

/* 发送一个字节数据到串口 */

USART1_SendByte((uint8_t) ch);

 

/* 等待发送完毕 */

while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

 

return (ch);

}

/****************************************************************************

* 名    称:int fgetc(FILE *f)

* 功    能:重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数

* 入口参数:FILE *f

* 出口参数:int

* 说    明:

* 调用方法:无 

****************************************************************************/

int fgetc(FILE *f)

{

/* 等待串口输入数据 */

while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

 

return (int)USART_ReceiveData(USART1);

}

/****************************************************************************

* 名    称:void uart_putc(uint8_t c)

* 功    能:向终端打印一个字符

* 入口参数:uint8_t c

* 出口参数:void

* 说    明:shell

* 调用方法:无 

****************************************************************************/

void uart_putc(uint8_t c)

{

USART1_SendByte(c);

    if(c == 'n')

        uart_putc('r');

}

/****************************************************************************

* 名    称:void uart_puts(uint8_t *str)

* 功    能:向终端打印一个字符串

* 入口参数:uint8_t *str

* 出口参数:无

* 说    明:shell

* 调用方法:无 

****************************************************************************/

void uart_puts(uint8_t *str)

{

    while(*str)

    {

        uart_putc(*str);

        str++;

    }

}

/****************************************************************************

* 名    称:uint8_t uart_getc(void)

* 功    能:从终端获取一个字符

* 入口参数:

* 出口参数:

* 说    明:

* 调用方法:无 

****************************************************************************/

uint8_t uart_getc(void)

{

    while(!rec_f);

rec_f = 0;

    return (uint8_t)*USART1_RxBuffer;

 

}

/****************************************************************************

* 名    称:void uart_gets(uint8_t *buf, uint32_t len)

* 功    能:从终端获取一个字符串

* 入口参数:uint8_t *buf, uint32_t len

* 出口参数:无

* 说    明:shell

* 调用方法:无 

****************************************************************************/

void uart_gets(uint8_t *buf, uint32_t len)

{

    int i = 0;

    uint8_t tmp = 0;

 

    while(i < (len-1))

    {

        tmp = uart_getc();

        if(tmp==0x08 && i==0)

            continue;

 

        /*回显*/

        uart_putc(tmp);

        buf[i] = tmp;

        /**/

        if(tmp == 'r')

            break;

        if(tmp == 0x08){

            uart_putc(' ');

            uart_putc(0x08);

            i--;

            continue;

        }

        i++;

    }

    buf[i] = '';

}

 

 

 

/****************************************************************************

* 名    称:void Shell_Mode(void)

* 功    能:进入Shell模式

* 入口参数:无

* 出口参数:无

* 说    明:shell

* 调用方法:无 

****************************************************************************/

void Shell_Mode(void)

{

uint8_t cmd_buf[32];

_cmd *ptr = (_cmd *)0;

/*判断是否输入进入Shell的命令*/

uart_gets(cmd_buf,sizeof(cmd_buf)); //等待输入"shell"命令

if(!strcmp((char *)cmd_buf,"shell"))

printf("nTANG Shell!n");

else 

return;

 

/*Shell模式*/

while(1)

{

uart_puts("nTANG(M3)# ");

uart_gets(cmd_buf,sizeof(cmd_buf));

if(!strcmp((char *)cmd_buf,"quit")){ //退出Shell模式

printf("nQuit Shell!nr");

break;

}

ptr = find_cmd(cmd_buf); //查找命令是否存在

if(ptr) {

printf("rn");

ptr->cmd_func(); //命令处理函数

printf("rn");

}

else{

uart_puts("nUnkonwn command ");

uart_puts(cmd_buf);

}

}

}

/****************************************************************************

* 名    称:uint8_t Kill(void)

* 功    能:杀掉当前函数

* 入口参数:无

* 出口参数:被杀返回1 无操作返回0

* 说    明:shell

* 调用方法:无 

****************************************************************************/

uint8_t Kill(void)

{

uint8_t cmd_buf[32];

if(rec_f){

rec_f = 0;

uart_gets(cmd_buf,sizeof(cmd_buf));

 

if(!strcmp((char *)cmd_buf,"kill")){ //结束函数执行

printf("nFunction terminated+n");

return 1;

}

else 

return 0;

}

return 0;

}

 

uart.h


#ifndef _USART_H_

#define _USART_H_

 

#include "global.h"

 

#define USART_BAUDRATE (9600)

 

extern uint8_t  USART1_RxBuffer[25]; //串口接收缓冲区

extern uint8_t  USART1_TxBuffer[3]; //串口发送缓冲区

extern __IO uint8_t rec_f;

 

void USART1_Configuration(void);

void USART1_SendByte(uint8_t TxData);

void uart_gets(uint8_t *buf, uint32_t len);

void uart_puts(uint8_t *str);

void Shell_Mode(void);

uint8_t Kill(void);

 

#endif //_USART_H_

串口中断处理


/**

  * @brief  This function handles NMI exception.

  * @param  None

  * @retval : None

  */

void USART1_IRQHandler(void)      //串口1 中断服务程序

{

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    //判断读寄存器是否非空

{

USART1_RxBuffer[0] = USART_ReceiveData(USART1);         //将读寄存器的数据缓存到接收缓冲区里

rec_f=1;

USART1_RxCounter++;  

LED_Control(GPIOC,GPIO_Pin_15,0);

//printf("IRQ串口发生中断!n");

}

 

if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                   //这段是为了避免STM32 USART 第一个字节发不出去的BUG 

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);      //禁止发缓冲器空中断, 

}

}


cmd.c


解释一下cmd_list[] 这是一个命令列表  支持的所有命令都在这里边  如下边hello是命令  输入之后会执行Hello这个函数 


#include "cmd.h"

 

_cmd cmd_list[]=

{

{"hello,Hello},

};

/****************************************************************************

* 名    称:_cmd *find_cmd(char *user_cmd)

* 功    能:查找命令对应的执行函数

* 入口参数:char *user_cmd

* 出口参数:_cmd *

* 说    明:

* 调用方法:无 

****************************************************************************/ 

_cmd *find_cmd(uint8_t *user_cmd)

{

    uint32_t i = 0;

    for(i = 0; i        if(strcmp((char *)user_cmd, cmd_list[i].cmd_name) == 0)

            return &(cmd_list[i]);       

    }

    return (_cmd *)0;

}

static void Hello(void)

{

printf("Hello,this is my shell!");

}


cmd.h


#ifndef __CMD_H__

#define __CMD_H__

 

#include "global.h"

 

typedef struct cmd

{

    char *cmd_name;//命令

    void (*cmd_func)(void);//对应处理函数

}_cmd;

 

extern _cmd *find_cmd(uint8_t *user_cmd);

 

/*支持的命令处理函数*/

static void Hello(void);

#endif //__CMD_H__

main.c


int main(void)

{

RCC_Configuration();     //系统时钟设置及外设时钟使能

NVIC_Configuration();     //中断源配置   

GPIO_Configuration();     //LED控制初始化  

USART1_Configuration();

推荐阅读

史海拾趣

Allied Electronic & Semiconductor Technology Inc公司的发展小趣事

AE&ST公司自创立之初,就深知技术创新是电子行业的核心竞争力。公司投入大量资源进行研发,不断探索新的半导体材料和生产工艺。在一次偶然的实验中,AE&ST的研发团队发现了一种新型半导体材料,这种材料在能效和稳定性方面表现出色。公司迅速将这一发现转化为产品,并推向市场。新产品一经推出,便因其卓越的性能获得了市场的广泛认可,AE&ST公司因此获得了巨大的商业成功。

GigPeak公司的发展小趣事

为了进一步增强市场地位和扩大产品线,GigPeak在2010年实施了一项重要的并购战略。公司成功收购了另一家在光纤通信领域具有深厚技术积累的企业,这次并购不仅为GigPeak带来了先进的产品线和研发资源,还显著提升了其在全球市场的份额。通过整合双方的优势资源,GigPeak在光纤通信领域的技术实力和市场份额均实现了质的飞跃。

Floeth Electronic Ltd公司的发展小趣事

GigPeak公司自成立之初,便专注于高速数据传输技术的研发。在2005年,公司研发团队成功开发出一种新型的光电转换器,该转换器能够在极低的功耗下实现前所未有的数据传输速率。这一技术创新迅速吸引了业界的关注,并成功应用于多个高端数据中心项目,帮助GigPeak在竞争激烈的市场中脱颖而出。随着技术的不断迭代和市场的广泛认可,GigPeak逐渐成为了高速数据传输领域的领军企业。

Baneasa SA公司的发展小趣事

随着国内市场的逐渐饱和,Baneasa SA开始将目光投向海外市场。公司制定了国际化的发展战略,通过在欧美等发达国家设立分支机构、参加国际展会等方式积极开拓国际市场。这些努力使得Baneasa SA的产品逐渐在国际市场上占据了一席之地,公司的业务范围也得到了进一步扩大。

Freeport Resources Enterprises Corp公司的发展小趣事

为了提升在电子材料领域的竞争力,Freeport Resources积极寻求国际合作,与多家国际知名电子材料生产商和研究机构建立了战略伙伴关系。通过技术引进和联合研发,公司成功掌握了先进的电子材料提纯和加工技术,大幅提高了产品的质量和性能。同时,国际合作也帮助Freeport Resources打开了国际市场,其产品远销全球多个国家和地区,进一步巩固了其在电子材料市场的地位。

Federal Custom Cable公司的发展小趣事

Federal Custom Cable非常重视客户服务工作。他们建立了完善的客户服务体系,为客户提供从产品咨询、选型、定制到售后服务的全方位支持。同时,Federal Custom Cable还积极与合作伙伴建立长期稳定的合作关系,共同推动电缆行业的发展。这种以客户需求为导向、以合作伙伴关系为基础的经营模式,为Federal Custom Cable的持续发展提供了有力保障。

问答坊 | AI 解惑

直流电机PWM调速,C51、Proteus环境

分享一个利用AT89C51产生PWM信号控制直流电机调速的模拟模型。 软件环境:Keil C51,Proteus 已有文件:Keil C51工程文件,C51源文件,Proteus模型。已经产生的hex文件…

查看全部问答>

传感器产业发展的新动向

传感器技术是现代科技的前沿技术,传感器产业也是国内外公认的具有发展前途的高技术产业,它以其技术含量高、经济效益好、渗透能力强、市场前景广等特点为世人瞩目。     我国自动化方面的专家呼吁:目前复杂系统越来越复杂,自动化已经 ...…

查看全部问答>

【Labview】labview学习网站有哪些

大家学习labview都在哪些网站和论坛上混啊?     本人常去的有两个,www.ni.com这是NI的网站,学习labview怎么能不上呢!     其次是www.gsdzone.net 这是我常去的Labview论坛,里面有资深NI工程师潜伏哦!…

查看全部问答>

WHY???

在下面代码中发现产生INTSRC_CAM中断后若BIT_SUB_CAM_P和BIT_SUB_CAM_C都没触发 那就执行 “//有疑问的代码”标记的代码 即屏蔽掉了Camera所有中断并返回了SYSINTR_NOP 这样相应的IST得不到执行也就不会调用InterruptDone来打开屏蔽的中断那以后 ...…

查看全部问答>

windows mobile 6.0 下ras拨号的问题

我在mobile5下使用ras函数RasDial拨号连接没有问题 同样的程序以及拨号配置在mobile 6下却无法拨号成功 不知道5跟6在这方面有什么不一样吗 有经验的大虾帮忙看看,谢谢!!!…

查看全部问答>

请教版主,stm32的抗静电等级与潮敏是多少?

您好,版主! 我想请教下stm32的抗静电等级与潮敏各是多少呢? 静电等级:J8000 J5000 J2000 J1000 J500 J200 是那个级别的 是j2000吗? 潮敏:C1 C2 C3 C4 C5是那个级别的呢?…

查看全部问答>

2013年电子设计大赛是不是9月7号晚上结束后就不能在做了

本帖最后由 paulhyde 于 2014-9-15 03:13 编辑 同题目    …

查看全部问答>

这里有----Multisim电子电路仿真教程

想学习模电的同学,也可以试试仿真软件哦,,这里有Multisim电子电路仿真教程,但动手还是主要的,,,,, 通过对该软件的学习和使用,读者可以轻松地拥有一个元件设备非常完善的虚拟电子实验室,进而可以完成电子电路的各种实验和设计。全书共9章 ...…

查看全部问答>

为什么输出电压的反馈取自于最终的输出电压后变压器就发出响声?

我刚开始的反馈是取自于辅助绕组,发现输出电压随着输入电压变化大约1.2V。现在用面包板搭了一个从输出电压反馈的电路,用了PC817+TL431的方法,上电后变压器就开始发出声音了,下面是我的电路图,就问,这个为什么会响呢?该怎么解决呢? …

查看全部问答>