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;
}
}
}