当前位置:文档之家› 5个IO口最多能扫描多少个按键

5个IO口最多能扫描多少个按键

5个IO口最多能扫描多少个按键
5个IO口最多能扫描多少个按键

5个IO口最多能扫描多少个按键?

简介:在做项目(工程)的时候,我们经常要用到比较多的按键,而且IO资源紧张,于是我们就想方设法地在别的模块中节省IO口,好不容易挤出一两个IO口,却发现仍然不够用,实在没办法了就添加一个IC来扫键。一个IC虽然价 ...

在做项目(工程)的时候,我们经常要用到比较多的按键,而且IO资源紧张,于是我们就想方设法地在别的模块中节省IO口,好不容易挤出一两个IO口,却发现仍然不够用,实在没办法了就添加一个IC来扫键。一个IC虽然价格不高,但对于大批量生产而且产品利润低的厂家来说,这是一笔不菲的开支!

那,我们能不能想到比较好的扫键方法:用最少的IO口,扫最多的键?可以吗?

举个例:给出5个IO口,能扫多少键?有人说是2*3=6个,如图一:

图一

对,大部分技术参考书都这么做,我们也经常这样做:用3个IO口作行扫描,2个IO作列检测(为方便描述,我们约定:设置某一IO口输出为“0”――称其为“扫某IO口”)。

用行线输出扫键码,列线检测是否有按键的查询方法进行扫键。扫键流程:在行线依次输出011,101,110扫键值,行线每输出一个扫键值,列线检测一次。当列线检测到有按键时,结合输出的扫键值可以判断相应的按键。

但是,5个IO真的只能扫6个键吗?有人说可以扫9个,很聪明!利用行IO与地衍生3

个键(要注意上拉电阻),如图二:

图二

扫键流程:先检测3个行IO口,对K1’,K2’,K3’进行扫键,之后如上述2*3扫键流程。5个IO口能扫9个键,够厉害吧,足足比6个键多了1/2!

动动脑,还能不能再多扫几个?就几个?一个也行!好,再想一下,硬是被逼出来了!如图三:

图三

不多不少,正好10个键!这种扫键方式比较少见吧!漂亮!扫键流程:设IO1输出为“0”,检测IO2…IO5,若判断有相应健按下,则可知有健;若无键,则继续扫键:设IO2输出为“0”,检测IO3,IO4,IO5,判断有无键按下,如此类推。这里应注意:当扫某一IO口(输出为“0”)时,不要去检测已经扫过的IO口。如:此时设置IO2输出为“0”,依次检测

IO3,IO4,IO5,但不要去检测IO1,否则会出错(为什么,请思考)。

感觉怎么样?不错吧!让我们再看看图三,好有成就感!看着,看着……又看到了什么?快!见图四:

图四

真强!被您看出20个键!多了一个对称的三角形。可是,像这样的排列能正确扫20个键吗?回答是肯定的:不能!上下三角形相互对称,其对称扫出的键无法区别。有没有注意到分析图三时提到的注意点?(à“当扫某IO口时,不要去检测已经扫过的IO口,否则会出错”)我们分析一下图四:当IO1输出“0”时,按下K11或K11’键都能被IO2检测到,但IO2检测却无法区别K11和K11’键!同理,不管扫哪个IO口,都有两个对称的键不能区分。

我们假想,如果能把对称键区分开来,我们就能正常地去判断按键。我们在思考:有没有单向导通性器件?有!见图五!

图五

很巧妙的思路!利用二极管的单向导通性,区别两个对称键。扫键思路:对逐个IO口扫键,其他四个IO口可以分别检测其所在的四个按键。这样,就不会有分析图三时提到的注意点。够酷吧!等等,大家先别满足现状,我们再看一下图二,是不是有点启发?对,我们再分析一下“用5个IO口对地衍生的5个键”。看图六:

图六

25个键!5个IO口扫出25个键!先别激动,我们再分析一下它的可行性,分析通得过才能真正使用。假设扫键流程:先扫对地的5个键,再如图五扫键。先扫对地5个键,判断没有按键,接着对逐一对IO口进行扫键。但当对某一IO口扫键时,如果有对地的键按下,这时有可能会误判按键,因为对地键比其他键有更高的响应优先级。例如:扫IO1,IO1输出“0”,恰好此时K62按下,IO2检测到有按键,那就不能判断是K11还是K62。我们可以在程序上避免这种按键误判:若IO2检测到有按键,那下一步就去判断是否有对地键按下,如果没有,那就可以正确地判断是K11了。

我们小结扫键个数S:

S = (N-1)*N + N ――启用二极管

S = (N-1)*N /2 + N ――省掉二极管

经典吗?太经典了!!告诉大家一个小道消息:第一个设计出此电路的人是一个美国大佬,他(她?)还为此申请了专利!

示例代码如下(出自孩儿们之手哈):

硬件描述:

键盘连接说明;

IO2 PC2

IO3 PC3

IO4 PC4

IO5 PC5

核心函数:

/***********************************************************

* 函数说明:五个端口扫描25个键盘的函数*

* 输入:无*

* 输出:键盘编号*

* 调用函数:无*

***********************************************************/

UINT8 _25Key_Scan(void)

{

UINT8 i = 0,Key_Num = 0;

//扫描最下面一行开关

DDRC |= BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC4)|BIT(PC5); PORTC |= BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC4)|BIT(PC5);

NOP();

NOP();

for(i = 1; i <= 5; i++)

{

if(!(PINC & BIT(i))) //PCi=0

{

Key_Num = i+20;

return Key_Num;

}

}

//扫描第一行开关

DDRC |= BIT(PC1); //PC1 输出

PORTC &= ~BIT(PC1); //PC1=0

DDRC &= ~(BIT(PC2)|BIT(PC3)|BIT(PC4)|BIT(PC5)); //PC2-PC5 输入PORTC |= BIT(PC2)|BIT(PC3)|BIT(PC4)|BIT(PC5); //PC2~PC5=1

NOP();

for(i = 2; i <=5; i++)

{

if(!((PINC & BIT(i))))

{

Key_Num = i-1;

return Key_Num;

}

}

