[51 microcontroller series] Interrupt system expansion experiment in C51

This article is an extended experiment on the 51 microcontroller interrupt system.

1. Extended Experiment 1: Use external interrupt 0 to control the buzzer and external interrupt 1 to control the DC motor.

The functions implemented in the external interrupt expansion experiment 1: Use external interrupt 0 to control the buzzer to sound/not sound, and external interrupt 1 to control the rotation/stop of the DC motor.

It can be known from the content of the buzzer that the buzzer is divided into active buzzer and passive buzzer; the buzzer has two pins. To make the buzzer sound, current needs to pass through the buzzer. That is, one end of the pin is connected to the positive electrode, and the other end of the pin is connected to the negative electrode. Active buzzers only need a certain voltage to sound, while passive buzzers require pulses of a certain frequency to sound. Two buzzers are designed here, both controlled by external interrupt 0.

The DC motor is driven in a similar way to a buzzer.

The hardware design in proteus is as follows. In order to display the sound of the buzzer, an LED is used to display whether the buzzer is sounding or not. One end of the buzzer is connected to the power supply, and the other end is connected to the P1.5 port through the ULN2003 chip. When P1.5=0, the buzzer sounds; one end of the DC motor is connected to the power supply, and the other end is connected to the P1.0 port through the ULN2003 , the motor rotates when P1.0=0. To reflect the interrupt, use an independent button module connected to the P3.2 and P3.3 ports. When the button is pressed, the buzzer sounds or the motor rotates.

proteus design external interrupt control buzzer and DC motor

The software design is as follows:

/*
	实现功能:外部中断0控制蜂鸣器发声,外部中断1控制直流电机转动
		- 与外部中断0和外部中断1有关的有两个寄存器IE和TCON,
		- IE是中断允许控制寄存器,TCON是中断请求标志寄存器。
		- IE中包括了
			- 总中断允许位(EA)
			- 外部中断0/1允许位(EX0/EX1)
			- 定时器0/1允许位(ET0/ET1)
			- 串口中断允许位(ES);
		- TCON中的低四位是外部中断允许和触发方式控制位,包括了
			- IT0/IT1是外部中断0/1触发方式控制位,0表示低电平触发,1表示下降沿触发;
			- IE0/IE1是外部中断0/1请求标志位
	[2023-12-19] zoya
*/

#include "reg52.h"
#include "typedef.h"
#include "Delay.h"

sbit BEEP = P1^5;
sbit MOTOR = P1^0;
sbit CTR_INT0 = P3^2;
sbit CTR_INT1 = P3^3;

/*************************************************************************
* 函数名:		IntInit
* 函数功能:	外部中断0/1初始化,设置中断触发方式为边沿触发
* 输入:			void
* 输出:			void
**************************************************************************/
void IntInit()
{
    
    
	// 1. 设置中断触发方式
	IT0=1;
	IT1=1;
	// 2. 打开外部中断0/1
	EX0=1;
	EX1=1;
	// 3. 打开总中断
	EA=1;
}


void main()
{
    
    
	MOTOR=0;
	BEEP=0;
	IntInit(); 
	while(1);
}

/*************************************************************************
* 函数名:		Int0
* 函数功能:	外部中断0中断服务函数,
* 						控制蜂鸣器发声
* 输入:			void
* 输出:			void
**************************************************************************/
void Int0() interrupt 0
{
    
    
	delayms(10);  // 按键延时消抖
	if(0 == CTR_INT0){
    
    
		BEEP = ~BEEP;
	}
}

/*************************************************************************
* 函数名:		Int1
* 函数功能:	外部中断1中断服务函数,
* 						控制直流电机转动
* 输入:			void
* 输出:			void
**************************************************************************/
void Int1() interrupt 2
{
    
    
	delayms(10);  // 按键延时消抖
	if(0 == CTR_INT1)
	{
    
    
		MOTOR=~MOTOR;
	}
}

Simulation results:

External interrupt controls buzzer and DC motor

2. Extended Experiment 2: Modify the initial value of the timer and set a 3-second timer to make the LED module flash.

How to calculate the initial value of the timer?

Calculated using a 12MHz crystal oscillator frequency. If a 12MHz crystal oscillator is used, the internal clock frequency of the microcontroller is divided by 12, that is, 12/12MHz=1MHz; then the corresponding machine cycle is 1/1MHz=1us. That is, the machine cycle of using a 12MHz crystal oscillator is 1us.

