51单片机入门学习篇-led灯、按键、数码管、中断

文章目录

  • 前言
  • 一、Proteus仿真
  • 二、Keil代码编写
    • 1.流水灯
    • 2.来回点灯
    • 3.按键操作
    • 4.中断操作
    • 5.数码管
    • 6 动态数码管
  • 三、 练习题
  • 总结


前言

本文用来记录博主学习单片机的过程与方法,希望对入门的同学有所帮助

该篇博客主要讲授如何基于proteus(仿真)+keil实现51单片机的点灯操作,本篇为入门篇,所以会介绍如何使用Proteus进行仿真,以及代码编写思路,实现简单的功能效果。


一、Proteus仿真

该软件的安装教程就不多赘述,网上资源很多,主要讲解满足51学习的使用,几个常用的功能。
51单片机入门学习篇-led灯、按键、数码管、中断_第1张图片
在Proteus搭成这样即可完成本文章下除了5.数码管的其他所有的仿真任务。

1、常见原件库,按p键即可进行搜索,搜索指定元器件代号既可选入。

51单片机:AT89C52
排阻:RP1(主要用于P0口做串口使用的时候需要接上拉电阻)
LED:LED
按键:BUTTON
数码管:display
动态数码管:7SEG

2、电源、地等元件库。

二、Keil代码编写

1.流水灯

51单片机入门学习篇-led灯、按键、数码管、中断_第2张图片

代码如下(示例):

#include 

void delay(void)
{
	unsigned int i = 40000;	 
	while(i--);
}

void main(void)
{
	unsigned char dat = 0x01, i=0;
    unsigned int direction = 0;
    //LED共阴,高电平点亮,设置0x01
    P1 = dat;
    //LED共阳,低电平点亮,设置0xfe,取反即可
    //P1 = ~data;
    while(1){
        if (direction == 0){
            P1 <<= 1;
            //P1+=1; //低电平点亮
            delay();
            if (P1 == 0x80){
                direction = 1;
            }        
        }
        if (direction == 1){
            P1 >>= 1;
            //P1|=0x80;//低电平点亮
            delay();
            if (P1 == 0x01){
                direction = 0;
            }
        }
    }
}

代码思路:
51单片机默认io口输出高电平,led灯采用的共阴极接法,所以初始化为0x01,移动1来使得亮的灯移动
定义一个direction 作为方向的判断符号,当direction为0的时候P1左移一位,相反为1的时候P1右移一位。

仿真
在keil中编译学好的代码,则会在本地该工程文件夹下的Object目录下生成一个后缀为.hex的文件,编译结果中也可以看到文件路径。
51单片机入门学习篇-led灯、按键、数码管、中断_第3张图片

在Proteus中双击芯片,点击如图所示的位置,选择上述的hex文件即可进行仿真。
51单片机入门学习篇-led灯、按键、数码管、中断_第4张图片

2.来回点灯

代码如下(示例):

#include 

void delay(void)
{
	unsigned int i = 30000;	 
	while(i--);
}

void main(void)
{
	unsigned char dat = 0x01, i=0, lastDat = 0x80, lastLight = 0xff, lastState = 0x01;
  int direction = 0;
  P1 = dat;
	delay();
	while(1){
		if (lastDat == 0x01){
			lastDat = 0x80;
			lastLight = 0xff;
			lastState = 0x01;
			P1 = lastState | (~lastLight);
			delay();
		}
			if (direction == 0){
					lastState <<= 1;
					//P1 <<= 1;
					P1 = lastState | (~lastLight);
					delay();
					if (P1 == (lastDat|(~lastLight))){
						lastLight >>= 1;
						lastDat >>= 1;
						direction = 1;
					}        
			}
			if (direction == 1){
					lastState >>= 1;
					//P1 >>= 1;
					P1 = lastState|(~lastLight);
					delay();
					if (P1 == (0x01|(~lastLight))){
							
							direction = 0;
					}
			}
			//P1 = dat;
	}
}

不仅定义了方向符号,还多定义了一个变量(0xff)右移与P1状态进行或运算来确保尾灯点亮。

3.按键操作

51单片机入门学习篇-led灯、按键、数码管、中断_第5张图片

#include 

void button_led(){
	P1 = ~P1;#取反
}
void main(){
	P1 = 0xff;
	while(1){
		while(P3_2);//监测按下
		while(!P3_2);//弹起,完成一次按键操作
		button_led();//执行
	}
}

