51单片机自学报告--实验部分

news/2024/7/1 3:03:18

微机接口技术-自主学习笔记

PPT链接:微机接口自学--51单片机自学汇报PPT_猫猫爱吃小鱼的博客-CSDN博客

效果演示gif:

 

 

 

 

四、Proteus仿真

仿真环境:电路仿真软件:                       Proteus

                  HEX可执行文件编写软件:    keil uVision4

keil uVision4新建项目简略步骤:

  1. new project,选择使用的芯片(例:AT89C51,AT89C52)。
  2. 创建main.c(或.asm),并添加进project。
  3. 选择生成 HEX 文件 ,因为单片机执行的时候,是通过执行 HEX 文件来执行的。
  4. 添加HEX文件,即可运行

图13 步骤1

 

图14 步骤2

图15 步骤3

可用芯片:AT89C51,AT89C52等,它们的区别如下所示:

(1)、RAM 空间增大:AT89C51 有128 字节的内部 RAM,称之为 DATA 存储区。AT89C52 的内部 RAM 扩展为 256 字节,其中高 128 字节,位于从 80H 开始的地址空间中,称之为 IDATA 存储区,但IDATA 区的访问只能是间接寻址方式。
    (2)、内部 FLASH 变大:AT89C51 有 4K 字节的内部 FLASH PERAM,而。AT89C52 的内部 FLASH PERAM 增加1倍,达到8K。
    (3)、中断源增加:在AT89C52 中P1.0和P1.1还可分别作为定时器/计数器2的外部计数输入(P1.0/T2)和(P1.1/T2EX),也就是说,P1.0同时可作为定时器/计数器 T2 的外部计数输入,和输出占空比 50% 的时钟脉冲端口,P1.1同时可作为定时器/计数器 T2 捕获/重新装载触发和方向控制端口。故,AT89C52 除了具备 AT89C51 的定时器/计数器 T0 和定时器/计数器 T1,还额外增加了一个定时器/计数器 T2。而定时器/计数器 T2 的控制和状态位单独位于T2CON、T2MOD,定时器/计数器 T2 在 16 位捕获方式或自动重新装载方式下的捕获/重载寄存器组是(TCAO2H、RCAP2L)。

4.1 简单LED灯的控制

这是一个简单来理解51单片机定时和计数的例子。

(1)先来介绍定时功能,当作为定时使用时,配置步骤:模式设置,配置TMOD寄存器;定时器初值设置 假设10ms中断;开定时器中断;开总中断;打开定时器。流程图如下图所示:

 

图16 定时器中断方式计时流程图

仿真电路图绘制如下图所示,实现每一秒点亮LED一次:

所含电路元器件:单片机AT89C51(频率12M),LED灯,电阻,电容,电源和地等(CRYSTAL和电容组成不可编程模块,可不添加)

 图17 定时点亮LED仿真电路

LED-RED接引脚P1.0,程序中需要这样配置:

sbit led=P1^0;

采用的是定时器0,16位定时器/计数器工作模式(工作与式1),参照图 TMOD格式

 图18 TMOD格式

程序中需要这样配置:

TMOD=0X01;

 因为:1s=50ms*20,对于12M的晶振单片机,12MHz除12为1MHz,也就是说一秒=1000000次机器周期,50ms=50000次机器周期;所以计数值为50000,每中断20次,则点亮LED灯。

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

........

//中断服务子程序

void time0() interrupt 1 {

TH0=(65536-50000)/256;      //重装初值

TL0=(65536-50000)%256;

a++;

}

a每加到20,则点亮LED灯,同时置0,需要注意每次触发中断后,都需要重新装入初值。

 图19 LED点亮

(2)定时计数器作为计数器使用,配置步骤如下:

1.模式设置,配置TMOD寄存器。

2.开计数器中断

3.开总中断

4.打开计数器

注意: 计数器可以不开中断,这样溢出时只是不会进去中断服务程序。

仿真电路图绘制如下图所示,实现每按五次按键(P3.4引脚)点亮LED一次:

 

图20 计数方式点亮LED灯

LED灯接法和定时方式下一样,但是TMOD寄存器配置不一样了,本设计中TMOD的D2位C/T为设为1,选择计数功能:

sbit led=P1^0;

 sbit s=P3^4;

TMOD=0x05; //模式设置,00000101,采用的是计数器0,工作模式1

比较定时方式下的电路,在这边的P3.4/T0口接了一个简单的开关电路,对P3.4口进行下降沿的脉冲计数。因为TR0:T0充许计数控制位,为1时充许T0计数(定时),所以初始化时需要将 TR0置1。

 TR0=1;    

本次的设计是用count存储计数值,到了5次,则人为让计数器进入中断,使得TH0和TL0溢出,进行中断处理。

   count=(TH0<<8)|TL0;

        if((count*10000)==50000)//按5下按键led状态取反  

            {

                led=0;

                TH0=0XFF;

                TL0=0XFF; //人为的让计数器进入中断

            }

中断服务程序中,使LED灯亮。

 图21  LED灯点亮

4.2 流水灯控制(定时器中断控制的独立式键盘扫描)

使用定时器中断控制获得按键值,实现按下S1,D8-D1循环点亮;按下S2,D1-D8循环点亮;按下S3,全部熄灭;按下S4,D1-D8同频率闪烁。仿真电路图设计如下:

 图22 按键控制流水灯方式

D1-D8接AT89C51的P3口,按键电路接P1口。

设计要点如下:

1.考虑到实际电路中按键的不稳定性,需要对按键进行消抖设计。

2.计数初值的选择,检测按键需要迅速。

3.LED需要一定的延时,不然看不到灯亮。

4.LED点亮方式P3由口的值进行控制。

基于以上的设计要点,消抖设计的时间为20ms,每次检测到有按键按下时,都先进行消抖延时:

void delay20ms(void)

{ unsigned char i,j;

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

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

}

计数初值选择1000,检测的比较迅速。P3口直接改变值,再适当延长时间来控制LED灯的流水状况。

P3=0xfe;         //第一个灯亮

led_delay();

P3=0xfd;          //第二个灯亮

led_delay();

P3=0xfb;          //第三个灯亮

led_delay();

P3=0xf7;          //第四个灯亮

led_delay();

P3=0xef;          //第五个灯亮

led_delay();

P3=0xdf;          //第六个灯亮

led_delay();

P3=0xbf;          //第七个灯亮

led_delay();

P3=0x7f;          //第八个灯亮

led_delay();  

运行结果如下图所示(左上为S1方式,右上为S2方式,左下为S3方式,右下为S4方式):

 

图23 流水灯结果

4.3 液晶时钟设计

基于51单片机实现计时(24小时制),并显示在LCD1602屏幕上。先来简单介绍下LCD1602液晶显示屏。

LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。它的引脚说明如下表所示:

表4 LCD引脚说明

编号

符号

引脚说明

标号

符号

引脚说明

1

VSS

电源地

9

D2|

数据

2

VDD

电源正极

10

D3

数据

3

VL

液晶显示偏压

11

D4

数据

4

RS

数据/命令选择

12

D5

数据

5

R/W

读/写选择

13

D6

数据

6

E

使能信号

14

D7

数据

7

D0

数据

15

BLA

背光源正极

8

D1

数据

16

BLK

背光源负极

引脚的具体功能不再进行展开,简单地介绍下我们本次设计中用到的几个指令(具体指令设计不再阐述):

表5 LCD指令

序号

指令

RS

R/W

D7

D6

D5

D4

D3

D2

D1

D0

1

清屏

0

0

0

0

0

0

0

0

0

1

2

初始化

0

0

0

0

1

1

1

0

0

0

3

开显示,无光标,不闪烁

0

0

0

0

0

0

1

1

0

0

4

光标右移,字符不移

0

0

0

0

0

0

0

1

1

0

仿真电路图设计如下图:

图24 液晶时钟仿真设计图

 

LCD1602的D0-D7连接AT89C52的P0端口,将RS位,定义为P2.0引脚,将RW位定义为P2.1引脚,将E位定义为P2.2引脚,将BF(忙碌标志位)位定义为P0.7引脚。

BF是忙碌标志位,每次写数据前都需检查显示屏是否忙碌,端口为1,则是忙碌,等待。为0则空闲,直接写数据。读时需注意:RS为低电平,RW为高电平时,可以读状态,即RS=0,RW=1,E=1

才允许读写。读完BF,将E恢复低电平,使E=0;    

LCD的初始化如下:

WriteInstruction(0x38); //确保初始化成功

delay(5);

WriteInstruction(0x0c);  //显示模式设置:显示开,无光标,光标不闪烁

delay(5);

WriteInstruction(0x06);  //显示模式设置:光标右移,字符不移

delay(5);

WriteInstruction(0x01);  //清屏幕指令,将以前的显示内容清除

delay(5);

将字符写进LCD中时,需要指定字符的位置,我们需要写两个函数,先指定位置,再写数据。

指定字符的实际地址函数为:

 void WriteAddress(unsigned char x)

 {

     WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"

 }

写数据时,RS为高电平,RW为低电平时,可以写入数据, 即RS=1,RW=0,E从0到1发生正跳变,将数据送入P0口,即将数据写入液晶模块,当E由高电平跳变成低电平时,液晶模块开始执行命令。

时间采用24小时制,控制程序就是中断服务程序,如下所示:

     count++;  //每产生1次中断,中断累计次数加1

if(count==20)  //如果中断次数计满20次

{count=0;  //中断累计次数清0

   s++;  }    //秒加1

if(s==60)   //如果计满60秒

{s=0;     //秒清0

   m++;    }    //分钟加1

if(m==60)    //如果计满60分

 { m=0;   //分钟清0

h++;    //小时加1

    }

if(h==24)  //如果计满24小时

  { h=0;   //小时清0

   }

计数器的初值:

TH0=(65536-46083)/256;   //定时器T0高8位重新赋初值

TL0=(65536-46083)%256;   //定时器T0低8位重新赋初值

因为晶振为11.059Mhz,11.0592MHz除12为921600Hz,就是一秒921600次机器周期,10ms=9216次机器周期。所以1s=20*50ms,而50ms=46083,所以计数初值为46083,可以实现比较精确的秒计时。

写时分秒分别写一个函数,时的函数如下:

void DisplayHour()

{

   unsigned char i,j;

i=h/10;                //取整运算,求得十位数字

j=h%10;                //取余运算,求得各位数字

   WriteAddress(0x44);   //写显示地址,将十位数字显示在第2行第5列

WriteData(digit[i]);  //将十位数字的字符常量写入LCD

WriteData(digit[j]);  //将个位数字的字符常量写入LCD

     

 }

分和秒的类似,只是写的地址不同(在屏幕上显示的位置不同),不在具体阐述。

结果如下图所示:

 图25 液晶时钟

和精确时钟进行对比,还是很精准的。短时间内没有任何问题。如果想改开始时间,则可以直接在源程序中改,加日期也是一样的道理。


http://lihuaxi.xjx100.cn/news/307425.html

相关文章

设计模型之单例设计

前言 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被…

【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总

目录 1.A题&#xff08;进制位数&#xff09; 位运算符 第一期 问题描述 解析 第二期 解析 代码 2.B题&#xff08;日期问题&#xff09; 第一期 问题描述 解析 代码实现 执行结果 第二期 问题描述 解析 3.C题&#xff08;数学问题&#xff09; 第一期 问题…

4. 死信队列

二八佳人体似酥&#xff0c;腰间仗剑斩愚夫。虽然不见人头落&#xff0c;暗里教君骨髓枯。 死信 概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将…

第十二章 Amortized Analysis平摊分析

第12章 Amortized Analysis平摊分析第10周 记于2022/11/29概率分析与平摊分析的区别概率分析平均执行时间考虑同一算法的所有可能输入情况 如果使用概率,则称为期望运行时间 针对单一操作/算法平摊分析针对某一数据结构的 操作序列 不使用概率 操作序列中的平均操作性能/代价【…

效率工具之Arthas

Arthas 阿里巴巴开源的Java诊断工具&#xff1b;追踪方法执行链、反编译、监控JVM状态 在线安装 使用 1. trace 跟踪调用链 解决痛点&#xff1a;定位问题根据日志推理分析&#xff0c;方法出入参不可见&#xff0c;分支判断太多情况下 定位很慢&#xff0c;分析出可能有问…

html5期末大作业——HTML+CSS公益关爱残疾人( 6个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

C++-关键字:auto

C98 auto 早在C98标准中就存在了auto关键字&#xff0c;那时的auto用于声明变量为自动变量&#xff0c;自动变量意为拥有自动的生命期&#xff0c;这是多余的&#xff0c;因为就算不使用auto声明&#xff0c;变量依旧拥有自动的生命期&#xff1a; int a 10 ; //拥有自动生命…

【算法】排序——直接排序

内部排序的全部过程都是在内存中进行的。按排序策略的不同可以将内部排序划分为直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序等。其中前三种排序方法属于简单的排序方法&#xff0c;其特点是排序过程直观、易于理解和实现&#xff0…