单片机学习笔记(三)

今天有些睡眠不足的说~哈欠。这次的内容相比前两次有点多了哦,首先补完了数码管,然后讲到了中断和计时/计数器。

Ex004:动态数码管
让数码管每一位从0变化到F。利用数组存储0-F对应段选的十六进制值
数组的定义方法:
unsigned code arrayname[ ];
注意要加code。

代码如下:

#include<reg52.h>
sbit dula=P2^6;
sbit wela=P2^7;

unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,0x66,		//0-4
0x6d,0x7d,0x07,0x7f,0x6f,		//5-9
0x77,0x7c,0x39,0x5e,0x79,0x71 	//A-F
};
/* 段选赋值 */

void delay(x)
{
 	unsigned int a,b;
	for (a=0;a<x;a++)  for (b=0;b<110;b++) 	;
}

void main()
{
	while(1)
 	{
		dula=1;
		P0=table[2];
		dula=0;
		wela=1;
		P0=0xFE;
		wela=0;
			delay(500);
		dula=1;
		P0=table[1];
		dula=0;
		wela=1;
		P0=0xFD;
		wela=0;
			delay(500); //减小两个delay,利用视觉残留实现连续效果
  	}
}

中断点我查看详细信息
CPU收到中断信号后暂停主程序,开始执行外围请求。

5个中断源:
INT0INT1- 外部中断0和1,P3^和P3^3端口接入,电平触发和边沿触发(下降沿有效)
T0T1- 定时器中断,计数器计满溢出引发中断信号,然后回零
TI/RI- 串行口中断,串行端口完成一帧字符发送、接收后引起

中断优先级排序
高优先级:外部0→定时器0→外部1→定时器1→串行口:低优先级

Ex005:外部中断

电路图如图增加:

元件Keywords:

button 开关

代码如下:

//外部中断:外部开关闭合时,电平为低,引起中断。
#include<reg52.h>
unsigned int a;

void main()
{
	EA=1;
	//CPU总中断允许
	EX0=1;
	//外部中断允许
	IT0=1;
	//触发方式选择:1下降沿触发;2电平触发

	a=0xAA;
	while(1) { P1=a; }
}

void ext() interrupt 0 using 0
//ext为名字。interrupt+中断序号:→0外部←;1定时器0;2外部1;3定时器1;4串行口
{
	a=~a; //收到中断信号是运行这里,然后返回主程序
}

Ex006:计时器中断
用定时/计数器精确计算时间
定时/计数器:高八位和低八位共十六个二进制位组成,一个机器周期计数器加一。

4种方式计数模式(TMOD=0x00;0x10;0x01;0x11对应方式0-3)
例如方式1(TMOD=0x10下):
16个二进制位加满溢出时(对应十进制为0到65536)计数器发出中断指令并清零。

计算:
晶振频率11.0592MHz
1机器周期=12震荡(晶振)周期
∴T晶振=1/11.0592E6s
T机器=12/11.0592E6s (计数器加一)
n=1/T机器=921600 (一秒钟运行语句数>65536,就是说计数器第一次溢出时还没到一秒)
1/20秒运行语句数=921600/20=46080<65536,65536-46080=19456
综上可知,计数器从0记录到46080时,过去1/20秒,此时与下一次溢出(即中断信号发出)还有19456个数
也就是说,让计数器溢出20次,每次都从19456开始计数到65536,这时可以得到精确的一秒

目前整体电路图如下:
单片机4 目前整体图

代码如下:

//定时器中断:每秒钟LED交替点亮,一个数码管加一。
#include<reg52.h>
sbit dula=P2^6;
sbit wela=P2^7;

unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,0x66,		//0-4
0x6d,0x7d,0x07,0x7f,0x6f,		//5-9
0x77,0x7c,0x39,0x5e,0x79,0x71 	//A-F
};
/* 段选赋值 */
unsigned int a,num,t;

void main()
{
	EA=1;
	//CPU总中断允许
	ET1=1;
	//定时器0中断允许
	TMOD=0x10;
	//计数方式选择:0x00;0x10;0x01;0x11 对应方式0;1;2;3

	TH1=(65536-(921600/20))/256;
	//计数器1的高八位初值计算
	TL1=(65536-(921600/20))%256;
	//计数器1的低八位初值计算
	TR1=1;
	//打开计数器1,计数器开始工作

	num=0;
	a=0xAA;
	wela=1;
	P0=0x1F;
	wela=0;
	dula=1;
	P0=table[0];
	dula=0;
	//初始情况:LEG亮一半,数码管显示“0”

	while(1)
	{
		P1=a;
		if (num==20) //溢出20次,达到1秒
		{
		 	num=0;
			a=~a;
			t++;
			if (t==10) t=0;
			wela=1;
			P0=0x1F;
			wela=0;
			dula=1;
			P0=table[t];
			dula=0;
		}
	}
}

void time() interrupt 3 using 0
//interrupt+中断序号:0外部0;1定时器0;2外部1;→3定时器1←;4串行口
{
	num++;
	TH1=(65536-(921600/20))/256;
	TL1=(65536-(921600/20))%256;
	//收到一次中断信号num+1,计数器回初值
}


本文来自 ZSXRPD,原文标题:单片机学习笔记(三),转载请标明来源。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
知识共享许可协议

1 thought on “单片机学习笔记(三)

发表评论

电子邮件地址不会被公开。 必填项已用*标注