实现功能:当按下一次按键就会使得P1取反,对应的管脚电平改变。

4.中断操作

#include 


void button_led(void) interrupt 0
{
	P1 = ~P1;
}
void main(){
	EA = 1;
	EX0 = 1;
	IT0 = 1;
	while(1);
}

实现功能:同3一样,通过按键来控制P1系列管脚的电平变化。
INT0对应的编号为0,INT1对应的编号为2,该编号为interrupt后的数字。

5.数码管

这里使用的是共阴极数码管,可以看见数码管段选接的地。
7个位选接在P0的7个位上。
51单片机入门学习篇-led灯、按键、数码管、中断_第6张图片
根据数码管的灯接的位置,输入对应的码值就可以构造出对应图形的数字。

#include 

void delay(){
	unsigned int i=40000;
	while(i--);
}

void main(){
	unsigned char code tab[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x76};#0-9码表
	unsigned int i=0;
	while(1){
		if (i>10){
			i=0;
		}
		P0 = tab[i];
		delay();
		i++;
	}
}

数码管从0-9循环显示。

6 动态数码管

51单片机入门学习篇-led灯、按键、数码管、中断_第7张图片位选:左边的八个引脚对应的就是八个位选,跟单个数码管的位选功能一样。

段选:左边的1234为段选,段选表示指定指定哪些数码管亮,这里总共有四个数码管,所以有四个段选位,从左到右对应1234,哪个位输入高电平则对应的数码管可以亮。

例子:在数码管上显示4567
原理:循环改变位选,依次从1-4输出高电平,在对应数码管高电平时给位选输入对应的码值显示指定数字,通过这样一直刷新来达到一直显示数字的目的。
代码(该数码管为共阳数码管):

#include 

void main(){
	unsigned char duanxuan[] = {0x01, 0x02, 0x04, 0x08};
	unsigned int num=0, displayNum[] = {4, 5, 6, 7};
	unsigned char code tab[]={
		0xc0,//0
		0xf9,//1
		0xa4,//2
		0xb0,//3
		0x99,//4
		0x92,//5
		0x82,//6
		0xf8,//7
		0x80,//8
		0x90,//9
		0x88,//A
		0x83,//B
		0xc6,//C
		0xa1,//D
		0x86,//E
		0x8e, //F
		0x8c, //P
		0xc1,//U
		0x91,//Y
		0x7c,//L
		~0x40, //"-"
		0x00,//全亮
		0xff //熄灭
	};
	while(1){
		if(num == 4){
			num = 0;
		}
		P2 = 0x00;//消隐
		P0 = tab[displayNum[num]];
		P2 = duanxuan[num];
		num++;
	}
}

效果
51单片机入门学习篇-led灯、按键、数码管、中断_第8张图片

三、 练习题

使动态数码管显示:“-56-”,通过中断控制按键,按一次56减一个数,当减到45时再按一次回到56。

#include 

unsigned char disNum[] = {20, 5, 6, 20};

void display(){
	unsigned char duanxuan[] = {0x01, 0x02, 0x04, 0x08};
	unsigned char code tab[]={
		0xc0,//0
		0xf9,//1
		0xa4,//2
		0xb0,//3
		0x99,//4
		0x92,//5
		0x82,//6
		0xf8,//7
		0x80,//8
		0x90,//9
		0x88,//A
		0x83,//B
		0xc6,//C
		0xa1,//D
		0x86,//E
		0x8e, //F
		0x8c, //P
		0xc1,//U
		0x91,//Y
		0x7c,//L
		~0x40, //"-"
		0x00,//全亮
		0xff //熄灭
	};

	int flag = 4;
	while(flag){
		flag--;
		P2 = 0x00;
		P0 = tab[disNum[flag]];
		P2 = duanxuan[flag];
	}
}

void key() interrupt 2
{
	if (disNum[2] == 5 && disNum[1] == 4){
		disNum[2] = 6;
		disNum[1] = 5;
	}
	else if (disNum[2] == 0){
		disNum[2] = 9;
		disNum[1] = 4; 
	}
	else{
		disNum[2] -= 1;
	}
} 

void main(){
	EA = 1;
	EX1 = 1;
	IT1 = 1;
	while(1){
		display();
	}
}

仿真1


总结

本文章为博主入门单片机的学习记录,希望可以帮助大家一起学习入门51单片机。
在这里插入图片描述

你可能感兴趣的:(单片机,51单片机,学习)