打印

刚写的AD键盘程序,欢迎拍砖!!

[复制链接]
1456|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dyd0311|  楼主 | 2013-12-13 17:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
空余时间学写程序有一段时间了,一直卡在AD这个地方不能动!为自己定了题目是写一个AD的键盘,搞了好久都没出来,真心不好意思上论坛向各位讨要现成的程序,就到处找资料,今天终于完成自己的心中所想,特请各位前辈拍拍砖……

附图中是简单的流程图!

单片机用的是STC的12C5A60S2,源程序如下:

C51 COMPILER V9.00   DYD_4                                                                 12/13/2013 16:44:22 PAGE 1   

   1          /*ad按键扫描程序
   2          功能:按下哪个键,就发送键值与键号到上位机
   3                    并点亮P2口对应的LED灯*/
   4          #include<reg52.h>
   5          sfr P1ASF     =0X9D;
   6          sfr ADC_CONTR =0XBC;
   7          sfr ADC_RES   =0XBD;
   8          sfr AUXR1     =0XA2;//AD寄存器定义
   9         
  10          sfr BRT       =0X9C;
  11          sfr AUXR      =0X8E;//串口寄存器定义
  12         
  13          #define uint unsigned int
  14          #define uchar unsigned char
  15          uint n,a;
  16          uint ADC_DATA;
  17         
  18          void get_key();
  19          void port_init();
  20          void adc_init();
  21          uint adc_res();
  22          void uart_init();
  23          void uart_put(uint d);
  24          void time0_init();
  25          void delay_1ms(uint z);
  26         
  27          void main()
  28          {
  29   1              port_init();
  30   1              adc_init();
  31   1              uart_init();
  32   1              time0_init();
  33   1              TR0=1;//启动定时器T0
  34   1              while(1)
  35   1              {
  36   2                      if(a==1)//判断10ms定时时间是否到来
  37   2                      {
  38   3                              a=0;//将a清0
  39   3                              ADC_DATA=adc_res();//取AD转换的结果
  40   3                              if(ADC_DATA>4)//判断是否有键按下
  41   3                              {
  42   4                                      delay_1ms(8);//等待5ms
  43   4                                      ADC_DATA=adc_res();//再次获取AD值,以消抖
  44   4                                      if(ADC_DATA>4)//判断AD键值
  45   4                                      {
  46   5                                              get_key();//AD键值判断函数
  47   5                                      }
  48   4                                      delay_1ms(150);//等待松手
  49   4                              }
  50   3                      }
  51   2              }
  52   1      
  53   1      }
  54         
  55          void port_init()
C51 COMPILER V9.00   DYD_4                                                                 12/13/2013 16:44:22 PAGE 2   

  56          {
  57   1              n=0;
  58   1              a=0;
  59   1              ADC_DATA=0;
  60   1              EA=1;//开总中断
  61   1              ES=1;//开串口中断
  62   1              ET0=1;//开定时器T0中断  
  63   1      }
  64         
  65          void adc_init()//AD初始化程序
  66          {
  67   1              P1ASF=0X01;//设置P1.0口作为AD口使用
  68   1              ADC_RES=0;//AD寄存器清0
  69   1              ADC_CONTR=0XA0;//打开AD电源,设置转换速度为360,清ADC_FLAG为0
  70   1                                              //通道设置为P1.0口,暂不启动AD
  71   1              delay_1ms(10);
  72   1      }
  73          uint adc_res()  //启动AD转换,将结果返回
  74          {
  75   1              ADC_CONTR=0XA8;//启动AD
  76   1              while((ADC_CONTR&0XF0)!=0XB0);
  77   1              ADC_CONTR=0XA0;//清ADC_FLAG标志
  78   1              ADC_RES=ADC_RES&0XFC;
  79   1              return ADC_RES;//返回AD值的高8位
  80   1      
  81   1      }
  82         
  83          void uart_init()//串口1初始化程序
  84          {
  85   1              
  86   1              SCON=0X40;//工作方式为1
  87   1              AUXR=0X95;//设置T0的速度不分频,启动BRTR,让BRT作为波特率发生器
  88   1              BRT=0XFD;//波特率设置为115200
  89   1      }
  90          void uart_put(uint d)//发送所获取的按键值
  91          {
  92   1              ES=0;
  93   1              SBUF=d;
  94   1              while(!TI);
  95   1              TI=0;
  96   1              ES=1;
  97   1      }
  98         
  99         
100          void time0_init()//定时器0初始化程序
101          {
102   1              TMOD=0X0A;//设置定时器T0为8位自动重装模式
103   1              TH0=0x26;
104   1              TL0=0x26;//设置定时器定时时间为60(18.08)us
105   1      }
106          void time0() interrupt 1
107          {
108   1              TF0=0;//清定时器中断标志位
109   1              n++;
110   1              if(n==168)
111   1              {
112   2                      n=0;
113   2                      a=1;//每59.68*167us=10ms产生一个标示位
114   2              }
115   1      }
116         
117          void delay_1ms(uint z)//1ms延时
C51 COMPILER V9.00   DYD_4                                                                 12/13/2013 16:44:22 PAGE 3   

118          {
119   1              uint x,y;
120   1              for(x=0;x<z;x++)
121   1                      for(y=0;y<875;y++);     
122   1      }
123         
124          void get_key()
125          {
126   1              
127   1              if((ADC_DATA>0X23)&&(ADC_DATA<0X27))
128   1                      {
129   2                              uart_put('1')   ;
130   2                              uart_put(ADC_DATA)      ;
131   2                              P2=0XFE;
132   2                      }
133   1              else if((ADC_DATA>0X42)&&(ADC_DATA<0X50))
134   1                      {
135   2                              uart_put('2')   ;
136   2                              uart_put(ADC_DATA)      ;
137   2                              P2=0XFD;        
138   2                      }
139   1              else if((ADC_DATA>0X58)&&(ADC_DATA<0X66))
140   1                      {
141   2                              uart_put('3')   ;
142   2                              uart_put(ADC_DATA)      ;
143   2                              P2=0XFB;        
144   2                      }
145   1              else if((ADC_DATA>0X78)&&(ADC_DATA<0X82))
146   1                      {
147   2                              uart_put('4')   ;
148   2                              uart_put(ADC_DATA)      ;
149   2                              P2=0XF7;        
150   2                      }
151   1              else if((ADC_DATA>0X98)&&(ADC_DATA<0X9C))
152   1                      {
153   2                              uart_put('5')   ;
154   2                              uart_put(ADC_DATA)      ;
155   2                              P2=0XEF;        
156   2                      }
157   1              else if((ADC_DATA>0XAE)&&(ADC_DATA<0XB2))
158   1                      {
159   2                              uart_put('6')   ;
160   2                              uart_put(ADC_DATA)      ;
161   2                              P2=0XDF;        
162   2                      }
163   1              else if((ADC_DATA>0XCD)&&(ADC_DATA<0XD2))
164   1                      {
165   2                              uart_put('7')   ;
166   2                              uart_put(ADC_DATA)      ;
167   2                              P2=0XBF;        
168   2                      }
169   1              else if(ADC_DATA>0XD5)
170   1                      {
171   2                              uart_put('8')   ;
172   2                              uart_put(ADC_DATA)      ;
173   2                              P2=0;   
174   2                      }
175   1                              
176   1      }
177         


C51 COMPILER V9.00   DYD_4                                                                 12/13/2013 16:44:22 PAGE 4   


简单流程图.jpg (22.85 KB )

简单流程图.jpg

相关帖子

沙发
cjseng| | 2013-12-13 21:47 | 只看该作者
很好,不过就是程序堵死了,CPU使用率100%。

使用特权

评论回复
板凳
ZG11211| | 2013-12-13 22:00 | 只看该作者
定时启动AD转换并将结果累计达到N次再执行,不会太难的。

使用特权

评论回复
地板
ayb_ice| | 2013-12-14 10:49 | 只看该作者
看过很多电视的本机按键(AD扫键),没有一个是管用的,按音量+它换频道。。。

使用特权

评论回复
5
dyd0311|  楼主 | 2013-12-17 08:18 | 只看该作者
cjseng 发表于 2013-12-13 21:47
很好,不过就是程序堵死了,CPU使用率100%。

:lol
那个倒还真没关注,只知道在我的机子上确实正常运行起来了,也没卡机!!

使用特权

评论回复
6
dyd0311|  楼主 | 2013-12-17 08:19 | 只看该作者
ayb_ice 发表于 2013-12-14 10:49
看过很多电视的本机按键(AD扫键),没有一个是管用的,按音量+它换频道。。。 ...

按键多的时候,处理不好,貌似是很容易出现串键的,这个也是我下阶段想去尝试的!

使用特权

评论回复
7
dyd0311|  楼主 | 2013-12-17 08:21 | 只看该作者
ZG11211 发表于 2013-12-13 22:00
定时启动AD转换并将结果累计达到N次再执行,不会太难的。

对!先前只是一直想不出好的流程,再加上又是新手,一直弄不出来!你说的这个值得尝试……

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

125

帖子

0

粉丝