《嵌入式硬件(二):中断》

1.独立按键

按下之后,原理图网络编号变为低电平(经过初始化后为高电平的情况下)

tips:==的运算级比&高

用按键控制晶体数码管的数字->按k几,数码管就亮几

main.c

cs 复制代码
#include <reg52.h>
#include "digiter.h"
#include "key.h"
#include "delay.h"



int main(void)
{
	init_key();
	init_key_P3();
	while(1)
	{  
	    show_number(key_pressed());
	}
}

digiter.c

cs 复制代码
#include <reg52.h>
#include "delay.h"
#include "digiter.h"

void bit_select(int n)
{
	P1 &= ~(0x0F << 0);
	P1 |= (1 << n);
}


void seqment_select(int n)
{
	unsigned char t[10] = {0X3F, 0X06, 0X5B, 0X4F, 0x66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F};
	P0 = t[n];
	delay(100);
	P0 = 0;
	delay(100);
}

void show_number(int n)
{	if(n > 9999)
	{
		return;
	}
	else if(n == 0)
	{
		 bit_select(0);
		 seqment_select(0);
	}
	else
	{
		int t = 0;
		while(n)
		{
			bit_select(t++);
			seqment_select(n % 10);
			n /= 10;
		}
	}
}

key.c

cs 复制代码
#include <reg52.h>
#include "key.h"
 void init_key(void)
{
	P1 |= (0x0F << 4);
}
void init_key_P3(void)
{
	P3 |= (0x0F << 4);
}
int key_pressed(void)
{
 	static int ret = 0;
	if((P1 & (1 << 4)) == 0)		 //0000 0001
	   {
	   		ret = 1;
	   }				   
	   else if((P2 & (1 << 5)) == 0)
	   {
	   		ret = 2;
	   }
	    else if((P1 & (1 << 6)) == 0)
	   {
	   		ret = 3;
	   }
	    else if((P1 & (1 << 7)) == 0)
	   {
	   		ret = 4;
	   }
	    else if((P3 & (1 << 5)) == 0)
	   {
	   		ret = 5;
	   }
	   return ret;	
}

delay.c

cs 复制代码
#include <reg52.h>
#include "delay.h"

void delay(unsigned int n)
{
	while(n--);
}

2.中断系统

中断:当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。

中断源:实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。

中断嵌套:当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。(51单片机最多俩层)

八种中断

中断执行流程

1)中断源发出中断请求

2)内核(cpu)检查是否响应相应中断以及该中断是否被屏蔽

3)内核会检查中断的中断的优先级

4)保护现场

5)执行中断服务函数

6)恢复现场

中断向量表:函数的指针的数组

中断向量:interr_table

中断的中断向量:interr_table[]

中断结构

3.中断寄存器

下面是详细介绍:

1)IE

2)TCON

利用中断,控制数码管,灯

main.c

cs 复制代码
#include <reg52.h>
#include "delay.h"
#include "digiter.h"

void init_enit0(void)
{
	IE |= (1 << 7)  | (1 << 0);
	TCON |= (1 << 0) | (1 << 1);	//下降沿
	P3 |= (1 << 2);	
}

void init_enit1(void)
{
	IE |= (1 << 7) | (1 << 2);
	TCON |= (1 << 3);
	TCON &= ~(1 << 2);	 //低电平
	P3 |= (1 << 3);		
}
int num = 0;		
void enit0_handler(void) interrupt 0
{
	P2 ^= 0xFF;

	++num;
	if(num > 9999)
	{
		num = 0;
	}
}

void enit1_handler(void) interrupt 2
{
	//P2 ^= 0xFF;
	--num;
	if(num < 0)
	{
		num = 9999;
	}
}

int main(void)
{
	//P2 = 0;
	init_enit0();
	init_enit1();
	while(1)
	{
	   show_number(num);
	}
}

delay.c

cs 复制代码
#include <reg52.h>
#include "delay.h"

void delay(unsigned int n)
{
	while(n--);
}

digiter.c

cs 复制代码
#include <reg52.h>
#include "delay.h"
#include "digiter"

void bit_select(int n)
{
	P1 &= ~(0x0F << 0);
	P1 |= (1 << n);
}


void seqment_select(int n)
{
	unsigned char t[10] = {0X3F, 0X06, 0X5B, 0X4F, 0x66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F};
	P0 = t[n];
	delay(100);
	P0 = 0;
	delay(100);
}