//扫描第二行开关

DDRC |= BIT(PC2); //PC2 输出

PORTC &= ~BIT(PC2); //PC2=0

DDRC &= ~(BIT(PC1)|BIT(PC3)|BIT(PC4)|BIT(PC5)); //PC1、PC3-PC5 输入PORTC |= BIT(PC1)|BIT(PC3)|BIT(PC4)|BIT(PC5); //PC1、PC3~PC5=1

if(!(PINC & BIT(1)))

{

Key_Num = 5;

return Key_Num;

}

else

{

for(i = 3; i <= 5; i++)

{

if(!(PINC & BIT(i)))

{

Key_Num = i+3;

return Key_Num;

}

}

}

//扫描第三行开关

DDRC |= BIT(PC3); //PC3 输出

PORTC &= ~BIT(PC3); //PC2=0

DDRC &= ~(BIT(PC1)|BIT(PC2)|BIT(PC4)|BIT(PC5)); //PC1、PC2、PC4、PC5 输入PORTC |= BIT(PC1)|BIT(PC2)|BIT(PC4)|BIT(PC5); //PC1、PC2、PC4、PC5=1

if(!(PINC & BIT(1)))

{

Key_Num = 9;

return Key_Num;

}

else if(!(PINC & BIT(2)))

{

Key_Num = 10;

return Key_Num;

}

else if(!(PINC & BIT(4)))

{

Key_Num = 11;

return Key_Num;

}

else if(!(PINC & BIT(5)))

{

Key_Num = 12;

return Key_Num;

}

//扫描第四行开关

DDRC |= BIT(PC4); //PC4 输出

PORTC &= ~BIT(PC4); //PC4=0

DDRC &= ~(BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC5)); //PC1~PC3、PC5 输入PORTC |= BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC5); //PC1~PC3、PC5=1

for(i = 1; i <= 3; i++)

{

if(!(PINC & BIT(i)))

{

Key_Num = i+12;

return Key_Num;

}

}

if(!(PINC & BIT(5)))

{

Key_Num = 16;

return Key_Num;

}

//扫描第五行开关

DDRC |= BIT(PC5); //PC5 输出

PORTC &= ~BIT(PC5); //PC5=0

DDRC &= ~(BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC4)); //PC1-PC4 输入PORTC |= BIT(PC1)|BIT(PC2)|BIT(PC3)|BIT(PC4); //PC1~PC4=1

for(i = 1; i <= 4; i++)

{

if(!(PINC & BIT(i)))

{

Key_Num = i+16;

return Key_Num;

}

}

return Key_Num;

//循环的方法实现使用的是PORTD口

/*

uint8 i = 0, j =0;

DDRD = 0;

PORTD = 0xff;

for(i = 0; i< 5; i++)

{

if(!(PIND&BIT(i)))

{

return i+1;

}

}

for(i = 0; i < 5; i++)

{

DDRD = BIT(i);

PORTD = ~BIT(i);

for(j = 0; j < 5; j++)

{

if((!(PIND&BIT(j)))&&(j != i))

{

if(j>=i)return i*4+j+5;

return i*4+j+6;

}

}

}

return 0;*/

}

根据最新成果,如果只考虑单个按键被按下的情况,键盘已经可以扩展为25 + 5 * (4 * 3 / 2)= 25 + 30 = 55个按键了……

实现这种方法的原理其实很简单。

假设,我们考虑如何解决K11和K12同时被按下的解决方案,此时,只需要:

1、将IO1设置为输入并开启上蜡电阻

2、将IO2设置为输出高电平,将其余IO设置为输出低电平

3、检测IO1的电平来判断K11是否被按下

4、将IO3设置为输出高电平,将其余IO设置为输出低电平

5、检测IO1的电平来判断K12是否被按下

这样就可以单独区别K11和K12了。

继续考虑,当K11和K12同时被按下时,相当于IO2和IO3被短路,如果在IO2和IO3之间增加一个用于短路的按键,就可以扩展一个按键了

如果在IO0为输入状态下,剩下的4个引脚任意选择2个引脚增加短路按键,则可以扩展出C4选2个按键也就是(4 * 3)/(2 * 1)共6个按钮。考虑还可以从5个IO中每次任

选一个座位输入,则一共有C5选1种也就是5 / 1个按钮。这样在原有25基础上可以继续扩出30个按键了。

更多3

?上一篇IPicture

?下一篇使用random_shuffle()算法随机化序列元素

实验三单片机IO口控制实验

实验三单片机I/O口控制实验 一、实验目的 利用单片机的P1口作I/O口,学会利用P1口作为输入和输出口。 二、实验设备及器件 PC机一台 https://www.doczj.com/doc/7611152672.html,单片机仿真器、编程器、实验仪三合一综合开发平台一台 三、实验内容 1.编写一段程序,用P1口作为控制端口,使D1区的LED轮流亮。 2.编写一段程序,用P1.0~P1.6口控制LED,P1.7控制LED的亮和灭(P1.7接按键,按下时LED亮,不按时LED灭)。 四、实验要求 学会使用单片机的P1口作为I/O口,如果有时间用户也可以利用P3口作I/O口来做该试验。 五、实验步骤 1.用导线把A2区的J61接口与D1区的J52接口相连。原理如图所示。 2.先编写一个延时程序。 3.将LED轮流亮的程序编写完整并使用TKStudy ICE仿真器调试运行。 4.使用导线把A2区的J61接口的P1.0~P1.6与D1区的J52接口的LED1~LED7相连,另外A2区J61接口的P1.7与D1区的J53的KEY1相连。原理如上图所示。 5.编写P1.7控制LED的程序,并调试运行。(按下K1看是否全亮) 6.A2区J61接口的P1.7与D1区的J54的SW1相连。然后再使用TKStudy ICE仿真器运行程序,查看结果。 六、实验预习要求 仔细阅读实验箱介绍中的各个接口内容,理解该实验的硬件结构。还可以先把程序编好,然后在Keil C51环境下进行软件仿真。

