空余时间学写程序有一段时间了,一直卡在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
|