陈梅芬,吴佳骏,王汉章
(厦门海洋职业技术学院,福建 厦门 361100)
近年来,随着信息技术的发展,特别是物联网及人工智能技术的发展,对嵌入式从业人员的需求与日俱增。许多本科院校及职业院校都有开设《嵌入式程序设计》或相关课程[1]。《嵌入式程序设计》是一门综合性较强的课程,既需要硬件基础知识,也需要软件基础知识。随着嵌入式技术的快速发展,高职的《嵌入式程序设计》的教学也显现出一些问题,特别是如何使得培养出来的学生更容易满足嵌入式行业的需求,本文以矩阵键盘项目为例,说明了项目式教学法在课程中的运用。
在高职院校中,《嵌入式程序设计》一般是安排在大二阶段进行学习,它的先修课程一般有《模拟电路》、《数字电路》、《单片机程序设计》或《C语言程序设计》,需要学生掌握的知识储备较多,很多学生在先前课程的学习中并不都能很好地掌握这些先修课程,造成学生在学习《嵌入式程序设计》课程时有畏难情绪[2]。
嵌入式的技术发展很快,有时候就会出现学校课堂上讲的知识点跟不上业界技术的发展。这就要求我们在使用项目教学法的时候,要尽量的从企业实际应用的案例中提取有效的项目,并与嵌入式相关的知识点较好地融合。
可以将《嵌入式程序设计》的教学过程分为三个阶段,基础教学、进阶教学和综合教学[3]。从几年的教学经验来看,学生经常会在进阶教学的阶段碰到困难,最大的困难是代码已按照自己的思路写出来了,在Keil软件也编译通过,但HEX文件下载到开发板后就是工作不正常,此时却找不到好的方法来解决问题,也不知道程序运行到哪里了。
键盘应用是人机交互中最常用的方法之一,也是构造各种实际的嵌入式应用系统的基本元素。矩阵式键盘的接口是由行线与列线组成,按键位于行、列的交叉线上,这种方法的优点相比较独立键盘,可以节约IO资源,相对于专用芯片式键盘,可以节约成本,因而其在各种嵌入式系统中得到了广泛的应用[4-5]。矩阵键盘项目是《嵌入式程序设计》课程进阶教学中碰到的第一个较难的项目,顺利地解决这个项目,对学生继续学习本门课程也会有很大的帮助。
在业界,一个嵌入式系统的项目通常是由一个团队来完成的,通常按照图1的流程来实现。在启动一个嵌入式系统的项目后,先是要对项目的需求进行分析,输出系统的设计目标文档,接着要对设计目标文档进行评审,评审通过后,团队成员分工合作,输出软硬件设计方案文档,软硬件设计方案文档评审通过后,就可以开始具体的硬件实现与软件设计,最后是系统验证及验证覆盖率的分析。
图1 嵌入式系统的项目实现流程
由于在课程教学过程中,课程的学时有限以及学生专业知识水平与企业工程师专业知识水平的差距,我们通常会将企业项目实现流程进行简化,以适应教学需求。在教学过程中,项目的设计目标通常是已经确定好了,项目中所用的硬件电路也通常用的是开发板的既定的电路,所以在教学过程中的项目实现流程中,前两步对设计的要求会少一些,更多的是去理解它们。在软件设计知识储备阶段中,老师须帮助学生建立实现项目所需的一些知识储备,如在矩阵键盘项目中,在这一阶段,学生要懂得矩阵键盘实现的一些基本方法,循环扫描法与行列反转法。软件设计完以后,学生需要对运行结果进行分析,判断所设计系统是否满足设计目标。如图2所示,为教学过程中的项目实现流程。
图2 教学过程中的项目实现流程
此次矩阵按键项目的系统设计目标为实现5×5按键的扫描,将对应的按键值打印到串口上。
矩阵键盘项目用的主控CPU为STM32F103VE,STM32F103VE带有Cortex-M3内核,共有5组16位的GPIO接口,5组USART接口。矩阵键盘的电路如图3所示,当有按键按下,相应的行线与列线就会连接,如当S101键按下时,K_PA0与K_COLOUT4就会相连接。此次项目使用到了STM32F103VE的USART1,对应的IO口为PA9/USART1_TX和PA10/USART1_RX。
图3 矩阵键盘电路
矩阵式键盘根据不同的软件扫描方式,通常可分为循环扫描法与行列反转法。循环扫描法的原理是让CPU不停地去扫描键盘的行线与列线,如可让列线固定为输出端口,行线固定为输入端口,同一个时刻列线的输出中只有一根线的输出为低电平,当行线有采集在低电平时,就说明有按键按下,此种方法,结构简单,行线与列线的输入输出模式固定,但扫描耗费的时间较长[6]。行列反转法是通过行线与列线的互换来确定按键,行线与列线的输入输出模式需要变化,但其检测速度较快,因而得到了广泛的应用。
如图4所示,为行列反转法按键检测流程,先是设置列端口为输出,数值为0,行端口为带上拉的输入;读取行端口的数值存储在row_data中;接着设置行端口为输出,数值为0,列端口为带上拉的输入;读取列端口的数值存储在col_data中;根据row_data与col_data就可以判断出按键的数值。
图4 行列反转法按键检测流程
多数按键采用的是机械式的弹性开关,机械式的开关经常会引入抖动,抖动过程的长短是由按键的机械特性决定,一般是10~20 ms,我们可以采用多次采样的方法来实现软件去抖。隔一定的时间去采一次按键的检测数值,程序里面会存储三个采样的数值,key(当前按键的数值),key_history1(上一次按键检测的数值),key_history2(上上次按键检测的数值),当我们检测到(key!=0)&&(key_history1==key)&&(key_history2==0)的条件为真的时候,就可以判断此时按键按下,这里的按键采样间隔时间可以根据需要采用定时器或者主函数的循环来实现。
在1.3小节里讲到学生在编写程序的时候碰到问题不知如何解决,在教学的过程中,笔者发现串口是嵌入式系统中非常重要的一个调试工具,学生在课程学习的进阶阶段的初期,就应该把串口架设起来,架设起来后,就可以将相应的调试信息用printf打印到串口上了,可以解决不知道程序运行到哪里的问题。
在USART1的驱动代码中加入如下的代码,就可以使用printf函数,将相应的调试信息打印在USART1上。
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x=x;
}
//重定义fputc函数
int fputc(int ch,FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR=(u8) ch;
return ch;
}
#endif
如图5所示,为矩阵键盘项目的运行结果,当有一个按键按下时,CPU会检测到相应的键值,并将键值打印到串口上,相应的程序调试信息也可以打印到串口上。
图5 矩阵键盘项目运行结果
在多项职业院校技能大赛中,都有嵌入式程序设计相关技能的考核要求,如嵌入式技术应用开发赛项、电子产品设计及制作赛项、集成电路开发及应用赛项等。对于参加技能竞赛训练的学生,对他们的要求会比普通学生的要求高一些,在对他们进行项目教学时,除了按照图2的流程进行训练外,还需要增加一项代码风格检查,如图6所示。当代码风格检查不通过时,须返工,经过几次的迭代,学生的嵌入式系统编程能力就可以得到明显的提高。
图6 竞赛训练中项目实现流程
代码风格检查过程的关键是规则的设定,嵌入式程序的代码风格规则的范围很广,不同的企业可能也会有不同的要求,这里以高职学生在进入技能竞赛训练前期经常出现的一些代码风格问题进行总结,如下:
1) 变量的命名需取有意义的名字,可以采用驼峰命名法或者下划线命名法。
2) 中断函数里面不允许做太多复杂的操作,不允许出现大段的延时。
3) 在main函数中尽量少用大段的延时。
4) 在写某个硬件模块驱动的时候,要考虑到使用者的易用性,要做好驱动使用者与硬件沟通的桥梁。在工程文件里,一般一个.c文件应对应一个.h文件。
5) 一般是系统中所有的硬件全部初始化完了,才将总中断打开(特殊的应用不一定要遵守这条规则)。
6) 复杂的逻辑,建议用状态机来控制,这样不容易出错。
通过学生们提交的课程总结报告中,可以发现将项目式的教学法运用到课程中,提高了学生们对这门课的兴趣,帮助学生们解决在课程中碰到的困难,学生们在项目的实现过程中获得了成就感。将改进后的项目教学法应用于技能竞赛训练中,可以明显地提高学生的专业技能能力。笔者将改进后的项目教学法应用于学生电子产品设计及制作赛项、集成电路开发及应用赛项的训练中,学生获得了2021年全国职业院校技能大赛集成电路开发及应用赛项一等奖,2022年福建省职业院校技能大赛电子产品设计及制作赛项一等奖。