(51单片机)第十三章-STC系列51单片机功能介绍

13.1 单片机空闲与掉电模式的应用

1. 空闲模式

        当单片机进入空闲模式时,CPU处于休眠状态外,其余硬件全部处于活动状态,芯片中程序未涉及的数据存储器和特殊功能寄存器中的数据在空闲模式期间都将保持原值。假若定时器正在运行,那么计数器寄存器中的值还将会增加。单片机在空闲模式下可由任一个中断或硬件复位唤醒。需要注意,使用中断唤醒单片机时,程序从原来停止处继续运行;当使用硬件复位唤醒单片机时,程序将从头开始执行。

        让单片机进入空闲模式的目的通常是为了降低系统的功耗,举个很简单的例子,数字万用表在正常使用时表内部的单片机处于正常工作模式,当不用却又忘记关掉万用表的电源时,大多数数字万用表在等待数分钟后,若没有人为操作,便会自动将液晶显示关闭,以降低系统功耗,类似这种功能的实现通常就是使用了单片机的空闲模式或掉电模式以STC89系列单片机为例,当单片机正常工作时的功耗通常为4mA~7mA,进入空闲模式时其功耗降至2mA,进入掉电模式时功耗可降至0.1A以下。

2. 掉电模式

        当单片机进入掉电模式(也称休眠模式)时,外部晶振停振,CPU、定时器、串行口全部停止工作,只有外部中断继续工作。使单片机进入掉电模式的指令将成为休眠前单片机执行的最后一条指令。进入掉电模式后,芯片中程序未涉及的数据存储器和特殊功能寄存器中的数据都将保持原值。可用外部中断低电平触发,或下降沿触发中断,或硬件复位模式唤醒单片机。需要注意,使用中断唤醒单片机时,程序从原来停止处继续运行;当使用硬件复位唤醒单片机时,程序将从头开始执行。

正常工作电流>空闲模式电流>休眠模式电流

        在 TX-1C 实验板上完成如下描述:开启两个外部中断,设置低电平触发中断,用定时器计数并且显示在数码管的前两位,当计数到5时,使单片机进入空闲(眠)模式,同时关闭定时器,当单片机响应外部中断后,从空闲(休眠)式返回,同时开启定时器。程序代码如下:

//开启两个外部中断,设置低电平触发中断,用定时器计数并且显示在数码管的前两位
//当计数到5时,使单片机进入空闲(眠)模式,同时关闭定时器
//当单片机响应外部中断后,从空闲(休眠)式返回,同时开启定时器。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7; //声明U2锁存器的锁存端
sbit led1=P1^0; //第一位发光二极管(0亮1灭)
sbit beep=P2^3;	//声明蜂鸣器引脚(0响1灭)

uchar code dula_table[]={
	0x3f,0x06,0x5b,0x4f, //0,1,2,3
	0x66,0x6d,0x7d,0x07, //4,5,6,7
	0x7f,0x6f,0x77,0x7c, //8,9,10,11
	0x39,0x5e,0x79,0x71  //12,13,14,15
};

uchar code wela_table[]=
{
	  0xdf,0xef,0xf7,0xfb,0xfd,0xfe	//从右向左数第一到六位
};

uchar num,a,b;
uint wei;

void main()
{
	uchar num1;	

	void init(); //初始化操作
	void delayxms(uint xms);
	void display();

	init();
	while(1)
	{
		if(num>=20)
		{
			num=0;
			num1++;
			if(num1==6)
			{
				ET0=0; //在下一句话进入休眠模式前要关闭定时器以等待外部中断的产生
				PCON=0x02;
			}
			a=num1/10;
			b=num1%10;
		}
		display();
	}	
}

void init() //初始化操作
{
	dula=0; //初始化,段选置0
	wela=0; //初始化,片选置0

	led1=1;	//初始化,二极管灯灭
	beep=1;	//初始化,蜂鸣器不响

	TMOD=0x01; //设置定时器0的工作方式为1(0000 0001)
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	EA=1; //打开总中断
	ET0=1; //打开定时器1中断
	EX0=1; //开启外部中断0
	EX1=1; //开启外部中断1
	TR0=1;//启动定时器1

}

void delayxms(uint xms)
{
	uint x,y;
	for(x=xms;x>0;x--)
		for(y=124;y>0;y--);	
} 

void display()
{
	void wedu(uchar dula_num,uchar wela_num);
	for(wei=0;wei<2;wei++)
	{
		switch(wei)
		{
			case 0: wedu(b,wei);break;
			case 1: wedu(a,wei);break;
		}	
	}
}


void wedu(uchar dula_num,uchar wela_num)
{
	wela=1; //打开U2锁存端
	P0=wela_table[wela_num]; //送入U2锁存端
	wela=0; //关闭U2锁存端
	P0=0xc0; //消影,防止P0残留电位信号干扰段选
	dula=1; //打开U1锁存端
	P0=dula_table[dula_num]; //送入段选信号
	dula=0; //关闭U1锁存端
	P0=0xff; //消影,防止P0残留电位信号干扰片选
	delayxms(1);
}

void T0_time() interrupt 1 //中断程序
{
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	num++;
	led1=~led1;
	beep=~beep;
} 

void ex_int0() interrupt 0 //外部中断0服务程序
{
	PCON=0; //进入外部中断服务程序后首先将PCON中原先设定的休眠控制位清除
	ET0=1; //开启定时器0
}

void ex_int1() interrupt 2
{
	PCON=0;
	ET0=1;
}

