p1口输入输出实验c语言程序,51单片机P1口输入输出实验实验报告.doc

51单片机P1口输入输出实验实验报告

实验一 P1口输入输出实验一 实验目的

1 掌握P1口作为I/O口时的使用方法。

2 理解读引脚和读锁存器的区别。

实验原理 由 AT89C51 组成的单片机系统,通常情况下 P0 口分时复用作为地址、数据总线, P2 口提供 A15-A8 即高 8 位地址, P3 口用作第二功能,只有 P1 口用作 I/O 口。 P1 口是 8 位准双向口,它的每一位都可独立地定义为输入或输出。既可作为 8 位的并行 I/O 口,也可作为 8 个不同的输入输出端。 P1 口的结构如图 2.1 所示,当其工作在输入方式时,对应锁存器必须先写 1 ,才能正确地读到引脚上的信号,否则,若对应锁存器的值为 0 ,执行读引脚指令时,读到的结果永远为 0 。每个 I/O 端口都有两种读入,即读锁存器和读引脚,读引脚指令一般都是以 I/O 端口为源操作数的指令,如 MOV C , P1.3 ,而读锁存器指令一般为“读 - 修改 - 写”指令,如 ANL P1.3 , C 指令,请同学们在实验中体会。图 2 中, P1.2 作为输出口, P1.3 作为输入口。

实验内容与要求

编写程序实现当P1.3为低电平时(SW1闭合),发光管亮;P1.3为高电平时发光管灭。

修改程序在执行读P1.3之前,先执行CLR P1.3,观察结果是否正确,分析在第二种情况下程序为什么不能正确执行,理解读引脚和读锁存器区别。 ORG 0000H

MAIN: MOV SP,#60H ; 设置堆栈指针SP为60H

MOV P1,#0FFH ;当P1口用作输入时,所有位对应的锁存器必须先置1

LOOP: ;CLR P1.3

MOV C,P1.3 ;读P1.3

JC LIGHT

CLR P1.2 ;LED灭

SJMP LOOP

LIGHT: SETB P1.2 ;LED 亮

SJMP LOOP

RET

END

若在执行读P1.3之前,先执行CLR P1.3,观察结果正确在执行读P1.3之前,先执行CLR P1.3,观察结果正确,程序不能正确执行,锁存器读引脚和读锁存器区别第一种方式是将引脚作为输入,那是真正地从外部引脚读进输入的值,第二种方式是该引脚处于输出状态时,有时需要改变这一位的状态,则并不需要真正地读引脚状态,而只是读入锁存器的状态,然后作某种变换后再输出。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,由于涉及到版权问题,我无法提供该文档的代码。但是,以下是一个简单的51单片机测速程序的示例代码,仅供参考: ``` #include <reg52.h> #include <intrins.h> sbit motor_pin = P1^0; // 电机控制引脚,此处为P1.0 sbit sensor_pin = P3^2; // 光电编码器输出引脚,此处为P3.2 unsigned char count = 0; // 计数器,记录电机转动次数 unsigned char speed = 0; // 电机转速,单位:r/min void delay(unsigned int t) // 延时函数 { unsigned int i, j; for (i = t; i > 0; i--) for (j = 110; j > 0; j--); } void main() { TMOD = 0x05; // 设置定时器0为模式1,定时器1为模式0 TH0 = 0x00; // 定时器0的初始计数值为0 TL0 = 0x00; TH1 = 0x00; // 定时器1的初始计数值为0 TL1 = 0x00; ET0 = 1; // 允许定时器0中断 TR0 = 1; // 启动定时器0 EA = 1; // 允许总中断开关 while (1) { motor_pin = 1; // 电机开始转动 delay(1000); // 延时1秒钟,让电机转动一定的时间 motor_pin = 0; // 电机停止转动 speed = count * 60; // 计算电机转速 count = 0; // 计数器清零 // 将电机转速通过串口输出 // ... } } void timer0_isr() interrupt 1 // 定时器0中断服务函数 { static bit sensor_state = 0; // 光电编码器状态,0表示未检测到光电信号,1表示检测到光电信号 TH0 = 0x4C; // 定时器0的重载值,使定时器计数1ms TL0 = 0x00; if (sensor_pin == 0 && sensor_state == 1) // 电机转动一圈 { count++; // 计数器加1 sensor_state = 0; // 光电编码器状态置为0 } else if (sensor_pin == 1 && sensor_state == 0) // 电机转动未满一圈 sensor_state = 1; // 光电编码器状态置为1 } ``` 上述代码实现的功能为通过光电编码器测量电机转速。在程序中,通过定时器0产生1ms的定时中断,检测光电编码器输出引脚的状态,当检测到从高电平到低电平的跳变时,表示电机转动一圈,计数器加1;反之,表示电机转动未满一圈。通过计算计数器的值,即可得到电机的转速。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值