七、实验参考程序 程序1: ORG 0000H LJMP Main ORG 0100H Main: MOV A,#0FFH CLR C MainLoop: CALL Delay RLC A MOV P1,A SJMP MainLoop Delay: MOV R7, #0 Loop: MOV R6, #0 DJNZ R6, $ DJNZ R6, $ DJNZ R6, $ DJNZ R7, Loop RET END 程序2: ORG 0000H LJMP Main ORG 0100H Main: JB P1.7,SETLED CLRLED: CLR P1.0 CLR P1.1 CLR P1.2 CLR P1.3 CLR P1.4 CLR P1.5 CLR P1.6 SJMP Main SETLED: SETB P1.0 SETB P1.1 SETB P1.2 SETB P1.3

单片机io口控制实验报告

单片机实验报告 实验名称:I/O口控制 姓名:张昊 学号:110404247 班级:通信2班 时间:2013.11.19 南京理工大学紫金学院电光系

一、实验目的 1、学习I/O口的使用。 2、学习延时子程序的编写和使用。 3、掌握单片机编程器的使用和芯片烧写方法。 二、实验原理 1、广告流水灯实验 (1)做单一灯的左移右移,八个发光二极管L1~L8分别接在单片机的P1.0~P1.7接口上,输出“0”的时候,发光二极管亮,开始时 P1.0->P1.1->P1.2->P1.3->...->P1.7->P1.6->...P1.0亮,重复循 环。 (2)系统板上硬件连线:把“单片机系统”A2区的J61接口的P1.0~P1.6端口与D1区的J52接口相连。要求:P1.0对应着L1,P1.1对应 L2,……,P1.7对应着L8。 P1口广告流水灯实验原理图如下

程序设计流程:流程图如下 2、模拟开关实验 (1)监视开关K1(接在P3.0端口上),用发光二极管L1(接在单片机P1.0端口上)显示开关状态,如果开关合上,L1亮,开关打开, L1熄火。 (2)系统板上硬件连线:把“单片机系统”A2区的P1.0端口用导线连接到D1区的LED1端口上;把“单片机系统”A2区的P3.0端口用 导线连接到D1区的KEY1端口上; 实验原理图如下图

程序设计流程 二、实验内容 1、流水灯 #include sbit p10=P1^0; sbit p11=P1^1; sbit p12=P1^2; sbit p13=P1^3; sbit p14=P1^4; sbit p15=P1^5; sbit p16=P1^6; sbit p17=P1^7; unsigned char count=0; bit flag; void main() {

IO口高低电平控制控制小灯

IO口高低电平控制 内容:左移,直至LED全部点亮,左移符号<< ------------------------------------------------*/ #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义void Delay(unsigned int t); //函数声明 /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char i; //定义一个无符号字符型局部变量i 取值范围0~255 Delay(50000); P1=0xfe; //赋初始值 for(i=0;i<8;i++) //加入for循环,表明for循环大括号中的程序循环执行8次 { Delay(50000); P1<<=1; } while (1) //主循环 { //主循环中添加其他需要一直工作的程序 } } /*------------------------------------------------ 延时函数,含有输入参数unsigned int t,无返回值 unsigned int 是定义无符号整形变量,其值的范围是 0~65535 ------------------------------------------------*/ void Delay(unsigned int t) { while(--t); }

实验2+++并行IO口的使用

实验二并行I/O端口的使用 一、实验目的 1.进一步熟悉Keil C、proteus软件的使用方法。 2.掌握分支结构语句、运算符和数组的运用。 3.掌握LED数码管的结构和静态显示工作原理。 二、实验内容 1.程序一:按键K0~K3,用分支语句实现P0口的多值输出。 2.程序二:用循环语句实现P0口的多值输出。 3.程序三:用数组方式控制跑马灯。 4程序四:在P2口连接的LED数码管上循环显示“0”,“1”,“2”,“3”,“4”。 三、实验仿真硬件图 在Proteus软件中建立如下图所示仿真模型并保存。 图2-1 并行I/O端口应用原理图 四、编程提示 程序一:分别用if语句、if-else-if语句、switch语句来实现当按下按键K0~K3时,对应D1~D4点亮。 程序二:运用三种基本的循环语句: for语句、while语句和do-while语句,实现D1~D8循环点亮。 程序三:用数组方式控制跑马灯。将跑马灯的全部状态用数组表达,然后用循环语句依次读取数组各元素,送P0口显示。 程序四:在P2口连接的LED数码管上循环显示“0”,“1”,“2”,“3”,“4”。思路同程序一,只不过数组元素是由共阴极数码管所对应的字形码所组成。 五、调试运行 1.四个程序在proteus仿真通过。

分别用if语句、if-else-if语句、switch语句来实现当按下按键K0~K3时,对应D1~D4点亮。 if语句的一般形式: if ( 表达式1 ) { 语句组1; } if ( 表达式 2) { 语句组2; } ... if-else-if语句的一般形式: if ( 表达式 1) { 语句组1; } else if( 表达式 2) { 语句组2; } ... else if( 表达式 n) { 语句组n; } else { 语句组n+1; } switch语句的一般形式为: switch(表达式) { case常量表达式1: 语句序列1;break; case常量表达式2: 语句序列2;break; ... case常量表达式n: 语句序列n;break; default : 语句序列n+1 } 2.运用三种基本的循环语句: for语句、while语句和do-while语句,实现D1~D8循环点亮。 for语句的一般形式:

单片机实验-IO口输入输出实验

实验二I/O口输入、输出实验 一、实验目的 1. 学习I/O口的使用方法。 2. 学习延时子程序、查表程序的编写和使用。 二、参考程序框图 led灯 500ms DJNZ R6,DE2; DJNZ R7,DE1; RET END 2、I/O口输入输出(方法一) ORG 0000H; START : MOV P2,#00H; //初始化 MOV P0,#00H; MOV P1,#0FFH; //p1 MOV DPTR,#TABLE; // MOV 50H,#0FEH; // L0 :MOV A,P1; //按键消抖 CJNE A,#0FFH,L1; AJMP L0; L1 :MOV A,P1; CJNE A,#0FFH,LL1; AJMP L0; LL1 :CJNE A,50H,LL2; //是否与地址50h中数据相等MOV P0,A; //相等输出对应led灯 MOV A,#00H; MOVC A,@A+DPTR;