13.2 “看门狗”概念及其应用

        在由单片机构成的系统中,由于单片机的工作有可能受到来自外界电磁场的干扰,造成程序的跑飞,从而陷入死循环,程序的正常运行被打断,由单片机控制的系统便无法继续工作,这样会造成整个系统陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称“看门狗”(Watch Dog)。

        加入看门狗电路的目的是使单片机可以在无人状态下实现连续工作,其工作过程如下:看门狗芯片和单片机的一个I/O 引脚相连,该I/O 引脚通过单片机的程序控制,使它定时地往看门狗芯片的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞而陷入某一程序段进入死循环状态时,给看门狗引脚送电平的程序便不能被执行到,这时,看门狗电路就会由于得不到单片机送来的信号,便对它与单片机复位引脚相连的引脚送出一个复位信号,使单片机复位,从而使单片机从程序存储器的起始位置重新开始执行程序,这样便实现了单片机的自动复位。通常,看门狗电路是通过将一个专门的看门狗芯片连接到单片机来实现的,不过这样会给电路设计带来复杂性,STC系列单片机内部自带了看门狗,通过对相应的特殊功能寄存器的设置就可实现看门狗的应用。STC89系列单片机内部有一个专门的看门狗定时器寄存器Watch Dog Timer 寄存器,其功能见下。

