51单片机学习笔记——代码和protues模拟案例

1、中断小案例(演示通过外部中断按钮触发LED)
在这里插入图片描述

#include<reg51.h>
#define uchar unsigned char

//定义LED的控制引脚P2^0,用来控制灯光的打开和关闭;
sbit led = P2^0;

//定义按钮的中断触发控制位,来触发执行中断函数;
sbit button=P3^2;

//延时函数抖动
void delayms(uchar ms){
   
	uchar i;
	while(ms--){
   
		for(i=0;i<123;i++){
   
			;
		}
	}
}

//定义中断函数,指定中断号码为0,INT0,外部中断,低电平下降沿触发;
void int0_action(void) interrupt 0
{
   
		//中断打开灯光
		delayms(1);
    led=1;
		delayms(1000);
}

//初始化中断配置项目
void int0_init(){
   
	//1、开中断是否允许接受中断(一级控制)
	EA=1; //IE中断中断寄存器:CPU的总中断允许控制位, EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。
	
	//2、选择寄存器
	IT0=1;//TCON标志控制寄存器:外部中断IT0,控制引脚P3^2,IT0=1设置低电平下降沿触发
	
	//3、设置所需寄存器的允许位(二级控制)
	EX0=1;//IE中断允许寄存器: 外部中断0中断允许位。EX0=1,允许中断;EX0=0禁止中断
	
/*********************************
	也可以将上边的寄存器合起来写,上边嘚瑟属于寄存器的位赋值方式;
	下边的合起来的属于寄存器的整体赋值;
	
	TCON=0X01; //TCON包含	IT0=1;
	
	IE=0X81; //IE包含EA=1;	EX0=1;
**********************************/
}

void main(){
   
	int0_init();
	while(1){
   
		led=0;
	}

}

2、定时器测试案例(演示通过定时器控制LED)
在这里插入图片描述
/******************************
定时器(内部)/ 计数器(外部):
包括时间源(北京时间)、时间长度(定时多久)、定时任务(到时间后触发什么动作)
时钟源:属于单片机内部时钟源,由单片机的晶振提供。计数器是外部;
计时长度:一个定时器对应两个8为寄存器,TH\TL,总共2^16=65536;
中断触发函数:执行中断任务;

触发定时器需要进行以下步骤:
1、设置定时器模式:
通过TMOD寄存器来设置定时器的工作模式。
例如,如果我们想将定时器0设置为模式1(16位定时/计数器模式),我们可以写入TMOD = 0x01;。
2、加载定时初值:
定时初值决定了定时器中断的触发频率。我们可以通过TH0和TL0寄存器来设置定时器0的初值。
例如,我们可以写入TH0 = 0xFC; TL0 = 0x18;来设置定时初值,他就会以这个数开始–。
在51单片机的定时器中,TH0是高8位,TL0是低8位。这两个寄存器共同组成了一个16位的定时/计数器。
当我们说"设置定时器的初值"时,通常是指同时设置这两个寄存器的值。
3、开启定时器中断:
通过IE寄存器来开启定时器的中断。例如,我们可以写入ET0 = 1; EA = 1;来开启定时器0的中断。
4、动定时器:
通过TR0位来启动定时器0。例如,我们可以写入TR0 = 1;来启动定时器。
在带有XX0中,0就是定时器编号,也可以写1,因为有两个定时器
******************************/

#include<reg52.h>
// 标志位,统计时间溢出次数
int flag=0;
// 驱动LED引脚
sbit LED = P2^0;
/*
外部中断0(INT0)		中断号0    入口地址0003H
定时/计数器0(T0)	中断号1    入口地址000BH
外部中断1(INT1)		中断号2    入口地址0013H
定时/计数器1(T1)	中断号3    入口地址001BH
串行口中(RI/TI)		中断号4 	 入口地址0023H
*/
void timer1(void) interrupt 3  //设置使用的是定时器1(模式1),所以需要选择与定时器1对应的终端号3
{
    
	/*
	8051系列单片机又在这个基础上进行细分,将一个机器周期划分为6个状态周期,也就是S1-S6,
	每个状态周期又由两个节拍组成,P1和P2,而P1=P2=时钟周期。这也就是经常说的8051系列单片机的的时钟频率是晶振频率的12分频,或者是1/12,
	
	如果依照f=12MHz晶振计算,每次时钟周期=1/f; 
	因为单片机时钟频率是晶振频率的1/12,所以单片机时钟周期是T=1/(f/12)=(1/f)*12 = 1/12000000=1微妙,那么单片机定时器16位计时范围2^16=65535
	50000次就是0.05秒,乘以20次,就是1秒钟
	*/
  TH1=(65536-50000)/256; //依照12MHz晶振计算,每次机器周期1/f = 1/12000000=1微妙,初始话定时器的处值,定时器从初值开始统计寄存器溢出次数
	TL1=(65536-50000)%256;
  flag++;		//每溢出一次,标志位加1,	每次溢出需要50毫秒					 
	if (flag==20)	     //达到1s
		{
   
			flag	=0; //累计一秒后重置0 
			LED=~LED; //一秒间隔闪烁取反
		}	  			
}

