这次我们要配合shift键打印大写的字母,先把代码贴出来:
- static int Shift_L;
- static int Shift_R;
- void Keyboard_Read()
- {
- u8 scan_code;
- int make;
- char disp[2];
- u32 *key_row;
- u32 key = 0;
- int col = 0;
- Memory_Set(&disp[0],2,0);
- if(kb_input_buffer.count > 0)
- {
- Disable_Int();
- scan_code = *(kb_input_buffer.p_head);
- kb_input_buffer.p_head++;
- kb_input_buffer.count--;
- if(kb_input_buffer.p_head >= kb_input_buffer.buffer + 256)
- {
- kb_input_buffer.p_head = kb_input_buffer.buffer;
- }
- Enable_Int();
- if(scan_code == 0xe1)
- {
- /* 暂时不做任何操作 */
- }
- else if(scan_code == 0xe0)
- {
- /* 暂时不做任何操作 */
- }
- else
- {
- make = (scan_code & NR_SCAN_CODES)? 0 : 1;
- key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];
- if(Shift_L || Shift_R)
- {
- col = 1;
- }
- key = key_row[col];
- switch(key)
- {
- case SHIFT_L:
- Shift_L = make;
- key = 0;
- break;
- case SHIFT_R:
- Shift_R = make;
- key = 0;
- break;
- default:
- if(!make)
- {
- key = 0;
- break;
- }
- }
- if(key)
- {
- disp[0] = key;
- Disp_Color_Str(disp,0xa);
- }
- }
- }
- }
先定义了两个static的全局局部变量,用来记录左边的shift和右边的shift键的状态,又在函数中定义了一个局部变量key,用来存放按下的键盘的相应的扫描码在表中对应的值,col和key_row的作用结合代码分析来说。
首先照例是判断一下按下的键的扫描码是Make Code还是Break Code,然后把key_row定位到指向相应扫描码在表中相应的行的首个元素,再判断之前是否有shift键按下,如果有则把col赋值为1,然后把key值赋值为表中相应的值,这里可以看到col的作用了吧,如果按下的字母键,之前又按下了shift键,key值就为大写字母的ASCII码,接着一个switch语句,如果按下的是左边的shift键,则相应状态就要起变化,Shift_L赋为make,这就很巧妙,如果是Make Code,表示按下状态,如果是Break Code,则为弹起状态,Shift_L就为0了,接着是把key赋值为0,因为shift键是不可打印的。右边的shift键是雷同的,无需赘言。其它的键就判断一下是否是Make Code,如果不是,同样把key赋为0,表示不打印。最后判断一下key的值,如果不为0,就把key赋给disp[0],然后打印出来。
make,运行,结果如图所示,按住shift不放,再按下字母键,就出现相应的大写字母,如果按下数字键,会出现相应的特殊字符:
我们的胃口还没有得到满足,还有更多键等着我们处理。