原创 [博客大赛]使用变参函数实现STM32串口接收指定字符的功能

2014-10-16 14:13 2038 19 22 分类: MCU/ 嵌入式 文集: C语言

串口经常需要接收指定范围的字符。比如程序运行到某处,提供给用户‘A’、‘B’、‘C’、‘D’四个选项,等待用户输入。如果输入是‘A’、‘B’、‘C’、‘D’的其中一个,则跳转;否则继续等待。
这个功能可以使用if判断语句来实现,它的优点是直观简单,缺点是代码有重复。如果程序中有十次这样的等待输入,就得编写十次if判断语句。
所以,这里使用变参函数将这个功能整合成一个模块。

// 定义在变参函数中,需要调用的显示函数,里面放置打印给用户的提示信息等等
// 函数类型需要符合变参函数中的uart_func
// USART_TypeDef用来选择串口号
// 第一个struct uartData用来存储串口接收中断的数据和标志位
// 第二个struct uartData是第一个的缓存,避免数据和标志位在处理的时候被串口接收中断更新
int uxah_dis(USART_TypeDef* USARTx, struct uartData *uartxData, struct uartData *uartxMain)
{
    usart_printf(USARTx, "\r\nplease enter your choice:  ");
    return sFALSE;
}


// uart_func  func是调用的显示函数,便于重复打印提示信息
// char *byte用来存储最终的有效字符
// int num是可用的字符数量,如果变参为‘A’、‘B’、‘C’、‘D,则num=4
int UART_wait_char(USART_TypeDef* USARTx, struct uartData *uartxData,
                struct uartData *uartxMain, uart_func func, char *byte, int num, ...)
{
    char *p = (char *)&num + sizeof(int);   
    uint32_t i = 0;

START:
    func(USARTx, uartxData, uartxMain); 
    for (i = 0; i < num; i++) {                 
        usart_send_byte(USARTx, *((char *)(p + i * sizeof(int)))); 
        if (i != num - 1)
             usart_printf(USARTx, "/");
    }
    usart_printf(USARTx, "  ");
    uartxData->recIrq = sFALSE;

    while (1) {     
        if (uartxData->recIrq >= sTRUE) {
            uartxMain->recTempH = uartxData->recTempH;
            uartxData->recIrq = sFALSE;                                         
            usart_send_byte(USARTx, uartxMain->recTempH);       

            for (i = 0; i < num; i++) {                                              
                if (uartxMain->recTempH == *((char *)(p + i * sizeof(int)))) {
                    *byte = uartxMain->recTempH;                 
                    return sTRUE;                                                 
                }
            }
            goto START;   
        }
    }
    return sFALSE;
}


当执行:
UART_wait_char(USART1,  uart1Data,  uart1Main,  uxah_dis, &temp, 4, 'A', 'B', 'C', 'D');
时,会打印:
please enter your choice:  A/B/C/D  w
please enter your choice:  A/B/C/D  q
please enter your choice:  A/B/C/D  A

如果接收到'A', 'B', 'C', 'D'其中一个,则继续执行后面的程序,否则重复打印上面的内容。

当执行:
UART_wait_char(USART1,  uart1Data,  uart1Main,  uxah_dis, &temp, 2, 'Y', 'N');
时,会打印
please enter your choice:  Y/N  Q
please enter your choice:  Y/N  N

如果接收到'Y', 'N'其中一个,则继续执行后面的程序,否则重复打印上面的内容。

变参函数,在形参的数量和内容不确定的情况下,能够简化分支判断语句,使代码干净整洁。
 

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

DiracFatCat 2013-11-30 12:04

要是只接受一个字符的话,防错防误输入可以在后面再加一级判断,比如输入A之后提示 “continue”,等待用户确认;多字符和任意字符的输入,可以在串口中断函数里面加入缓存区的数组指针或者计数变量来操作。有限的字符接收还是比较好实现的,网上有人实现了循环缓冲区,还有STM32的DMA功能,那个比较麻烦一些。

用户406780 2013-11-30 09:35

思路不错 给你两个作业: 把防错、防误输入考虑进去你看会变成什么样? 还有多字符输入,或者任意字符的输入该如何设计?

ydcman_691947663 2013-11-28 20:04

不错
相关推荐阅读
DiracFatCat 2018-09-05 12:14
【博客大赛】卡尔曼滤波学习笔记(11)从位置估计速度
卡尔曼滤波器,不仅仅是一个低通滤波器,否则也不会持续发展50年。 示例:桑先生需要测试高速列车的性能。测试的目的是判断列车在直线上能否保持80m/s的速度。速度和位置每0.1秒测量一次,但是由于...
DiracFatCat 2018-08-31 19:32
【博客大赛】卡尔曼滤波学习笔记(10)一个简单的示例
《Kalman Filtering: Theory and Practice Using MATLAB》第三章,看不懂,暂时略过。《Kalman Filtering: Theory and Pract...
DiracFatCat 2018-07-19 15:09
对sed命令的练习
sed是流编辑器。它每次处理一个输入,因此很有效率。官方手册:https://www.gnu.org/software/sed/manual/sed.html学习Linux命令,当然要阅读官方手册,所...
DiracFatCat 2018-06-19 15:10
【博客大赛】卡尔曼滤波学习笔记(八)可观测性和可控制性 ...
可观测性是指,在给定模型的情况下,动力学系统的状态是否由它的输入输出唯一确定。可观测性是系统模型的特征。如果传感器矩阵H是可逆的,则本系统可观测,因为有:如果传感器矩阵H某些时候是不可逆的,则本系统仍...
DiracFatCat 2018-06-19 10:56
【博客大赛】卡尔曼滤波学习笔记(七)Z变换
如果我们仅仅对离散线性系统感兴趣,那么就使用下面这个表达式:如果u是常量,那么可以写成:为了简化表达式,我们可以将上面写成:离散线性时不变系统的Φ求解,可以使用Z变换。(* 由于本人已经忘记了Z变换的...
DiracFatCat 2018-06-19 10:54
【博客大赛】卡尔曼滤波学习笔记(六)拉普拉斯变换
对于线性时变/时不变系统,求解Φ(t)有多种方式,拉普拉斯变换是其中一种。(* 由于本人已经忘记了拉普拉斯变换的内容,因此本节待续。)...
EE直播间
更多
我要评论
3
19
关闭 站长推荐上一条 /3 下一条