void timer_init(){
   
/************设置特殊功能寄存器TMOD:选择定时器、以及定时器工作模式*********************/
	/*  
	符号位 GATE C/T M1 M0 	GATE C/T M1 M0
	●GATE=1时,“与门”的输出信号K由INTx输入电平和TRx位的状态一起决定(即此时K=TRx·INTx),当且仅当TRx=1,INTx=1(高电平)时,计数启动;否则,计数停止。
	当INT0引脚为高电平时且TR0置位,TR0=1;启动定时器T0;
	当INT1引脚为高电平时且TR1置位,TR1=1;启动定时器T1。
	●GATE=0时,“或门”输出恒为1,“与门”的输出信号K由TRx决定(即此时K=TRx),定时器不受INTx输入电平的影响,由TRx直接控制定时器的启动和停止。
	当TR0=1,启动定时器T0。
	当TR1=1,启动定时器T1。
	●C/T=0时为定时功能: 加1计数器对脉冲f进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出;
	●C/T=1时为计数功能: 加1计数器对来自输入引脚T0(P3.4)和T1(P3.5)的外信号脉冲进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出;
	●M1 0/1
	●M0 0/1
	//0 0 方式0 13位计数器 TMOD=0x00
	//0 1 方式1 16位计数器 TMOD=0x01
	//1 0 方式2 自动重装8位计数器 TMOD=0x02
	//1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 TMOD=0x03 
	*/
	TMOD=0x10; //0x10 = 0000 0001,高四位是定时器1、第四位是定时器0,
	
/******************定时器赋初始值****************************/
	//1)假设我使用的单片机的晶振为12MHZ,其机器周期是1us,即每1us产生一次计数;
	//2)1s需要1*10^6个机器周期,但定时器T0只能对机器周期能进行最大65536次计数,很明显已经超过了,并不能直接采用T0的默认值;
	//3)取个65535之内的整数值,经过简单倍数关系即可转换为1s。很明显,50ms符合要求。即一次中断5 * 10^4次,中断20次即为1s
	//4)但根据中断原理,T0中断器溢出时计数1次,但5 * 10^4<65536,根本不会发生溢出。
	//  如果我给T0定时器附上初始值,使其从初试值开始计数,最终读数为65536发生溢出,中断一次。这个初始值就是65536和5 * 104的差值  
	//5)T0中断器由两个8位构成,低8位,即2^8,满打满算也只能计数256个机械周期,当大于256个机械周期就必须采用高8位了。换而言之,高8位每增加1,低八位就装满一次。
	//6)故用初始值除以256取整,存入高8位。取余,即小于256次数,放入低8位。
	TH1=(65536-50000)/256; 
	TL1=(65536-50000)%256;  
	
/*****************配置中断允许控制寄存器************************/
	/*
	位符号 EX0 ET0 EX1 ET1 ES -- -- EA
	EX0:外部中断0允许位。EX0=1,允许外部中断0中断;EX0=0,禁止外部中断0中断。当EX0=1( SETB EX0 )时,同时单片机P3.2引脚上出现中断信号时,单片机中断主程序的执行而“飞”往中断服务子程序,执行完后通过中断返回指令RET 动返回主程序。当EX0=0( CLR EX0)时,即使单片机P3.2引脚上出现中断信程序也不会从主程序“飞” 出去执行,因为此时单片机的CPU相当于被“堵上了耳朵”,根本接收不到P3.2引脚上的中断信号,但是这并不表示这个信号不存在。如果单片机的CPU有空查一下TCON中的IE0位,若为1就说明有中断信号出现过。 [3]
	ET0:T0溢出中断允许位。ET0=1,允许T0中断;ET0=0,禁止T0中断。
	EX1:外部中断1允许位。EX1=1,允许外部中断1中断;EX1=0,禁止外部中断1中断。当EX1=1( SETB EX1)时,并且外部P3.3引脚上出现中断信号时,单片机CPU会中断主程序而去执行相应的中断服务子程序;当EX1=0( CLR EX1)时使外部P3.3引脚上即使出现中断信号,单片机的CPU也不能中断主程序转而去行中断服务子程序。 [3]因此,可以这样认为,EX0和EX1是决定CPU能否感觉到外部引脚P3.2P3.3上的中断信号的控制位。
	ET1:T1溢出中断允许位。ET1=1,允许T1中断;ET1=0,禁止T1中断。
	ES:串行中断允许位。ES=1,允许串行口中断;ES=0,禁止串行口中断。
	EA:中断总允许位。EA=1,CPU开放中断;EA=0,CPU禁止所有的中断请求。总允许EA好比一个总开关。EA就相当于每家水管的总闸,如果总闸不开,各个龙头即
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值