If you want to time 1ms, you need to count 1ms/1us=1000. The timer works in mode 1, then the initial value is 2 16 − 1000 = 64536 2^{16}-1000 = 645362161000=64536 = 0xFC18. That is, the initial values ​​THx=0xfc, TLx=0x18.

If you want to time 1s, you can set the timer 1ms through the initial value. When the timer ends, reassign the initial value and set a global variable to accumulate the number of times of 1ms. When the global variable accumulates 1000 times, it means the timer is 1s.

If you want to set the 3s time, you can set the timing to 3ms through the initial value, and the other timings are the same as 1ms. Timing 3ms requires counting 3ms/1us=3000. The timer works in mode 1. The initial value is 2 16 − 3000 2^{16} - 3000.2163000 = 62536 = 0xF448, that is, the initial value THx=0xF4, TLx=0x48.

In this experiment, based on the previous usage example, changing the initial counting value can achieve a timing of 3 seconds to achieve the flashing of the LED module. The LED module is designed in proteus as follows, and the timer module is inside the microcontroller.

Proteus design timer controls LED module flashing

The software design is as follows:

/*
	实现功能:定时器0定时3s实现LED模块亮灭
		- 与定时/计数器工作有关的寄存器有IE、TCON、TMOD、THx、TLx
		- IE是中断允许控制寄存器,TCON是中断请求标志寄存器,TMOD是定时/计数器工作方式寄存器
		- THx和TLx是计数初值赋值寄存器。
		
		- IE中包括了
			- 总中断允许位(EA)
			- 外部中断0/1允许位(EX0/EX1)
			- 定时器0/1允许位(ET0/ET1)
			- 串口中断允许位(ES);
		
		- TCON中的高四位用于控制定时/计数器的启动和中断申请,包括TR0/1、TF0/1
			- TR0/TR1是T0/T1运行控制位,TR0=1时开始工作,TR0=0时停止工作,TR1与TR0类似;
			- TF0/TF1是T0/T1溢出中断请求标志位,溢出时由硬件自动置位,CPU响应中断后由硬件自动清0
				可随时查询该位状态,也可软件置1或清0.
				
		- TMOD高四位控制T1,低四位控制T0,高四位和低四位分别为有GATE、C/T、M1M0
			- GATE是门控位,
				- GATE=0表示不受外部中断信号影响,仅TR0/TR1控制定时/计数器工作,
				- GATE=1表示受外部中断信号影响,即TR0/TR1+INT0控制定时/计数器工作
			- C/T是定时/计数器模式选择位,C/T=0为定时模式,C/T=1为计数模式;
			- M1M0是工作方式设置位,有四种方式:00 01 10 11
	[2023-12-20] zoya
*/

#include "reg52.h"
#include "typedef.h"
#include "Delay.h"

#define GPIO_LED P2
/*************************************************************************
* 函数名:		Timer0Init
* 函数功能:	定时器0初始化,工作方式1定时3ms,仅TR0启动或停止计数
* 输入:			void
* 输出:			void
**************************************************************************/
void Timer0Init()
{
    
    
	// 1. 设置工作方式1,仅TR0控制
	TMOD |= 0x01;
	// 2. 设置定时3ms的初值,0xf448
	TH0 = 0xf4;
	TL0 = 0x48;
	// 3. 打开中断允许位
	EA = 1;
	ET0 = 1;
	// 4. 置位TR0,开始计数
	TR0 = 1;
}


void main()
{
    
    
	Timer0Init(); 
	while(1);
}


/*************************************************************************
* 函数名:		Timer0
* 函数功能:	定时器0中断服务函数,定时3s控制LED模块亮灭
* 输入:			void
* 输出:			void
**************************************************************************/
void Timer0() interrupt 1
{
    
    
	static u16 i;
	// 重新赋初值
	TH0 = 0xf4;
	TL0 = 0x48;
	i++;
	if(1000 == i)
	{
    
    
		i=0;
		GPIO_LED = ~GPIO_LED;
	}
}

Simulation results:

Timer 0 controls the LED module to turn on and off for 3 seconds.

3. Extended Experiment 3: Design a digital clock using timer 1 and digital tube

For the setting of the timer, refer to Extended Experiment 2.

The digital clock uses a 24-hour format and displays in the "00-00-00" format.

Here the digital tube uses an eight-bit common cathode digital tube, the chip 74HC138 is used to control the bit selection of the digital tube, and the chip 74HC245 is used to control the segment selection of the digital tube; the P0 port controls the input of the 74HC245, and P2.2 ~ P2.4 controls the 74HC138 input of. The proteus design is as follows:

Proteus designs timer 1 and digital tube to implement a digital clock