MOV P2,A; //输出表格数据到数码管 LCALL DELAY; //延时 LJMP START; //返回程序开头 LL2 :XCH A,50H; //交换数据 RL A; //左移 XCH A,50H; //再次交换,此时地址50h中数据左移一位 INC DPTR; //表格数据地址加一 LJMP LL1; //返回继续比较 DELAY : MOV R7,#01H; //延时程序 DE1 : MOV R6,#28H; DE2 : MOV R5,#5AH; DJNZ R5,$; DJNZ R6,DE2; DJNZ R7,DE1; RET TABLE : ;//DB 0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H; DB 06H,5BH,4FH,66H,6DH,7DH,07H,7FH; //表格数据 END 程序二(方法二) ORG 0000H MOV P2,#00H; //I./O口初始化 MOV P1,#0FFH; //P1口赋FFH初值 MOV P0,#00H; START : MOV P2,#00H; //P2清0; MOV P0,#00H; //P0清0; MOV R1 ,P1; MOV A,R1; //读P1口 CJNE A,#0FFH,L1; //是否有数据输入 AJMP START; //无输入则跳转,继续查询 LCALL DELAY; L1 : MOV R1,P1; //消除按键抖动 MOV A,R1; CJNE A, #0FFH,LL1; AJMP START; LL1 : CJNE A,#0FEH,LL2; //是否按键1输入 MOV P2,#06H; //是则P2输出相应的按键号码 CPL A; //A取反 MOV P0,A; //输出到P0口 LCALL DELAY; //延迟 AJMP LP; //跳转到LP LL2 : CJNE A,#0FDH,LL3; //是否按键2输入 MOV P2,#5BH; //以下同上 CPL A;

单片机io口实验报告

实验一 以下所有KEIL工程、程序均命名为自己姓名的拼音 一、实验目的: 熟悉KEIL软件的开发,掌握程序下载流程 二、实验环境: 1.硬件:PC微机、单片机开发板 2.软件:KEIL 三、实验步骤: 1.在KEIL中新建工程文件,在工程文件下新建C文件“姓名首字母.c”并加入到工程 中(注意C语言编程时,工程中要保留STARTUP.A51汇编文件)。 2.编写程序,初始化内部数据寄存器0x40开始的100个地址单元,写入0x55,然后复 制到0x60开始的存储器中,使用软件仿真的方式调试程序,观察程序模拟运行的结果: #include "reg52.h" unsigned char *p,*q; unsigned char i; int main(){ p=0x40; for(i=0;i<10;i++) { *p=0x55; p++; } for(i=0;i<10;i++) { *p=*q;

q++; p++; while(1); } } 调试时,在调试界面中依次找到 a) 变量观察窗口 b) 存储器窗口 c) 单步运行 d) 全速运行 程序运行结果(存储器窗口截图): 3.编写程序,控制实验板上的LED灯:D1-D3点亮,D4-D7熄灭,D8点亮#include”reg52.h” sbit P1_4=P1^4; int main() { P1_4=0; P0=0x1E;

While(1); } 4.编写C语言程序,实现LED灯循环点亮 #include "reg52.h" void delay (unsigned z) { while(z--); } int main() { unsigned char i; P1&=~(0x01<<4); P0=0xff; i=0x01; while (1) { P0=~i; i=i<<1; if(i==0x0) i=0x01; delay(10000); } } 四、实验总结

STM32_IO口操作

1、不使用库函数的IO口操作 Systick 部分内容属于NVIC控制部分,一共有4个寄存器 SysTick_CTRL, 0xE000E010 -- 控制寄存器默认值:0x0000 0004 SysTick_LOAD, 0xE000E014 -- 重载寄存器默认值:0x0000 0000 SysTick_VAL, 0xE000E018 -- 当前值寄存器默认值:0x0000 0000 SysTick_CALIB, 0xE000E01C -- 校准值寄存器默认值:0x0002328 SysTick_CTRL 寄存器内有4个bit具有意义 第0位:ENABLE,Systick 使能位(0:关闭Systick功能;1:开启Systick功能) 第1位:TICKINT,Systick 中断使能位(0:关闭Systick中断;1:开启Systick中断) 第2位:CLKSOURCE,Systick时钟源选择(0:使用HCLK/8 作为Systick时钟;1:使用HCLK 作为系统时钟) 第16位:COUNTFLAG,Systick计数比较标志 IO口的位操作实现 该部分代码实现对STM32各个IO口的位操作,包括读入和输出。当然在这些函数调用之前,必须先进行IO口时钟的使能和IO口功能定义。此部分仅仅对IO口进行输入输出读取和控制。代码如下: #define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 55

单片机实验-单片机并行IO口的应用实验

单片机并行I/O口的应用实验 一、实验目的 1、熟悉Proteus软件和Keil软件的使用方法。 2、熟悉单片机应用电路的设计方法。 3、掌握单片机并行I/O口的直接应用方法。 4、掌握单片机应用程序的设计和调试方法。 二、实验内容或原理 1、利用单片机并行I/O口控制流水灯。 2、利用单片机并行I/O口控制蜂鸣器。 三、设计要求 1、用Proteus软件画出电路原理图。要求在P1.0至P1.7口 线上分别接LED0至LED7八个发光二极管,在P3.0口线上 接一蜂鸣器。 2、编写程序:要求LED0至LED7以秒速率循环右移。 3、编写程序:要求LED0至LED7以秒速率循环左移。 4、编写程序:要求在灯移动的同时,蜂鸣器逐位报警。 四、实验报告要求 1、实验目的和要求。 2、设计要求。 3、实验程序流程框图和程序清单。 4、电路原理图。 5、实验结果 6、实验总结。 7、思考题。 五、思考题 1、编程实现LED0至LED7以十六进制计数规律亮灯? 原理图:

程序清单: /*(1)LED0~LED7以秒速率循环右移 蜂鸣器逐位报警*/ ORG 0000H MAIN:MOV A, #11111110B;赋初值 LOOP:MOV P1,A ;赋值给P1口 CPL P3.0 ;低电平有效 LCALL DELAY ;调用延时电路 SETB P3.0 ;控制蜂鸣器叫的时间间隔 LCALL DELAY RL A LJMP LOOP DELAY:MOV R7,#0FFH LOOP1:MOV R6,#0F4H LOOP2:MOV R5,#02H DJNZ R5,$ ;"$"当前的PC值,R5的内容减1不为零,继续执行该语句 DJNZ R6,LOOP2 DJNZ R7,LOOP1 RET END /*(2)LED0~LED7以十六进制计数规律亮灯*/ ORG 0000H MOV A,#0FFH LOOP: MOV P1,A LCALL DELAY DEC A CJNE A, #0FFH,LOOP MOV A, #0FFH LJMP LOOP DELAY:MOV R7, #0A7H LOOP1:MOV R6, #0ABH LOOP2:MOV R5, #10H DJNZ R5, $ ;"$"当前的PC值。R5的内容减1不为零 DJNZ R6, LOOP2 DJNZ R7, LOOP1 RET END

51单片机IO口工作原理

51单片机I/O口工作原理 一、P0端口的结构及工作原理 P0端口8位中的一位结构图见下图: 由上图可见,P0端口由锁存器、输入缓冲器、切换开关、一个与非门、一个与门及场效应管驱动电路构成。再看图的右边,标号为P0.X引脚的图标,也就是说P0.X引脚可以是P0.0到P0.7的任何一位,即在P0口有8个与上图相同的电路组成。 下面,我们先就组成P0口的每个单元部份跟大家介绍一下: 先看输入缓冲器:在P0口中,有两个三态的缓冲器,在学数字电路时,我们已知道,三态门有三个状态,即在其的输出端可以是高电平、低电平,同时还有一种就是高阻状态(或称为禁止状态),大家看上图,上面一个是读锁存器的缓冲器,也就是说,要读取D锁存器输出端Q的数据,那就得使读锁存器的这个缓冲器的三态控制端(上图中标号为…读锁存器?端)有效。下面一个是读引脚的缓冲器,要读取P0.X引脚上的数据,也要使标号为…读引脚?的这个三态缓冲器的控制端有效,引脚上的数据才会传输到我们单片机的内部数据总线上。 D锁存器:构成一个锁存器,通常要用一个时序电路,时序的单元电路在学数字电路时我们已知道,一个触发器可以保存一位的二进制数(即具有保持功能),在51单片机的32根I/O口线中都是用一个D触发器来构成锁存器的。大家看上图中的D锁存器,D端是数据输入端,CP是控制端(也就是时序控制信号输

入端),Q是输出端,Q非是反向输出端。 对于D触发器来讲,当D输入端有一个输入信号,如果这时控制端CP没有信号(也就是时序脉冲没有到来),这时输入端D的数据是无法传输到输出端Q及反向输出端Q非的。如果时序控制端CP的时序脉冲一旦到了,这时D端输入的数据就会传输到Q及Q非端。数据传送过来后,当CP时序控制端的时序信号消失了,这时,输出端还会保持着上次输入端D的数据(即把上次的数据锁存起来了)。如果下一个时序控制脉冲信号来了,这时D端的数据才再次传送到Q端,从而改变Q端的状态。 多路开关:在51单片机中,当内部的存储器够用(也就是不需要外扩展存储器时,这里讲的存储器包括数据存储器及程序存储器)时,P0口可以作为通用的输入输出端口(即I/O)使用,对于8031(内部没有ROM)的单片机或者编写的程序超过了单片机内部的存储器容量,需要外扩存储器时,P0口就作为…地址/数据?总线使用。那么这个多路选择开关就是用于选择是做为普通I/O口使用还是作为…数据/地址?总线使用的选择开关了。大家看上图,当多路开关与下面接通时,P0口是作为普通的I/O口使用的,当多路开关是与上面接通时,P0口是作为…地址/数据?总线使用的。 输出驱动部份:从上图中我们已看出,P0口的输出是由两个MOS管组成的推拉式结构,也就是说,这两个MOS管一次只能导通一个,当V1导通时,V2就截止,当V2导通时,V1截止。 与门、与非门:这两个单元电路的逻辑原理我们在第四课数字及常用逻辑电路时已做过介绍,不明白的同学请回到第四节去看看。 前面我们已将P0口的各单元部件进行了一个详细的讲解,下面我们就来研究一下P0口做为I/O口及地址/数据总线使用时的具体工作过程。 1、作为I/O端口使用时的工作原理 P0口作为I/O端口使用时,多路开关的控制信号为0(低电平),看上图中的线线部份,多路开关的控制信号同时与与门的一个输入端是相接的,我们知道与门的逻辑特点是“全1出1,有0出0”那么控制信号是0的话,这时与门输出的也是一个0(低电平),与让的输出是0,V1管就截止,在多路控制开关的控制信号是0(低电平)时,多路开关是与锁存器的Q非端相接的(即P0口作为I/O口线使用)。 P0口用作I/O口线,其由数据总线向引脚输出(即输出状态Output)的工作过程:当写锁存器信号CP 有效,数据总线的信号→锁存器的输入端D→锁存器的反向输出Q非端→多路开关→V2管的栅极→V2的漏极到输出端P0.X。前面我们已讲了,当多路开关的控制信号为低电平0时,与门输出为低电平,V1管是截止的,所以作为输出口时,P0是漏极开路输出,类似于OC门,当驱动上接电流负载时,需要外接上拉

51单片机的一个IO口控制speaker发声

51单片机的一个I/O口控制speaker发声,演奏老鼠爱大米。 主要器件以及电路图 单片机——AT89C51,蜂鸣器——speaker。 C语言程序源码 C语言的程序代码更好读一些,相比较前面两个汇编的蜂鸣器程序,这个程序比较好理解。 /* 蜂鸣器--蜂鸣器奏乐-老鼠爱大米*/ #include #define uint unsigned int #define uchar unsigned char #define ulong unsigned long sbit beep=P2^7; //蜂鸣器输出引脚 uchar th0_f; //中断装载T0高8位 uchar tl0_f; //T0低8位