void show_number(int n)
{	if(n > 9999)
	{
		return;
	}
	else if(n == 0)
	{
		 bit_select(0);
		 seqment_select(0);
	}
	else
	{
		int t = 0;
		while(n)
		{
			bit_select(t++);
			seqment_select(n % 10);
			n /= 10;
		}
	}
}

4.定时器

unsigned short 范围0~0xFFFF

counter计数器,会自动往上加,52单片机是加计数器

Clock时钟

晶振:12Mhz 11.0592Mhz,实际工作为1/12,10^6

计数器加一,用时1us(微秒)

1)TCON

2)TMOD工作模式

16位定时器:TL0存储低位,TL0存储高位,大小都是一字节。

定时器控制灯开关,一秒一次

cs 复制代码
#include <reg52.h>


void init_time0(void)
{
	TMOD &= ~(3 << 2);
	TMOD &= ~(3 << 0);
	TMOD |= (1 << 0);
	TCON |= (1 << 4); 

	IE |= (1 << 7) | (1 << 1);

	TH0 = 64535 >> 8;
	TL0 = 64535;
}

void timer0_handler(void)  interrupt 1
{
	static int t = 0;
	if(t >= 500)
	{
		P2 ^= 0xFF;
		t = 0;
	}
	++t;
	TH0 = 64535 >> 8;
	TL0 = 64535;
}

int main(void)
{
	init_time0();

	while(1)
	{

	}
}

5.PWM

PWM是 **脉冲宽度调制(Pulse Width Modulation),**用 "占空比" 控制 "平均输出"

1.周期

2.占空比:一个周期内高电平的时间

有源蜂鸣器 无源蜂鸣器 源->震荡源 有源,固定频率的响;无源,传方波

蜂鸣器

cs 复制代码
#include <reg52.h>
#include "key.h"
#define Hz200 64285
#define Hz400 63035
#define Hz600 64535

unsigned short n = Hz200;
void init_time0(void)
{
	TMOD &= ~(3 << 2);
	TMOD &= ~(3 << 0);
	TMOD |= (1 << 0);
	TCON |= (1 << 4); 

	IE |= (1 << 7) | (1 << 1);

	TH0 = n >> 8;
	TL0 = n;
}

void timer0_handler(void)  interrupt 1
{
	P2 ^= 1 << 1;
	TH0 = n >> 8;
	TL0 = n;
}

int main(void)
{
	init_time0();
	init_key();
	init_key_P3();
	while(1)
	{
		if((P1 & (1 << 4)) == 0)		 //0000 0001
	   {
	   		n = Hz200;
	   }				   
	    else if((P1 & (1 << 6)) == 0)
	   {
	   		n = Hz400;
	   }
	    else if((P1 & (1 << 7)) == 0)
	   {
	   		n = Hz600;
	   }
	}
}
相关推荐
ting_zh2 天前
用定时器生成PWM信号
stm32·单片机·嵌入式硬件·tim·pwm
普中科技12 天前
【普中51单片机开发攻略--基于普中-2&普中-3&普中-4】-- 第 13 章 独立按键实验
单片机·嵌入式硬件·51单片机·开发板·按键·独立按键·普中科技
♛识尔如昼♛13 天前
计算机组成原理(26) 第六章 - iO方式2-程序中断方式
中断
云雾J视界14 天前
PWM不只是调速!深入电机驱动中的动态响应、EMI抑制与电源完整性设计
mcu·pwm·emi·电机驱动·电源完整性·mosfet
加成BUFF17 天前
树莓派5-TB6612电机驱动模块完整实战教程
嵌入式硬件·pwm·树莓派5·tb6612·pwm波控制电机
一个平凡而乐于分享的小比特17 天前
时钟源与定时器:澄清概念
定时器·时钟源
特立独行的猫a18 天前
C++使用Boost的Asio库优雅实现定时器与线程池工具类
开发语言·c++·线程池·定时器·boost·asio
Felven21 天前
飞腾D2000 GPIO中断调试
linux·gpio·中断·d2000
利刃大大22 天前
【JavaSE】十五、线程同步wait | notify && 单例模式 && 阻塞队列 && 线程池 && 定时器
java·单例模式·线程池·定时器·阻塞队列
YouEmbedded22 天前
解码信号与槽(含 QTimer 应用)
qt·定时器·信号与槽