单片机按键加减报告
- 格式:docx
- 大小:248.09 KB
- 文档页数:9
实验五矩阵键盘实验一、实验内容1、编写程序,做到在键盘上每按一个数字键(0-F)用发光二极管将该代码显示出来。
按其它键退出。
2、加法设计计算器,实验板上有12个按键,编写程序,实现一位整数加法运算功能。
可定义“A”键为“+”键,“B”键为“=”键。
二、实验目的1、学习独立式按键的查询识别方法。
2、非编码矩阵键盘的行反转法识别方法。
三、实验说明1、MCS51系列单片机的P0~P3口作为输入端口使用时必须先向端口写入“1”。
2、用查询方式检测按键时,要加入延时(通常采用软件延时10~20mS)以消除抖动。
3、识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
行反转法识别闭合键时,要将行线接一并行口,先让它工作在输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口在各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上输入值,那么,在闭合键所在行线上的值必定为0。
这样,当一个键被接下时,必定可以读得一对唯一的行线值和列线值。
由于51单片机的并口能够动态地改变输入输出方式,因此,矩阵键盘采用行反转法识别最为简便。
行反转法识别按键的过程是:首先,将4个行线作为输出,将其全部置0,4个列线作为输入,将其全部置1,也就是向P1口写入0xF0;假如此时没有人按键,从P1口读出的值应仍为0xF0;假如此时1、4、7、0四个键中有一个键被按下,则P1.6被拉低,从P1口读出的值为0xB0;为了确定是这四个键中哪一个被按下,可将刚才从P1口读出的数的低四位置1后再写入P1口,即将0xBF写入P1口,使P1.6为低,其余均为高,若此时被按下的键是“4”,则P1.1被拉低,从P1口读出的值为0xBE;这样,当只有一个键被按下时,每一个键只有唯一的反转码,事先为12个键的反转码建一个表,通过查表就可知道是哪个键被按下了。
任务:MSP-EXP430G2 板上P1.0 上接了一个LED,而在配套的LaunchPad 扩展板上,将MSP430G2553 的P2.0 和P2.5 引出作为电容触摸按键。
要求按下P2.0 后LED 亮,按下P2.5 后LED 灭,程序运行过程中不阻塞CPU,并且实现低功耗运行。
硬件连接:如图所示程序代码:TouchIN.c:#include "MSP430G2553.h"#define KEY_NUM 2 /*触摸按键数目,根据需要修改*/ //=============具体触摸按键IO宏定义,根据需要添加代码===============#define KEY0_INIT P2DIR &= ~BIT0; P2SEL &= ~ BIT0; P2SEL2 |= BIT0 /*按键1开启振荡*/ #define KEY1_INIT P2DIR &= ~BIT5; P2SEL &= ~ BIT5; P2SEL2 |= BIT5 /*按键2开启振荡*/ #define ALL_OSC_OFF P2SEL2 &= ~(BIT0 + BIT5) /*关闭全部触摸振荡*/ /*门限频率的取值取决于定时扫描的时长,3300对应的是1.9ms定时情况,实际定时可取1ms~20ms*/const unsigned int FREQ_THRESHOLD[KEY_NUM]={3300,3300}; /*参考值,需用仿真器查看后调整*///-----静态局部变量----static unsigned int Freq[KEY_NUM]={0}; //当前测频值static unsigned char Key_Buff[KEY_NUM][4]={0}; // 软件FIFOstatic unsigned char Key_Num=0; //按键编号//-----全局变量,复杂程序中可以移植到Global.h统一管理-----unsigned char TouchIN=0; //相当于PxIN寄存器作用,支持8个触摸按键void Key_Measure_Freq(){Freq[Key_Num]=TAR; //当前编号按键的频率被测得ALL_OSC_OFF; //关闭所有振荡IOKey_Num++; //切换下一振荡IOif (Key_Num>=KEY_NUM) Key_Num=0; //各触摸按键循环交替switch (Key_Num){case 0 : KEY0_INIT; break; //振荡IO初始化case 1 : KEY1_INIT; break;default: break;}TA0CTL = TASSEL_3+MC_2+TACLR; //增计数清0,并开始计数}void Key_FIFO() //存储连续4次测量数据{Key_Buff[Key_Num][0]=Key_Buff[Key_Num][1];Key_Buff[Key_Num][1]=Key_Buff[Key_Num][2];Key_Buff[Key_Num][2]=Key_Buff[Key_Num][3];if( Freq[Key_Num]<FREQ_THRESHOLD[Key_Num]) //判断是否识别为按键Key_Buff[Key_Num][3]=1;elseKey_Buff[Key_Num][3]=0;}void Key_Judge() //按键仲裁,只有连续4次测量结果一致,才算数{if( (Key_Buff[Key_Num][0]==0)&&(Key_Buff[Key_Num][1]==0)&&(Key_Buff[Key_Num][2]==0)&&(Key_Buff[Key_Num][3]==0) )// TouchIN=0<<Key_Num; //按键松开(错误代码)TouchIN &=~(1<<Key_Num); //按键松开(正确代码)if( (Key_Buff[Key_Num][0]==1)&&(Key_Buff[Key_Num][1]==1)&&(Key_Buff[Key_Num][2]==1)&&(Key_Buff[Key_Num][3]==1) )// TouchIN =1<<Key_Num; //按键按下(错误代码)TouchIN |=1<<Key_Num; //按键按下}void TouchIN_Dect() //触摸输入检测{Key_Measure_Freq(); //测频Key_FIFO(); //软件FIFO缓存最近4次测量数据Key_Judge(); //仲裁按键是否按下或松开}TouchIN.h:/***** TouchIN.h******/#ifndef TOUCHIN_H_#define TOUCHIN_H_extern void TouchIN_Dect() ; //WDT中断事件extern unsigned char TouchIN; // 相当于PxIN寄存器作用,支持8个触摸按键#endif /* TOUCHIN_H_ */main.c:#include "MSP430G2553.h"#include "TouchIN.h" /*触摸按键检测库函数*/void WDT_Ontime(void);//-----对硬件相关代码进行宏定义处理-----#define LED_ON P1OUT |= BIT0 /*宏定义LED所在IO*/#define LED_OFF P1OUT &= ~BIT0 /*宏定义LED所在IO*/void main(void) {WDTCTL = WDTPW+WDTHOLD; //关狗//-----初始化GPIO-----P1DIR |= BIT0; //LED所连IO口P1.0设为输出P1OUT &= ~BIT0;//-----初始化WDT定时中断为16ms-----WDTCTL = WDT_ADLY_16; // “超级”宏定义IE1 |= WDTIE; //使能WDT中断_EINT(); // 使能总中断__bis_SR_register(LPM3_bits); //等同LPM3}#pragma vector=WDT_VECTOR // Watch dog Timer interrupt service routine__interrupt void WDT_ISR(void){WDT_Ontime();}void WDT_Ontime(void){ //-----首先必须定时扫描触摸按键检测函数-----TouchIN_Dect();if(TouchIN & BIT0) LED_ON;if(TouchIN & BIT1) LED_OFF;}调试情况:第一次调试:TouchIN_Dect函数重复定义第二次调试:正常调试结果:按下P2.0 后LED 亮,按下P2.5 后LED 灭,任务达成。
实验二实现多字节加(减)法一、 实验目的:a)熟悉单片机指令系统,b)学会用汇编语言编写计算程序二、 实验内容:(一)实验要求:正确建立工程文件、编写程序,会利用keil进行程序调试并观察运行结果。
z基本要求:编写程序,将存放在内部RAM起始地址为20H和30H的两个3字节无符号相加,结果存放在内部RAM单元70H、71H、72H中(低位对应低字节)。
数据要求初始化:参考将20H和30H分别存放两个三字节的无符号数333333H和222222H。
z提高要求:将基本要求中的“相加”改成“减法”,其它要求与基本要求相同,数据要求初始化:参考将20H和30H分别存放两个三字节的无符号数333333H和223344H。
编写相应的程序并给予适当的注释。
(二)实验基本步骤:1.打开Keil,新建工程:Project/New Project,输入工程名,并保存2.选项选择器件:Atmel 的89C513.新建程序文本,并另存为该文件为汇编文件格式: (1)“File/New”,(2) File/Save As/键入欲使用的文件名及后缀名,即“文件名.asm”。
再单击“保存”4.添加该文件该工程:回到编辑界面后,单击“Target 1”前面的“+”号,然后在“SourceGroup 1”上单击右键,单击“Add File to Group ‘Source Group 1’”选择刚才新建的汇编文件。
5.在keil的汇编文件中输入程序代码,并编译,调试。
(1)写完代码后单击“Project”菜单,再在下拉菜单中单击“Built Target”选项(或者使用快捷键F7),编译成功后(0个errors),(每次修改程序后都要重新编译下,才能生效)。
(2)再单击“Debug”菜单,在下拉菜单中单击“Start/Stop Debug Session”(或者使用快捷键Ctrl+F5),点击RUN进行运行,或者按F11进行单步运行。
一、实验目的1. 理解单片机按键的工作原理和电路连接方法;2. 掌握按键消抖原理及其实现方法;3. 学会使用单片机编程控制按键功能,实现简单的输入控制;4. 提高单片机实验操作能力和编程能力。
二、实验仪器及设备1. 单片机开发板(如STC89C52);2. 按键;3. 万用表;4. 电脑;5. Keil C编译器。
三、实验原理1. 按键原理:按键是一种电子开关,按下时导通,松开时断开。
在单片机应用中,按键常用于输入控制信号。
2. 按键消抖原理:由于按键机械弹性,闭合和断开时会有一连串的抖动。
若直接读取按键状态,容易导致误操作。
因此,需要进行消抖处理。
3. 消抖方法:主要有软件消抖和硬件消抖两种方法。
本实验采用软件消抖方法,即在读取按键状态后,延时一段时间再读取,若两次读取结果一致,则认为按键状态稳定。
四、实验步骤1. 硬件连接:将按键一端接地,另一端与单片机的某个I/O口相连。
2. 编写程序:使用Keil C编译器编写程序,实现以下功能:(1)初始化I/O口,将按键连接的I/O口设置为输入模式;(2)读取按键状态,判断按键是否被按下;(3)进行消抖处理,若按键状态稳定,则执行相应的功能。
3. 编译程序:将编写好的程序编译成HEX文件。
4. 烧录程序:将编译好的HEX文件烧录到单片机中。
5. 实验验证:观察实验现象,验证按键功能是否实现。
五、实验结果与分析1. 硬件连接正确,程序编译无误。
2. 实验现象:当按下按键时,单片机执行相应的功能;松开按键后,按键功能停止。
3. 分析:通过软件消抖处理,有效避免了按键抖动导致的误操作。
六、实验总结1. 本实验成功实现了单片机按键控制功能,掌握了按键消抖原理及实现方法。
2. 通过实验,提高了单片机编程和实验操作能力。
3. 在后续的单片机应用中,可以灵活运用按键控制功能,实现各种输入控制需求。
4. 本次实验为单片机应用奠定了基础,为进一步学习单片机技术打下了良好基础。
first_ge equ 60h ;伪指令first_shi equ 61hsecond_ge equ 62hsecond_shi equ 63hresult_ge equ 64hresult_shi equ 65hresult_bai equ 66hresult_qian equ 67hal equ 68hp_can bit 40hc_can bit 41hover bit 42horg 0000hljmp startorg 0050hstart:mov first_ge,#0mov first_shi,#0mov second_ge,#0mov second_shi,#0mov al,#5mov result_ge,#0mov result_shi,#0mov result_bai,#0mov result_qian,#0mov 45h,#0mov 46h,#0mov 35h,#0mov 36h,#0mov 37h,#0mov 38h,#0clr p_canclr c_canclr overmov 10h,#0main: lcall xianshimov p0,#0f0hmov a,p0cjne a,#0f0h,next ;判断是否有键按下ljmp mainnext: lcall delay ;延时去斗mov p0,#0f0hmov a,p0cjne a,#0f0h,key_num ;确定有键按下ljmp mainlcall xianshikey_num:mov p0,#0f0h ;取键值mov a,p0mov 20h,amov p0,#0fhmov a,p0add a,20hmov 10h,await: mov P0,#0f0h ;等键放开mov a,P0cjne a,#0f0h,waitmov a,10hlcall displaylcall xianshiljmp main;============================== display: ;判断键值cjne a,#0eeh,next1ljmp display0next1:cjne a,#0edh,next2ljmp display1next2:cjne a,#0ebh,next3ljmp display2next3:cjne a,#0e7h,next4ljmp display3next4:cjne a,#0deh,next5ljmp display4next5:cjne a,#0ddh,next6ljmp display5next6:cjne a,#0dbh,next7ljmp display6next7:cjne a,#0d7h,next8ljmp display7next8:cjne a,#0beh,next9ljmp display8next9:cjne a,#0bdh,nextaljmp display9nexta:cjne a,#0bbh,nextbljmp displayanextb:cjne a,#0b7h,nextcljmp displaybnextc:cjne a,#7eh,nextdljmp displaycnextd:cjne a,#7dh,nexteljmp displaydnexte:cjne a,#7bh,nextfljmp displayenextf:cjne a,#77h,wrongljmp displayfwrong:ret;===================================display0: ;1jb c_can,d_0_0jb p_can,d_0_1mov first_ge,#1setb p_canretd_0_1: mov 61h , 60hmov 60h,#1retd_0_0:jb p_can,d_0_2mov second_ge,#1setb p_canretd_0_2:mov 63h , 62hmov 62h,#1retdisplay1: ;4jb c_can,d_1_0jb p_can,d_1_1mov first_ge,#4setb p_canretd_1_1: mov 61h , 60hmov 60h,#4retd_1_0:jb p_can,d_1_2mov second_ge ,#4setb p_canretd_1_2: mov 63h , 62hmov 62h,#4retdisplay2: ;7jb c_can,d_2_0jb p_can,d_2_1mov first_ge,#7setb p_canretd_2_1: mov 61h , 60hmov 60h,#7retd_2_0:jb p_can,d_2_2mov second_ge,#7setb p_canretd_2_2:mov 63h , 62hmov 62h,#7setb p_canretdisplay3: ;clrmov first_ge,#0mov first_shi,#0mov second_ge,#0mov second_shi,#0mov al,#5mov result_ge,#0mov result_shi,#0mov result_bai,#0mov result_qian,#0mov 45h,#0mov 46h,#0mov 35h,#0mov 36h,#0mov 37h,#0mov 38h,#0clr p_canclr c_canclr overmov 10h,#0retdisplay4: ;2jb c_can,d_4_0jb p_can,d_4_1mov first_ge,#2setb p_canretd_4_1: mov 61h , 60hmov 60h,#2retd_4_0:jb p_can,d_4_2mov second_ge,#2setb p_canretd_4_2:mov 63h , 62hmov 62h,#2setb p_canretdisplay5: ;5jb c_can,d_5_0jb p_can,d_5_1mov first_ge,#5setb p_canretd_5_1: mov 61h , 60hmov 60h,#5retd_5_0: jb p_can,d_5_2mov second_ge,#5setb p_canretd_5_2:mov 63h , 62hmov 62h,#5setb p_canretdisplay6: ;8jb c_can,d_6_0jb p_can,d_6_1mov first_ge,#8setb p_canretd_6_1: mov 61h , 60hmov 60h,#8retd_6_0:jb p_can,d_6_2mov second_ge,#8setb p_canretmov 62h,#8setb p_canretdisplay7: ;0jb c_can,d_7_0jb p_can,d_7_1mov first_ge,#0setb p_canretd_7_1: mov 61h , 60hmov 60h,#0retd_7_0:jb p_can,d_7_2mov second_ge,#0setb p_canretd_7_2:mov 63h , 62hmov 62h,#0setb p_canretdisplay8: ;3jb c_can,d_8_0jb p_can,d_8_1mov first_ge,#3setb p_canretd_8_1: mov 61h , 60hmov 60h,#3retd_8_0:jb p_can,d_8_2mov second_ge,#3setb p_canretd_8_2:mov 63h , 62hmov 62h,#3setb p_canretdisplay9: ;6jb c_can,d_9_0jb p_can,d_9_1mov first_ge,#6setb p_canretmov 60h,#6retd_9_0:jb p_can,d_9_2mov second_ge,#6setb p_canretd_9_2:mov 63h , 62hmov 62h,#6setb p_canretdisplaya: ;9jb c_can,d_a_0jb p_can,d_a_1mov first_ge,#9setb p_canretd_a_1: mov 61h , 60hmov 60h,#9retd_a_0:jb p_can,d_a_2mov second_ge,#9setb p_canretd_a_2:mov 63h , 62hmov 62h,#9setb p_canretdisplayb: ;=setb overmov a,al;````````````````cjne a,#0,d_b_0 ;加法程序mov a,first_shiswap aorl a,first_gemov 45h,amov a,second_shiswap aorl a,second_geadd a,45hda ajnc bai_no_addmov result_bai,#1bai_no_add:mov 46h,aanl a,#0fhmov result_ge,amov a,46hanl a,#0f0hswap amov result_shi,aret;``````````````````````````````d_b_0:cjne a,#1,d_b_1 ;减法程序mov a,first_shiswap aorl a,first_gemov 45h,amov a,second_shiswap aorl a,second_gemov 46h,amov a,#9ah ;取补码9ahsubb a,46hadd a,45hda amov 46h,aanl a,#0fhmov result_ge,amov a,46hanl a,#0f0hswap amov result_shi,aret;``````````````````d_b_1:cjne a,#2,tiao ;乘法程序sjmp chengtiao:ljmp d_b_2;-----------------;十进制个位与个位相乘cheng:mov a,first_gemov b,second_gemul ab ;结果不大于81,存放于a中mov b,#10div ab ;十位数存于a,个位数存于bmov result_ge,b ;求出个位数mov 35h,a ;存十位寄35h;-----------------;个位与十位相乘mov a,first_shimov b,second_gemul abmov b,#10div abmov 36h,a ; 存百位寄存36hmov a,badd a,35hmov 35h,a ;clr csubb a,#10jc bai_no_jin_1inc 36h;如有进位,加一mov 35h,abai_no_jin_1:mov a,36hclr csubb a,#10jc qian_no_jin_1inc 37hmov 36h,aqian_no_jin_1: ;----------------------;十位与个位相乘mov a,first_gemov b,second_shimul abmov b,#10div abmov 33h,a ;结果寄放clr cmov a,badd a,35hmov 35h,a ;十位处理clr csubb a,#10jc bai_no_jin_2inc 36hmov 35h,abai_no_jin_2:mov a,33hadd a,36hmov 36h,a ;百位处理clr csubb a,#10 ;千位处理jc qian_no_jin_2inc 37hmov 36h,aqian_no_jin_2:;--------------------------;十位与十位相乘mov a,first_shimov b,second_shimul abmov b,#10div abmov 33h,aclr cmov a,badd a,36hmov 36h,aclr csubb a,#10jc qian_no_jin_3inc 37hmov 36h,aqian_no_jin_3:mov a,33hadd a,37hmov 37h,a ;--mov result_shi,35hmov result_bai,36hmov result_qian,37hret;```````````````````````````d_b_2:cjne a,#3,d_b_3 ;除法程序mov a,first_shiswap aorl a,first_gemov 45h,a ;第一个bcd码数字存放mov a,second_shiswap aorl a,second_gemov 46h,a ;第二个bcd码数字存放recom:mov a,45hclr csubb a,46hjc xiaomov a,#9ahsubb a,46hadd a,45hda amov 45h,ainc 38hjmp recomxiao:mov a,38hmov b,#10div abmov result_shi,amov result_ge,bret;d_b_3:retdisplayc: ;+mov al,#0setb c_canclr p_canretdisplayd: ;-mov al,#1setb c_canclr p_canretdisplaye: ;*mov al,#2setb c_canclr p_canretdisplayf: ;/mov al,#3setb c_canclr p_canret;========================delay:mov r7,#10loop0:mov r6,#08fhloop1:djnz r6,loop1djnz r7,loop0ret ;===================================xianshi:mov dptr,#TABjb over,over_loopjb c_can,c_loopmov a,first_ge ;显示第一个数movc a,@a+dptrmov P1,amov P2,#0fehlcall delaymov P1,#0ffhmov P2,#0ffhmovc a,@a+dptrmov P1,amov P2,#0fdhlcall delaymov P1,#0ffhmov P2,#0ffhret;-----------------------;显示第二个数c_loop:mov a,second_gemovc a,@a+dptrmov P1,amov P2,#0fehlcall delaymov P1,#0ffhmov P2,#0ffhmov a,second_shimovc a,@a+dptrmov P1,amov P2,#0fdhlcall delaymov P1,#0ffhmov P2,#0ffhretover_loop: ;显示运算结果mov a,result_gemovc a,@a+dptrmov P1,amov P2,#0fehlcall delaymov P1,#0ffhmov P2,#0ffhmov a,result_shimovc a,@a+dptrmov P1,amov P2,#0fdhlcall delaymov P1,#0ffhmov P2,#0ffhmov a,result_baimovc a,@a+dptrmov P1,amov P2,#0fbhlcall delaymov P2,#0ffhmov a,result_qianmovc a,@a+dptrmov P1,amov P2,#0f7hlcall delaymov P1,#0ffhmov P2,#0ffhretTAB: DB 0C0H,0F9H,0A4H,0B0H,99H ;0,1,2,3,4, DB 92H,82H,0F8H,80H,90H ;5,6,7,8,9,DB 88H,83H,0C6H,0A1H,86H ;A,B,C,D,E,DB 8EH;f。
#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define LCD_IO P2sbit KK1 = P3^2; //按键输入;sbit KK2 = P3^3; //按键输入;sbit LCD_RS = P3^5;sbit LCD_RW = P3^6;sbit LCD_EN = P3^7;uchar code LCD_line1[] = " The Counter";int idata mydata=0;/************************************************************** * 名称: Delay_1ms()* 功能: 延时子程序,延时时间为1ms * x* 输入: x (延时一毫秒的个数)* 输出: 无***************************************************************/ void Delay_1ms(uint x){uchar i, j;for(i = 0; i < x; i++) for(j = 0; j <= 148; j++);}/************************************************************** * 名称: lcd_bz( )* 功能: 测试忙碌子程序* 输入: 无* 输出: result***************************************************************/ bit lcd_bz(){bit result;LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();_nop_();_nop_();result=(bit)(P3&0x80);LCD_EN = 0;return result;}/*************************************************************** 名称: W_LCD_Com( )* 功能: 写指令子程序* 输入: com* 输出: 无***************************************************************/void W_LCD_Com(uchar com){while(lcd_bz());LCD_RS = 0; LCD_RW=0; LCD_EN = 0; // LCD_RS和R/W同时为低电平时,可以写入指令LCD_IO = com; Delay_1ms(5); //下面用EN输入一个高脉冲LCD_EN = 1; Delay_1ms(5); LCD_EN = 0;}/*************************************************************** 名称: W_LCD_Dat( )* 功能: 写数据子程序* 输入: dat* 输出: 无***************************************************************/void W_LCD_Dat(uchar dat){while(lcd_bz());LCD_RS = 1; LCD_RW=0;LCD_EN = 0; // LCD_RS为高,LCD_RW为低时,可以写入数据LCD_IO = dat; Delay_1ms(5); //下面用EN输入一个高脉冲LCD_EN = 1; Delay_1ms(5); LCD_EN = 0;}/*************************************************************** 名称: W_LCD_STR( )* 功能: 写字符串子程序* 输入: *s* 输出: 无***************************************************************/void W_LCD_STR(uchar *s){while(*s > 0) {W_LCD_Dat(*s); s++;}}/*************************************************************** 名称: LCD_cursor( )* 功能: 设置光标位置子程序* 输入: pos* 输出: 无***************************************************************/void LCD_cursor(uchar pos) //LCD光标定位到处{W_LCD_Com(pos+0x80); //第一行地址是0x80}/*************************************************************** 名称: initial( )* 功能: 初始化子程序* 输入: 无* 输出: 无* 指令:#define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一#define LCD_DISPLAY_ON 0x0C //显示开#define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示***************************************************************/void initial(){W_LCD_Com(0x06|0x04);W_LCD_Com(0x0c|0x08);W_LCD_Com(0x38);W_LCD_STR(LCD_line1);}/*************************************************************** 名称: Main()* 功能: 主函数***************************************************************/void main(){bit flag;uchar temp;uchar pos;Delay_1ms(10) ;initial();while(1){pos=0x4f;if(mydata>255)mydata=0;else if(mydata<0)mydata=255;if(mydata>127) //把mydata当做-128~127的有符号数来显示{flag=1;temp=256-mydata;}else {temp=mydata;flag=0;}LCD_cursor(pos);W_LCD_Dat((temp%10)+'0');pos--;//光标左移(其实光标不显示,只是为了输出高位)Delay_1ms(10);if(temp/100 || temp/10){LCD_cursor(pos);W_LCD_Dat((temp/10)%10+'0');pos--;}Delay_1ms(10);if(temp/100){LCD_cursor(pos);W_LCD_Dat((temp/100)%10+'0');pos--;}if(flag){LCD_cursor(pos);W_LCD_Dat('-');//负号}else{ LCD_cursor(pos);W_LCD_Dat(' ');//清除负号(空格代替)}if(!KK1){while(KK2);while(!KK2);mydata++;}else if(!KK2){while(KK1);while(!KK1);mydata--;}} }。
单片机独立按键实验报告总结本次实验我们使用了单片机进行了独立按键实验,通过学习掌握了单片机输入输出口的基本使用方法以及独立按键的使用方法和技巧。
以下是本次实验的总结:一、实验内容本次实验的主要内容是独立按键的使用方法和技巧。
通过学习,我们掌握了独立按键的接法原理和基本应用方法。
在实验中,我们首先通过理论学习了按键的工作原理,了解了按键在电路中的应用和接法方法,然后实际动手进行了按键电路的搭建和单片机程序的编写,最后进行了按键测试和实验结果分析。
二、实验步骤1.理论学习:首先,我们学习了独立按键的工作原理和接法原理,了解按键在电路中的应用和接法方法,掌握了按键接口的输入输出方式,并对具体实现过程和技巧进行了分析和探讨。
2.电路搭建:根据学习到的按键接法原理和电路图,我们使用面包板和导线搭建了独立按键电路,将按键连接到单片机的输入端口上,并设置相应的电阻来保护电路和单片机芯片。
3.程序编写:通过阅读单片机说明书和参考其他资料,我们学习了单片机输入输出口的基本使用方法和指令,编写了程序代码,实现了独立按键操作的功能。
我们实现了多种按键操作方式,包括单击、长按等方式,并添加了相应的提示和保护措施,以确保程序的可靠性和稳定性。
4.测试实验:最后,我们进行了独立按键测试实验,通过按键操作,观察测试实验结果,进行了数据分析和结论汇总。
实验结果表明,我们的按键电路和程序代码都实现了预期的功能和效果,证明了我们在实验中掌握的独立按键技巧和方法是正确和有效的。
三、实验结论通过本次实验,我们掌握了单片机输入输出口的基本使用方法和独立按键的使用方法和技巧,了解了按键在电路中的应用和接法方法,探索了独立按键实现的多种方式和技巧,提高了我们的电路设计能力和程序设计能力。
同时,本次实验还加强了我们的实验动手操作能力,增强了我们的实际应用能力和创新思维能力,为我们以后的学习和工作打下了坚实的基础。
实验报告(2021--2022学年第二学期)课程名称:单片机原理与应用实验项目名称:按键计数器实验一、实验目的1.掌握数码管的动态显示方法;2.掌握独立按键的扫描及去抖动方法。
二、实验仪器1、安装Keil uVison4的计算机;2、USB转串口驱动CH341SER.EXE;3、ISP下载软件stc-isp-15xx-v6.82e.exe;4、单片机开发板一块和USB线(公对公)一条。
三、实验内容编写程序对独立按键进行扫描,根据不同的按键完成不同的操作。
当S2按下时,执行加1操作;当S3按下时,执行减1操作;当S4按下时,执行加2操作;当S5按下时,执行减2操作,并将按键计数值显示在数码管上,显示格式如下所示。
四、实验步骤①在桌面建立一个文件夹。
先用Keil软件建立一个新的工程,芯片选择STC里的89C52RC芯片。
然后新建空白文件,将其保存为后缀为“.c”的文件并添加到这个工程中。
②根据实验要求把要调用的函数做出声明,按要求将代码编写完成。
写完之后要点击“Target Options”选项,在“Output”选项选择“Create HEX File”,将文件编译后生成后缀为“.hex”的文件。
③将程序烧入开发板中并运行,根据实验要求按下S2、S3、S4、S5按钮并拍照记录实验结果。
五、实验原始数据记录与数据处理#include <reg52.h>sbit WE=P2^7;sbit DU=P2^6;unsigned char code table[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X0 7,0X7F,0X6F,0X00,0X40};unsigned char dspbuf[]={0,1,2,2,11,1,4,5};unsigned char dspcom;void delayms(unsigned int x);void Display();unsigned char counter;void main(){unsigned char temp;while(1){Display();P3=0X0F;/temp=P3&0X0F;if(temp!=0x0F);{delayms(10);temp=P3&0X0F;if(temp!=0X0F);{switch(temp){case 0X0E:counter--;break;case 0X0D:counter++;break;case 0X0b:counter+=2;break; case 0X07:counter-=2;break; default:break;}dspbuf[5]=counter/100;dspbuf[6]=counter/10%10;dspbuf[7]=counter%10; while((P3&0X0F)!=0X0F);}}}}void Display(){P0=0X00;DU=1;DU=0;P0=~(1<<dspcom);WE=1;WE=0;P0=table[dspbuf[dspcom]];DU=1;DU=0;if(++dspcom==8)dspcom=0;}void delayms(unsigned int x) {unsigned int i,j;for(i=x;i>0;i--);for(j=113;j>0;j--);}六、实验结果与分析讨论根据编写的程序,第一次运行时,显示的是“0138-122”当S2按下时,执行加1操作,屏幕显示为“0138-123”,当S3按下时,执行减1操作,屏幕显示还原为“0138-122”。
湖北第二师范学院计算机学院09计应单片机课程设计实验报告课程设计名称:电子计算器课程设计单位:10计应(1)班课设小组成员:徐凡(1060310039)凡平(1060310058)彭浩(1060310045)桂银(1060310010)潘光卉(1060300033)完成时间:2012年04月02日至2012年04月 24 日单片机课程设计实验报告课程设计题目:简易计算器作品功能描述:当通过输入键盘数字时,能够在显示器上显示输出的数值,并且通过想实现的简单运算功能,实现计算器的加、减、乘、除和清零,并将结果显示出来。
小组成员工作分工:徐凡:程序主框架的构造和主要功能函数的设计。
凡平:原理图的设计和硬件的焊接。
彭浩:基本功能函数的设计(“+,-,*,/”)。
桂银:程序流程图的设计和键盘扫描程序的实现。
潘光卉:编写文档和功能测试。
硬件电路设计:本设计中我们用的是AT89C52芯片,LCD1602 (PROTEUS中为LM016L)就是那个液晶屏,因为可以显示2行16个字符,故叫做LCD1602.11.0592M或12M晶振(CRYSTAL),两者均可,但要涉及到串口需选用12MKEYPAD-SMALLCALC就是那个4X4键盘电容20~30PF(CAP),接最小电路电容10PF主要接复位电路RESPACK-8排阻,为20K的,一个引脚接正极,另8个引脚接I/O口接RES电阻10K,接复位电路实物照片:硬件原理图原理说明:1,上电后,屏幕初始化;2,计算。
按下数字键,屏幕显示要运行的第一个数字,再按下符号键,然后再按下数字键,屏幕显示要运算的第二个数字,最后按下“=”号键,屏幕上显示出计算结果。
3,如果要再次计算,可以按下“ON/C”键清零,或者继续按下数字键,即可重新计算。
键盘使用说明如下:按键功能说明:Array“+”实现两个数的相加“-”实现两个数的相减“×”实现两个数的乘积“÷”实现两个数商的运算“ON/C”计算器显示的清零和接通电源程序控制流程图:软件设计:在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法。
单片机实验一一、实验目的1.学习多字节压缩BCD 码加减法运算的程序设计;2.学习单字节有符号数加减运算的程序设计。
二、实验设备统一电子开发平台三、实验要求1.编写通用4 字节压缩BCD 码的加、减法运算程序;2.编写通用单字节有符号二进制数加、减法运算程序;四、实验原理对于简单的8 位加减可以直接调用指令就可以了。
例如加法可以使用指令ADD 以及带进位加ADDC,但单字节加减法只能在256 之内进行运算;在实际应用中经常需要进行多字节运算,从而处理更大的数据。
该实验介绍单片机BCD 码多字节加、减运算通用程序的设计。
1.多字节无符号压缩BCD 码加法运算假设多字节无符号被加数的最低字节的地址为R0,加数的最低字节地址为R1,字节数共为len;计算结果的地址于被加数相同。
◆入口参数:R0:被加数地址指针;R1:加数地址指针;len:字节数。
◆出口参数:@R0:计算结果;rLen:计算结果字节数。
◆使用资源:ACC,R0、R1,内部RAM 单元len、rlen 及存放被加数、加数、计算结果的内存单元。
示例程序如下:;多字节无符号压缩BCD 码加法运算rlen data 30h; 存放计算结果字节数len data 31h; 存放相加字节数; r0 定位40h,r1 定位50h; 此处的程序的问题是前面字节的进位没有处理,; 只是对最后字节相加处理了进位ORG 0000h;ADDl: PUSH PSW ;保护标志寄存器内容CLR C ;进位位清0MOV rlen,#00H ;和的字节数先清0ADD: MOV A,@R0 ;取被加数ADD A,@R1 ;求和DA A ;十进制调整MOV @R0,A ;保存INC R0 ;地址增1INC R1INC rlen ;字节数增1DJNZ len,ADD ;所有字节未加完继续,否则向下执行JNC ADD20 ;和的最高字节无进位转ADD20MOV @R0,#01H ;和的最高字节地址内容为01HINC rlenADD20: POP PSWRETEND多字节加法运算一般是按从低字节到高字节的顺序进行的,所以必须考虑低字节向高字节的进位情况,被加数和加数的压缩BCD 码,最大不超过99,而99+99+1(进位)=199,此时不需要使用ADDC 指令,但当两字节当最低两字节相加后,必须使用“DA A”进行十进制调整,调整后产生进位。
按键加减计数(数码管显⽰,中断⽅式)按键加减计数(数码管显⽰,中断⽅式)(合肥⼯⼤周宁)课程设计对象A08电⽓⼯程及⾃动化本科班,共38+39⼈。
⼀.课程设计的任务和⽬的本课程设计要求学⽣在1.5周内编程设计⼀个单⽚机应⽤系统,完成设计报告。
通过设计实践,使学⽣掌握单⽚机的应⽤特点、编程⽅法,学会单⽚机实际应⽤系统的设计开发过程及设计报告的规范书写,为毕业设计打下良好的基础。
⼆.课程设计内容及要求(⼀)、课程设计题⽬可从如下⽅⾯参考选择(⾃⼰出题的必须经⽼师批准):1.单⽚机在计时控制⽅⾯的应⽤设计。
如:时钟、频率计、彩灯、交通灯2.单⽚机在计数控制⽅⾯的应⽤设计。
如:计数器、计分器、抢答器、报警器3.单⽚机在运算控制⽅⾯的应⽤设计。
如:密码锁、计算器、乒乓球游戏机4.单⽚机在波形发⽣⽅⾯的应⽤设计。
如:电⼦琴、⾳乐盒、调光LED灯5.单⽚机在通讯技术⽅⾯的应⽤设计。
如:双机通讯、PC可控单⽚机系统、对话机器⼈6.单⽚机A/D转换技术⽅⾯的应⽤设计。
如:电压表、温度计、照度计(⼆)、具体要求:1.完成控制程序的编制,能演⽰系统功能。
2.完成设计并上交纸质设计报告1份。
3.系统功能要求及设计报告格式范⽂见附件1、附件2。
三.时间与学时安排1.课程设计时间在本学期第16-17周(共1.5周)。
2.总体教学时间安排:课程设计成绩按学⽣设计报告按五级评分制综合评定。
六.评分标准1.设计报告:按版⾯格式、⽂字语法、观点正确性、图表规范性等综合评分。
机电⼯程学院电⽓系胡佳⽂2010年12⽉12⽇附件1:单⽚机原理与应⽤课程设计功能要求1.单⽚机在计时控制⽅⾯应⽤的设计功能要求:(1)时钟能计时,可校准时间,⾄少有⼀种附带功能(如秒表、定时器或闹钟功能);(2)频率计能测试并显⽰1HZ—10KHZ频率、5V的⽅波,可附带⽅波发⽣器功能;(3)彩灯要求控制16个LED有两种以上闪烁⽅式;(4)交通灯要求模拟控制⼗字路⼝交通信号,有倒计时显⽰。
第1篇一、实验背景按键作为电子设备中常见的输入装置,其功能丰富,应用广泛。
本实验旨在通过设计和实现一系列按键功能,加深对按键工作原理的理解,并提高电子设计实践能力。
二、实验目的1. 掌握按键的基本原理和电路设计方法。
2. 熟悉按键在不同应用场景下的功能实现。
3. 培养电子设计实践能力,提高问题解决能力。
三、实验内容1. 实验器材:51单片机最小核心电路、按键、LED灯、电阻、电容、面包板等。
2. 实验内容:(1)单按键控制LED灯闪烁(2)按键控制LED灯点亮与熄灭(3)按键控制LED灯亮度调节(4)按键实现数字时钟调整(5)按键实现多功能计数器(6)按键实现密码输入与验证四、实验步骤1. 根据实验要求,设计电路图,并选择合适的元器件。
2. 使用面包板搭建实验电路,包括单片机、按键、LED灯、电阻、电容等。
3. 编写程序,实现按键功能。
4. 对程序进行调试,确保按键功能正常。
5. 实验完成后,撰写实验报告。
五、实验结果与分析1. 单按键控制LED灯闪烁实验结果:按下按键,LED灯闪烁;松开按键,LED灯停止闪烁。
分析:本实验通过单片机定时器实现LED灯的闪烁。
当按键按下时,定时器开始计时;当定时器达到设定时间后,LED灯点亮;定时器继续计时,当达到设定时间后,LED灯熄灭。
如此循环,实现LED灯的闪烁。
2. 按键控制LED灯点亮与熄灭实验结果:按下按键,LED灯点亮;再次按下按键,LED灯熄灭。
分析:本实验通过单片机的I/O口控制LED灯的点亮与熄灭。
当按键按下时,单片机将I/O口置为高电平,LED灯点亮;当按键再次按下时,单片机将I/O口置为低电平,LED灯熄灭。
3. 按键控制LED灯亮度调节实验结果:按下按键,LED灯亮度逐渐增加;松开按键,LED灯亮度保持不变。
分析:本实验通过单片机的PWM(脉宽调制)功能实现LED灯亮度的调节。
当按键按下时,单片机调整PWM占空比,使LED灯亮度逐渐增加;松开按键后,PWM占空比保持不变,LED灯亮度保持不变。
第1篇一、实验目的1. 理解按键输入的基本原理。
2. 掌握C语言编程中按键扫描和响应的实现方法。
3. 实现基于按键输入的加减功能,并能够查询结果。
二、实验环境1. 开发工具:Keil uVision52. 实验平台:STM32F103系列单片机开发板3. 外设:按键模块三、实验原理1. 按键扫描原理:通过查询或中断方式检测按键是否被按下,并判断是哪个按键被按下。
2. 单片机编程:使用C语言编写程序,实现对按键的扫描和加减功能的实现。
四、实验步骤1. 准备实验环境,连接按键模块到单片机开发板上。
2. 编写按键扫描函数,实现按键的检测和识别。
3. 编写加减功能函数,实现加法和减法运算。
4. 编写主函数,实现按键输入和结果显示。
五、实验代码```cinclude "stm32f10x.h"// 按键定义define KEY_ADD GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) // PA0define KEY_SUB GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) // PA1// 全局变量volatile int result = 0;// 按键扫描函数void KeyScan(void) {if (KEY_ADD == 0) {while (KEY_ADD == 0); // 防抖动 result += 1;}if (KEY_SUB == 0) {while (KEY_SUB == 0); // 防抖动 result -= 1;}}// 加减功能函数void AddSub(void) {KeyScan();// 显示结果// ... (此处省略显示代码)}// 主函数int main(void) {// 初始化GPIO// ... (此处省略初始化代码)while (1) {AddSub();}}```六、实验结果与分析1. 实验结果:通过按键输入,可以实现对数字的加减操作,并实时显示结果。
一、实训目的1. 掌握单片机的基本工作原理和硬件结构;2. 熟悉单片机编程环境及编程方法;3. 学习按键控制的基本原理和编程技巧;4. 提高动手能力和解决问题的能力。
二、实训内容1. 单片机简介2. 单片机编程环境及编程方法3. 按键控制原理及编程4. 实验设计与实现三、实训步骤1. 单片机简介(1)单片机定义:单片机是一种集成度高、功能强大的微处理器,具有运算、存储、输入输出、定时计数等功能。
(2)单片机硬件结构:主要包括中央处理单元(CPU)、存储器(RAM、ROM)、输入输出接口(I/O)、定时器/计数器、串行通信接口等。
2. 单片机编程环境及编程方法(1)编程环境:Keil uVision、IAR EWARM等。
(2)编程语言:C语言、汇编语言等。
3. 按键控制原理及编程(1)按键控制原理:按键作为一种输入设备,其作用是将物理信号转换为电信号,通过单片机对电信号进行处理,实现相应的功能。
(2)按键编程技巧:① 按键消抖:由于按键存在机械特性,按下和释放时会产生抖动,导致单片机检测到多个按键动作。
为了消除抖动,通常采用软件消抖方法,如延时消抖、计数消抖等。
② 按键扫描:按键扫描是检测按键状态的一种方法,通过单片机的I/O口循环检测每个按键的状态,实现按键的识别。
③ 按键去抖:在按键扫描过程中,若检测到按键动作,则需要进行去抖处理,以消除抖动对按键识别的影响。
4. 实验设计与实现(1)实验目的:通过按键控制LED灯的亮灭。
(2)实验原理:当按下按键时,单片机检测到按键动作,通过编程控制LED灯亮起;当按键释放时,单片机检测到按键释放,控制LED灯熄灭。
(3)实验步骤:① 准备实验器材:单片机、按键、LED灯、电阻、面包板等。
② 连接电路:将按键、LED灯、电阻等元器件连接到单片机的相应引脚上。
③ 编写程序:根据实验原理,编写控制LED灯的亮灭程序。
④ 烧录程序:将编写的程序烧录到单片机中。
⑤ 测试程序:观察LED灯的亮灭状态,验证程序的正确性。
PIC之闪烁显示及按键的串键加减实验实验环境: Proteus编程语言:汇编编程环境: MPLAB单片机:PIC16F877晶振:20MHz功能说明:该实验旨在对按键调试过程中的闪烁显示和串键加减进行研究和实验,如图所示.主体显示采用的是定时器定时的数字时钟,为防止误按加减而导致时钟数据的改变,采用了两级锁定的方式,首先要按下总键,按一次进入分钟调试,两次为小时,第三次退出按键模式.在按键调试模式下,还要按移位键才能对分钟或小时进行加减,按下移位键后(可通过它选择是对十位调节还是对个位调节),选中的位会闪烁显示,然后才可通过加减键对数值进行调节.长按加减键半秒以上可实现连加连减.图(1)无按键显示图图(2)按移位键后的闪烁显示,上图为个位闪烁,下图(3)为十位闪烁图(3)部分源程序:;*******************ORG 0X0000GOTO MAINORG 0X0004MOVWF BWSW APF STA TUS,0CLRF STA TUSMOVWF BSTA TUSMOVF FSR,0MOVWF BFSRMOVF PCLA TH,0MOVWF BPCH;***************************以上是中断现场保护CLRF PCLA THBTFSS INTCON,5GOTO INTOUTBTFSC INTCON,2GOTO T0INT;******************以上是中断源判别INTOUT: CLRF STA TUSMOVF BFSR,0MOVWF FSRMOVF BPCH,0MOVWF PCLA THSW APF BSTA TUS,0MOVWF STA TUSSW APF BW,1SW APF BW,0RETFIE;***********************************以上是中断现场恢复T0INT: BCF INTCON,2MOVLW 0X14MOVWF TMR0INCF T01MMOVLW .20;1ms刷新一次显示XORWF T01M,0BTFSS STA TUS,ZGOTO INTOUTCLRF T01MCLRF PORTDMOVLW .8SUBWF DSPC,0;DSPC起到显示指针的作用BTFSC STA TUS,CCLRF DSPCMOVF DSPC,0ADDLW DIS0MOVWF FSRBTFSC FLAG1,6;移位标志BTFSS FLAG1,5;闪烁标志GOTO NSHFTMOVLW .5BTFSC FLAG1,1MOVLW .2MOVWF SHIFT1MOVF SHIFT,0BTFSC STA TUS,ZGOTO NSHFTSUBWF SHIFT1,0XORWF DSPC,0BTFSS STA TUS,ZGOTO NSHFTCLRF ICOMMOVLW ICOMMOVWF FSRNSHFT: MOVLW H'E8'ANDWF PORTAMOVF DSPC,0IORWF PORTAMOVF INDF,0MOVWF PORTDINCF DSPCDECFSZ T020MGOTO INTOUTMOVLW .23MOVWF T020MBSF FLAG1,7DECFSZ T01SGOTO INTOUTMOVLW .39MOVWF T01SINCF SECONDMOVLW .60XORWF SECOND,0BTFSS STA TUS,ZGOTO INTOUTCLRF SECONDINCF MINUTEMOVLW .60XORWF MINUTE,0BTFSS STA TUS,ZGOTO INTOUTCLRF MINUTEINCF HOURMOVLW .24XORWF HOUR,0BTFSS STA TUS,ZGOTO INTOUTCLRF HOURGOTO INTOUT;************************************************* MAIN: CALL INITGOTO KEYSCAN;*******待分解数据在com0中,显示单元在FSR中******** LEDS: SW APF COM0,0ANDLW H'0F'CALL LEDDISMOVWF INDFINCF FSRMOVF COM0,0ANDLW H'0F'CALL LEDDISMOVWF INDFINCF FSRRETURN;***********************************************LEDDIS: ADDWF PCLDT 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6FDT 0X77,0X7C,0X39,0X5E,0X79,0X71;****************************;************除十,被除数存入com3,出口:com3为商,com5为余数DIV10: MOVLW D'10'MOVWF COM4CLRF COM5MOVLW D'8'MOVWF COM6DIV101: BCF STA TUS,CRLF COM3RLF COM5BSF COM3,0MOVF COM4,0SUBWF COM5BTFSS STA TUS,CCALL ADDDECFSZ COM6GOTO DIV101RETURNADD: MOVF COM4,0ADDWF COM5BCF COM3,0RETURN;********************************************************** MUL10: MOVF COM3,0;八位乘10MOVWF COM4BCF STA TUS,CRLF COM3RLF COM3RLF COM3RLF COM4,0ADDWF COM3,0RETURNKEYSCAN:BTFSS FLAG1,7GOTO DISBCF FLAG1,7;定时20msGOTO $+9INCF T0SHMOVLW .15XORWF T0SH,0;BTFSS STA TUS,ZGOTO $+4CLRF T0SHMOVLW H'20'XORWF FLAG1;每隔半秒左右取反flag1,5MOVF PORTB,0ANDLW H'F0'XORLW H'F0'BTFSC STA TUS,Z;判断是否有键按下GOTO NKEYMOVWF KEYCOM0INCF KEYCMOVLW .30XORWF KEYC,0BTFSS STA TUS,ZGOTO DISCLRF KEYC;按键计时单元BTFSC KEYCOM0,KEY2GOTO KADDBTFSC KEYCOM0,KEY3GOTO KSUBGOTO DISNKEY: CLRF KEYCBTFSC KEYCOM0,KEY0GOTO KSETBTFSC KEYCOM0,KEY1GOTO SHFTBTFSC KEYCOM0,KEY2GOTO KADDBTFSS KEYCOM0,KEY3GOTO DISKSUB: BTFSC FLAG1,0BTFSS FLAG1,6GOTO KOUTMOVLW MINUTEBTFSC FLAG1,1MOVLW HOURMOVWF FSRMOVLW .1MOVLW .10SUBWF INDFMOVLW .59BTFSC FLAG1,1MOVLW .23BTFSC INDF,7;无论哪个键按下,处理后都要清KEYCOM0键值寄存器MOVWF INDFGOTO KOUTKSET: BTFSC FLAG1,0GOTO KSET1BSF FLAG1,0GOTO KOUTKSET1: INCF FLAG1BSF FLAG1,0CLRF SHIFTBTFSC FLAG1,2CLRF FLAG1GOTO KOUTSHFT: BTFSS FLAG1,0GOTO KOUTINCF SHIFTMOVLW .3SUBWF SHIFT,0BTFSS STA TUS,CGOTO $+3MOVLW .1MOVWF SHIFTBSF FLAG1,6GOTO KOUTKADD: BTFSC FLAG1,0BTFSS FLAG1,6GOTO KOUTMOVLW MINUTEBTFSC FLAG1,1MOVLW HOURMOVWF FSRMOVLW .1BTFSC SHIFT,1MOVLW .10ADDWF INDFMOVLW .60BTFSC FLAG1,1MOVLW .24BTFSC STA TUS,CCLRF INDFGOTO KOUTKOUT: CLRF KEYCOM0DIS: MOVF SECOND,0MOVWF COM3CALL DIV10MOVF COM5,0CALL LEDDISMOVWF DIS7MOVF COM3,0CALL LEDDISMOVWF DIS6MOVF MINUTE,0MOVWF COM3CALL DIV10MOVF COM5,0CALL LEDDISMOVWF DIS4MOVF COM3,0CALL LEDDISMOVWF DIS3MOVF HOUR,0MOVWF COM3CALL DIV10MOVF COM5,0CALL LEDDISMOVWF DIS1MOVF COM3,0CALL LEDDISMOVWF DIS0GOTO KEYSCANINIT: CLRF INTCON;初始化函数CLRF PIR1CLRF PIR2CLRF FLAG1CLRF FLAG2MOVLW .1MOVWF T01SMOVWF T020MMOVWF T0TMMOVWF T01MBANKSEL TRISACLRF PIE1CLRF PIE2MOVLW H'F0'MOVWF TRISBCLRF TRISACLRF TRISDMOVLW H'0F'MOVWF OPTION_REGBANKSEL PORTAMOVLW H'06'MOVWF DIS0MOVLW H'66'MOVWF DIS1MOVLW H'40'MOVWF DIS5MOVWF DIS2MOVLW H'7F'MOVWF DIS4MOVLW H'6D'MOVWF DIS3MOVLW H'4F'MOVWF DIS6MOVLW H'3F'MOVWF DIS7MOVLW .14MOVWF HOURMOVLW .58MOVWF MINUTEMOVLW .30MOVWF SECONDMOVLW H'14'MOVWF TMR0MOVLW H'E0'MOVWF INTCONRETURNEND。
单片机按键加减报告
————————————————————————————————作者:————————————————————————————————日期:
ﻩ
单片机实验报告
一、实验目的
1、学习利用单片机设计简单加减计数,并学会定时/计数器T0/T1的使用。
2、学习使用keil和proteus软件。
3、熟悉汇编语言并能利用汇编语言编写程序。
二、实验思路
用T0、T1设计10位以内的按键加减计数:
利用T0/T1计数功能实现每次按键的中断,且采用方式2,可以自动重载初值,较为方便。
这里不考虑优先级的问题。
再分别对T0、T1编写中断处理的程序。
要注意的是,加法时,9加1显示0的情况;减法时,0减1显示9的情况。
三、实验原理
(以下不考虑T2的情况)
1、中断的概念
CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。
2、定时/计数器
(1)中断控制寄存器(TCON)
TCON的高4位用于控制定时/计数器的启动和中断申请。
其格式如下:
TF1(TCON.7):T1溢出中断请求标志位。
T1计数溢出时由硬件自动置TF1为1。
CPU响应中断后TF1由硬件自动清0。
T1工作时,CPU可随时查询TF1的状态。
所以,TF1可用作查询测试的标志。
TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
TR1(TCON.6):T1运行控制位。
TR1置1时,T1开始工作;TR1置0时,T1停止工作。
TR1由软件置1或清0。
所以,用软件可控制定时/计数器的启动与停止。
TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
TR0(TCON.4):T0运行控制位,其功能与TR1类同。
本次试验要用到T0、T1,即TR0、TR1置1。
(2)中断允许控制(IE)
EX0(IE.0),外部中断0允许位;
ET0(IE.1),定时/计数器T0中断允许位;
EX1(IE.2),外部中断1允许位;
ET1(IE.3),定时/计数器T1中断允许位;
ES(IE.4),串行口中断允许位;
EA(IE.7),CPU中断允许(总允许)位。
以上都是为1时开启,为0时关闭。
本次试验需要开启EA、ET1、ET0,即令IE为8AH。
(3)工作方式寄存器TMOD
GATE:门控位。
GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作。
C/T:定时/计数模式选择位。
C/T=0为定时模式;C/T=1为计数模式。
M1M0:工作方式设置位。
定时/计数器有四种工作方式,由M1M0进行设置。
这次试验需要计数模式且为方式二,所以,TMOD值设为66H。
3、数码管
在这里我们使用的是7SEG-COM-AN-GRN数码管,由7个发光管组成的8字形构成的,如下图所示,左边接线顺序下来分别命名为ABCDEFG
数码管的接线为共阳接法,即低电平亮,高电平灭。
实验中用P0.0-P0.6控制数码管的7段,P0口的八位与发光管的对应关系见下表所示。
显示P0.7P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0
HEX ——G F E D C B A
H
1 0 1 1 1 1 0 0 1 79H
2 0 0 1 0 0 1 0 0 24H 30 0 1 10 0 0 0 30H
4 0 0 0 1 1 0 0 1 19H
5 00 0 1 00 1 012H
6 0 0 0 0 0 0 1 0 02H
7 0 1 1 1 10 0 0 78H
8 0 0 00 0 0 0 0 00H
9 0 0 0 1 1 0 0 0 18H
四、设计流程
N
Y
Y
ﻩN ﻩY ﻩ N
(a)主程序 (b)中断响应
五、原理图
存数寄存器
中断初
开始 数码管等待中
按键
R0
是否为加法
R0是否为9
R0是否为0
R0R0R0中断
运行后,初始如上图所示,当按一下第一个键时,数码管显示1,此后每按一次数码管显示数值加1,当数码管显示为9时,按下第一个键,显示为0;初始状态下,当按下第二个键时,数码管显示9,此后每按一次第二个键,数码管显示数值减1。
说明实验成功
六、汇编程序
ORG0000H
JMP MAIN
ORG 000BH//T0(加法)中断入口
JMP T0_ADD
ORG 001BH //T1(减法)中断入口
JMP T1_SUB
MAIN: //主程序
MOV TMOD,#66H//设置T1、T0方式2计数
MOVTL1,#0FFH //为T1、T0设置初值
ﻩMOVTH1,#0FFH
ﻩMOV TL0,#0FFH
ﻩMOVTH0,#0FFH
ﻩMOV IE,#8AH//CPU、T0、T1开启中断
SETB TR1 //启动T1计数器
SETB TR0 //启动T0计数器
ﻩ MOVR0,#0//设置显示的初始值及其地址
ﻩMOVDPTR,#TAB
LOOP:
MOV A,R0//输出显示数值
MOVC A,@A+DPTR
MOVP0,A
SJMP LOOP//等待中断
T0_ADD:
ﻩ CJNE R0,#9,T_END0 //是否需要进位
MOV R0,#0
RETI
T1_SUB:
CJNE R0,#0,T_END1 //是否需要借位
ﻩ MOVR0,#9
ﻩ RETI
T_END0:
INC R0 //加1
RETI
T_END1:
DEC R0 //减1
RETI
TAB: //选择0-9的输出
DB0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18
END
七、小结
这次实验中,我进一步加深了对单片机及其应用的了解。
通过查找资料和老师的帮助,进一步熟练了对keil和proteus软件的操作。
在编写程序的过程中也遇到了一些问题,一些语句的使用不够熟练,但现在对它们有了更深的记忆。
在编写程序的过程中,我加深了对中断概念和对计数器工作原理的理解。
同时,感受了设计程序的流程,为以后的实验积累了一定经验。