The software design is as follows:

/*
	实现功能:定时器1和数码管设计一个数字时钟
		- 与定时/计数器工作有关的寄存器有IE、TCON、TMOD、THx、TLx
		- IE是中断允许控制寄存器,TCON是中断请求标志寄存器,TMOD是定时/计数器工作方式寄存器
		- THx和TLx是计数初值赋值寄存器。
		
		- IE中包括了
			- 总中断允许位(EA)
			- 外部中断0/1允许位(EX0/EX1)
			- 定时器0/1允许位(ET0/ET1)
			- 串口中断允许位(ES);
		
		- TCON中的高四位用于控制定时/计数器的启动和中断申请,包括TR0/1、TF0/1
			- TR0/TR1是T0/T1运行控制位,TR0=1时开始工作,TR0=0时停止工作,TR1与TR0类似;
			- TF0/TF1是T0/T1溢出中断请求标志位,溢出时由硬件自动置位,CPU响应中断后由硬件自动清0
				可随时查询该位状态,也可软件置1或清0.
				
		- TMOD高四位控制T1,低四位控制T0,高四位和低四位分别为有GATE、C/T、M1M0
			- GATE是门控位,
				- GATE=0表示不受外部中断信号影响,仅TR0/TR1控制定时/计数器工作,
				- GATE=1表示受外部中断信号影响,即TR0/TR1+INT0控制定时/计数器工作
			- C/T是定时/计数器模式选择位,C/T=0为定时模式,C/T=1为计数模式;
			- M1M0是工作方式设置位,有四种方式:00 01 10 11
		
		使用一个八位一体的共阴极数码管显示时间,74HC138芯片控制数码管的位选,74HC245控制数码管的段选。
	[2023-12-20] zoya
*/

#include "reg52.h"
#include "typedef.h"
#include "Delay.h"

#define GPIO_DISPLAY P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

// 共阴极数码管的码表,0-9以及:
u8 code smg[] = {
    
    0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67, 0x40};

static u16 h, m, s;

/*************************************************************************
* 函数名:		Timer0Init
* 函数功能:	定时器0初始化,工作方式1定时3ms,仅TR0启动或停止计数
* 输入:			void
* 输出:			void
**************************************************************************/
void Timer1Init()
{
    
    
	// 1. 设置工作方式1,仅TR0控制
	TMOD |= 0x10;
	// 2. 设置定时1ms的初值,0xFC18
	TH1 = 0xFC;
	TL1 = 0x18;
	// 3. 打开中断允许位
	EA = 1;
	ET1 = 1;
	// 4. 置位TR1,开始计数
	TR1 = 1;
}

void DigDisplay()
{
    
    

	LSA=0; LSB=0; LSC=0; GPIO_DISPLAY = smg[h/10];
	delayms(1);
	LSA=1; LSB=0; LSC=0; GPIO_DISPLAY = smg[h%10];
	delayms(1);
	LSA=0; LSB=1; LSC=0; GPIO_DISPLAY = smg[10];
	delayms(1);
	LSA=1; LSB=1; LSC=0; GPIO_DISPLAY = smg[m/10];
	delayms(1);
	LSA=0; LSB=0; LSC=1; GPIO_DISPLAY = smg[m%10];
	delayms(1);
	LSA=1; LSB=0; LSC=1; GPIO_DISPLAY = smg[10];
	delayms(1);
	LSA=0; LSB=1; LSC=1; GPIO_DISPLAY = smg[s/10];
	delayms(1);
	LSA=1; LSB=1; LSC=1; GPIO_DISPLAY = smg[s%10];
	delayms(1);
}

void main()
{
    
    
	GPIO_DISPLAY = 0x00;
	Timer1Init(); 
	while(1)
	{
    
    
		DigDisplay();
	}
}

/*************************************************************************
* 函数名:		Timer1
* 函数功能:	定时器1中断服务函数,控制数码管显示
* 输入:			void
* 输出:			void
**************************************************************************/
void Timer1() interrupt 3
{
    
    
	static u16 j;
	// 重新赋初值
	TH1 = 0xFC;
	TL1 = 0x18;
	j++;
	if(1000 == j)
	{
    
    
		j=0;
		s++;
		if(60 == s)
		{
    
    
			s=0; m++;
			if(60 == m)
			{
    
    
				m=0; h++;
				if(24 == h)
				{
    
    
					h=0;
				}
			}
		}
	}
}

Simulation results:

Timer 1 and digital tube realize a digital clock

Guess you like

Origin blog.csdn.net/sinat_41752325/article/details/135108419