51单片机笔记[1]-基础实验

实验目的

  1. 掌握使用KEIL,Proteus软件
  2. 掌握程序下载方法

实验内容

点亮发光二极管

按下K1按键(P2.0),点亮发光二极管(P1.0)LED1
按下K2按键(P2.1),LED1~LED8(P1口)双向流水灯
P1.0口连接的发光二极管,编写子程序,实现闪烁5次后,常亮

矩阵键盘按键显示

按下矩阵键盘(4*4),通过数码管静态显示按键键码值0-F

数码管显示

P2口连接的7段共阳极数码管,编写子程序实现循环显示1-F
P1口连接的7段共阳极数码管,编写子程序实现循环显示9-1

实验原理

io口的4种模式

  • 推挽输出
  • 高阻输入(上拉输入)
  • 开漏输出
  • 准双向I/O

51单片机操作io口

sbit:定义特殊功能寄存器的位变量.
P4^0:P4组io的第一个管脚

4x4键盘读取

常见的按键扫描方式有:

  • io口直接与按键一一对应,适用于io口较多的情况
  • 矩阵式,通过行扫描和列扫描最终确定按键,但是这样会造成键位冲突
  • 使用逻辑芯片扩展,如74HC595D并入串出芯片
  • 电阻采样扩展,设置不同的按键电阻,按下键时单片机AD采样到不同的电压

矩阵键盘的按键扫描方式

对于矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。因此,我们可以得到矩阵键盘的基本扫描步骤:

  1. R1输出低电平,R2、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号,如果都为高电平则R1行上没有按键按下。
  2. R2输出低电平,R1、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号。
  3. R3输出低电平,R1、R2、R4输出高电平,发现C2列信号为低电平,那么可以判断得R3行的C2列的按键有按下动作。
  4. R4输出低电平,R1、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号。

如此循环往复,扫描的按键的我们知道有按键按下动作,那么又怎么知道是哪一个按键按下呢?这时,我们最好定义一个键值全局变量,给矩阵行列上的每一个的按键编一个唯一的号码。当扫描的某一行某一列的按键动作后,把对应的编号复制给键值变量,这样我们判断这个键值,就知道是哪个按键有触发动作了。

注意事项:R行引脚全部设置为开漏,C列引脚全部设为上拉输入
还有一种扫描方法称为线反转法.
[https://blog.csdn.net/shmily_cml0603/article/details/7079554]
[https://blog.csdn.net/weixin_39799646/article/details/112065230]

实验过程

仿真图

LED流水灯 矩阵键盘按键

流程图

画的可能不太标准,还请见谅

发光二极管 双向流水灯 LED闪烁 数码管显示 矩阵键盘扫描

程序

1.c

#include <reg52.h>
#include <stdio.h>
sbit LED0=P1^0;
sbit BUTTON1=P2^0;
sbit BUTTON2=P2^1;
void delay()//延时函数
{
  unsigned char a,b;
	for(a=0;a<200;a++)
	for(b=0;b<200;b++);;
}
void key()
{
	if(BUTTON1==0)
	{
		delay();
		if(BUTTON1==0)
		{
			LED0=~LED0;
		}
		while(!BUTTON1);
		          
	}
}
void main(void){
while(1){
	LED0=1;
	key();
}
}

2.c

//流水灯

#include <reg52.h>
#include <stdio.h>
#include <intrins.h>//循环移位
#define LED(NUM) LED##i
sbit BUTTON=P2^1;
	//灯
	sbit LED1=P1^0;
	sbit LED2=P1^1;
	sbit LED3=P1^2;
	sbit LED4=P1^3;
	sbit LED5=P1^4;
	sbit LED6=P1^5;
	sbit LED7=P1^6;
	sbit LED8=P1^7;
	unsigned char LED[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//延时函数
void delay(){
	int a,b;
	for(a=0;a<200;a++) for(b=0;b<200;b++);;
}
int main(void){
	while(1){
		BUTTON=1;
		if(BUTTON==0){
			int i;
			for(i=1;i<8;i++){
				//LED(NUM)=1;
				P1=LED[i];
				delay();
			}
			for (i=8;i>0;i--){
				P1=LED[i];
				delay();
				
			}
		}
	}
}

3.c:面向百度编程😏

#include <stdio.h>
#include <reg52.h>
//矩阵键盘按键显示
//TODO:按键消抖

//段码表
unsigned char distab[16] = {
	0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};//0-F
	//显示0字符:P1=distab[0]
//显示函数
void show_char(int input){
	//while(1){
		P0=0xFF;
		P0=~distab[input];
 //}
}
//延时函数
delay(){
	int i,j;
	for(i=0;i<200;i++){
		for(j=0;j<200;j++);
	}
}
	//回调函数
_delay(int function){
	int i,j;
}
//按键检测
unsigned char keyscan()
{   unsigned char tempkey;
		int num;
    P1=0xfe;
    tempkey=P1;
    tempkey=tempkey&0xf0;
    while(tempkey!=0xf0)
    {
        
        tempkey=P1;
        tempkey=tempkey&0xf0;
        while(tempkey!=0xf0)
        {
            tempkey=P1;
            switch(tempkey)
            {
                case 0xee:num=10;show_char(10); //A
                break;
                case 0xde:num=3;show_char(3);
                break;
                case 0xbe:num=2;show_char(2);
                break;
                case 0x7e:num=1;show_char(1);
                break;
            }
            while(tempkey!=0xf0)
            {
                tempkey=P1;
                tempkey=tempkey&0xf0;
            }

        }
    }




            P1=0xfd;
            tempkey=P1;
            tempkey=tempkey&0xf0;
            while(tempkey!=0xf0)
                {
                    
                    tempkey=P1;
                    tempkey=tempkey&0xf0;
                    while(tempkey!=0xf0)
                    {
                        tempkey=P1;
                    switch(tempkey)
                        {
                            case 0xed:num=11;show_char(11);//B
                                break;
                            case 0xdd:num=6;show_char(6);
                                break;
                            case 0xbd:num=5;show_char(5);
                                break;
                            case 0x7d:num=4;show_char(4);
                                break;
                        }
                    while(tempkey!=0xf0)
                        {
                            tempkey=P1;
                            tempkey=tempkey&0xf0;
                        }

                    }
                }


            P1=0xfb;
            tempkey=P1;
            tempkey=tempkey&0xf0;
            while(tempkey!=0xf0)
                {
                   
                    tempkey=P1;
                    tempkey=tempkey&0xf0;
                    while(tempkey!=0xf0)
                    {
                        tempkey=P1;
                    switch(tempkey)
                        {
                            case 0xeb:num=12;show_char(12); //C
                                break;
                            case 0xdb:num=9;show_char(9);
                                break;
                            case 0xbb:num=8;show_char(8);
                                break;
                            case 0x7b:num=7;show_char(7);
                                break;
                        }
                    while(tempkey!=0xf0)
                        {
                            tempkey=P1;
                            tempkey=tempkey&0xf0;
                        }

                    }
                }


            P1=0xf7;
            tempkey=P1;
            tempkey=tempkey&0xf0;
            while(tempkey!=0xf0)
                {
                    
                    tempkey=P1;
                    tempkey=tempkey&0xf0;
                    while(tempkey!=0xf0)
                    {
                        tempkey=P1;
                    switch(tempkey)
                        {
                            case 0xe7:num=13;show_char(13);
                                break;
                            case 0xd7:num=14;show_char(14);
                                break;
                            case 0xb7:num=0;show_char(0);
                                break;
                            case 0x77:num=14;show_char(15);
                                break;
                        }
                    while(tempkey!=0xf0)
                        {
                            tempkey=P1;
                            tempkey=tempkey&0xf0;
                        }
                    }
                }


}
//开机加载效果
void onload(){
	int i;
	for(i=0;i<16;i++){
		P1=0x0;
		show_char(i);
		delay();
	}
	//清屏
	P0=0xff;
}
//主函数
int main(void){
	onload();
	while(1){
		keyscan();
		//key();
	}
}

备注

最终实现可能与实验内容有一点点出入(管脚不同或功能增减)

真机调试

平台:“普中-3”51开发板
备注:开发板与仿真管脚排列及配置有所不同

开发板原理图

开发板实物图

代码

编译及烧录



USB转TTL模块短接好(即 P31T 与 URXD 连接,P30R 与 UTXD 连接)
单片机:STC89C52RC
注意:使用STC-ISP下载时,需要先上电电脑识别到串口,打开hex文件点击下载后重新开启电源(冷启动)

然后按一下reset键

效果

posted @ 2022-08-29 00:00  qsBye  阅读(589)  评论(1编辑  收藏  举报