独立按键程序
- 格式:doc
- 大小:21.50 KB
- 文档页数:4
51单片机:键盘控制程序2009-11-14 16:12键盘控制1.功能说明:用八位指拨开关(DIP)作单片机的输入,控制输出端口连接的八只LED发光二极管。
如若DIP1开关为 ON(向右拨动)则LED1亮,其它开关作用同。
程序:LOOP: MOV A, P3 ; 从P3读入DIP开关值MOV P1, A ; 从P1输出03: JMP LOOP ; 无穷循环04: END ;程序结束2.功能说明:用DIP开关中的低4位作二进制的输入,控制输出端数码管显示器的输出。
程序:01: MOV DPTR,#TABLE ; 存表02: MOV P0, #0FFH ; LED全灭03: LOOP: MOV A, P3 ; 从P3口读入DIP开关值04: ANL A, #0FH ; 高4位清0,取低四位05: ACALL CHANG ; 转成七段显示码06: MOV P0, A ; 从P0输出07: JMP LOOP ; 转移LOOP处,循环08: CHANG: MOVC A,@A+DPTR ; 取码09: RET ; 返回转换显示码子程序10: TABLE: DB 0C0H, 0F9H, 0A4H, 0B0H ;11: DB 99H, 92H, 82H, 0F8H ;12: DB 80H, 90H, 88H, 83H ;13: DB 0C6H, 0A1H, 86H, 8EH ; 显示码表14: END ;程序结束3.功能说明:用两个按键开关K1和K2作输入,K1为电源指示灯开关,K2为工作指示灯开关。
分别控制电源指示灯(P1.0接的LED)和工作指示灯(P1.7接的LED)的接通和关闭。
接通电源时,电源指示灯是在亮的状态。
当按K2时,工作指示灯亮,电源指示灯灭。
按K1时,电源指示灯亮,工作指示灯灭。
程序:01: START: MOV P1, #11111110B ; P1.0所接LED亮02: JB P2.5 , $ ; 判断P2.5(K2键)是否为103: ON: MOV P1, #01111111B ; P1.7所接LED亮04: JNB P2.4, START ; 判断P2.4(K1键)是是否为005: JMP ON ; 未按K1键,则跳至ON06: END ;程序结束4.功能说明:由四个按键开关组成独立式键盘,控制灯左移、右移和闪烁。
主题:单片机独立按键控制LED灯实验原理目录1. 概述2. 单片机独立按键控制LED灯实验原理3. 实验步骤4. 结语1. 概述单片机在现代电子设备中起着至关重要的作用,它可以通过编程实现各种功能。
其中,控制LED灯是单片机实验中常见的任务之一。
本文将介绍单片机独立按键控制LED灯的实验原理及实验步骤,希望对初学者有所帮助。
2. 单片机独立按键控制LED灯实验原理单片机独立按键控制LED灯的实验原理主要涉及到单片机的输入输出端口及按键和LED的连接方式。
在单片机实验中,按键与单片机的输入端口相连,LED与单片机的输出端口相连。
通过按键的按下和松开来改变单片机输出端口电平,从而控制LED的亮灭。
3. 实验步骤为了完成单片机独立按键控制LED灯的实验,需要按照以下步骤进行操作:步骤一:准备材料- 单片机板- 按键- LED灯- 连线- 电源步骤二:搭建电路- 将按键与单片机的输入端口相连- 将LED与单片机的输出端口相连- 连接电源步骤三:编写程序- 使用相应的单片机开发软件编写程序- 程序中需要包括按键状态检测和LED控制的部分步骤四:烧录程序- 将编写好的程序烧录到单片机中步骤五:运行实验- 按下按键,观察LED的亮灭情况- 确保按键可以正确控制LED的亮灭4. 结语通过上述实验步骤,我们可以实现单片机独立按键控制LED灯的功能。
这个实验不仅可以帮助学习者了解单片机的输入输出端口控制,还可以培养动手能力和程序设计能力。
希望本文对单片机实验初学者有所帮助,谢谢阅读!实验步骤在进行单片机独立按键控制LED灯实验时,需要按照一定的步骤进行操作,以确保实验能够顺利进行并取得预期的效果。
下面将详细介绍实验步骤,帮助读者更好地理解和掌握这一实验过程。
1. 准备材料在进行单片机独立按键控制LED灯实验前,首先需要准备相应的材料。
这些材料包括单片机板、按键、LED灯、连线和电源。
在选择单片机板时,需要根据具体的实验需求来确定,常见的有51单片机、Arduino等,不同的单片机板具有不同的特性和使用方法,因此需要根据实验要求来选择适合的单片机板。
基于状态转移的独立按键程序设计本章所描述的按键程序要达到的目的:检测按键按下,短按,长按,释放。
即通过按键的返回值我们可以获取到如下的信息:按键按下(短按),按键长按,按键连发,按键释放。
不知道大家还记得小时候玩过的电子钟没有,就是外形类似于CALL 机(CALL )的那种,有一个小液晶屏,还有四个按键,功能是时钟,闹钟以及秒表。
在调整时间的时候,短按+键每次调整值加一,长按的时候调整值连续增加。
譬如,用一个智能充电器给你的手机电池充电,刚开始,它是处于快速充电状态,随着电量的增加,电压的升高,当达到规定的电压时候,它会转换到恒压充电。
总而言之,细心观察,你会发现生活中的总总都可以归结为一个个的状态,而状态的变换或者转移总是由某些条件引起同时伴随着一些动作的发生。
我们的按键亦遵循同样的规律,下面让我们来简单的描绘一下它的状态流程转移图。
下面对上面的流程图进行简要的分析。
首先按键程序进入初始状态S1,在这个状态下,检测按键是否按下,如果有按下,则进入按键消抖状态2,在下一次执行按键程序时候,直接由按键消抖状态进入按键按下状态3,在此状态下检测按键是否按下,如果没有按键按下,则返回初始状态S1,如果有则可以返回键值,同时进入长按状态S4,在长按状态下每次进入按键程序时候对按键时间计数,当计数值超过设定阈值时候,则表明长按事件发生,同时进入按键连发状态S5。
如果按键键值为空键,则返回按键释放状态S6,否则继续停留在本状态。
在按键连发状态下,如果按键键值为空键则返回按键释放状态S6,如果按键时间计数超过连发阈值,则返回连发按键值,清零时间计数后继续停留在本状态。
看了这么多,也许你已经有一个模糊的概念了,下面让我们趁热打铁,一起来动手编写按键驱动程序吧。
下面是我使用的硬件的连接图。
硬件连接很简单,四个独立按键分别接在P3^0------P3^3四个I/O上面。
因为51单片机I/O口内部结构的限制,在读取外部引脚状态的时候,需要向端口写1.在51单片机复位后,不需要进行此操作也可以进行读取外部引脚的操作。
1. LED程序:#include "reg52.h"void delay(void);void main(){ unsigned char i;while(1){for(i=0;i<8;i++){ P0 = ~(1<<i);P2 |= 0xE0;P2 &= 0x9F;delay();}}}//软件延时程序void delay(void){unsigned char i,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}3.1 1602程序:#include "reg52.h"#include "intrins.h"unsigned char text1[] = "LCD 1602 TEST" ; unsigned char text2[] = "" ;sbit RS = P2^0;sbit RW = P2^1;sbit EN = P1^2;void delay_ms(unsigned char t);void init_1602(void);void write_command(unsigned char cmd); void write_data(unsigned char dat);void dsp_onechar(unsigned char pos,unsigned char c);void dsp_string(unsigned char line,unsigned char *p,unsigned char length);void main(void){init_1602();delay_ms(15);dsp_string(0,text1,13);dsp_string(1,text2,12); 2.1 独立按键程序:#include "reg52.h"void main(void){while(1){switch(P3){case 0xFE: //S1{P0 = 0xFC;P2 |= 0xE0;P2 &= 0x9F;break;}case 0xFD: //S2{P0 = 0xF3;P2 |= 0xE0;P2 &= 0x9F;break;}case 0xFB: //S3{P0 = 0xCF;P2 |= 0xE0;P2 &= 0x9F;break;}case 0xF7: //S4{P0 = 0x3F;P2 |= 0xE0;P2 &= 0x9F;break;}}}}2.2 键盘矩阵程序:#include "reg52.h"unsigned char dspflag;unsigned char keyflag;unsigned char tflag;unsigned char code dsp_code_ca[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80 ,0x90};unsigned char keyscan(void);void display(unsigned char d);void main(){unsigned char temp;while(1);}void delay_ms(unsigned char t){unsigned char i;while(t--){for(i=0;i<112;i++);}}void write_command(unsigned char cmd) {delay_ms(5); // check busy flagEN = 0;RS = 0;RW = 0;_nop_();EN = 1;P0 = cmd;EN = 0;}void write_data(unsigned char dat){delay_ms(5); //busy flag checkEN = 0;RS = 1;RW = 0;_nop_();EN = 1;P0 = dat;EN = 0;RS = 0;}void dsp_onechar(unsigned char pos,unsigned char c){unsigned char p;if (pos>=0x10)p=pos+0xb0;elsep=pos+0x80;write_command(p);write_data(c);}void dsp_string(unsigned char line,unsigned char *p,unsigned char length){unsigned char l,i;l=line<<4;for (i=0;i<length;i++)dsp_onechar(l++,*(p+i));TMOD = 0x02;TH0 = 0x06;TL0 = 0x06;EA = 1;ET0 = 1;TR0 = 1;while(1){if(keyflag){temp = keyscan();keyflag = 0;}display(temp);}}//定时器0中断服务函数void isr_t0(void) interrupt 1{tflag++;if(tflag == 16) // 4ms{dspflag++;if(dspflag == 2)dspflag = 0;}if(tflag == 20) //10ms{tflag = 0;keyflag = 1;}}// 4×4键盘矩阵扫描函数unsigned char keyscan(void){unsigned char keyvalue;P3 = 0x7F; //S4 S5 S6 S7 switch(P3){case 0x7E: keyvalue = 0;break;case 0x7D: keyvalue = 4;break;case 0x7B: keyvalue = 8;break;case 0x77: keyvalue = 12;break;default: break;}P3 = 0xBF; //S8 S9 S10 S11 switch(P3){case 0xBE: keyvalue = 1;break;case 0xBD: keyvalue = 5;break;case 0xBB: keyvalue = 9;break;case 0xB7: keyvalue = 13;break;default: break;}}void init_1602(void){delay_ms(15);write_command(0x38);write_command(0x38);write_command(0x38);write_command(0x06);write_command(0x0c);write_command(0x01);}3.2 数码管程序;#include "reg52.h"unsigned char code dsp_code_ca[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0 x80,0x90};unsigned int tflag;unsigned char dspflag;unsigned char second;unsigned char dflag;void display(unsigned char d);void main(){TMOD |= 0x02;TH0 = 0x06;TL0 = 0x06;EA = 1;ET0 = 1;TR0 = 1;while(1){display(second);}}//T0中断服务函数void isr_t0(void) interrupt 1{tflag++;dflag++;if(dflag == 16){dflag = 0;dspflag++;if(dspflag == 2)dspflag = 0;}if(tflag == 4000){tflag = 0;second++;P3 = 0xDF; //S12 S13 S14 S15 switch(P3){case 0xDE: keyvalue = 2;break;case 0xDD: keyvalue = 6;break;case 0xDB: keyvalue = 10;break;case 0xD7: keyvalue = 14;break;default: break;}P3 = 0xEF; //S16 S17 S18 S19 switch(P3){case 0xEE: keyvalue = 3;break;case 0xED: keyvalue = 7;break;case 0xEB: keyvalue = 11;break;case 0xE7: keyvalue = 15;break;default: break;}return keyvalue;}//数码管显示函数,显示两位void display(unsigned char d){if((dspflag == 0) && (d/10 != 0)) {P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d/10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x40;P2 |= 0xC0;P2 &= 0x3F;}if(dspflag == 1){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x80;P2 |= 0xC0;P2 &= 0x3F;}}if(second == 60)second = 0;}}//显示程序void display(unsigned char d){if((dspflag == 0) && (d/10 != 0)){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d/10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x40;P2 |= 0xC0;P2 &= 0x3F;}if(dspflag == 1){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x80;P2 |= 0xC0;P2 &= 0x3F;}}5. common程序:#include "reg52.h"sbit buzzer = P0^6;sbit relay = P0^4;void main(void){//关闭蜂鸣器buzzer = 0; //高有效P2 = 0xA0;P2 = 0x00;//关闭继电器relay = 0; //高有效P2 = 0xA0;P2 = 0x00; 4. UART(串行数据总线)程序;#include "at89x52.h"unsigned char txbuffer1[] = "STC89C52RC UART TEST PROGRAM";unsigned char txbuffer2[] = "============================"; unsigned char enter[] = {0x0A,0x0D};void uart_tx(unsigned char *p,unsigned char length);void main(){SCON = 0x50;TMOD = 0x20;TH1 = 0xF3;TL1 = 0xF3;TR1 = 1;uart_tx(txbuffer2,28);uart_tx(enter,2); //Enteruart_tx(txbuffer1,28);uart_tx(enter,2); //Enteruart_tx(txbuffer2,28);uart_tx(enter,2); //Enterwhile(1);}void uart_tx(unsigned char *p,unsigned char length){unsigned char i;for(i=0;i<length;i++){SBUF = *(p+i);while(TI == 0);TI = 0;}}6.1 DS18b20(温度传感器)主程序:#include "reg52.h"#include "ds18b20.h"unsigned int tflag;bit secflag = 0;unsigned char text[] = "Temperature = "; unsigned char enter[] = {0x0A,0x0D}; //回车符//关闭数码管显示P0 = 0x00; //位选置低P2 = 0xC0;P2 = 0x00;//关闭发光二极管显示P0 = 0xFF; //低有效P2 = 0x80;P2 = 0x00;while(1);}8. 1 AT24C02(2K位串行CMOS E2PROM)主程序:#include "reg52.h"#include "24c02.h"unsigned char dspflag;unsigned char cnt;unsigned char tflag;unsigned char code dsp_code_ca[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0 x80,0x90};void display(unsigned char d);void init_t0(void);void main(){//wrbyte_24c02(0x00,0x00);cnt = rdbyte_24c02(0x00);wrbyte_24c02(0x00,cnt+1);init_t0();while(1){display(cnt);}}void isr_t0(void) interrupt 1{tflag++;if(tflag == 16){tflag = 0;dspflag ++;if(dspflag == 3)dspflag = 0;}} void uart_tx(unsigned char *p,unsigned char length);char dat(char a);void main(void){unsigned char temp;SCON = 0x50;TMOD = 0x22;TH1 = 0xF3;TL1 = 0xF3;TH0 = 0x06;TL0 = 0x06;EA = 1;ET0 = 1;TR0 = 1;TR1 = 1;while(1){if(secflag == 1){secflag = 0;uart_tx(text,14);temp = rd_temperature();if(temp>99){SBUF = temp/100 + 0x30;while(TI == 0);TI = 0;}if(temp>9){SBUF = temp%100/10 + 0x30;while(TI == 0);TI = 0;}SBUF = temp%100%10 + 0x30;while(TI == 0);TI = 0;uart_tx(enter,2);}}}//定时器TO中断服务函数void isr_t0(void) interrupt 1void init_t0(void){TMOD = 0x02;TH0 = 0x06;TL0 = 0x06;ET0 = 1;EA = 1;TR0 = 1;}void display(unsigned char d){if((dspflag == 0)&&(d>99)){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d/100];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x20;P2 |= 0xC0;P2 &= 0x3F;}if((dspflag == 1)&&(d>9)){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%100/10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x40;P2 |= 0xC0;P2 &= 0x3F;}if(dspflag == 2){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%100%10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x80;P2 |= 0xC0;P2 &= 0x3F;}}8. 2 AT24C02(2K位串行CMOS E2PROM)程序:#include "24c02.h" {tflag++;if(tflag == 4000){tflag = 0;secflag = 1;}}//串口传输函数void uart_tx(unsigned char *p,unsigned char length){unsigned char i;for(i=0;i<length;i++){SBUF = *(p+i);while(TI == 0);TI = 0;}}6.2 DS18b20(温度传感器)程序:#include "ds18b20.h"//延时函数void delay(unsigned int t){while(t--);}//DS18B20初始化函数bit init_ds18b20(void){bit initflag = 0;DQ = 1;delay(12);DQ = 0;delay(80); // 延时大于480usDQ = 1;delay(10); // 14initflag = DQ; // initflag等于1初始化失败delay(5);return initflag;}//通过单总线向从器件写一个字节void wr_ds18b20(unsigned char byt){unsigned char i;for(i=0;i<8;i++){DQ = 0;void iic_start(void){SDA = 1;_nop_();SCL = 1;somenop;SDA = 0;somenop;SCL = 0;}void iic_stop(void){SDA = 0;_nop_();SCL = 1;somenop;SDA = 1;}void iic_ack(bit ackbit){if(ackbit)SDA = 0;elseSDA = 1;somenop;SCL = 1;somenop;SCL = 0;SDA = 1;somenop;}bit iic_waitack(void){SDA = 1;somenop;SCL = 1;somenop;if(SDA){SCL = 0;iic_stop();return 0;}else{SCL = 0;return 1;}}void iic_sendbyte(unsigned char byt) {unsigned char i;DQ = byt&0x01;delay(5);DQ = 1;byt >>= 1;}delay(5);}//通过单总线从从器件读一个字节unsigned char rd_ds18b20(void){unsigned char i;unsigned char byt;for(i=0;i<8;i++){DQ = 0;byt >>= 1;DQ = 1;if(DQ){byt |= 0x80;}delay(5);}return byt;}//温度转换、读取及数据处理器函数unsigned char rd_temperature(void) {unsigned char low,high;char temp;init_ds18b20();wr_ds18b20(0xCC);wr_ds18b20(0x44); //启动温度转换delay(200);init_ds18b20();wr_ds18b20(0xCC);wr_ds18b20(0xBE); //读取寄存器low = rd_ds18b20(); //低字节high = rd_ds18b20(); //高字节temp = high<<4;temp |= (low>>4);return temp;}for(i=0;i<8;i++){if(byt&0x80)SDA = 1;elseSDA = 0;somenop;SCL = 1;byt <<= 1;somenop;SCL = 0;}}unsigned char iic_recbyte(void){unsigned char da;unsigned char i;for(i=0;i<8;i++){SCL = 1;somenop;da <<= 1;if(SDA)da |= 0x01;SCL = 0;somenop;}return da;}void wrbyte_24c02(unsigned char add,unsigned char dat){// Device Address 1100 000 R/Wiic_start();iic_sendbyte(0xa0);iic_waitack();iic_sendbyte(add);iic_waitack();iic_sendbyte(dat);iic_waitack();iic_stop();delay(10);}unsigned char rdbyte_24c02(unsigned char add){// Device Address 1100 000 R/W unsigned char da;iic_start();iic_sendbyte(0xa0);iic_waitack();iic_sendbyte(add);iic_waitack();iic_start(); 9.1 ADC主程序:#include "reg52.h"#include "pcf8591.h"void init_t0(void);void init_pcf8591(void);void display(unsigned char d);bit adcflag = 0;unsigned char dspflag;unsigned char tflag1;unsigned char tflag2;unsigned char code dsp_code_ca[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80 ,0x90};void main(void){unsigned char adcvalue;init_pcf8591();init_t0();while(1){display(adcvalue);if(adcflag == 1){adcvalue = adc_pcf8591();adcflag = 0;}}}void isr_t0(void) interrupt 1{tflag1++;tflag2++;if(tflag1 == 16) //4ms{tflag1 = 0;dspflag++;if(dspflag == 3)dspflag = 0;}if(tflag2 == 80) //20ms{tflag2 = 0;adcflag = 1;}}void init_t0(void){TMOD = 0x02;TH0 = 0x06;TL0 = 0x06;iic_sendbyte(0xa1);iic_waitack();da = iic_recbyte();iic_ack(0);iic_stop();return da;}void delay(unsigned char t){unsigned char i;while(t--){for(i=0;i<112;i++);}}10.1 DAC主程序:#include "reg52.h"#include "pcf8591.h"#include "math.h"unsigned char idata table[128];void main(void){unsigned char i = 0;for(i=0;i<128;i++){table[i] = 127*sin(2.0*3.1415/256.0*i*2)+128;}iic_start();iic_sendbyte(0x90);iic_waitack();iic_sendbyte(0x40); //选择DAC功能iic_waitack();while(1){for(i=0;i<128;i++){iic_sendbyte(table[i]); //通过PCF8591输出正弦波iic_waitack();}}}ET0 = 1;EA = 1;TR0 = 1;}void init_pcf8591(void){iic_start();iic_sendbyte(0x90);iic_waitack();iic_sendbyte(CHANNEL_3);iic_waitack();iic_stop();delay(10);}void display(unsigned char d){if((dspflag == 0)&&(d>99)){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d/100];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x20;P2 |= 0xC0;P2 &= 0x3F;}if((dspflag == 1)&&(d>9)){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%100/10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x40;P2 |= 0xC0;P2 &= 0x3F;}if(dspflag == 2){P0 = 0xFF;P2 |= 0xE0;P2 &= 0x1F;P0 = dsp_code_ca[d%100%10];P2 |= 0xE0;P2 &= 0x1F;P0 = 0x80;P2 |= 0xC0;P2 &= 0x3F;}10.2 DAC(pcf8591)程序:#include "pcf8591.h"void iic_start(void){SDA = 1;_nop_();SCL = 1;somenop;SDA = 0;somenop;SCL = 0;}void iic_stop(void){SDA = 0;_nop_();SCL = 1;somenop;SDA = 1;}bit iic_waitack(void){SDA = 1;somenop;SCL = 1;somenop;if(SDA){SCL = 0;iic_stop();return 0;}else{SCL = 0;return 1;}}void iic_sendbyte(unsigned char byt) {unsigned char i;for(i=0;i<8;i++){if(byt&0x80)SDA = 1;elseSDA = 0;somenop;SCL = 1;byt <<= 1;somenop;SCL = 0;}} }9.2 ADC(pcf8591)程序:#include "pcf8591.h"void iic_start(void){SDA = 1;_nop_();SCL = 1;somenop;SDA = 0;somenop;SCL = 0;}void iic_stop(void){SDA = 0;_nop_();SCL = 1;somenop;SDA = 1;}void iic_ack(bit ackbit){if(ackbit)SDA = 0;elseSDA = 1;somenop;SCL = 1;somenop;SCL = 0;SDA = 1;somenop;}bit iic_waitack(void){SDA = 1;somenop;SCL = 1;somenop;if(SDA){SCL = 0;iic_stop();return 0;}else{SCL = 0;return 1;}}void iic_sendbyte(unsigned char byt) {unsigned char i;for(i=0;i<8;i++){if(byt&0x80)SDA = 1;elseSDA = 0;somenop;SCL = 1;byt <<= 1;somenop;SCL = 0;}}unsigned char iic_recbyte(void) {unsigned char da;unsigned char i;for(i=0;i<8;i++){SCL = 1;somenop;da <<= 1;if(SDA)da |= 0x01;SCL = 0;somenop;}return da;}void delay(unsigned char t){unsigned char i;while(t--){for(i=0;i<112;i++);}}unsigned char adc_pcf8591(void) {unsigned char temp;iic_start();iic_sendbyte(0x91);iic_waitack();temp = iic_recbyte();iic_ack(0);iic_stop();return temp; }。
设计报告项目:独立按键的加1计数显示班级:电气121姓名:学号:12322081设计报告四独立按键的加1计数显示1、设计目标(1)认识8051的独立按键功能;(2)能够在C语言的程序里启用独立按键功能;(3)能够编写独立按键加1计数程序。
2、设计要求使用1个独立按键,当主程序正常执行时,P2口连接的数码管循环显示0-9。
3、硬件电路设计硬件电路图:4.软件系统设计(要求:对程序块进行注释)#include<reg52.h>sbit key=P1^3;#define uchar unsigned charuchar m;uchardisplay_data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ;void delay10ms(unsigned int z);void delay10ms(unsigned int z){unsigned int x,y;for(x=2;x>0;x--)for(y=z;y>0;y--);}void main(){m=0;P2=0x00;key=1;while(1){if(key==0){delay10ms(625);if(key==0){P2=display_data[m];m++;if(m==10)m=0;delay10ms(625);while(key==0);//判断按键是否弹起}}}}5、小结(1)认识了8051的独立按键功能;(2)能够在C语言的程序里启用独立按键功能;(3)能够编写独立按键加1计数程序。
实验项目五独立按键电路的设计与仿真[实验目的]1.掌握独立键盘的工作原理2.掌握独立键盘硬件电路的设计方法3.掌握对独立键盘的控制方法[实验原理][实验仪器]PC机一台[Proteus用到器件的关键词]单片机(at89c52)、数码管(7seg-com-cathode)、排阻(respack-7)、按键(button)、蜂鸣器(buzzer active)[实验内容与步骤]1.用Proteus软件设计出独立键盘接口电路原理图。
2.用P2.1口来控制独立键盘ADDKEY,每按一次按键,让数码管显示的数值加1一次,一直加到9,再按一次,数码管重新显示0。
同时,每按一次键,蜂鸣器会发“滴”的声音。
3.在进行按键处理时,要注意按键去抖动的软件处理方法,在按键松开时要进行按键松手检测。
4.用Keil编写程序,完上上面所描述的任务,最后调试程序、编译后生成HEX文件。
5.将HEX文件装载到MCU AT89C52中,单击Start按钮开始动态仿真。
[实验数据记录]ADDKEY BIT P2.1BEEP BIT P2.6ORG 0000HAJMP MAINORG 0050HMAIN: MOV P0,#00HLCALL DELAYMOV DPTR,#0100HLP: JB ADDKEY,$ ;检测到有键按下CLR BEEPLCALL DELAY ;软件延时去抖SETB BEEPJB ADDKEY,$ ;确实有键按下JNB ADDKEY,$ ;松手检测LCALL DISPLAYSJMP LPDISPLAY:MOVC A,@A+DPTRMOV P0,AINC DPTRCLR AMOV R2,DPLCJNE R2,#10,DONE ;数码显示到9,给DPL重新赋值,并清零计数器R2MOV R2,#00HMOV DPL,#00HDONE: RETDELAY: MOV R0,#64H ;延时100msDL1: MOV R1,#0C8HDL2: NOPNOPNOPDJNZ R1,DL2DJNZ R0,DL1RETORG 0100HTAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;段选代码,对应0123456789 END[实验数据处理][实验结果及讨论]。
实验5 独立键盘和矩阵键盘一、实验目的1、学会用C语言进行独立按键应用程序的设计。
2、学会用C语言进行矩阵按键应用程序的设计。
二、实验内容1、独立按键:对四个独立按键编写程序:当按k1时,8个LED同时100ms闪烁;当按k2时,8个LED从左到右流水灯显示;当按k3时,8个LED从右到左流水灯显示;当按k4时,8各LED同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭;2、矩阵按键:采用键盘扫描方式,顺序按下矩阵键盘后,在一个数码管上顺序显示0~F,采用静态显示即可。
3、提高部分(独立按键、定时器、数码管动态扫描):编写程序,实现下面的功能。
用数码管的两位显示一个十进制数,变化范围为00~59,开始时显示00,每按一次k1,数值加1;每按一次k2,数值减1;每按一次k3,数值归零;按下k4,利用定时器功能使数值开始自动每秒加1;再按一次k4,数值停止自动加1,保持显示原数。
三、实验步骤1、硬件连接(1)使用MicroUSB数据线,将实验开发板与微型计算机连接起来;(2)在实验开发板上,用数据线将相应接口连接起来;2、程序烧入软件的使用使用普中ISP软件将HEX文件下载至单片机芯片内。
查看结果是否正确。
四、实验结果——源代码1. #include "reg52.h"typedef unsigned char u8;typedef unsigned int u16;#define LED P2sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;const char tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; u8 code begMid[]={0x7e, 0xbd,0xdb,0xe7, 0xdb, 0xbd, 0x7e}; void Delay(u16 i){ while(i--);}void KeyDown(){u8 i;if(key2==0){Delay(1000);if(key2==0){for(i=0;i<8;i++){LED=tab[i];Delay(50000);}while(!key2);}LED=0xff;}else if(key1==0){Delay(1000);if(key1==0)for(i=0;i<3;i++){LED=0x00;Delay(10000);LED=0xff;Delay(10000);}}}}void Int0Init(){IT0=1;EX0=1;EA=1;}void Int1Init(){IT1=1;EX1=1;EA=1;} void main(){Int0Init();Int1Init();while(1){KeyDown();}}void Int0() interrupt 0{u8 i;if(key3==0){Delay(1000);if(key3==0)for(i=7;i>=0;i--){LED=tab[i];Delay(50000);}}}}void Int1() interrupt 2{u8 i;if(key4==0){Delay(1000);if(key4==0){for(i=0;i<=6;i++){LED=begMid[i];Delay(50000);}}}}2.#include "reg52.h"typedef unsigned int u16;typedef unsigned char u8;#define GPIO_DIG P0#define GPIO_KEY P1sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;u8 KeyValue;u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//??0~F?? void delay(u16 i){while(i--);}void KeyDown(void){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f){delay(1000);if(GPIO_KEY!=0x0f){GPIO_KEY=0X0F;switch(GPIO_KEY){case(0X07): KeyValue=0;break;case(0X0b): KeyValue=1;break;case(0X0d): KeyValue=2;break;case(0X0e): KeyValue=3;break;}GPIO_KEY=0XF0;switch(GPIO_KEY){case(0X70): KeyValue=KeyValue;break;case(0Xb0): KeyValue=KeyValue+4;break;case(0Xd0): KeyValue=KeyValue+8;break;case(0Xe0): KeyValue=KeyValue+12;break;}while((a<50)&&(GPIO_KEY!=0xf0)){delay(1000);a++;}}}}void main(){LSA=0;LSB=0;LSC=0;while(1){KeyDown();GPIO_DIG=smgduan[KeyValue];}}3.#include <reg52.h>typedef unsigned int u16;typedef unsigned char u8;#define KEYPORT P3sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;u16 t;u8 sec;u8 DisplayData[2];u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void Time1Init(){TMOD |= 0x10;TH1=0Xd8;TL1=0Xf0;EA=1;ET1=1;}void delay(u16 i){while(i--); }void DigDisplay(){u8 i;for(i=0;i<2;i++){switch(i){case 0:LSA=0;LSB=0;LSC=0;break;case 1:LSA=1;LSB=0;LSC=0;break;}P0=DisplayData[i];delay(100);P0=0x00;}}void datapros(){DisplayData[0]=smgduan[sec%10];DisplayData[1]=smgduan[sec/10];}void main(){Time1Init();while(1){if(key4==0){delay(1000);if(key4==0){TR1=!TR1;while(key4==0);}}if(key3==0){delay(1000);if(key3==0){sec=0;while(key3==0);}}if(key2==0){delay(1000);if(key2==0){sec--;while(key2==0);}}if(key1==0){delay(1000);if(key1==0){sec++;while(key1==0);}}}}void Time1() interrupt 2{TH1=0Xd8;TL1=0Xf0;t++;if(t==100){t=0;sec++;if(sec>=60){sec=0;}}datapros();DigDisplay();}五、实验体会——结果分析1、独立按键:位定义四个按键key1、key2、key3、key4,宏定义LED为P2口,tab数组保存流水灯D0-D7依次点亮的数值,begMid数组保存流水灯同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭的赋值方式。
/********************************************************************
* 文件名:独立按键.c
* 描述: 该程序实现独立按键的判断,按了相应的独立按键后,
会在数码管上显示最先被按下的值,只有按复位按键或者重新开电才消失。
* 创建人:2013年2月7日
* 版本号:1.0
* 杜邦线接法:
独立按键接法:
P3.2接J8的1端。
P3.3接J8的2端。
P3.4接J8的3端。
P3.5接J8的4端。
用8针排线把P0口和J12的1-8连接(P0.0接J12的1端)。
P2.0对应J13的8端。
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^2;
sbit KEY2 = P3^3;
sbit KEY3 = P3^4;
sbit KEY4 = P3^5;
//数码管的段码编码
uchar table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/********************************************************************
* 名称: Delay_1ms()
* 功能: 延时子程序,延时时间为1ms * x
* 输入: x (延时一毫秒的个数)
* 输出: 无
***********************************************************************/
void Delay_1ms(uint i)
{
uint x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/********************************************************************
* 名称: Delay()
* 功能: 实现按键功能,并在LED上显示
* 输入: 无
* 输出: 无
***********************************************************************/ uchar KEY(void)
{
if(KEY1==0 || KEY2==0 || KEY3==0 || KEY4==0)
{
Delay_1ms(20); //20毫秒软件防抖
if(KEY1 == 0)
{
while(1)
{
if(KEY1 == 1)
{
Delay_1ms(20);;
if(KEY1 == 1)
{
break;
}
}
}
return 1;
}
else if(KEY2 == 0)
{
while(1)
{
if(KEY2 == 1)
{
Delay_1ms(20);
if(KEY2 == 1)
{
break;
}
}
}
return 2;
}
else if(KEY3 == 0)
{
while(1)
{
if(KEY3 == 1)
{
Delay_1ms(20);
if(KEY3 == 1)
{
break;
}
}
}
return 3;
}
else if(KEY4 == 0)
{
while(1)
{
if(KEY4 == 1)
{
Delay_1ms(20);
if(KEY4 == 1)
{
break;
}
}
}
return 4;
}
}
return 0;
}
/********************************************************************
* 名称: Main()
* 功能: 实现按键控制LED的显示
* 输入: 无
* 输出: 无
***********************************************************************/ void Main(void)
{
uchar temp;
while(1)
{
temp = KEY(); //判断是否有按键按下
if(temp != 0)
{
break; //如果按下,那么退出循环}
}
P0 = table[temp]; //显示是哪个按键按下了P2 = 0xfe;
while(1); //程序停止
}。