stm32_ps2键盘显示测试程序

发布者:快乐之源最新更新时间:2016-01-11 来源: eefocus关键字:stm32  ps2键盘  显示测试 手机看文章 扫描二维码
随时随地手机看文章
[cpp] view plaincopy
 
  1. //PS2键盘测试程序,可换行,按shift不放接着输入  
  2. //可输出大写,按下CAPS输出大写,再次按下输出小写  
  3. //此程序只用来测试,代码冗余,仅供参考,可根据需要自行删减  
  4. //PA13->PS2.CLK  PA15->PS2.DATA  
  5.   
  6. #include   
  7. #include "sys.h"  
  8. #include "usart.h"        
  9. #include "delay.h"    
  10. #include "led.h"   
  11. #include "key.h"  
  12. #include "exti.h"  
  13. #include "wdg.h"  
  14. #include "timer.h"  
  15. #include "lcd.h"         
  16.   
  17. const u8 unshifted[][2]=            //shift键没按下译码表  
  18. {         
  19.   0x0e,'`',  
  20.   0x15,'q',  
  21.   0x16,'1',  
  22.   0x1a,'z',  
  23.   0x1b,'s',  
  24.   0x1c,'a',  
  25.   0x1d,'w',  
  26.   0x1e,'2',  
  27.   0x21,'c',  
  28.   0x22,'x',  
  29.   0x23,'d',  
  30.   0x24,'e',  
  31.   0x25,'4',  
  32.   0x26,'3',  
  33.   0x29,' ',  
  34.   0x2a,'v',  
  35.   0x2b,'f',  
  36.   0x2c,'t',  
  37.   0x2d,'r',  
  38.   0x2e,'5',  
  39.   0x31,'n',  
  40.   0x32,'b',  
  41.   0x33,'h',  
  42.   0x34,'g',  
  43.   0x35,'y',  
  44.   0x36,'6',  
  45.   0x39,',',  
  46.   0x3a,'m',  
  47.   0x3b,'j',  
  48.   0x3c,'u',  
  49.   0x3d,'7',  
  50.   0x3e,'8',  
  51.   0x41,',',  
  52.   0x42,'k',  
  53.   0x43,'i',  
  54.   0x44,'o',  
  55.   0x45,'0',  
  56.   0x46,'9',  
  57.   0x49,'.',  
  58.   0x4a,'/',  
  59.   0x4b,'l',  
  60.   0x4c,';',  
  61.   0x4d,'p',  
  62.   0x4e,'-',  
  63.   0x52,''',  
  64.   0x54,'[',  
  65.   0x55,'=',  
  66.   0x5b,']',  
  67.   0x5d,'\',  
  68.   0x61,'<',  
  69.   0x69,'1',  
  70.   0x6b,'4',  
  71.   0x6c,'7',  
  72.   0x70,'0',  
  73.   0x71,'.',  
  74.   0x72,'2',  
  75.   0x73,'5',  
  76.   0x74,'6',  
  77.   0x75,'8',  
  78.   0x79,'+',  
  79.   0x7a,'3',  
  80.   0x7b,'-',  
  81.   0x7c,'*',  
  82.   0x7d,'9',  
  83.   0,0  
  84. };  
  85. const u8 shifted[][2]=      //shift键按下译码表  
  86. {  
  87.   0x0e,'~',  
  88.   0x15,'Q',  
  89.   0x16,'!',  
  90.   0x1a,'Z',  
  91.   0x1b,'S',  
  92.   0x1c,'A',  
  93.   0x1d,'W',  
  94.   0x1e,'@',  
  95.   0x21,'C',  
  96.   0x22,'X',  
  97.   0x23,'D',  
  98.   0x24,'E',  
  99.   0x25,'$',  
  100.   0x26,'#',  
  101.   0x29,' ',  
  102.   0x2a,'V',  
  103.   0x2b,'F',  
  104.   0x2c,'T',  
  105.   0x2d,'R',  
  106.   0x2e,'%',  
  107.   0x31,'N',  
  108.   0x32,'B',  
  109.   0x33,'H',  
  110.   0x34,'G',  
  111.   0x35,'Y',  
  112.   0x36,'^',  
  113.   0x39,'L',  
  114.   0x3a,'M',  
  115.   0x3b,'J',  
  116.   0x3c,'U',  
  117.   0x3d,'&',  
  118.   0x3e,'*',  
  119.   0x41,'<',  
  120.   0x42,'K',  
  121.   0x43,'I',  
  122.   0x44,'O',  
  123.   0x45,')',  
  124.   0x46,'(',  
  125.   0x49,'>',  
  126.   0x4a,'?',  
  127.   0x4b,'L',  
  128.   0x4c,':',  
  129.   0x4d,'P',  
  130.   0x4e,'_',  
  131.   0x52,'"',  
  132.   0x54,'{',  
  133.   0x55,'+',  
  134.   0x5b,'}',  
  135.   0x5d,'|',  
  136.   0x61,'>',  
  137.   0x69,'1',  
  138.   0x6b,'4',  
  139.   0x6c,'7',  
  140.   0x70,'0',  
  141.   0x71,'.',  
  142.   0x72,'2',  
  143.   0x73,'5',  
  144.   0x74,'6',  
  145.   0x75,'8',  
  146.   0x79,'+',  
  147.   0x7a,'3',  
  148.   0x7b,'-',  
  149.   0x7c,'*',  
  150.   0x7d,'9',  
  151.   0,0  
  152. };  
  153.   
  154. void Decode(u8 scancode);// 声明函数原型  
  155. u8 bitcount=11,ascii=' ';   // bitcount为位计数值;ascii为翻译后的ASCII码,初值为空格  
  156. u8 hang=0,lie=0;  //彩屏显示位置  
  157.   
  158. int main(void)  
  159. {         
  160.   Stm32_Clock_Init(9);//系统时钟设置  
  161.     delay_init(72);     //延时初始化  
  162.     uart_init(72,9600); //串口1初始化    
  163.     EXTIX_Init();  
  164.     LED_Init();  
  165.     LCD_Init();  
  166.     LCD_Clear(YELLOW);  
  167.       
  168.     POINT_COLOR=RED;  
  169.     BACK_COLOR=YELLOW;  
  170.       
  171.   while(1)   
  172.     {             
  173.         if(hang>=240) //换行  
  174.         {hang=0;lie+=16;if(lie>=320)lie=0;}   
  175.         LCD_ShowChar(hang,lie,ascii,16,0);      // 显示键盘字符  
  176.     }                                                 
  177. }  
  178.   
  179. /******************************************* 
  180. 函数名称: Decode 
  181. 功    能:  
  182. 参    数: scancode--需要翻译的扫描码 
  183. 返回值  : 无 
  184. ********************************************/  
  185. void Decode(u8 scancode)  
  186. {  
  187.  static u8 up=0,shift=0;    //up为通、断码标志,shift为shift键按下标志  
  188.  u8 i;  
  189.  if (!up)          //已接收的11位数据是通码(up为0)  
  190.  {  
  191.   switch (scancode)//开始翻译扫描码  
  192.   {  
  193.    case 0xF0:      //键盘释放标志(随后的一个字节是断码)  
  194.         up=1;      //设置up为断码标志  
  195.         break;  
  196.    case 0x12:      //左shift键按下  
  197.         shift=1;   //设置shift为按下标志  
  198.         break;  
  199.    case 0x59:      //右shift键按下  
  200.         shift=1;   //设置shift为按下标志  
  201.         break;     
  202.      case 0x58:  //CAPS键按下处理  
  203.           shift=(shift==0)?1:0;//shift取反  
  204.             break;  
  205.      case 0x66: // backspace键按下时处理  
  206.             //backspace键按下时处理  
  207.             break;  
  208.      case 0x5a:// 回车键按下时处理:换行  
  209.             ascii=' ';  
  210.             hang=0;  
  211.             lie=lie+16;  
  212.             break;  
  213.    default:          
  214.         if(!shift)            //如果shift键没有按下  
  215.         {                     //查找unshifted表,表中左列是扫描码,右列是对应的ASCII码  
  216.            for(i=0;unshifted[i][0]!=scancode&&unshifted[i][0];i++);  
  217.            if(unshifted[i][0]==scancode)   
  218.            {  
  219.             ascii=unshifted[i][1];  
  220.                      hang=hang+8;  
  221.            }  
  222.         }   
  223.         else                  //如果shift键按下  
  224.         {                     //查找shifted表  
  225.            for(i=0;shifted[i][0]!=scancode&&shifted[i][0];i++);  
  226.            if(shifted[i][0]==scancode)   
  227.            {  
  228.             ascii=shifted[i][1];  
  229.                       hang=hang+8;  
  230.            }  
  231.         }     
  232.         break;  
  233.   }  
  234.  }   
  235.  else                   //已接收的11位数据是断码(up为1)  
  236.  {  
  237.   up = 0;               //将断码标志复位  
  238.   switch (scancode)     //检测shift键释放  
  239.   {  
  240.    case 0x12 :          //左shift键  
  241.         shift = 0;  
  242.         break;  
  243.    case 0x59 :          //右shift键  
  244.         shift = 0;  
  245.         break;  
  246.    default:  
  247.         break;  
  248.   }  
  249.  }  
  250. }  

 

此外还需修改中断文件夹中的两个函数

[cpp] view plaincopy
 
  1. void EXTIX_Init(void)  
  2. {  
  3.     RCC->APB2ENR|=1<<2;     //使能PORTA时钟  
  4.     JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD     
  5.   
  6.     GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入        
  7.     GPIOA->CRL|=0X00000008;     
  8.     GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入        
  9.     GPIOA->CRH|=0X80800000;                   
  10.     GPIOA->ODR|=1<<13;    //PA13上拉,PA0默认下拉  
  11.     GPIOA->ODR|=1<<15;    //PA15上拉  
  12.   
  13.     Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发  
  14.     //Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发  
  15.     Ex_NVIC_Config(GPIO_A,15,FTIR|RTIR);//下降、上升沿触发  
  16.   
  17.     MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);    //抢占2,子优先级2,组2  
  18.     MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2      
  19. }  
  20.   
  21. //外部中断15~10服务程序  
  22. void EXTI15_10_IRQHandler(void)  
  23. {             
  24.       
  25.     static u8 data;   // 声明局部静态变量来保存扫描码  
  26.   if (!PAin(15))                // 如果是下降沿触发中断  
  27.   {  
  28.   if(bitcount < 11 && bitcount > 2)    //3到10位是数据,起始位,校验位和停止位忽略  
  29.   {   
  30.     data = (data >> 1);                  //右移保存数据  
  31.     if(PAin(13)&0x01)  
  32.     {  
  33.       data|=0x80;                      //存储一个'1'  
  34.     }  
  35.   }  
  36.  }   
  37.  else                    //如果是上升沿触发中断  
  38.  {   
  39.   if(--bitcount==0)      //如果11位全部接收完毕  
  40.   {  
  41.    Decode(data);     //将扫描码翻译成ASCII码     
  42.    bitcount = 11;        //重新设为11位数据  
  43.   }  
  44.  }  
  45. //  delay_ms(10);    //消抖              
  46. //  if(KEY0==0)      //按键0  
  47. //  {  
  48. //      LED0=!LED0;  
  49. //  }else if(KEY1==0)//按键1  
  50. //  {  
  51. //      LED1=!LED1;  
  52. //  }  
  53. //  EXTI->PR=1<<13;     //清除LINE13上的中断标志位    
  54.     EXTI->PR=1<<15;     //清除LINE15上的中断标志位    
  55.   
  56. }  

关键字:stm32  ps2键盘  显示测试 引用地址:stm32_ps2键盘显示测试程序

上一篇:STM32GPIO——快速IO的使用
下一篇:STM32入门笔记(1)——时钟

推荐阅读最新更新时间:2024-03-16 14:43

stm32之ADC应用实例(单通道、多通道、基于DMA)
硬件:STM32F103VCT6 开发工具:Keil uVision4 下载调试工具:ARM仿真器 网上资料很多,这里做一个详细的整合。(也不是很详细,但很通俗)。 所用的芯片内嵌3个12位的模拟/数字转换器(ADC),每个ADC共用多达16个外部通道,2个内部通道。 3个:代表ADC1、ADC2、ADC3(下图是芯片固件库的截图) 12位:也叫ADC分辨率、采样精度。先来看看二进制的12位可表示0-4095个数,也就是说转换器通过采集转换所得到的最大值是4095,如:“111111111111”=4095,那么我们怎么通过转换器转换出来的值得到实际的电压值呢?如果我们要转换的电压范围是0v-3.3v的话,转换器就会把0v
[单片机]
<font color='red'>stm32</font>之ADC应用实例(单通道、多通道、基于DMA)
解答LCR测试仪上显示的D和Q是什么/LP与LS有什么区别
LCR测试仪凭借其功能直接、操作简便的测试方法并得到广泛使用,通常使用LCR测试仪进行准确测试各种元件的参数,具有很稳定的效果,从而在保障着生产性的质量,节省企业开支,得到广泛使用。LCR测试仪当中,经常会显示D和Q,然而许多人不知道什么意思,还有在LCR测试仪的参数当中有LP与LS之分,也不知道其区别在哪里,下面则对这两个问题进行解答。 LCR测试仪上显示的D是损耗值正切角,Q是品质因数。两个量的定义如下: 1、损耗值正切角: 如果对一个电容加上一个电压,除了对电容充电的电流外还有漏掉的电流(电容的漏电流),漏电流被消耗成了热能,因此表示为电阻上的电流。漏电流与纯电容的充电电流之比就是电容损耗角正切值 2、品质因数: 电学和
[测试测量]
基于STM32从零写操作系统系列---bootloader
本章主要使用汇编语言编写STM32F103(以下称为“该芯片”)的启动代码。具体结构如图: 启动模式 该芯片可以通过设置BOOT0和BOOT1两个引脚,选择不同的启动方式,正常情况下BOOT0=0,BOOT1=0(0为低电平)。即,芯片将从Flash中加载代码启动。 当芯片上电/复位后,芯片首先从地址0x0000_0000处获取栈地址,然后将地址0x0000_0004处的值赋值给PC寄存器。按照PC寄存器的值,取第一条指令,执行......具体如图: 地址0x0800_0205处的具体代码如图: 简单来说,地址0x0000_0004处存放的是复位处理函数的地址。当上电/复位时,芯片硬件会自动将
[单片机]
基于<font color='red'>STM32</font>从零写操作系统系列---bootloader
STM32应用-简单的串口接收与发送程序
简介:与上位机的串口通信是一个很常用的程序。碧海蓝天在刚刚接触stm32芯片时写的第一个简单程序就是串口通信,现在把程序代码甩出来与大家分享。完整的程序哦。 库版本 :ST3.0.0 文件:mian.c //功能:串口初始化、打开定时器中断,然后一直接收数据状态就好了。发送在中断中实现 #include stm32f10x.h #include usart.h u8 USART_rx_data; int main(void) { RCC_Configuration(); //系统时钟配置 GPIO_Configuration(); //端口初始化 NVIC_Configuration();
[单片机]
STM32中断配置
STM32的中断配置看起来较为复杂,实际配置时并不复杂,主要有以下4步组成。 1、配置好需要使用作为中断的引脚,以下是将PA1设置成外部中断,当然在此之前需要配置好时钟和GPIO,这两部分请参考上两篇博客。 http://blog.csdn.net/u014449366/article/details/52716900 http://blog.csdn.net/u014449366/article/details/52716900 void NAIC_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphC
[单片机]
STM32低功耗总结
本文主要解读STM32低功耗模式的机制,并不侧重STM32低功耗的程序实现,而且借助STM32固件库实现STM32低功耗会变的非常简单。 一、STM32芯片性能 使用芯片型号:stm32,CORTEX -M0.封装TSSOP20. 运行模式:内部时钟(HSI),系统时钟频率采用48MHZ。 工作电压:3.3V 芯片具体参数如下: 二、芯片功耗 功耗: 芯片工作模式: 工作模式:外设正常运行,内核CPU及SRAM供电,未使用外设的时钟默认关闭。 睡眠模式:只有CPU停止工作,各个外设正常工作,依靠任何中断/事件唤醒。 停机模式:1.8V供电区域时钟被停止,内部HSI,PLL,外部时钟HSE均关闭,同时电压检测
[单片机]
<font color='red'>STM32</font>低功耗总结
STM32】3-外部中断实验(EXTI)步骤及解析
一、外部中断介绍 1.1 EXTI 简介 STM32F10x外部中断/事件控制器(EXTI)包含多达 20 个用于产生事件/中断请求的边沿检测器。EXTI的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独立地被屏蔽。 1.2 EXTI 结构框图 1.3 外部中断/事件线映射 STM32F10x的EXTI具有20个中断/事件线,如下: 二、外部中断配置步骤 要使用外部中断我们就需要先配置它,通常都需经过这几步:(EXTI相关库函数在stm32f10x_exti.c和stm32f10x_exti.h文件中) (1)使能IO口时钟,配置IO口模式为输入 (2)
[单片机]
【<font color='red'>STM32</font>】3-外部中断实验(EXTI)步骤及解析
基于STM32的平衡小车设计过程分享(3)
一、简介 续上文,电机驱动、MPU6050驱动均已完成,接下来我们给他加上PID让它站起来 二、PID控制 我们将小车PID控制函数放到MPU6050中断函数中,每当MPU6050有数据输出时,引脚INT有相应的电平输出。依次来触发外部中断作为控制周期。保持MPU6050数据的实时性。 2.1直立环控制 通过传入的KP、KD参数,让平衡车的pitch轴保持在水平位置。 直立环是用于控制机械系统中垂直方向运动的一种控制器。在这些应用中,垂直方向的运动通常是非常稳定的,因此I控制器的积分作用并不是必需的。而PD控制器可以提供足够的控制性能,同时避免了可能出现的积分饱和问题,因此在直立环中通常只使用PD控制器,而不使用I控
[单片机]
基于<font color='red'>STM32</font>的平衡小车设计过程分享(3)
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved