IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 郭天祥的10天学会51单片机_第三节 -> 正文阅读

[嵌入式]郭天祥的10天学会51单片机_第三节

单片机管脚,P3口有两个功能,上电默认情况下就使用P3口的普通IO口,当对单片机内部的某些寄存器设置时就启用P3口的第二个功能

P3^4和 P3^5可以作为计时器或定时器使用,给这两个口输入方波,进行计数

做一个频率计数器时,当是正弦波时加一个比较器变成方波,送给单片机的计数器端口,由程序来计数,当三角波通过积分变成方波,送给P3^4和 P3^5

XTAL1和XTAL2是外部晶振输入端

TX-1C型单片机实验板原理图中复位电路在右边晶振电路的下面,电容是通交隔直的,当S22按下,上边电路接通,10k和1k电阻分压,5V*10/11,接近5V,所以S22按下后复位;开始上电时也可以复位,通过电容充电,下边电路出现电流,RST接10K电阻会分到电压,上电结束,电容放电,将电通过10K电阻,10K电阻接地,将电流放掉

晶振在复位电路的上面,30P的电容指的是30PF,两个电容是帮助晶振起振;11.0592M的晶振用30P的电容,6M的晶振用20P的电容

20管脚是Vss接地

29管脚是PSEN,一般不用

30管脚是ALE/PROG,PROG编程时用,编程时给31 管脚Vpp端加12V电压才能写入程序;ALE可以输出1/6时钟周期的方波,检测单片机是否正常工作,就用示波器接ALE,看输出是否是1/6个晶振频率的方波

31管脚的EA,见书P11,选择内部存储器或外部存储器;一般EA接高电平,从内部存储器执行

见书P112.3.3P0口是8位三态双向IO口,P1P2P38位准双向IO口;三态是高电平,低电平和高阻态;P0口没有上拉电阻,P1P2P3有上拉电阻;P1P2P38位准双向IO口,是在输入时要先写个1,然后才能输入,即准备一下才能输入

见书P16P26,复位时,P0口、P1P2P3口是0xff,其它寄存器全部清零

LEDLCD显示器有两种显示结构:段显示(7段、米字型等)和点阵显示(5×88×8点阵等)

设计单片机时,一定要给P0口加上拉电阻,电阻值是10K,接法见课件PPTLESSON3_数码管静态显示及定时器和中断应用的P11

数码管内部由8个发光二极管构成

单片机P26连接段锁存端(DULA),P27连接位锁存端(WELA),见电路设计图

快速复制的小技巧:一直按住SHIFT,按下HOME,然后按下DELETE,再按两次INSERT

?

晶振6MHz对应20pF,晶振12MHz对应30pF

?LED显示器分为“共阴极和共阳极两类,见上图,左端为共阴极,右端为共阳极

位选(WE)(程序中为wela):选中一位,单片机上共六个数码管,每一个数码管即一位

段选(程序中为dula):控制一个数码管哪几段亮

见上图共阴极a图,简单的说位选就是位选是右边的接地(第二个锁存器给相应的位WE赋给低电平),段选就是左边的八个管脚(第一个锁存器给相应的段DU赋给低电平)

本教程用共阴极,共阴极就是发光二极管的共阴极接在一起,共阴极的地端就是位选线(对应TX-1C型单片机实验板原理图中的WE),比如给共阴极高电平就不会让该数码管亮,即控制哪个数码管亮,也可以理解成控制哪个位的数码管亮;agdp是段选线,即控制这个数码管的哪几段亮,来显示相应的数字

TX-1C型单片机实验板原理图中的六个数码管的管脚不必管,只要看要显示的数字和锁存器74HC573的位,因为要用单片机直接控制锁存器74HC573

让发光二极管全亮,就给八个二极管高电平,二极管的右边送低电平就可以

一个char型变量是8位,因为要写一个字需要8个位,一个int型的变量是16

TX-1C型单片机实验板原理图中的六个LED就是数码管,LED图中的内部管脚标错了,外部管脚标的是对的,WE1是共阴极端,即段选端,六个数码管所有的段选都是连在一起的,位选是独立开的,通过位选控制某一个数码管亮,通过段选控制该数码管亮什么;见单片机左边的两个锁存器74HC573,第一个锁存器控制数码管的段选,第二个控制数码管的位选,锁存器的输入端是D0到D7,单片机左边紧靠的是10K的上拉电阻,因为P0口是8位三态双向IO口,无法进行低电平或高电平的操作,加个上拉电阻之后一上电就是高电平,然后单片机的P0口通过上拉电阻输入到锁存器;锁存端是高电平时,输入端和输出端是直通的,锁存端是低电平时,输入端和输出端是断开的,输出端保持原来的值,所以先给位选的锁存器的锁存端(WELA)高电平,并控制选择要亮的数码管,然后拉低锁存端,保持住选择的数码管,再把段选的锁存器(DULA)打开,将其锁存端拉高,输入要显示的段,再将锁存端拉低,保持住要显示

锁存器的锁存端一个下降沿将数据保持在锁存器的输出端

两个锁存器的锁存端DULAWELA分别连接单片机的P2^6口和P2^7口,

CSAD是锁存器的片选,高电平有效

共阴数码管码表:

  • 0x3f? , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d ,
  • ?? 0? ? 1? ????? 2? ? 3??????? 4???????? 5
  • ?0x7d , 0x07 , 0x7f? , 0x6f , 0x77 , 0x7c ,
  • ?? 6? ? 7? ????? 8? ? 9??????? A??????? B
  • ?0x39 , 0x5e , 0x79 , 0x71 , 0x00
  • ?? C??????? D??????? E???????? F?????? ???? 无显示

见实验板原理图,LED数码管的管脚8连接WE,就是控制该数码管是否使用

看U2:WELA控制“位”,

想让第一个数码管亮,让WE1=0(共阴极的地端就是位选线,选择哪个数码管,对应位选应该赋给低电平),WE2到WE6和13、12口都为1,即十六进制的fe

#include<reg52.h>

sbit dula=P2^6;

sbit wela=P2^7;

void main()

{

?????? wela=1;//位选锁存器打开

?????? P0=0xfe;//第一个数码管亮, 如果要显示两个就P0=0xfc

?????? wela=0;//位选锁存器关闭,数据保持

?????? dula=1;//段选锁存器打开

?????? P0=0x06;//显示数字1,如果要显示0就,P0=0x3f

?????? dula=0;//段选锁存器关闭,数据保持

?????? while(1);

}

见课件PPT的LESSON3_数码管静态显示及定时器和中断应用,单片机内部的电流很弱,不足以点亮发光二极管,所以要加个上拉电阻用5V电压,才能点亮发光二极管

程序0到F的变化:

#include<reg52.h>

sbit dula=P2^6;

sbit wela=P2^7;

#define uint unsigned int

#define uchar unsigned char

uchar num;//用多大的变量就定义相应的类型

uchar code table[]={? ? ? ? ? ? ?

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delay(uint z);

void main()

{

?????? while(1)

?????? {

????????????? wela=1;

????????????? P0=0xc0;//所有数码管全亮

????????????? wela=0;

????????????? for(num=0;num<16;num++)

????????????? {

???????????????????? dula=1;

???????????????????? P0=table[num];

???????????????????? dula=0;

???????????????????? delay(1000);

????????????? }

?????? }

}

void delay(uint z)//经测试得:z=1时是一毫秒

{

?????? uint x,y;

?????? for(x=z;x>0;x--)

????????????? for(y=110;y>0;y--);

}

第一三五数码管亮:

#include<reg52.h>

sbit dula=P2^6;

sbit wela=P2^7;

#define uint unsigned int

#define uchar unsigned char

uchar num;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delay(uint z);

void main()

{

?????? wela=1;

?????? P0=0xc0;//所有数码管全亮

?????? wela=0;

?????? while(1)

?????? {

???????????????????? for(num=0;num<16;num++)

????????????? {

???????????????????? dula=1;

???????????????????? P0=table[num];

???????????????????? dula=0;

???????????????????? delay(1000);

????????????? }

?????? }

}

void delay(uint z)

{

?????? uint x,y;

?????? for(x=z;x>0;x--)

????????????? for(y=110;y>0;y--);

}

中断:见书P54P55

单片机的核心就是中断,定时器,串口通信

P3.2口控制外部中断0,给低电平时进行中断0

置位表示置1

中断优先级:

?

中断序号:01234,对应上表中的从高到低的顺序中断,外部中断0中断序号是0

中断响应条件:

中断源有中断请求;例如设定中断函数void exter0() interrupt 0

此中断源的中断允许位为1;例如开外部中断0,让IE0=1

CPU开中断(即EA=1)。

以上三条同时满足时,CPU才有可能响应中断。

寄存器的位数能被8整除的寄存器都可以直接进行位寻址,位寻址就是可以直接操作某一位

用杜邦线一端接地一端接P3.2口,即给P3.2口低电平,小灯亮,产生中断,数码管显示数字不变,拔掉杜邦线数码管数字变化:

#include<reg52.h>

sbit dula=P2^6;

sbit wela=P2^7;

sbit d1=P1^0;

#define uint unsigned int

#define uchar unsigned char

uchar num;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delay(uint z);

void main()

{

??? EA=1;//开总中断

?????? IT0=0;//IT0=0为电平触发方式,IT0=1为跳沿触发方式

?????? //IT0=1也可以设置为TCON=0x01;

?????? EX0=1;//开外部中断0,P3.2口有低电平时进行中断0,中断设置好就跳到中断函数处执//行中断函数

?????? wela=1;

?????? P0=0xea;//所有数码管全亮

?????? wela=0;

?????? while(1)

?????? {

???????????????????? for(num=0;num<16;num++)

????????????? {

???????????????????? d1=1;

???????????????????? dula=1;

???????????????????? P0=table[num];

???????????????????? dula=0;

???????????????????? delay(1000);

????????????? }

?????? }

}

void delay(uint z)

{

?????? uint x,y;

?????? for(x=z;x>0;x--)

????????????? for(y=110;y>0;y--);

}

IT0=0为电平触发方式,用杜邦线的两端连接地和P3.2口发光二极管一直亮,数码管一直不变,即一直在中断程序中,直到杜邦线断开;IT0=1为跳沿触发方式,用杜邦线连上,发光二极管亮一下就熄灭,即使杜邦线一直连着二极管也不亮,数码管继续变化,即中断一下跳变沿结束中断就结束,返回主程序

一般中断是设置成跳变沿触发方式,因为如果设置成电平触发方式容易忘记在程序中再给P2.3口高电平,回不去主程序,结束不了中断

void exter0() interrupt 0//interrupt表示中断服务程序,

//interrupt后面的0表示中断序号,中断序号:01234,中断序号是几就对应哪个中//;中断函数不需要声明

{

?????? d1=0;?????

}

由溢出时计数器的值减去计数初值才是加1计数器的计数值。

计数器就是连接P3.4口或P3.5口就自动计数

计数器来源于T0T1引脚输入的外部脉冲源,定时器来源是由系统的时钟振荡器输出脉冲经12分频后送来(即每12个振荡周期即一个机器周期,计数器加1

TCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如下:

?

其中TF1TF0是由单片机自动控制,这里不用管它,我们只需考虑TR1TR0,这里我们只用TR0控制定时器T0TR01时,T0开始工作,TR00时,T0停止工作

两个十六位定时器最大定时65ms65536us约等于65ms

设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t

初始化程序应完成如下工作:

  • 对TMOD赋值,以确定T0和T1的工作方式。
  • 计算初值,并将其写入TH0、TL0或TH1、TL1。
  • 中断方式时,则对IE赋值,开放中断。
  • 使TR0或TR1置位,启动定时/计数器定时或计数。

思路:定时1s:进行20次中断,每次中断进行的时间是50ms并且对一个变量加1,进入一次中断就加1,一直加到20次,在主程序中进行判断,一旦到20让数码管变化一次

#include<reg52.h>

sbit dula=P2^6;

sbit wela=P2^7;

sbit d1=P1^0;

#define uint unsigned int

#define uchar unsigned char

uchar num,tt;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void main()

{

?????? num=0;

?????? tt=0;

?????? TMOD=0x01;//设置定时器0为工作方式1,C/T=0为定时模式, GATE=0用软件控制

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

??? EA=1;//开总中断

?????? ET0=1;//开定时器0中断

?????? TR0=1;//启动定时器0,定时器就开始工作,计数器就开始计数,50ms一到就进入中断

//程序中

?????? wela=1;

?????? P0=0xea;//所有数码管全亮

?????? wela=0;

?????? dula=1;

?????? P0=0x3f;//开始时要给数码管一个要显示的数字,否则会出现乱码

?????? dula=0;

?????? while(1)

?????? {

????????????? if(tt==20)

????????????? {

????????????? ????? tt=0;

???????????????????? num++;

???????????????????? if(num==16) //因为num计数到16就找不到值了

???????????????????? num=0;

???????????????????? dula=1;

???????????????????? P0=table[num];

???????????????????? dula=0;

????????????? }

?????? }

}

void exter0() interrupt 1//定时器中断0中断序号为1

{

?????? TH0=(65536-50000)/256;//50000表示50毫秒,即经过50毫秒中断一次,TH0和TL0

//是设定的初值,从初值开始计数到65536就经过50毫秒

?????? TL0=(65536-50000)%256;//因为当定时器计数值满再加1变成0才能从主程序进入中断//后,此时定时器的计数值为0,这里要重新装一次值,再进行计数,下一次50ms后才能再//次进入中断,否则定时器的计数值会从0开始,一直计数到65536才再次进入中断

?????? tt++;

}

课件作业:

利用定时/计数器T0从P1.0输出周期为1s的方波,让发光二极管以1HZ闪烁,设晶振频率为12MHz:重点就是让P1.0口正负正负不断变化

我的方法:

#include<reg52.h>

#define uchar unsigned char

sbit D1=P1^0;

uchar flag,tt;

void main()

{

????????????? tt=0;

????????????? //D1=1;

????????????? TMOD=0x01;

????????????? TH0=(65536-50000)/256;

????????????? TL0=(65536-50000)%256;

????????????? EA=1;

????????????? ET0=1;

?????? ?????? TR0=1;

?????? while(1)

?????? {????

????????????? if(tt==10)

????????????? {

???????????????????? tt=0;????????????????????

???????????????????? D1=~D1;??????????????

????????????? }

?????? }

}

void inter0() interrupt 1

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? tt++;

}

课件的方法:

#include<reg52.h>? //52单片机头文件

#define uchar unsigned char? //宏定义

sbit P1_0=P1^0;

uchar tt;

void main()?????????? ??? //主函数

{

?????? TMOD=0x01;//设置定时器0为工作方式1

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? EA=1;//开总中断

?????? ET0=1;//开定时器0中断

?????? TR0=1;//启动定时器0

?????? while(1);//等待中断产生

??????

}

void timer0() interrupt 1

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? tt++;

?????? if(tt==20)//直接在中断函数里进行方波程序

?????? {

????????????? tt=0;

????????????? P1_0=~P1_0;

?????? }

}

利用定时/计数器T1产生定时时钟,由P1口控制8个发光二极管,使8个指示灯依次一个一个闪动,闪动频率为10次/秒(8个灯依次亮一遍为一个周期),循环:

我的方法:

#include<reg52.h>

#include <intrins.h>

#define uint unsigned int

#define uchar unsigned char

uint num,tt;

void main()

{

?????? uchar a;

?????? TMOD=0x10;

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? EA=1;

?????? ET1=1;

?????? TR1=1;

?????? a=0xfe;

?????? while(1)

?????? {

????????????? if(tt==2)

????????????? {

???????????????????? tt=0;

???????????????????? P1=a;

????????????? ?????? a=_crol_(a,1);

????????????? }

?????? }

}

void inter1() interrupt 3

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? tt++;

}

课件的方法:

#include<reg52.h>? //52单片机头文件

#include <intrins.h> //包含有左右循环移位子函数的库

#define uint unsigned int??? //宏定义

#define uchar unsigned char? //宏定义

sbit P1_0=P1^0;

uchar tt,a;

void main()?????????? ??? //主函数

{

?????? TMOD=0x01;//设置定时器0为工作方式1

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? EA=1;//开总中断

?????? ET0=1;//开定时器0中断

?????? TR0=1;//启动定时器0

?????? a=0xfe;

?????? while(1);//等待中断产生

??????

}

void timer0() interrupt 1

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? tt++;

?????? if(tt==2)

?????? {

????????????? tt=0;

????????????? P1=a;

????????????? a=_crol_(a,1);

?????? }

}

同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔2s依次输出1,10,50,100,200,400,800,1k(hz)的方波:

我的方法:先做一下中断0控制一下蜂鸣器在300ms内以频率1响一下,再控制蜂鸣器以频率110响,再依次做下面的频率,思想是从简单到复杂,一步一步完成

在中断1中控制同个频率持续的时间,再用一个变量a来控制是以何种频率进行,为中断0做准备

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit beep=P2^3;

uint num,a,b;

void main()

{

?????? TMOD=0x11;//注意在中断0和中断1同时使用时要在TMOD中一起设置不要分开设置

?????? TH1=(65536-50000)/256;

?????? TL1=(65536-50000)%256;

?????? EA=1;

?????? ET1=1;

?????? TR1=1;

?????? //TMOD=0x01;

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? //EA=1;

?????? ET0=1;

?????? TR0=1;

?????? beep=0;

?????? while(1);

}

void inter1() interrupt 3

{

?????? TH1=(65536-50000)/256;

?????? TL1=(65536-50000)%256;

?????? num++;

?????? if(num==40)

?????? {

????????????? num=0;

????????????? a++;

????????????? if(a==8)

????????????? {

???????????????????? a=0;

????????????? }

?????? }

}

void inter0() interrupt 1

{

?????? if(a==0)

?????? {

????????????? TH0=(65536-50000)/256;

????????????? TL0=(65536-50000)%256;

????????????? b++;

????????????? if(b==20)

????????????? {

???????????????????? b=0;

???????????????????? beep=~beep;

????????????? }

?????? }

?????? if(a==1)

?????? {

????????????? TH0=(65536-50000)/256;

????????????? TL0=(65536-50000)%256;

????????????? beep=~beep;

????????????? b++;

????????????? if(b==2)

????????????? {

???????????????????? b=0;

???????????????????? beep=~beep;

????????????? }

?????? }

?????? if(a==2)

?????? {

????????????? TH0=(65536-20000)/256;

????????????? TL0=(65536-20000)%256;

????????????? beep=~beep;

?????? }

?????? if(a==3)

?????? {

????????????? TH0=(65536-10000)/256;

????????????? TL0=(65536-10000)%256;

????????????? beep=~beep;

?????? }

?????? if(a==4)

?????? {

????????????? TH0=(65536-5000)/256;

????????????? TL0=(65536-5000)%256;

????????????? beep=~beep;

?????? }

?????? if(a==5)

?????? {

????????????? TH0=(65536-2500)/256;

????????????? TL0=(65536-2500)%256;

????????????? beep=~beep;

?????? }

?????? if(a==6)

?????? {

????????????? TH0=(65536-1250)/256;

????????????? TL0=(65536-1250)%256;

????????????? beep=~beep;

?????? }

?????? if(a==7)

?????? {

????????????? TH0=(65536-1000)/256;

????????????? TL0=(65536-1000)%256;

????????????? beep=~beep;

?????? }

?????? b=0;

}

课件的程序:

#include<reg52.h>? //52单片机头文件

#include <intrins.h> //包含有左右循环移位子函数的库

#define uint unsigned int??? //宏定义

#define uchar unsigned char? //宏定义

sbit beep=P2^3;

uchar tt;

uint fre,flag;

void main()?????????? ??? //主函数

{

?????? fre=50000;

?????? beep=0;

?????? TMOD=0x11;//设置定时器0,定时器1为工作方式1

?????? TH0=(65536-fre)/256;

?????? TL0=(65536-fre)%256;

?????? TH1=(65536-50000)/256;

?????? TL1=(65536-50000)%256;

?????? EA=1;//开总中断

?????? ET0=1;//开定时器0中断

?????? ET1=1;

?????? TR1=1;

?????? TR0=1;//启动定时器0

?????? while(1);//等待中断产生

??????

}

void timer0() interrupt 1 ??//定时器0中断