uchar code freq[36*2]={ //音阶码表0xf7,0xd8, //440hz , 1 //0 0xf8,0x50, //466hz , 1# //1 0xf8,0xbc, //494hz , 2 //2 0xf9,0x26, //524hz , 2# //3 0xf9,0x85, //554hz , 3 //4 0xf9,0xe5, //588hz , 4 //5 0xfa,0x3d, //622hz , 4# //6 0xfa,0x92, //660hz , 5 //7 0xfa,0xdd, //698hz , 5# //8 0xfb,0x29, //740hz , 6 //9 0xfb,0x70, //784hz , 6# //10 0xfb,0xb0, //830hz , 7 //11 0xfb,0xef, //880hz , 1 //12 0xfc,0x29, //932hz , 1# //13 0xfc,0x62, //988hz , 2 //14 0xfc,0x95, //1046hz, 2# //15 0xfc,0xc7, //1108hz, 3 //16 0xfc,0xf5, //1174hz, 4 //17 0xfd,0x20, //1244hz, 4# //18 0xfd,0x4c, //1318hz, 5 //19 0xfd,0x72, //1396hz, 5# //20 0xfd,0x97, //1480hz, 6 //21 0xfd,0xbb, //1568hz, 6# //22 0xfd,0xdc, //1662hz, 7 //23

IO口实验

IO口实验: 参见基础实验1、2、3.(课件第2章单片机结构.doc) 1.输入输出综合实验(查询方式,1S由软件延时控制):要求:每一次按键,蜂鸣器响一次。同时要求LED1~LED8循环点亮。 1)初始状态或按下KEY1键(松开后保持),只点亮一只LED 灯,每隔1秒右循环显示,移到LED8后回到LED1。 LED1LED8 ………………………… LED1LED8 2)按下KEY2键(松开后保持),同时点亮相邻的两只LED 灯,每隔1秒右循环显示,移到LED8后回到LED1。 LED1LED8 3)按下KEY2键(松开后保持),同时点亮间隔的两只LED 灯,每隔1秒右循环显示,移到LED8后回到LED1。 LED1LED8

4)按下KEY2键(松开后保持),点亮一只LED灯,每隔1 秒多点亮一只LED灯,直到LED灯全亮,然后回到一只LED点亮状态循环。 LED1LED8 LED1LED8 ………………………… LED1LED8 5)按下KEY3键(松开后保持),同时点亮相邻的两只LED 灯,隔1秒后再次增加点亮相邻的两只LED灯,直到全亮后再隔1秒点亮123456,后又1234,直到全灭后重新循环。 LED1LED8 LED1LED8 ………………………… LED1LED8 ………………………… LED1LED8 6)按下KEY键(松开后保持),开始点亮LED1灯,隔1秒 后点亮23,再隔1秒点亮345,隔1秒后5678,隔1秒后8,隔1秒后76 ,隔1秒后654,隔1秒后4321,隔

1秒后1重复。 LED1LED8 LED1LED8 LED1LED8 ………………………… LED1LED8 7)按下KEY3键(松开后保持),开始点亮LED1、LED8灯, 隔1秒后点亮12、78,再隔1秒点亮123、678,直到全亮后再隔1秒点亮123、678,后又12、78,直到点亮LED1、LED8灯后重新循环。 LED8 LED1LED8 ………………………… LED1LED8 LED8 ………………………… LED8

单片机实验-IO口的输入输出实验

单片机实验-IO口的输入输出实验

实验二 I/O 口输入、输出实验 一、实验目的 1. 学习I/O 口的使用方法。 2. 学习延时子程序、查表程序的编写和使用。 二、参考程序框图 开延时 设置初始数据输左移开始 读入P1口置计数P1口置1 将读入的值P1=0 Y N 输入值右移Cy=0 N 计数Y 以计数值段码输出

三、程序设计 1、P0口循环点亮程序 ORG 0030H START : MOV P2,#00H; //消影 MOV A ,#01H; // LOOP : MOV P2 ,A; //点亮一个led灯ACALL DELAY; //延时500ms RL A; //左移一位 AJMP LOOP; //跳转循环DELAY : MOV R7,#10; //延时程序 DE1 : MOV R6,#200; DE2 : MOV R5,#123; DJNZ R5,$;

DJNZ R6,DE2; DJNZ R7,DE1; RET END 2、I/O口输入输出(方法一) ORG 0000H; START : MOV P2,#00H; //初始化 MOV P0,#00H; MOV P1,#0FFH; //p1口初始化给ffh值 MOV DPTR,#TABLE; //表地址存入DPTR MOV 50H,#0FEH; //比较初值载入地址50h L0 :MOV A,P1; //按键消抖 CJNE A,#0FFH,L1; AJMP L0; L1 :MOV A,P1; CJNE A,#0FFH,LL1;

AJMP L0; LL1 :CJNE A,50H,LL2; //是否与地址50h 中数据相等 MOV P0,A; //相等输出对应led灯 MOV A,#00H; MOVC A,@A+DPTR; MOV P2,A; //输出表格数据到数码管 LCALL DELAY; //延时 LJMP START; //返回程序开头LL2 :XCH A,50H; //交换数据 RL A; //左移 XCH A,50H; //再次交换,此时地址50h中数据左移一位 INC DPTR; //表格数据地址加一 LJMP LL1; //返回继续比较 DELAY : MOV R7,#01H; //延时程序 DE1 : MOV R6,#28H;

实验三简单IO口扩展实验2

3.2.2简单i/o口扩展实验 一、实验目的: 1.学习在单片机系统中扩展简单I/O接口的方法。 2.学习数据输出程序的设计方法。 3.学习模拟交通灯控制的实现方法。 二、实验设备: EL-MUT-III型实验箱,8051CPU板 三、实验内容: 扩展实验箱上的74LS273做为输出口,控制八个发光二极管燃灭,模拟交通灯管理。 四、实验原理: 要完成本实验,首先必须了解交通路灯的燃灭规律。本实验需要用到实验箱上八个发光二极管中的六个,即红、黄、绿各两个。不妨将L1(红)、L2(绿)、L3(黄)做为东西方向的指示灯,将L5(红)、L6(绿)、L7(黄)做为南北方向的指示灯。而交通灯的燃灭规律为:初始态是两个路口的红灯全亮,之后,东西路口的绿灯亮,南北路口的红灯亮,东西方向通车,延时一段时间后,东西路口绿灯灭,黄灯开始闪烁。闪烁若干次后,东西路口红灯亮,而同时南北路口的绿灯亮,南北方向开始通车,延时一段时间后,南北路口的绿灯灭,黄灯开始闪烁。闪烁若干次后,再切换到东西路口方向,重复上述过程。各发光二极管的阳极通过保护电阻接到+5V的电源上,阴极接到输入端上,因此使其点亮应使相应输入端为低电平。 五、实验原理图 六、实验步骤: 74LS273的输出O0~O7接发光二极管L1~L8,74LS273的片选CS273接片选信号 CSO,此时74LS273的片选地址为CFA0H~CFA7H之间任选。 运行实验程序,观察LED显示情况是否与实验内容相符。 七、程序框图: 八、参考程序:T3.ASM

NAME T3 ;I/O口扩展实验一 PORT EQU 0CFA8H ;片选地址CS0 CSEG AT 0000H LJMP START CSEG AT 4100H START: MOV A,#11H ;两个红灯亮,黄灯、绿灯灭 ACALL DISP ;调用273显示单元(以下雷同) ACALL DE2S ;延时2秒 LLL: MOV A,#12H ;东西路口绿灯亮;南北路口红灯亮ACALL DISP ACALL DE10S ;延时10秒 MOV A,#10H ;东西路口绿灯灭;南北路口红灯亮 ACALL DISP MOV R2,#05H ;R2中的值为黄灯闪烁次数 TTT: MOV A,#14H ;东西路口黄灯亮;南北路口红灯亮ACALL DISP ACALL DE02S ;延时0.2秒 MOV A,#10H ;东西路口黄灯灭;南北路口红灯亮 ACALL DISP ACALL DE02S ;延时0.2秒 DJNZ R2,TTT ;返回TTT,使东西路口黄灯闪烁五次 MOV A,#11H ;两个红灯亮,黄灯、绿灯灭 ACALL DISP ACALL DE02S ;延时0.2秒 MOV A,#21H ;东西路口红灯亮;南北路口绿灯亮 ACALL DISP ACALL DE10S ;延时10秒 MOV A,#01H ;东西路口红灯亮;南北路口绿灯灭 ACALL DISP MOV R2,#05H ;黄灯闪烁五次 GGG: MOV A,#41H ;东西路口红灯亮;南北路口黄灯亮ACALL DISP ACALL DE02S ;延时0.2秒 MOV A,#01H ;东西路口红灯亮;南北路口黄灯灭 ACALL DISP ACALL DE02S ;延时0.2秒 DJNZ R2,GGG ;返回GGG,使南北路口;黄灯闪烁五次 MOV A,#03H ;两个红灯亮,黄灯、绿灯灭 ACALL DISP ACALL DE02S ;延时0.2秒 JMP LLL ;转LLL循环 DE10S: MOV R5,#100 ;延时10秒 JMP DE1 DE3S: MOV R5,#20 ;延时2秒

使用IO口模拟IIC来控制24c

/**********延时函数*****************/ /*----------------------------------------------- delay_us :1us延时函数 ------------------------------------------------*/ void delay_1us(void) { asm("nop"); } /*----------------------------------------------- delay_nus :长延时函数 输入参数: t :延时时间us ------------------------------------------------*/ void delay_us(unsigned int t) { while(t--) delay_1us(); } /*---------------------------------------------- delay_ms :1ms延时函数 -----------------------------------------------*/ void delay_1ms(void) { unsigned int i; for(i=0;i<1140;i++); } /*---------------------------------------------- delay_nms :长延时函数 输入参数: t :延时时间ms -----------------------------------------------*/ void delay_ms(unsigned int t) { while(t--) delay_1ms(); } /*typedef union reccnt { unsigned int rcnt; unsigned char rcntl[2]; }LngToChar;*/ #define sda PC1 #define scl PC0 #define sda_h PORTC|=BIT(sda) #define sda_l PORTC&=~BIT(sda) #define scl_h PORTC|=BIT(scl)

实验1单片机IO口控制实验

实验1 单片机IO口控制实验 1、P0~P3口都是并行I/O口 2、P0口和P2口,还可用来构建系统的数据总线和地址总线,所以在电路中有一个MUX,以进行转换。/P0口的MUX的一个输入端为“地址/数据”信号。/P2口的MUX的一个输入信号为“地址”信号。 3、而P1口和P3口无构建系统的数据总线和地址总线的功能,因此,无MUX。 4、在4个口中只有P0口是一个真正的双向口,P1~P3口都是准双向口。 5、P3口的口线具有第二功能,为系统提供一些控制信号。因此P3口增加了第二功能控制逻辑。这是P3口与其它各口的不同之处。 8051输出模式)、推挽输出/强上拉、仅为输入(高阻)或开漏输出功能。每个口由2个控制寄存器中的相应位控制每个引脚工作类型。 8、STC15F2K60S2系列单片机上电复位后为准双向口/弱上拉(传统8051的I/O口)模式。 9、单片机能及时地响应和处理单片机外部事件或内部事件所提出的中断请求。 10、对事件的整个处理过程,称为中断处理(或中断服务) 13、中断允许寄存器IE

CPU对中断源的开放或屏蔽,由片内的中断允许寄存器IE控制。字节地址为A8H,可位寻址。格式如下 IE对中断的开放和关闭为两级控制:总的开关中断控制位EA(IE.7位): EA=0,所有中断请求被屏蔽。 EA=1,CPU开放中断,但五个中断源的中断请求是否允许,还要由IE中的5个中断请求允许控制位决定。 SETB bit; CLR bit。 14、中断优先级寄存器IP 低优先级可被高优先级中断,反之则不能。 ?同级中断不会被它的同级中断源所中断。 ?若CPU正在执行高优先级的中断,则不能被任何中断源所中断

