单片机原理图

avatar

控制led

#include <reg52.h>
unsigned int a;
sbit LED1 = P2^0;   //sbit定义特殊功能寄存器的位变量,这里是定义P2的0位也就是控制led的第一个灯
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;

void main(){
		a = 3000;
		while(1){
			LED1 = 0; //这里是给低电平亮
			while(a--); //进行延迟,如果不写会让led一直亮,因为电平来的太快了
			LED1 = 1;
			while(a--);
			LED2 = 0;
			while(a--);
			LED2 = 1;
			while(a--);
			LED3 = 0;
			while(a--);
			LED3 = 1;
			while(a--);
			LED4 = 0;
			while(a--);
			LED4 = 1;
			while(a--);
		}
		
		
}

呼吸灯

这里他通过控制电平速度来达到id的亮暗程度

void main()
{
	int t=500; int n=0;
	while(1)
	{
		for(n=1;n<t;n++)
		{	
		P2=0xff;  //这里是led控制io口
		delay(n);
		P2=0xfe;
		delay(t-n);
		}	
	}	
}

数码管

数码管分为共阴和共阳,b为共阳输入低电平,c为共阴输入高电平有效 数码管原理图

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char


void delay(uint xms);
//这里定义了一个数组里面存放数码管共阴的码表
uint code Duanarray[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 

void main(){
	uint i,a;
	a = 3000;
	while(1){
		for(i=0;i<10;i++){
		while(a--)
		P0 = Duanarray[i];
		}
	}
	
	
		
}
//这里是延迟函数
void delay(uint xms){
		uint i;
		for(i = 100;i>0;i--)
				for(xms;i>0;i--);
}

这里只能单独控制一个数码管,下面是通过74HC138译码器来进行多位显示

74HC138真值表 avatar

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

sbit LSA1 = P2^2;    //74HC138控制输入进行位选
sbit LSA2 = P2^3;
sbit LSA3 = P2^4;

uchar code tubeArray[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  

void digitalTubeSelect();
void delay(uint a);

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


void digitalTubeSelect(){ 
			uint i;
			for(i=0;i<8;i++){
				switch(i){
					case 0:
						LSA1 = 0;
						LSA2 = 0;
						LSA3 = 0;
						break;
					case 1:
						LSA1 = 1;
						LSA2 = 0;
						LSA3 = 0;
						break;
					case 2:
						LSA1 = 0;
						LSA2 = 1;
						LSA3 = 0;
						break;
					case 3:
						LSA1 = 1;
						LSA2 = 1;
						LSA3 = 0;
						break;
					case 4:
						LSA1 = 0;
						LSA2 = 0;
						LSA3 = 1;
						break;
					case 5:
						LSA1 = 1;
						LSA2 = 0;
						LSA3 = 1;
						break;
					case 6:
						LSA1 = 0;
						LSA2 = 1;
						LSA3 = 1;
						break;
					case 7:
						LSA1 = 1;
						LSA2 = 1;
						LSA3 = 1;
						break;
				}
				delay(1000);
				P0 = tubeArray[i];
				delay(30000);
				P0 = 0x00;
			}

}

void delay(uint a){
	if(a > 0){
		while(a--);
	}
}

独立按键

当独立按键还没有按下时,51单片机io口有上拉电阻默认高电平,当按下时变为低电平,但是因为机械特性会有抖动,这里采用软件消抖

大概几毫秒过后如果还是低电平则执行操作点亮led

void passkeyBute(){
		if(Key1 == 0){
			delay(1000);
			If(Key1==0)
			{
			led1 = 0; //点亮led
			}
		}
}

矩阵按键

这里采用行列扫描 消抖也可以用上面独立按键的方法, 高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输 出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

void KeyDown(void)
{
	char a=0;
	P1=0x0f;
	
	if(P1!=0x0f)
	{
		delay(1000);
		if(GPIO_KEY!=0x0f)
		{	
			//列
			P1=0X0F;
			switch(P1)
			{
				case(0X07):	
				KeyValue=0;
				break;
				case(0X0b):	
					KeyValue=1;
				break;
				case(0X0d): 
					KeyValue=2;
				break;
				case(0X0e):	
					KeyValue=3;
				break;
			}
			//行
			
			P1=0XF0;
			switch(P1)
			{
				case(0X70):	
					KeyValue=KeyValue;
				break;
				case(0Xb0):	
					KeyValue=KeyValue+4;
				break;
				case(0Xd0): 
					KeyValue=KeyValue+8;
				break;
				case(0Xe0):	
					KeyValue=KeyValue+12;
				break;
			}
			
		}

		
	}
	while((a<50)&&(P1!=0xf0))	 //检测按键松手检测
	{
		delay(100);
		a++;
	}
}

中断

中断是单片机非常重要的一个概念,c51有5个中断源,c52有6个多了一个定时器 avatar 使用中断前需要打开中断开关,使用中断中断允许寄存器IE

EA   //中断总开关

ET2  //定时器2中断开关

ES   //串口通信中断开关

ET1  //定时器1中断开关

EX1  //外部1中断中断开关

ET0  // 定时器0中断开关

EX0  //外部1中断中断开关

优先级控制中断优先级寄存器IP PS—串行口中断优先级控制位。

PS=1,串行口中断定义为高优先级中断。

PS=0,串行口中断定义为低优先级中断。

PT1—定时器/计数器1中断优先级控制位。

PT1=1,定时器/计数器1中断定义为高优先级中断。

PT1=0,定时器/计数器1中断定义为低优先级中断。

PX1—外部中断1中断优先级控制位。

PX1=1,外部中断1中断定义为高优先级中断。

PX1=0,外部中断1中断定义为低优先级中断。

PT0—定时器/计数器0中断优先级控制位。

PT0=1,定时器/计数器0中断定义为高优先级中断。

PT0=0,定时器/计数器0中断定义为低优先级中断。

PX0—外部中断0中断优先级控制位。

PX0=1,外部中断0中断定义为高优先级中断。

PX0=0,外部中断0中断定义为低优先级中断。

先看外部中断的使用

#include <reg52.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char

sbit led1 = P2^0;
void main(){
	while(1){
		keypass();
	}
}

void mod(){
	EA = 1; //开关中断
	//外部中断
	EX0 = 1;   //设置中断允许位
	IT0 = 1;	//设置中断方式负跳变沿触发
}

void interrupt1() interrupt 0 {    
		if(key2 == 0){
				P2 = 0xff;
				led1 = ~led1;
		}
				
}

void keypass(){	
		if(key2 == 0){
			P2 = 0xff;
			delay(1000);
		}
}