{

?????? TR0=0;??? //进中断后先把定时器0中断关闭,防止内部程序过多而造成中断丢失

?????? TH0=(65536-fre)/256;

?????? TL0=(65536-fre)%256;

?????? tt++;

?????? if(flag<40)??? //以下几个if分别用来选取不同的频率,flag<40即第一个2s时间内

????????????? if(tt==10)

???????????????????? {

??????????????????????????? tt=0;

??????????????????????????? fre=50000;

??????????????????????????? beep=~beep;

???????????????????? }

?????? if(flag>=40&&flag<80)//flag>=40&&flag<80即第二个2s时间内

????????????? {

???????????????????? tt=0;

???????????????????? fre=50000;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=80&&flag<120)

????????????? {

???????????????????? tt=0;

???????????????????? fre=10000;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=120&&flag<160)

????????????? {

???????????????????? tt=0;

???????????????????? fre=5000;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=160&&flag<200)

????????????? {

???????????????????? tt=0;

???????????????????? fre=2500;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=200&&flag<240)

????????????? {

???????????????????? tt=0;

???????????????????? fre=1250;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=240&&flag<280)

????????????? {

???????????????????? tt=0;

???????????????????? fre=625;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=280&&flag<320)

????????????? {

???????????????????? tt=0;

???????????????????? fre=312;

???????????????????? beep=~beep;??

????????????? }

?????? if(flag>=320&&flag<360)

????????????? {

???????????????????? tt=0;

???????????????????? fre=156;

???????????????????? beep=~beep;??

????????????? }

?????? TR0=1;

}

void timer1() interrupt 3? //定时器1中断用来产生2秒时间定时

{

?????? TH1=(65536-50000)/256;

?????? TL1=(65536-50000)%256;

?????? flag++;

?????? if(flag==360)

?????? ? {

?????? ??? flag=0;

?????? ??? fre=50000;//因为到if(flag>=320&&flag<360)这步时fre回不到50000,所以这里还

//原一下fre

?????? ? }

}

用定时器以间隔500MS在6位数码管上依次显示0、1、2、3….C、D、E、F,重复:

我的程序:

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit dula=P2^6;

sbit wela=P2^7;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

uint num,a;

void main()

{

?????? num=0;

?????? a=0;

?????? wela=1;

?????? P0=0xc0;

?????? wela=0;

?????? TMOD=0x01;

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? EA=1;

?????? ET0=1;

?????? TR0=1;

?????? dula=1;

?????? P0=0x3f;

?????? dula=0;

?????? while(1);

}

void inter0() interrupt 1

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? num++;

?????? if(num==10)

?????? {????

????????????? a++;

????????????? if(a==16)

????????????? {

???????????????????? a=0;

????????????? }

????????????? num=0;

????????????? dula=1;

????????????? P0=table[a];

????????????? dula=0;

?????? }

}

课件的程序:

#include<reg52.h>? //52单片机头文件

#include <intrins.h> //包含有左右循环移位子函数的库

#define uint unsigned int??? //宏定义

#define uchar unsigned char? //宏定义

sbit dula=P2^6;?????? //数码管段选锁存端

sbit wela=P2^7;?????? 数码管位选锁存端

uchar num,tt;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void main()

{

?????? num=0;

?????? tt=0;

?????? TMOD=0x01;//设置定时器0为工作方式1

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? EA=1;//开总中断

?????? ET0=1;//开定时器0中断

?????? TR0=1;//启动定时器0

?????? dula=1;

?????? P0=0x3f;? //给段开始送显示0。

?????? dula=0;//关闭段选锁存端,防止开始时出现乱码。

?????? wela=1;//11101010

?????? P0=0xc0; // 打开六个数码管位选

?????? wela=0;

?????? while(1)//把数码管显示放到主程序里执行

?????? {

????????????? if(tt==10)?? //每进入10次中断即为500ms,执行一次显示变化。

????????????? ?? {

??????????????????????????? tt=0;

??????????????????????????? num++;

??????????????????????????? if(num==16)

??????????????????????????? num=0;

??????????????????????????? dula=1;

??????????????????????????? P0=table[num];

??????????????????????????? dula=0;??

???????????????????? }

?????? }

}

void exter0() interrupt 1??? // 定时器0中断

{

?????? TH0=(65536-50000)/256;

?????? TL0=(65536-50000)%256;

?????? tt++;

}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:20:39  更:2021-09-26 10:21:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:52:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码