IO接口控制

一、实验目的 熟悉ARM芯片I/O口编程配置方法。 通过实验掌握ARM芯片的I/O口控制LED显示的方法。 二、实验原理及基本技术路线图(方框原理图) S3C44B0X芯片上共有71个多功能的输入输出管脚,它们分为7组I/O端口。 ●两个9位的输入/输出端口(端口E和F) ●两个8位的输入/输出端口(端口D和G) ●一个16位的输入/输出端口(端口C) ●一个10位的输出端口(端口A) ●一个11位的输出端口(端口B) 每组端口都可以通过软件配置寄存器来满足不同系统和设计的需要。在运行主程序之前,必须先对每一个用到的管脚的功能进行设置,如果某些管脚的复用功能没有使用,可以先将该管脚设置为I/O口。 1.S3C44B0X芯片和端口相关的寄存器有: (1) 端口控制寄存器(PCONA-G) 在S3C44B0X里,大多数的引脚都是多功能引脚。因此,应当为每个引脚选择功能。端口控制寄存器(PCONn)决定了每一个引脚的功能。 (2) 端口数据寄存器(PDATA-G) 如果这些端口被设定为输出端口,输出数据可以被写入到PDATn的相应的位;如果被设定为输入端口,输入数据可以被读到PDATn的相应的位。 (3) 端口上拉寄存器(PUPC-G) 端口上拉寄存器控制着每一个端口组的上拉寄存器的使能端。当相应的位被设为0时,引脚接上拉电阻;当相应的位为1时,引脚不接上拉电阻。 (4) 外部中断控制寄存器(EXTINT) 8个外部中断可以用多种信号方式所请求。外部中断寄存器为外部中断设置了信号触发方法选择位,也设置了触发信号的极性选择位。外部中断请求信号触发的方法有以下几种:低电平触发、高电平触发、下降沿触发、上升沿触发、双沿触发。 8个外部中断寄存器的具体设置情况请详见I/O的特殊功能寄存器。 因为每个外部中断引脚都有一个数字滤波器,这让中断控制器能够识别长于3个时钟周期的请求信号。 在实验板上端口B的引脚PB9和PB10被设置为输出口,并且分别与LED1、LED2连接。 2.电路原理 如图3-3所示,发光二极管LED1和LED2的正极与S3C44B0X芯片的47脚VDD33连接,VDD33可以输出3.3V的电压,负极通过限流电阻R95、R96和S3C44B0X芯片的23脚(NGCS4)、24(NGCS5)脚连接。这两个管脚属于端口B,已经配置为输出口。通过向PDATB寄存器中相应的位写入0或1可以使管脚23、24输出低电平或高电平。当23、24管脚输出低电平时,LED点亮;当23、24管脚输出高电平时,LED熄灭。 三、所用仪器、材料(设备名称、型号、规格等) Embest S3CEV40实验板 ARM软件模拟器

2单片机IO口控制实验实验报告

单片机IO口控制实验 一、实验目的 1、熟悉MCS-51的I/O结构; 2、掌握MCS-51 I/O的使用方法; 3、掌握MCS-51的中断机制。 二、实验原理 1、MCS-51单片机的硬件结构片内结构: 2、内部数据存储器(字节地址为00H~0FH):

3、SFR的名称及其分布: 4、I/O端口地址: 5、P0~P3端口功能总结: (1)P0~P3口都是并行I/O口,但P0口和P2口,还可用来构建系统的数据总线和地址总线,所以在电路中有一个MUX,以进行转换。而P1口和P3口无构建系统的数据总线和地址总线的功能,因此,无MUX。P0口的MUX的一个输入端为“地址/数据”信号。P2口的MUX的一个输入信号为“地址”信号。 (2)在4个口中只有P0口是一个真正的双向口,P1~P3口都是准双向口。 原因:P0口作数据总线使用时,需解决芯片内外的隔离问题,即只有在数据传送时芯片内外才接通;不进行数据传送时,芯片内外应处于隔离状态。为此,

P0口的输出缓冲器应为三态门。P0口中输出三态门是由两只场效应管(FET)组成,所以是一个真正的双向口。 P1~P3口,上拉电阻代替P0口中的场效应管,输出缓冲器不是三态的-准双向口。(3)P3口的口线具有第二功能,为系统提供一些控制信号。 因此P3口增加了第二功能控制逻辑。这是P3口与其它各口的不同之处。 6、P0口结构及特点: ⑴P0口结构与运作 1个输出锁存器,用于进行输出数据的锁存; 2个三态输入缓冲器,分别用于锁存器和引脚数据的输入缓冲;1个多路开关MUX,它的一个输入来自锁存器,另一个输入是地址/数据信号的反相输出。在控制信号的的控制下能实现对锁存器输出端和地址/数据线之间的切换;由两只场效应管组成的输出驱动电路。 ⑵P0口的特点 P0口是一个双功能的端口:地址/数据分时复用口和通用I/O口; 具有高电平、低电平和高阻抗3种状态的I/O端口称为双向I/O端口。P0口作地址/数据总线复用口时,相当于一个真正的双向I/O口。而用作通用I/O口时,由于引脚上需要外接上拉电阻,端口不存在高阻(悬空)状态,此时P0口只是一个准双向口; 为保证引脚上的信号能正确读入,在读入操作前应首先向锁存器写1; 单片机复位后,锁存器自动被置1; 一般情况下,如果P0口已作为地址/数据复用口时,就不能再用作通用I/O口使用;P0口能驱动8个TTL负载。 7、P1口的结构及特点: ⑴P1口结构与运作 一个数据输出锁存器,用于输出数据的锁存; 两个三态输入缓冲器,BUF1用于读锁存器,BUF2用于读引脚; 数据输出驱动电路,由场效应管VT和片内上拉电阻R组成。

相关主题
文本预览
相关文档 最新文档