定时器中断控制键盘扫描实验
- 格式:doc
- 大小:50.50 KB
- 文档页数:3
msp430中断方式实现键盘扫描例程类别:技术文章来源:未知作者:未知关键字:键盘扫描加入日期:2010-5-1// 此示例程序为中断方式,得到键盘的键值,存放在队列keybuff[10]中// 此示例程序没有显示,// 键盘的按键按下引起P1口的中断服务程序,得到键盘的键值,保存到键值队列// 在其他的中断服务程序中通过键值队列中的数据引导程序的流程#include <msp430x14x.h>unsigned char keybuff[10];unsigned char keypoint=0;void delay(int v){while(v!=0)v--;}unsigned char key(void){unsigned char x=0xff;P1DIR=0X0F;P1OUT=0X01; //扫描第一行if((P1IN&0X70)==0X10)x=0;elseif((P1IN&0X70)==0X20)x=1;elseif((P1IN&0X70)==0x40)x=2;else{P1OUT=0X2; //扫描第二行if((P1IN&0X70)==0X10)x=3;elseif((P1IN&0X70)==0X20)x=4;elseif((P1IN&0X70)==0x40)x=5;else{P1OUT=0X4; //扫描第三行if((P1IN&0X70)==0X10)x=6;elseif((P1IN&0X70)==0X20)x=7;elseif((P1IN&0X70)==0x40)x=8;else{P1OUT=8; //扫描第四行if((P1IN&0X70)==0X10)x=9;elseif((P1IN&0X70)==0X20)x=10;elseif((P1IN&0X70)==0x40)x=11;}}}return(x);}unsigned char keyj(void){unsigned char x;P1DIR=0x0f;P1OUT=0x0f; //键盘硬件:P10--P13为行线,最上面一根为P10x=(P1IN&0X70); // P14--P16为列线,最左边一根为P14,列线下拉return(x); // 无按键,返回 0?; 有按键返回非0}interrupt[PORT1_VECTOR] void port1key(void){if(keyj()!=0X00){delay(300) ; //消抖动if(keyj()!=0X0){keybuff[keypoint]=key(); //按键见键值保存到队列keypoint++; //if(keypoint==10)keypoint=0;}}P1OUT=0X0F;P1IFG=0X0; //清除中断标志}void main(void){WDTCTL = WDTPW + WDTHOLD; /* // Stop WDT */ P1DIR=0XF;P1OUT=0XF;P1IES=0X0;P1IE=0X70; //列线上升沿允许P1中断_EINT(); /*/ Enable interrupts */while(1){LPM0;_NOP();}}。
实验八键盘扫描实验一、实验目的1. 掌握中断键盘扫描编程方法。
2. 掌握LED动态显示方法。
二、实验原理及实验内容1. 实验原理无论是单片机控制系统还是单片机测量系统,都需要一个人机对话装置,这种人机对话装置通常采用键盘和显示器。
键盘是单片机应用系统中人机对话常用的输入装置,而显示器是单片机应用系统人机对话中的常用输出装置。
键盘是由若干个按键开关组成,键的多少根据单片机应用系统的用途而定。
键盘由许多键组成,而每个键相当于一个机械开关触点,当键按下时,触点闭合,当键松开时,触点断开。
单片机接收到按键的触点信号后作相应的功能处理。
因此对于单片机系统来说键盘接口信号是输入信号。
单片机的键盘接口分为独立式和矩阵式。
独立式键盘的每个按键都有一个信号线与单片机电路相连,所有按键有一个公共地或公共正端,每个键相互独立互不影响。
如图7-7所示,当按下键1时,无论其它键是否按下,键1的信号线就由1变0;当松开键1时,无论其它键是否按下,键1的信号线就由0变1。
矩阵式键盘的按键触点接于由行、列母线构成的矩阵电路的交叉处,每当一个按键按下时通过该键将相应的行、列母线连通。
若在行、列母线中把行母线逐行置0(一种扫描方式),那么列母线就用来作信号输入线。
矩阵式键盘原理图如图7-8所示。
图7-7 独立式按键原理图图7-8 矩阵式按键原理图针对以上两大类键盘工作方式,单片机又有三种键盘扫描方式:查询方式;定时扫描方式和中断扫描方式。
查询方式是指在程序中用一段专门的扫描和读按键程序不停查询有无按键按下,确定键值。
这种方式电路简单,但需要占用单片机的机器时间。
定时扫描方式是指利用单片机内的定时器来产生定时中断,然后在定时中断的服务程序中扫描,检查有无按键按下,确定键值。
这种方式的电路也比较简单,不占用单片机的机器时间,但需要占用一个定时器,同时定时的时间不能过长,否则可能检测不到相应得按键。
中断扫描方式是指当有键按下时由相应的硬件电路产生中断信号,单片机在中断服务程序中扫描,检查有无按键按下,确定键值。
竭诚为您提供优质文档/双击可除c51定时中断实验报告篇一:51单片机定时器实验报告51单片机定时器实验实验内容:实验内容:(1)编写程序使定时器0或者定时器1工作在方式1,定时50ms触发蜂鸣器。
c语言程序#include#defineuintunsignedint#defineucahrunsignedcharsbitFm=p0^0;voidmain(){TmoD=0x01;Th0=(65535-50000)/256;Th0=(65535-50000)%256;eA=1;//开总中断eT0=1;//开定时器0中断TR0=1;while(1);}voidT0_time()interrupt1{}汇编程序oRg0000hJAmpmAInoRg000bhTh0=(65535-50000)/256;Th0=( 65535-50000)%256;Fm=~Fm;LJmpInT0_InToRg0100hmIAn:seTbeAseTbeT0AJmp$InT0_InT:moVR2,#0FAhmoVR3,#0c8hDJnZR3,$DJnZR2,InT0_InTReTI(2)编写程序使定时器0或者定时器1工作在方式1,定时500ms使两位数码管从00、01、02……98、99每间隔500ms加1显示。
#include#defineuintunsignedint#defineucahrunsignedcharuintnum,num1;sbitFm=p0^7;intshi,ge,a;voiddelay(uint);voidshumaguan();unsignedcharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0 x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳极数码管0-F编码表voidmain(){TmoD=0x01;Th0=(65535-50000)/256;Th0=(65535-50000)%256;eA=1;//开总中断eT0=1;//开定时器0中断TR0=1;while(1)}voidT0_time()interrupt1{}voidshumaguan(){p3=0x01;p2=table[shi];delay(5);p3=0x02;p2=table[ge];delay(5);Th0=(65535-50000)/256;Th0=(65535-50000)%25 6;num1++;if(num1==10){}num1=0;num++;shi=num/10;ge=n um%10;if(num==100){num=0;}{}shumaguan();voidzuoyi(){}voiddelay(uintx){}(3)编写程序使定时器0或者定时器1工作在方式2,自动重装载模式,定时500ms使两位数码管从00、01、02……98、99每间隔500ms加1显示。
MSP430_按键的定时器扫描//按键的定时器扫描:每1ms进入一次time中断,10ms进行一次按键检测。
#includechar Key_Pressed_Flag=0;//按键标志位char Key_Front=1, Key_Current=1;//上次按键值,本次按键值int Key_Det_1ms_Cnt=0;int main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗//配置系统时钟DCOCTL = 0;BCSCTL1 = CALBC1_1MHZ; // 设置 DCO为1MDCOCTL = CALDCO_1MHZ;//配置定时器P1DIR |=BIT0; // 2P1.0为输出P1OUT |=BIT0; //初始化CCTL0 = CCIE; // CCR0中断使能CCR0 = 1000; //设置定时器计数值TACTL = TASSEL_2 + MC_1; // SMCLK为定时器时钟,向上计数模式//配置按键P1SEL &= ~(BIT3); // 1设置P1.3为IO口P1DIR &= ~BIT3; // 2设置P1.3为输入P1REN |= BIT3; // 3使能SW2为上下拉 (P1.3)P1OUT |= BIT3; // 4设置SW2为上拉 (P1.3)//配置串口模块P1SEL |= BIT1 + BIT2 ; // 配置引脚P1SEL2|= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TX UCA0CTL1 |= UCSSEL_2; // 模块时钟选择为SMCLK UCA0BR0 = 104; // 设置波特率UCA0BR1 = 0; // 1MHz/104=9600bpsUCA0MCTL = UCBRS0; // 调整波特率UCA0CTL1 &= ~UCSWRST; // **使能系统复位** IE2 |= UCA0RXIE; // 使能USCI_A0接收中断//使能全局中断_BIS_SR(GIE); // 使能中断while(1){//按键处理if(Key_Pressed_Flag){Key_Pressed_Flag=0;P1OUT ^=BIT0; //位的异或运算:使得输出改变}}}// Timer A0 interrupt service routine#pragma vector=TIMER0_A0_VECTOR__interrupt void Timer_A (void){//基于定时器的按键检测Key_Det_1ms_Cnt++;//计数器if(Key_Det_1ms_Cnt==10){Key_Det_1ms_Cnt=0;//计数器置0,为下一次计数做准备Key_Current=BIT3 & P1IN;if((Key_Current==0)&&(Key_Front>0))Key_Pressed_Flag=1;Key_Front=Key_Current;}}// Echo back RXed character, confirm TX buffer is ready first #pragma vector=USCIAB0RX_VECTOR__interrupt void USCI0RX_ISR(void){while (!(IFG2&UCA0TXIFG)); // 检测发送是否准备好UCA0TXBUF = UCA0RXBUF; // 将接收数据发送给主机}。
实验二按键中断实验一、实验目的了解中断的含义二、实验内容板子加电后,按动板子上K1-K3按键,可控制对应的LED1-LED3的亮灭,该实验学习了外部中断(EXTI)程序的编制及控制流程。
三、实验仪器、设备计算机、开发板、keil软件四、硬件设计在开发板上V6、V7、V8分别与MCU的PB5、PD6、PD3相连,如下图所示键盘部分如下图所示:例程所用到的列扫描线:PC5,PC2,PC3。
例程所用到的行扫描线(EXTI中断线):PE2。
五、实验要求和步骤开发板上有3个蓝色状态指示灯V6(LED1),V7(LED2),V8(LED3),通过对应的按键K1-K3,控制LED的亮灭,将PE2引脚配置为外部中断,当其上出现下降沿时产生一个中断,根据扫描PC5,PC2,PC3来判别是哪个按键按下。
首先我们了解一下什么是外部中断/事件控制器(EXTI)。
外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。
每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。
每个输入线都可以被独立的屏蔽。
挂起寄存器保持着状态线的中断要求。
EXTI控制器的主要特性如下:每个中断/事件都有独立的触发和屏蔽每个中断线都有专用的状态位支持多达19 个中断/事件请求检测脉冲宽度低于APB2 时种宽度的外部信号如要产生中断,中断线必须事先配置好并被激活。
这是根据需要的边沿检测通过设置2个触发寄存器,和在中断屏蔽寄存器的相应位写“1”到来允许中断请求。
当需要的边沿在外部中断线上发生时,将产生一个中断请求,对应的挂起位也随之被置1。
通过写“1”到挂起寄存器,可以清除该中断请求。
为产生事件触发,事件连接线必须事先配置好并被激活。
这是根据需要的边沿检测通过设置2个触发寄存器,和在事件屏蔽寄存器的相应位写“1”到来允许事件请求。
当需要的边沿在事件连线上发生时,将产生一个事件请求脉冲,对应的挂起位不被置1。
定时器中断控制键盘扫描实验实验电路图如下:本实验用定时器1每1ms扫描一次键盘,要求按下s1键时,p3口的8位LED 正向流水点亮;按下s2键时,p3口的8位LED反向流水点亮;按下s3键时,p3口的8位LED熄灭;按下s4键时,p3口的8位LED闪烁。
实验代码:#include<reg51.h>unsigned char tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //段码表sbit S1=P1^4; //将S1位定义为P1.4引脚sbit S2=P1^5; //将S2位定义为P1.5引脚sbit S3=P1^6; //将S3位定义为P1.6引脚sbit S4=P1^7; //将S4位定义为P1.7引脚unsigned char key=0;/*流水灯延时*/void delay0(){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++);}/*软件消抖延时*/void delay1(){unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<100;j++);}/*正转*/void zheng(){int i;for(i=0;i<8;i++){P3=tab[i];delay0();}}/*反转*/void fan(){int i;for(i=7;i>=0;i--){P3=tab[i];delay0();}}/*关闭*/void close(){P3=0xff;}/*闪烁*/void shan(){P3=0xff;delay0();P3=0x00;delay0();}void main(){TMOD=0x10; //定时器1工作与状态1 EA=1; //开总中断ET1=1; //开定时器1中断TH1=(65536-1000)/256; //每1毫秒扫描一次TL1=(65536-1000)%256;TR1=1; //启动定时器1while(1){switch(key){case 1: zheng();break;case 2: fan();break;case 3: close();break;case 4: shan();break;}}}void int1() interrupt 3 using 0{P1=0xf0;TR1=0;if((P1&0xf0)!=0xf0) //判断是否有按键按下{delay1(); //用软件延时消抖if((P1&0xf0)!=0xf0) //再判断{if(S1==0)key=1;if(S2==0)key=2;if(S3==0)key=3;if(S4==0)key=4;}}TH1=(65536-1000)/256;TL1=(65536-1000)%256;TR1=1;}。
随着科技的飞速发展,单片机技术已成为现代电子技术的重要分支。
为了更好地学习和掌握单片机编程及应用,我们设计并实现了一款基于单片机的简易电子琴。
本实验旨在通过设计一个简易电子琴,让学生深入了解单片机的原理和应用,提高动手实践能力。
二、实验目的1. 掌握单片机的基本原理和编程方法。
2. 学会使用定时器、中断、键盘扫描等技术。
3. 了解电子琴的工作原理和制作方法。
4. 培养学生的创新意识和团队协作能力。
三、实验原理本实验采用STC12C5A32S2单片机作为核心控制单元,通过定时器产生方波信号,驱动蜂鸣器发出不同频率的声音,实现电子琴的演奏功能。
具体原理如下:1. 单片机原理:STC12C5A32S2单片机是一款高性能、低功耗的单片机,具有丰富的片上资源,如定时器、中断、串口等。
2. 定时器:定时器用于产生固定频率的方波信号,驱动蜂鸣器发出不同频率的声音。
通过调整定时器的计数值,可以改变方波信号的频率,从而改变音调。
3. 中断:中断技术用于实现按键扫描功能。
当按键被按下时,单片机响应中断,读取按键状态,并产生相应的音调。
4. 键盘扫描:键盘扫描技术用于检测按键状态。
通过扫描键盘矩阵,可以判断哪个按键被按下,并产生相应的音调。
四、实验内容1. 硬件设计:主要包括单片机、蜂鸣器、键盘、电阻、电容等元器件。
将元器件按照电路图连接,形成电子琴的硬件电路。
2. 软件设计:主要包括主程序、定时器中断服务程序、按键扫描程序等。
通过Keil C编程,实现电子琴的演奏功能。
3. 调试与测试:对电子琴进行调试和测试,确保其能够正常工作。
1. 搭建电路:按照电路图连接元器件,形成电子琴的硬件电路。
2. 编写程序:使用Keil C编写主程序、定时器中断服务程序、按键扫描程序等。
3. 编译程序:将编写好的程序编译成HEX文件。
4. 烧录程序:将编译好的HEX文件烧录到单片机中。
5. 调试与测试:使用万用表测试电路是否正常工作,并对程序进行调试,确保电子琴能够正常演奏。
用单片机中断来扫描键盘的程序用单片机中断来扫描键盘的程序/*程序效果:用51单片机的中断来扫描键盘,按下按键,蜂鸣器响,数码管有相应的键值显示,按下E键继电器关,按下C键继电器开。
这与上一程序的功能相同,比上一程序简洁但理解相对困难些。
开发设计:/*/#include<reg52.h> //头文件#include<intrins.h>#define uchar unsigned char //宏定义#define uint unsigned intsbit jdq=P3^5; //位声明,驱动继电器管脚sbit fmq=P3^4; //位声明,驱动蜂鸣器管脚code uchar table[]={0x3f,0x06,0x5b,//数码管显示的数值0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};code uchar key_tab[17]={ //此数组为键盘编码0xed,0x7e,0x7d,0x7b, // 0,1,2,3,0xbe,0xbd,0xbb,0xde, // 4,5,6,7,0xdd,0xdb,0x77,0xb7, // 8,9,a, b,0xee,0xeb,0xd7,0xe7,0xff}; // c,d,e,f,uchar l_key=0x00; //定义变量,存放键值uchar l_keyold=0xff; //作为按键放开否的凭证void readkey(); //扫描键盘,获取键值void display(uchar *lp,uchar lc); //显示子函数void delay(); //延时子函数void main() //主函数{EA=1; //打开总中断EX0=1; //打开外部中断P0=0xf0; //键值高4位为高电平,低4位为低电平while(1){display(&l_key,1); //调用显示子函数if(l_key==14) //是否按下E键,是则关闭继电器jdq=1;if(l_key==12) //是否按下C键,是则打开继电器jdq=0;}}void key_scan() interrupt 0//外部中断0,0的优先级最高{EX0=0; //在读键盘时,关闭外部中断,防止干扰带来的多次中断TMOD&=0xf1; //设置定时器为工作方式1TH0=0x2e; //设置初值,为12毫秒,十进制值为11776TL0=0x00;ET0=1; //开启定时器中断0TR0=1; //启动定时器计数}void time0() interrupt 1 //定时器0的中断函数{TR0=0; //关闭定时器0readkey(); //定时12ms后产生中断,调用此函数,读取键值}void readkey() //扫描键盘子函数{uchar i,j,key; //定义局部变量j=0xfe; //设定初值key=0xff;for(i=0;i<4;i++) // 逐列扫描键盘{P0=j;if((P0&0xf0)!=0xf0) //有按键按下,高4位不可能全为1 {key=P0; //读取P0口的值,推出循环,否则循环下次break;}j=_crol_(j,1); //此函数的功能是:左移循环}if(key==0xff) //如果读取不到P0口的值,如干扰,则返回{l_keyold=0xff;P0=0xf0; // 恢复P0口的值,等待按键按下fmq=1;EX0=1; //在返回前,打开外部中断return;}fmq=0; //有按键按下,打开蜂鸣器if(l_keyold==key) // 检查按键放开否,如果相等表明没有放开{TH0=0x2e; //设置初值TL0=0x00;TR0=1; //继续启动定时器,检查按键放开否return;}TH0=0x2e;TL0=0;TR0=1; //启动定时器l_keyold=key; //获取键值,作为放开否的凭证for(i=0;i<17;i++) //查表获得相应的16进制值存放到l_key中{if(key==key_tab[i]){l_key=i;break;}}//程序运行到此,就表明有键值存放到l_key中,主程序//就可以检测键盘值并作相应的处理}void display(uchar *lp,uchar lc) //显示子函数{uchar i; //定义局部变量P1=0xf8; //点亮第一个数码管P2=0; //P2口为输出值for(i=0;i<lc;i++) //循环显示{P2=table[lp[i]]; //查表获得相应的要显示的数字的数码段delay(); //延时P2=0; //清零,准备显示下一个数值}}void delay() //延时子函数{_nop_();_nop_();_nop_();_nop_();_nop_();}如果程序无法编译,请删除所有前导空白.。
定时器中断控制键盘扫描实验
实验电路图如下:
本实验用定时器1每1ms扫描一次键盘,要求按下s1键时,p3口的8位LED 正向流水点亮;按下s2键时,p3口的8位LED反向流水点亮;按下s3键时,p3口的8位LED熄灭;按下s4键时,p3口的8位LED闪烁。
实验代码:
#include<reg51.h>
unsigned char tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //段码表
sbit S1=P1^4; //将S1位定义为P1.4引脚
sbit S2=P1^5; //将S2位定义为P1.5引脚
sbit S3=P1^6; //将S3位定义为P1.6引脚
sbit S4=P1^7; //将S4位定义为P1.7引脚
unsigned char key=0;
/*流水灯延时*/
void delay0()
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/*软件消抖延时*/
void delay1()
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
;
}
/*正转*/
void zheng()
{
int i;
for(i=0;i<8;i++)
{P3=tab[i];
delay0();}
}
/*反转*/
void fan()
{
int i;
for(i=7;i>=0;i--)
{P3=tab[i];
delay0();}
}
/*关闭*/
void close()
{
P3=0xff;
}
/*闪烁*/
void shan()
{
P3=0xff;
delay0();
P3=0x00;
delay0();
}
void main()
{
TMOD=0x10; //定时器1工作与状态1 EA=1; //开总中断
ET1=1; //开定时器1中断
TH1=(65536-1000)/256; //每1毫秒扫描一次
TL1=(65536-1000)%256;
TR1=1; //启动定时器1
while(1)
{
switch(key)
{
case 1: zheng();
break;
case 2: fan();
break;
case 3: close();
break;
case 4: shan();
break;
}
}
}
void int1() interrupt 3 using 0
{
P1=0xf0;
TR1=0;
if((P1&0xf0)!=0xf0) //判断是否有按键按下{
delay1(); //用软件延时消抖
if((P1&0xf0)!=0xf0) //再判断
{
if(S1==0)
key=1;
if(S2==0)
key=2;
if(S3==0)
key=3;
if(S4==0)
key=4;
}
}
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
TR1=1;
}。