看门狗定时器寄存器(WDR_CONTR

        STC系列单片机看门狗定时器寄存器在特殊功能寄存器中的字节地址为E1H,不能位寻址,该寄存器用来管理STC单片机的看门狗控制部分,包括启/停看门狗、设置看门狗溢出时间等。单片机复位时该寄存器不一定全部被清 0,在 STC 下载程序软件界面上可设置复位关看门狗或只有停电关看门狗的选择,可根据需要做出适合自己设计系统的选择。其各位的定义如下表所示。

        EN WDT—看门狗允许位,当设置为1时,启动看门狗。

        CLR WDT—看门狗清0位,当设为1时,看门狗定时器将重新计数。硬件自动将此位清 0

        IDLE WDT—看门狗IDLE模式位,当设置为1时,看门狗定时器在单片机的“空闲模式”计数;当该位清0时,看门狗定时器在单片机的“空闲模式”时不计数。

        PS2,PS1,PS0—看门狗定时器预分频值,12MHz晶振条件下不同值对应预分频数如下表所示。

        看门狗溢出时间与预分频数有直接的关系,公式如下:

看门狗溢出时间=(N*预分频数*32768)/晶振频率

        式中,N表示 STC单片机的时钟模式。STC单片机有两种时钟模式,一种是单倍速,也就是12 时钟模式,该时钟模式下,STC 单片机与其他公司 51 单片机具有相同的机器周期,即 12个振荡周期为一个机器周期;另一种是双倍速,又称6时钟模式,在该时钟模式下,STC单片机比其他公司的 51单片机运行速度快一倍。在下载程序软件界面上有单倍速与双倍速的设置选择,大家可自行下载测试程序运行速度。预分频数的值由PS2,PS1和PS0的组合确定如上表所示。晶振频率即为当前系统的时钟频率

        在应用看门狗时,需要在整个大程序的不同位置喂狗,每两次喂狗的时间间隔一定不能小于看门狗定时器的溢出时间,否则程序会不停地复位。

        在 TX-1C 实验板上实现如下描述:程序启动后设定看门狗溢出时间为 2s,然后点亮第一个发光二极管,稍延时一会,然后熄灭发光二极管,使程序进入等待死循环状态,并且在死循环中大约每隔1s喂狗一次,看程序运行是否正常。程序代码如下:

//程序启动后设定看门狗溢出时间为 2s,然后点亮第一个发光二极管,稍延时一会
//然后熄灭发光二极管,使程序进入等待死循环状态,并且在死循环中大约每隔1s喂狗一次
//看程序运行是否正常。程序代码如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sfr WDT_CONTR=0Xe1; //定义STC单片机中新加入的看门狗寄存器

sbit led1=P1^0; //第一位发光二极管(0亮1灭)
sbit beep=P2^3;	//声明蜂鸣器引脚(0响1灭)

void main()
{
	void delayxms(uint xms);

	WDT_CONTR=0X35; 
	led1=0;
	beep=0;
	delayxms(500);
	led1=1;
	beep=1;
	while(1)
	{
		delayxms(1000);
		//WDT_CONTR=0X35; //若将此举删掉,则看门狗定时器溢出后单片机复位从头执行,小灯闪烁
	}	
}

void delayxms(uint xms)
{
	uint x,y;
	for(x=xms;x>0;x--)
		for(y=124;y>0;y--);	
} 

13.3 用软件实现系统复位

        用户应用程序在运行过程中,有时会有特殊需求,需要实现单片机系统复位(热启动之一),传统的 8051单片机由于硬件上不支持此功能,用户必须用软件模拟实现,实现起来比较麻烦。STC单片机增加了相应的硬件功能,内部的ISPAP控制寄存器ISP_CONTR便可以实现此功能。用户只需简单控制ISP_CONTR 特殊功能寄存器中的 SWBS 和 SWRST 两位就可以实现系统复位。

ISP/IAP控制寄存器(ISPCONTR)

        STC 单片机 ISP/IAP 控制寄存器在特殊功能寄存器中的字节地址为 E7H,不能位寻址,该寄存器用来管理和 ISP/IAP 相关的功能设定及是否软件复位等。单片机复位时该寄存器全部被清 0。其各位的定义如下表所示。

        ISPEN—ISP/IAP 功能允许位。0禁止ISP/IAP编程改变 Flash。1允许编程改变 Flash。SWBS-软件选择从用户应用程序区启动(0),还是从ISP程序区启动(1)。要与SWRST直接配合才可以实现。

        SWRST—0不操作;1产生软件系统复位,硬件自动清0。

        WT2,WT1, WTO—ISP/AP 编程时设定 CPU等待的最长时间。ISP/IAP 编程时可对 Flash进行读操作、写操作、擦除操作。当进行这些操作时,时钟将被CPU锁定只进行这些操作而不同的操作将会耗费 CPU 不同的时间,这里我们通过人为设定可以给 CPU 一个最长的等待时间,若在此时间段内相应的操作未完成,数据将丢失或错误。下表给出了芯片厂商推荐的等待时间参考表。

        SWBS与SWRST组合情况如下:

        从用户应用程序区(AP 区)软件复位并切换到用户应用程序区(AP区)开始执行程:

ISP_CONTR=00100000B,SWBS=0(选择AP区),SWRST=1(软复位)

        从系统 ISP 监控程序区软件复位并切换到用户应用程序区(AP区)开始执行程序:

ISP CONTR=00100000B,SWBS=0(选择AP区),SWRST=1(软复位)

        从用户应用程序区(AP 区)软件复位并切换到系统ISP监控程序区开始执行程序:

ISP CONTR=01100000B,SWBS=1(选择ISP区),SWRST=1(软复位)

        从系统 ISP 监控程序区软件复位并切换到系统ISP监控程序区开始执行程序:

ISP CONTR=01100000B,SWBS=1(选择ISP区),SWRST=1(软复位)。

        本复位是整个系统复位,所有的特殊功能寄存器都会复位到初始值,I/O 口也会被初始化,用户应用程序区(AP区)指仅仅是用户自己编写的程序区。ISP 监控程序区 ISP 区是指芯片出厂时就已经固化在单片机内部的一段程序,STC单片机可以进行ISP 串行下载程序,这就是因为芯片在出厂时已经在单片机内部固化了ISP引导码程序首次上电时先会从ISP 区开始执行代码,体现在实际实验中时,就是我们在下载程序时先要单击下载软件界面上的下载,然后再开启单片机电源,当单片机检测到上位机有下载程序的需要时,便启用ISP下载功能给单片机下载程序。若经过短暂的时间没有检测到上位机有下载程序的需求,单片机便会从用户应用程序区(AP区)开始执行代码。

        下面通过一个例子实现程序运行中的突然复位。

        在 TX-1C实验板上实现如下描述:在数码管前两位显示以秒递增的数,增加到10 时,利用STC单片机的软件复位功能让单片机复位。程序代码如下:

//在数码管前两位显示以秒递增的数
//增加到10 时,利用STC单片机的软件复位功能让单片机复位。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sfr ISP_CONTR=0xe7; //定义ISP/IAP控制寄存器

sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7; //声明U2锁存器的锁存端
sbit led1=P1^0; //第一位发光二极管(0亮1灭)
sbit beep=P2^3;	//声明蜂鸣器引脚(0响1灭)

uchar code dula_table[]={
	0x3f,0x06,0x5b,0x4f, //0,1,2,3
	0x66,0x6d,0x7d,0x07, //4,5,6,7
	0x7f,0x6f,0x77,0x7c, //8,9,10,11
	0x39,0x5e,0x79,0x71  //12,13,14,15
};

uchar code wela_table[]=
{
	  0xdf,0xef,0xf7,0xfb,0xfd,0xfe	//从右向左数第一到六位
};

uchar num,a,b;
uint wei;

void main()
{
	uchar num1;	

	void init(); //初始化操作
	void delayxms(uint xms);
	void display();

	init();

	while(1)
	{
		if(num>=20)
		{
			num=0;
			num1++;
			led1=~led1;
			beep=~beep;
			if(num1==10)
			{
				ISP_CONTR=0x20; //用软件复位到用户应用程序区(AP区),重新开始执行程序
			}
			a=num1/10;
			b=num1%10;
		}
		display();
	}
}

void init() //初始化操作
{
	dula=0; //初始化,段选置0
	wela=0; //初始化,片选置0

	led1=1;	//初始化,二极管灯灭
	beep=1;	//初始化,蜂鸣器不响

	TMOD=0x01; //设置定时器0的工作方式为1(0000 0001)
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	EA=1; //打开总中断
	ET0=1; //打开定时器1中断
	TR0=1;//启动定时器1
}

void delayxms(uint xms)
{
	uint x,y;
	for(x=xms;x>0;x--)
		for(y=124;y>0;y--);	
} 

void display()
{
	void wedu(uchar dula_num,uchar wela_num);
	for(wei=0;wei<2;wei++)
	{
		switch(wei)
		{
			case 0: wedu(b,wei);break;
			case 1: wedu(a,wei);break;
		}	
	}
}


void wedu(uchar dula_num,uchar wela_num)
{
	wela=1; //打开U2锁存端
	P0=wela_table[wela_num]; //送入U2锁存端
	wela=0; //关闭U2锁存端
	P0=0xc0; //消影,防止P0残留电位信号干扰段选
	dula=1; //打开U1锁存端
	P0=dula_table[dula_num]; //送入段选信号
	dula=0; //关闭U1锁存端
	P0=0xff; //消影,防止P0残留电位信号干扰片选
	delayxms(1);
}

void T0_time() interrupt 1 //中断程序
{
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	num++;
} 

13.4 内部扩展RAM的应用

        RAM 是在程序运行中存放随机变量的数据空间,51单片机默认的内部RAM只有128B;52单片机增加至 256B;STC89C52增加到512B;STC89C54,55,58,516等增加到1280B.对于编程者来说,一个芯片的RAM 空间越大,写起程序来就越容易得心应手,不会总考虑RAM 不够用怎么办,连过多的变量都不敢定义。

        如果定义一个变量后,不对这个变量进行初始化,这个变量默认的初值就是 0,其实这个结论是需要一定的条件的,在用Kei1编写程序时,总程序中所有变量占用的字节之和要小于128B,并且存储器模式为small模式的前提下,对定义的变量不进行初始化时,编译器会默认将变量值设定为0。一旦程序中的总变量超过128B,必须对所有变量进行初始化,否则没有被初始化的变量默认值将是不确定的。当变量总和超过128B时,还必须要在编译器中重新设定存储器的存储模式。

        存储器模式一共有三种,分别为smallcompactlarge 式,在Keil编译器中有可选项,选项表如下图所示。它决定了没有明确指定存储类型的变量、函数参数等数据的默认存储区域。如果在某些函数中需要使用非默认的存储模式,也可以使用关键字直接说明。下面分别介绍这三种模式。

1. small 模式

        small 模式中,所有默认变量均装入单片机内部128B的RAM中,当定义类似如uchar a;”“float b;等变量时,这些变量都装入内部128B RAM 中。使用该模式的优点是访问速度快缺点是空间有限且对堆栈的空间分配比较少,难以把握,碰到递归调用的时候需要小心。这种模式只适用于小程序。

2. compact 模式

        compact模式中,所有默认变量均位于单片机内部256B的RAM中,和在small 模式中使用关键字 pdata 来定义变量的效果相同,如uchar pdata a[100];在该模式下,程序总变量空间不得超过 256B。对于只有128B 的单片机,使用此模式定义变量超过128B 时,程序将出错。优点是空间较 small 模式宽裕,速度较 smal 慢,但较large 模式要快,是一种中间状态

3. large 模式

        在1arge模式中,所有默认变量可放在多达64KB的RAM区,包括内部RAM和外部RAM这和使用关键字 xdata 来定义变量的效果相同。该模式的优点是空间大,可存变量多缺点是访问速度慢,尤其对于两个以上的多字节变量访问速度来说更是如此。

        STC单片机要访问扩展RAM时,可直接用以下方法。

        首先,在编译器中设置存储器模式为large 模式,如上图所示。

        其次,为安全起见,当程序中定义多于128B的其他变量时,最好申明为xdata型,如“ucharxdata table[100];"意思为定义一个 100个字节容量的数组,将其在扩展 RAM 中分配存储空间。另外,一定要注意,在1arge模式下编写程序,定义的变量总数千万不要超过对应单片机的内部最大 RAM 字节数,因为即使超过了,编译器也不会提示错误,但是程序必定会出错。

13.5 扩展P4口的应用

        对于 POFP-44 和 PLCC-44 封装的 STC89 系列单片机增加了4I/O ,即 P4口。P4口在特殊功能寄存器的地址为E8H,可以进行位寻址,用户在使用P4口之前需要先定义地址然后就像操作其他I/O 口一样操作 P4 口。

        另外,P4 口的 P4.2P4.3 引脚新增加了两个外部中断作为它们的第二功能,使用这两个外部中断时,和使用 P3.2和P3.3引脚的外部中断方法相同。P4.2(INT2)的中断向量入口地址为33H,中断序号为6;P4.3(INT3)的中断向量地址为3BH,中断序号为7;P4口的外部中断由另一个新增加的扩展中断控制寄存器来设置。

扩展中断控制寄存器(XICON)

        STC89系列单片机扩展中断控制寄存器在特殊功能寄存器中的字节地址为C0H,能位寻址,该寄存器用来管理扩展中断开启、关闭及中断优先级设定。单片机复位时该寄存器全部被清 0。其各位的定义如下表所示。

        PX3—置位表明外部中断3的优先级为高,但优先级最终由中断优先级寄存器IP,扩展中断优先级寄存器 IPH 和扩展中断控制寄存器XICON中的PX3与 PX2共同决定,如[PX3H,PX3]=[0,0],[0,1],[1,0],[1,1]代表不同的优先级。

        EX3—置1,允许外部中断3中断;清0,禁止外部中断3中断。

        IE3—外部中断3中断请求标志位,中断条件成立后,IE3=1,该位由硬件自动清0。

        IT3—置1时,外部中断3为下降沿触发中断;清0时,为低电平触发中断。

        PX2—置位表明外部中断2的优先级为高,但优先级最终由中断优先级寄存器IP,扩展中断优先级寄存器 IPH 和扩展中断控制寄存器XICON中的PX3,PX2共同决定,如[PX2H,PX2]=[0,0],[0,1],[1,0],[1,1]代表不同的优先级。

        EX2—置1,允许外部中断2中断;清0,禁止外部中断2中断。

        IE2—外部中断2中断请求标志位,中断条件成立后,IE2=1,该位由硬件自动清0。

        IT2—置1时,外部中断2为下降沿触发中断;清0时,为低电平触发中断,

扩展中断优先级寄存器(IPH)

        STC89系列单片机扩展中断优先级寄存器在特殊功能寄存器中的字节地址为B7H,不能位寻址。该寄存器与中断优先级寄存器、扩展中断控制寄存器 XICON 中的 PX3 和 PX2 位共同决定单片机所有中断的最终优先级。单片机复位时该寄存器全部被清 0。其各位的定义如下表所示。

        关于扩展中断优先级寄存器的用法是这样的:假定[PX3H,PX3]=[1,1],[PX2H,PX2]=[1,1],其他中断的组合均不是[1,1],则这时外部中断 3、外部中断2的优先级比其他中断优先级都高,因为不可能有两个最高。所以再来看系统默认的优先级,在软件设置优先级相同时,外部中断2的优先级更高。用此方法可设置任一个中断的优先级。使用 P4 口编写C语言代码时,需要在程序开始处加上如下语句,以后便可像操作其他I/O 口一样操作 P4 口。

sfr P4=0xe8;

        注:STC89LE516AD,STC89LE516X2,STC89LE58AD,STC89LE54ADr的P4地址为COH。

13.6 内部E2PROM的应用

        STC89C51,STC89C52内部都自带有2KB的EPROM;54,55和58都自带有16KB的E2PROM,STC单片机是利用IAP技术实现的E2PROM,内部Flash擦写次数可达100000次以上,下面先来介绍 ISP 与IAP 的区别和特点。

ISPIAP介绍

        ISP(In System Programable)是指在系统编程。通俗地讲,就是片子已经焊在板子上不用取下,就可以简单而方便地对其进行编程。比如,我们通过计算机给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。

        IAP(In Application Programable )是指在应用编程。就是片子提供一系列的机制(硬件软件上的),当片子在运行程序时可以提供一种改变 Fash 数据的方法。通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的 ISP 功能就是通过 IAP 技术来实现的,即片子在出厂前就已经有一段小的 boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。大家要注意,千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了

        STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP 功能的,见下表。

        ISP_DATA-ISP/AP 操作时的数据寄存器。ISPAP从Flash 读出的数据放在此处,向Flash写入的数据也放在此处。

        ISP ADDRH-ISP/IAP操作时的地址寄存器高八位。

        ISP ADDRL-ISP/IAP操作时的地址寄存器低八位,

        ISP_CMD-ISPIAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。其模式设置如下表所示。

        程序在系统 ISP 程序区时可以对用户应用程序区/数据 Flash 区(E2PROM)进行字节读/字节编程/扇区擦除;程序在用户应用程序区时,仅可以对数据Flash区(E2PROM)进行字节读/字节编程/扇区擦除。STC89C51RC/RD+系列单片机出厂时已经固化有ISP 引导码,并设置为上电复位进入ISP程序区,并且出厂时就已完全加密。

        ISP TRIG-ISP/IAP操作时的命令触发寄存器

        在ISPEN(ISPCONTR.7)=1时,对ISPTRIG先写入46H,再写入B9H,ISPAP 命令才会生效。

        STC89C52RC,STC89LE52RC单片机内部可用的DataFlash(E2PROM)的地址如下表所示,其他型号单片机请查阅相关资料。

        每个扇区为 512B,建议大家在写程序时,将同一次修改的数据放在同一个扇区,方便修改,因为在执行擦除命令时,一次最少擦除一个扇区的数据,每次更新数据前都必须擦除原数据方可重新写入新数据,不能直接在原来数据基础上更新内容。

        在 TX-1C实验板上实现如下描述:操作 STC单片机自带的 E’PROM,存储一组按秒递增的两位数据,并且将数据实时显示在数码管上,数据每变化一次就往EPROM中写入一次,当关闭实验板电源并再次开启电源时,从EPROM中读取先前存储的数据,接着递增显示。程序代码如下:

#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int
#define RdCommand 0x01 //定义ISP操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定义CPU等待时间

sfr ISP_DATA=0xe2; //寄存器声明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;

sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7; //声明U2锁存器的锁存端

uchar code dula_table[]={
	0x3f,0x06,0x5b,0x4f, //0,1,2,3
	0x66,0x6d,0x7d,0x07, //4,5,6,7
	0x7f,0x6f,0x77,0x7c, //8,9,10,11
	0x39,0x5e,0x79,0x71  //12,13,14,15
};

uchar code wela_table[]=
{
	  0xdf,0xef,0xf7,0xfb,0xfd,0xfe	//从右向左数第一到六位
};

uchar num,a,b,num1;
uint wei;

void delayxms(uint xms)
{
	uint x,y;
	for(x=xms;x>0;x--)
		for(y=124;y>0;y--);	
} 

void display()
{
	void wedu(uchar dula_num,uchar wela_num);
	for(wei=0;wei<2;wei++)
	{
		switch(wei)
		{
			case 0: wedu(b,wei);break;
			case 1: wedu(a,wei);break;
		}	
	}
}


void wedu(uchar dula_num,uchar wela_num)
{
	wela=1; //打开U2锁存端
	P0=wela_table[wela_num]; //送入U2锁存端
	wela=0; //关闭U2锁存端
	P0=0xc0; //消影,防止P0残留电位信号干扰段选
	dula=1; //打开U1锁存端
	P0=dula_table[dula_num]; //送入段选信号
	dula=0; //关闭U1锁存端
	P0=0xff; //消影,防止P0残留电位信号干扰片选
	delayxms(1);
}

//打开ISP,IAP功能
void ISP_IAP_enable(void)
{
	EA=0; //关中断
	ISP_CONTR=ISP_CONTR&18;	//0001,1000
	ISP_CONTR=ISP_CONTR|WaitTime; //写入硬件延时
	ISP_CONTR=ISP_CONTR|0x80; //ISPEN=1
}

//关闭ISP,IAP功能
void ISP_IAP_disable(void)
{
	ISP_CONTR=ISP_CONTR&0x7f; //ISPEN=0
	ISP_TRIG=0x00;
	EA=1; //开中断
}

//公用的触发代码
void ISPgoon(void)
{
	ISP_IAP_enable(); //打开ISP,IAP功能
	ISP_TRIG=0x46; //触发ISP_IAP命令字节1
	ISP_TRIG=0xb9; //触发ISP_IAP命令字节2
	_nop_();
}

//字节读
uchar byte_read(uint byte_addr)
{
	ISP_ADDRH=(uchar)(byte_addr>>8); //地址赋值
	ISP_ADDRL=(uchar)(byte_addr&0x00ff);
	ISP_CMD=ISP_CMD&0xf8; //清除低3位
	ISP_CMD=ISP_CMD|RdCommand; //写入读命令
	ISPgoon(); //触发执行
	ISP_IAP_disable(); //关闭ISP,IAP功能
	return(ISP_DATA); //返回读到的数据	
}

//扇区擦除
void SectorErase(uint sector_addr)
{
	uint iSectorAddr;
	iSectorAddr=(sector_addr&0xfe00); //取扇区地址
	ISP_ADDRH=(uchar)(iSectorAddr>8); //地址赋值
	ISP_ADDRL=0x00;
	ISP_CMD=ISP_CMD&0xf8; //清除低3位
	ISP_CMD=ISP_CMD|EraseCommand; //擦除命令3
	ISPgoon(); //触发执行
	ISP_IAP_disable(); //关闭ISP,IAP功能
}

//字节写
void byte_write(uint byte_addr,uchar original_data)
{
	ISP_ADDRH=(uchar)(byte_addr>>8); //地址赋值
	ISP_ADDRL=(uchar)(byte_addr&0x00ff);
	ISP_CMD=ISP_CMD&0xf8; //清除低3位
	ISP_CMD=ISP_CMD|PrgCommand; //写命令2
	ISP_DATA=original_data; //写入数据准备
	ISPgoon(); //触发执行
	ISP_IAP_disable(); //关闭ISP,IAP功能	
}

void init() //初始化操作
{
	dula=0; //初始化,段选置0
	wela=0; //初始化,片选置0

	TMOD=0x01; //设置定时器0的工作方式为1(0000 0001)
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	EA=1; //打开总中断
	ET0=1; //打开定时器1中断
	TR0=1;//启动定时器1
}

void main()
{	
	init();
	num1=byte_read(0x2000); //程序开始时读取EEPROM中的数据
	if(num1>=60) num1=0;
	while(1)
	{
		if(num>=20)
		{
			num=0;
			num1++;
			SectorErase(0x2000); //擦除扇区
			byte_write(0x2000,num1); //重新写入数据
			if(num1==60)
			{
				num1=0;
			}
			a=num1/10;
			b=num1%10;
		}
		display();
	}
}

void T0_time() interrupt 1 //中断程序
{
	TH0=(65536-50000)/256; //装初值
	TL0=(65536-50000)%256; //装初值
	num++;
} 

13.7 STC89系列单片机内部A/D应用

        STC89LE52AD,54AD,58AD,516AD这几款89系列的STC单片机内部自带有8路8位的 A/D 转换器,分布在P1口的8位上,当时钟在 40MHz 以下时,每 17个机器周期可完成一次 A/D 转换。

        与 AD 相关的几个寄存器如下表所示。

        P1 ADC EN—P1.x口的 AD 使能寄存器相应位设置为1时,对应的P1.x口作为AD转换使用,内部上拉电阻自动断开。ADC_CONTR-A/D 转换控制寄存器。

        ADC START—AD转换启动控制位,设置为1时,AD开始转换。ADC FLAG-AD 转换结束标志位,当AD转换完成后,ADCFLAG=1。CHS2,CHS1,CHS0-模拟输入通道选择,其设置如下表所示ADC DATA-AD 转换结果寄存器。AD转换结果的计算公式如下:

结果=256xUin/Vcc

        式中,Uin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作电压作为模拟参考电压。

13.8 STC12系列单片机内部A/D应用

        STC12C2052AD系列单片机自带8路8位AD转换器,STC12C5410AD系列单片机带8路 10 位 A/D 转换器,它们的 A/D 转换口都在 P1 口(P1.0~P1.7),转换速度均可达到 100kHz(10万次/秒)。该8路 AD 转换器为电压输入型,可做温度检测、电池电压检测、按键扫描频谱检测等。上电复位后P1口为弱上拉型IO口,用户可以通过软件设置将8路中的任一路设置为 A/D 转换,不需作为 AD 使用的口可继续作为 IO 口使用。

        需作为 A/D 使用的口需先将其设置为开漏模式或高阻输入,在P1M0,P1M1 寄存器中对相应的位进行设置,其端口配置模式如下表所示。

        下表为STC12系列单片机与A/D相关的寄存器。

        ADC_CONTR—寄存器的 CHS2,CHS1,CHS0位为 A/D 通道选择位,与 STC89 系列用法相同。

        ADC START—转换启动控制位,设置为1时,开始转换,转换结束后清0。

        ADC FLAG—模转换结束标志位,当AD 转换完成后,ADC FLAG=1,必须由软件清 0。不管是 AD转换完成后由该位申请产生中断,还是由软件查询该标志位判断 AD 转换是否结束,当A/D 转换完成后,ADCFLAG都将置1,该位必须由软件清0。

        SPEED1,SPEED0-转换速度控制位,见下表。

        ADC_POWER—电源控制位。置0关闭 A/D 转换器电源;置1打开 AD 转换器电源。如果软件设置进入空闲模式,该电源会自动关闭。启动 AD 转换前一定要确认 AD 电源已打开,AD 转换结束后关闭 AD 电源可降低功耗,也可不关闭。初次打开内部 AD 转换模拟申源,需适当延时,等内部模拟电源稳定后,再启动 AD 转换,建议启动 AD 转换后,在 AD转换结束之前,不改变任何 IO 口的状态,这样有利于提高 AD 转换精度。

        ADC DATA,ADC LOW2—A/D 转换结果寄存器,对于STC12C5412AD 系列单片机来说,因为其 A/D为10位精度,ADC_DATA寄存器存储转换结果的高8位,ADCLOW2的低2位存储转换结果的最低2位:STC12C2052AD系列单片机AD转换精度只有8位,固无ADC_LOW2寄存器。

        A/D 转换结果计算公式如下:

转换结果(ADC DATA[7:0],ADC LOW2[1:0])=1024*Uin/Vcc

        式中,Uin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作电压作为模拟参考电压。

        取 ADC_DATA 的8位为 A/D 转换的高8位,取 ADC_LOW2的低2位为 A/D 转换的低2位,则为10位精度;如果舍弃ADCLOW2的低2位,只用ADCDATA寄存器的8位,则 AD 转换结果为8位精度。

结果 ADC_DATA[7:0]=256*Uin/Vcc

        关于 AD 转换模块参考电压源的一点说明:

        STC12C5410AD和STC12C2052AD系列单片机的参考电压源是输入工作电压Vcc,所以.般不用外接参考电压源。如 7805 的输出电压是5V,但实际电压可能是4.88V或4.96V,用户需要精度比较高的话,可在出厂时将实际测出的工作电压值记录在单片机内部的E-PROM里面,以供计算。如果有些用户的Vc不固定,如电池供电,电池电压在5.3~4.2V之间漂移则 Vcc不固定,就需要在8路 AD 转换的一个通道外接一个稳定的参考电压源,来计算出此时的工作电压 Vcc,再计算出其他几路 AD转换通道的电压。如可在 AC 转换通道的第7通道外接一个1.25V(或1V…)的基准参考电压源,由此求出此时的工作电压Vcc,再计算出其他几路 A/D 转换通道的电压。

13.9 STC12系列单片机的PCA/PWM介绍(略)

        PCA(Programable Counter Array)是可编程计数器阵列,PWM(Pulse Width Modulation)是脉宽调制,这两项技术在单片机内部都是由定时器/计数器和比较/捕捉模块组成,如下图所示。

13.10 STC12系列单片机的SPI接口介绍(略)

        STC12C5410AD及STC12C2052AD系列单片机还提供另一种高速串行通信接口--SPI接口。SPI是一种全双工、高速、同步的通信总线,它有两种操作模式:主模式和从模式。在主模式中,它支持高达3Mbps的速率( 系统时钟频率为12MHz时,如果CPU主频采用20MHz~36MHz,则其速率可更高,而从模式时速度无法太快,8以内较好),同时还具有传输完成标志和写冲突标志保护。

13.11 STC12系列单片机的“576MHz”超速运行(略)

        通常在使用 AT及其他公司的51单片机时,外接时钟频率为12MHz或11.0592MHz不过大多数单片机所支持的最高时钟频率为24MHz,它们的机器周期还要将时钟周期12分频。而STC89系列单片机时钟频率最高可支持80MHz,STC12系列单片机时钟频率最高可支持48MHz,并且该系列单片机有1T指令模式,即执行指令时,一个时钟周期就是一个机器周期,比通用8051内核单片机执行速度快12倍,12X48MHz=576MHz,由此可知STC单片机的运行速度的确快得惊人。

参考资料: 

[1] 郭天祥. 新概念51单片机C语言教程:入门、提高、开发、拓展全攻略[M]. 北京: 电子工业出版社, 2009.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/575563.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第一篇:Python简介:开启你的编程之旅

Python简介&#xff1a;开启你的编程之旅 在这个系列文章中&#xff0c;我将带领大家深入了解Python——一个极具魅力的编程语言。如果你对编程感兴趣&#xff0c;想要掌握一门既实用又强大的语言&#xff0c;那么Python无疑是一个绝佳的选择。本篇文章是这个系列的序章&#…

大数据基础

基本简介 大数据特点 数据量大 种类多样 结构化&#xff1a;多指关系型数据库中&#xff0c;信用卡号码、日期、财务金额、电话号码、地址 半结构化&#xff1a;xml/json 非结构化&#xff1a;全文文本、图象、声音、影视、超媒体等信息。 应用价值高 大数据的作用 追溯…

protobuf协议逆向解析

protobuf协议逆向解析 地址: aHR0cHM6Ly93d3cudGlrdG9rLmNvbS9tZXNzYWdlcz9sYW5nPWVu找到接口/v2/message/get_by_user_init 如图所示, 参数和响应并不是可直接使用的, 虽然部分内容可读。 跟栈到这里&#xff0c; 找到封包前的数据 打上断点&#xff0c; 查看变量t就是请…

数字安全实操AG网址漏洞扫描原理与技术手段分析

在数字化世界的大舞台上&#xff0c;网络安全如同守护者一般&#xff0c;默默保卫着我们的虚拟疆界。当我们在享受互联网带来的便利时&#xff0c;一场无形的战争正在上演。黑客们利用各种手段试图攻破网站的安全防线&#xff0c;而防守方则依靠先进的技术和策略来抵御入侵。其…

武汉星起航:创新孵化模式,一站式服务助力卖家全球化拓展

在全球化浪潮席卷而来的今天&#xff0c;跨境电商行业已成为推动国际贸易的重要力量。武汉星起航电子商务有限公司&#xff0c;作为这一领域的佼佼者&#xff0c;以其前瞻性的战略眼光和创新的经营模式&#xff0c;积极践行“走出去”战略&#xff0c;凭借自营店铺运营经验和跨…

Golang | Leetcode Golang题解之第50题Pow(x,n)

题目&#xff1a; 题解&#xff1a; func myPow(x float64, n int) float64 {if n > 0 {return quickMul(x, n)}return 1.0 / quickMul(x, -n) }func quickMul(x float64, n int) float64 {if n 0 {return 1}y : quickMul(x, n/2)if n%2 0 {return y * y}return y * y * …

云赛道---深度学习

• 分析问题定位任务:首先定位问题&#xff0c;将实际问题转化为机器学习问题&#xff0c;需要什么样的 数据&#xff0c;然后进行数据的采集。包含数据探查、场景抽象、算法选择。比如逻辑回归可 以决定我们是不是能喝咖啡&#xff1b;那另外朴素贝叶斯算法可以用来区分垃圾…

Linux|Awk 变量、数字表达式和赋值运算符

引言 本部分[1]将深入学习 Awk 的高级应用&#xff0c;以应对更为复杂的文本或字符串过滤任务。将介绍包括变量、数值表达式和赋值运算符在内的 Awk 功能。 这些概念与你之前可能在诸如shell、C、Python等许多编程语言中接触过的概念并没有本质上的不同&#xff0c;所以你不必过…

SaaS云HIS平台源码 采用云部署模式,部署一套可支持多家医院共同使用

目录 云HIS门诊业务使用流程 云HIS住院业务使用流程 云HIS系统使用流程 云HIS优势 云HIS系统功能模块 医疗业务&#xff1a; 电子病历&#xff1a; 经济管理&#xff1a; 药物管理&#xff1a; 统计报表&#xff1a; 系统管理&#xff1a; 运营运维&#xff1a; 通…

NLP step by step -- 了解Transformer

Transformer模型 Transformer相关历史 首先我们先看一下有关Transformer模型的发展历史&#xff0c;下面的图是基于Transformer架构的一些关键模型节点&#xff1a; 图片来源于Hugging Face 图片来源于Hugging Face Transformer 架构 于 2017 年 6 月推出。原本研究的重点是…

deepin 亮相 Intel 合作伙伴交流会,展示AI大模型应用最新成果

内容来源&#xff1a;deepin 社区 2024 年 4 月 18 日&#xff0c;备受业界瞩目的 Intel Channel Partner Networking Fair 在香港天际万豪酒店隆重举办。 在这场行业盛会上&#xff0c;deepin&#xff08;深度&#xff09;受邀参与了 Intel Demo Showcase 环节&#xff0c;向…

JDBC查询大数据时怎么防止内存溢出-流式查询

文章目录 1.前言2.流式查询介绍3.使用流式查询3.1不开启流式查询的内存占用情况3.2开启流式查询的内存占用情况 4.开启流式查询的注意点 1.前言 在使用 JDBC 查询大数据时&#xff0c;由于 JDBC 默认将整个结果集加载到内存中&#xff0c;当查询结果集过大时&#xff0c;很容易…

python与pycharm如何设置文件夹为源代码根目录

相信大家遇到过下面这种情况 当我们在当前项目下引入了其它项目的代码&#xff0c;这是其它项目的包的导入路径是不用于当前项目的&#xff0c;这样导致项目无法正常起来&#xff0c;但是我们又不可能一个个文件去处理&#xff0c;这时可以用下面的方式解决 pycharm直接设置 …

Centos 5 的yum源

背景 有使用较老的Centos 5 系统内部安装软件无法正常报错&#xff0c;是由于系统叫老yum源存在问题 处理方法 更换下述yum源&#xff0c;可以将其他repo源文件备份移动到其他目录&#xff0c;添加下述源后重新测试 [C5.11-base] nameCentOS-5.11 baseurlhttp://vault.c…

非对称渐开线齿轮学习笔记分享

最近有小伙伴遇到了非对称渐开线齿轮的加工问题,花了些时间学习了解一下,下面是总结的学习笔记,有兴趣的朋友可以瞅瞅: 目录: 为什么要采用非对称? 非对称有什么优点? 非对称齿形如何加工? 非对称齿轮怎么测量? 非对称齿轮建模 为什么要采用非对称? 现在的传动要求…

【SSM进阶学习系列丨整合篇】Spring+SpringMVC+MyBatis 框架配置详解

文章目录 一、环境准备1.1、创建数据库和表1.2、导入框架依赖的jar包1.3、修改Maven的编译版本1.4、完善Maven目录1.5、编写项目需要的包1.6、编写实体、Mapper、Service 二、配置MyBatis环境2.1、配置mybatis的主配置文件2.2、编写映射文件2.3、测试环境是否正确 三、配置Spri…

streamlit data_editor学习之 LLM理论内存占用量计算器

streamlit data_editor学习之 LLM理论内存占用量计算器 一.效果二.代码三.运行命令四.参考链接 根据用户设置的LLM参数,计算设备内存的占用量。以web的形式方便共享,可以插入多条记录,表格更新后,可以动态计算结果 一.效果 二.代码 import streamlit as st #1.31.1 import cv…

【八股】Spring Boot

SpringBoot是如何实现自动装配的&#xff1f; 首先&#xff0c;SpringBoot的核心注解SpringBootApplication里面包含了三个注解&#xff0c;SpringBootConfigurationEnableAutoConfigurationComponentScan&#xff0c;其中EnableAutoConfiguration是实现自动装配的注解&#x…

如何最大程度使用AWS?

随着云计算技术的不断发展&#xff0c;AWS已经成为众多企业的首选&#xff0c;为其提供了强大的基础设施和服务。那么如何最大程度地、灵活地利用AWS&#xff0c;成为许多企业专注的焦点。九河云作为AWS的合作伙伴&#xff0c;为读者们提供一些技巧和策略&#xff0c;帮助读者充…

UL认证防逆流多功能监测装置AGF-AE-D

安科瑞薛瑶瑶18701709087/17343930412 在单逆变器系统中&#xff0c;仪表直接与逆变器相连。如果您的变频器有一个内置的收入等级表&#xff08;RGM&#xff1b;该变频器 被称为收入等级变频器&#xff09;&#xff0c;您可以在 RGM 的同一总线上连接一个外部仪表。
最新文章