姓名:徐娇 学号:17011210547
转自http://mp.weixin.qq.com/s/YUXrJbin_rnwModTY2Ds_A
【嵌牛导读】
C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
20世纪80年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言订定了一套完整的国际标准语法,称为ANSI C,作为C语言最初的标准。
【嵌牛鼻子】C语言、嵌入式系统编程、注意事项之键盘操作
【嵌牛提问】C语言在嵌入式系统编程时的注意事项
【嵌牛正文】C语言嵌入式系统编程注意事项之键盘操作
处理功能键
让我们来看看WIN32编程中用到的“窗口”概念,当消息(message)被发送给不同窗口的时候,该窗口的消息处理函数(是一个callback函数)最终被调用,而在该窗口的消息处理函数中,又根据消息的类型调用了该窗口中的对应处理函数。通过这种方式,WIN32有效的组织了不同的窗口,并处理不同窗口情况下的消息。
我们从中学习到的就是:
(1)将不同的画面类比为WIN32中不同的窗口,将窗口中的各种元素(菜单、按钮等)包含在窗口之中;
(2)给各个画面提供一个功能键“消息”处理函数,该函数接收按键信息为参数;
(3)在各画面的功能键“消息”处理函数中,判断按键类型和当前焦点元素,并调用对应元素的按键处理函数。
/*将窗口元素、消息处理函数封装在窗口中*/
struct windows
{
BYTE currentFocus;
ELEMENT element[ELEMENT_NUM];
void(*messageFun) (BYTE key);
…
};
/*消息处理函数*/
void message(BYTE key)
{
BYTE i = 0;
/*获得焦点元素*/
while( (element .ID!= currentFocus)&&(i《ELEMENT_NUM) )
{
i++;
}
/* “消息映射” */
if(i《ELEMENT_NUM)
{
switch(key)
{
case OK:
element.OnOk();
break;
…
}
}
}
在窗口的消息处理函数中调用相应元素按键函数的过程类似于“消息映射”,这是我们从WIN32编程中学习到的。编程到了一个境界,很多东西都是相通的了。其它地方的思想可以拿过来为我所用,是为编程中的“拿来主义”。
在这个例子中,如果我们还想玩得更大一点,我们可以借鉴MFC中处理MESSAGE_MAP的方法,我们也可以学习MFC定义几个精妙的宏来实现“消息映射”。
处理数字键
用户输入数字时是一位一位输入的,每一位的输入都对应着屏幕上的一个显示位置(x坐标,y坐标)。此外,程序还需要记录该位置输入的值,所以有效组织用户数字输入的最佳方式是定义一个结构体,将坐标和数值捆绑在一起:
/*用户数字输入结构体*/
typedef struct tagInputNum
{
BYTE byNum; /*接收用户输入赋值*/
BYTE xPos; /*数字输入在屏幕上的显示位置x坐标*/
BYTE yPos; /*数字输入在屏幕上的显示位置y坐标*/
}InputNum,*LPInputNum;
那么接收用户输入就可以定义一个结构体数组,用数组中的各位组成一个完整的数字:
InputNum inputElement[NUM_LENGTH]; /*接收用户数字输入的数组*/
/*数字按键处理函数*/
extern void onNumKey(BYTE num)
{
if(num==0|| num==1)/*只接收二进制输入*/
{
/*在屏幕上显示用户输入*/
DrawText(inputElement[currentElementInputPlace].xPos,inputElement[currentElementInputPlace].yPos,“%1d”,num);
/*将输入赋值给数组元素*/
inputElement[currentElementInputPlace].byNum = num;
/*焦点及光标右移*/
moveToRight();
}
}
将数字每一位输入的坐标和输入值捆绑后,在数字键处理函数中就可以较有结构的组织程序,使程序显得很紧凑。
整理用户输入
继续第2节的例子,在第2节的onNumKey函数中,只是获取了数字的每一位,因而我们需要将其转化为有效数据,譬如要转化为有效的XXX数据,其方法是:
/*从2进制数据位转化为有效数据:XXX */
void convertToXXX()
{
BYTE i;
XXX = 0;
for(i = 0; i《NUM_LENGTH; i++)
{
XXX += inputElement.byNum*power(2,NUM_LENGTH - i - 1);
}
}
反之,我们也可能需要在屏幕上显示那些有效的数据位,因为我们也需要能够反向转化:
/*从有效数据转化为2进制数据位:XXX */
void convertFromXXX()
{
BYTE i;
XXX = 0;
for(i = 0; i《NUM_LENGTH; i++)
{
inputElement.byNum = XXX / power(2,NUM_LENGTH - i - 1)% 2;
}
}
当然在上面的例子中,因为数据是2进制的,用power函数不是很好的选择,直接用“《《 》》”移位操作效率更高,我们仅是为了说明问题的方便。试想,如果用户输入是十进制的,power函数或许是唯一的选择了。
总结
本篇给出了键盘操作所涉及的各个方面:功能键处理、数字键处理及用户输入整理,基本上提供了一个全套的按键处理方案。对于功能键处理方法,将LCD屏幕与Windows窗口进行类比,提出了较新颖地解决屏幕、键盘繁杂交互问题的方案。
计算机学的许多知识都具有相通性,因而,不断追赶时髦技术而忽略基本功的做法是徒劳无意的。我们最多需要“精通”三种语言(精通,一个在如今的求职简历里泛滥成灾的词语),最佳拍档是汇编、C、C++(或JAVA),很显然,如果你“精通”了这三种语言,其它语言你应该是可以很快“熟悉”的,否则你就没有“精通”它们。