文章目录
- 51单片机之点灯
- 51单片机之灯的亮灭交替
- 51单片机之灯的流水灯
- 51单片机之数码管数字显示
- 51单片机之数码管数字的流水灯
- 51单片机之数码管数字的0-7显示
- 51单片机之蜂鸣器的鸣叫与关闭
- 51单片机之DS1302时钟设置
- 51单片机之读出温度传感器温度
- 代码模块化汇总
- 主函数
- main.c
- 延时函数Delay
- Delay.c
- Delay.h
- 矩阵键盘MatriXKey
- MatriXKey.c
- MatriXKey.h
- 数码管NiXie
- NiXie.c
- NiXie.h
- 时钟DS1302
- DS1302.c
- DS1302.h
前言: 我在学习江科大视频后被我们学校的蓝桥杯选拔赛考试,刚好学校的选拔赛出的实现类的题目比较贴合江科大UP主讲的知识,所以这次就总结一下学习江科大视频后我写出来的51单片机基础知识代码总结,当然你也可以拿到我这一篇博客来作为练习的题目,从而迅速掌握视频的大部分精髓
51单片机之点灯
这个操作是我们学校选拔赛的第一道题目,控制矩阵键盘的第一个按键,从而实现LED_1 电灯亮。
这里给出代码:
KeyNum = MatriXie();
if(KeyNum == 1)
{
LED_1=~LED_1;
}
51单片机之灯的亮灭交替
这个操作是我们学校选拔赛的第二道题目,控制矩阵键盘的第二个按键,从而实现LED_2电灯的5毫秒的亮灭交替。
这里给出代码:
if(KeyNum == 2)
{
KeyNum = 0;
while(1)
{
LED_1 = 0;
Delay(100);
LED_1 = 1;
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 2)
{
LED_1 = 1;
break;
}
}
}
51单片机之灯的流水灯
这个操作是我们学校选拔赛的第三道题目,控制矩阵键盘的第三个按键,从而实现LED的流水灯效果,默认是从左到右流水灯,这里没说延迟多少,所以默认就是Delay(1000) ms。
流水灯这里可以补充一些基础的知识,就是P2 控制的是LED灯,所以只需要对P2 进行赋值16进制的数字即可。
这里给出代码:
if(KeyNum == 3)
{
while(1)
{
P2 = 0xFE; // 1111 1110
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xFD; // 1111 1101
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xFB; // 1111 1011
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xF7; // 1111 0111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xEF; // 1110 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xDF; // 1101 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xBF; // 1011 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0x7F; // 0111 1111
Delay(100);
//flag=1;
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
}
}
51单片机之数码管数字显示
这个操作是我们学校选拔赛的第四道题目,控制矩阵键盘的第四个按键,从而实现数码管显示数字0。
数码管这里补充一些基础知识,就是数码管的数字显示是分为A、B、C、D、E、F、G 以及DP的,详细的可以查看下面这个图片来学习,(这个图片来自江科大的PPT),A、B、C、D对应的16进制的低四位,所以不难得出E、F、G、DP控制的是16进制的高四位。
这里给出代码:
if(KeyNum == 4)
{
KeyNum = 0;
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
while(1)
{
P0 = 0x66; // 0111 1101
KeyNum = MatriXie();
if(KeyNum == 4)
{
P0 = 0xFF;
break;
}
}
}
51单片机之数码管数字的流水灯
这个操作是我们学校选拔赛的第五道题目,控制矩阵键盘的第五个按键,从而实现数码管显示数字0,并且进行“流水灯”的效果,这里显然很简单,可以封装一个函数NiXie来表示数码管在哪一个位置显示哪一个数字,然后去Delay多少毫秒,就可以完成流水灯的效果。
这里给出代码:
if(KeyNum == 5)
{
KeyNum = 0;
while(1)
{
NiXie(1,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(2,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(3,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(4,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(5,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(6,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(7,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(8,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
}
}
51单片机之数码管数字的0-7显示
这个操作是我们学校选拔赛的第六道题目,控制矩阵键盘的第六个按键,这道题更是送分题了,没什么思考难度,直接不断调用NiXie函数去显示数码管即可。
这里给出代码:
if(KeyNum == 6)
{
KeyNum = 0;
while(1)
{
NiXie(1,0);
NiXie(2,1);
NiXie(3,2);
NiXie(4,3);
NiXie(5,4);
NiXie(6,5);
NiXie(7,6);
NiXie(8,7);
KeyNum = MatriXie();
if(KeyNum == 6)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
}
}
51单片机之蜂鸣器的鸣叫与关闭
这个操作是我们学校选拔赛的第七道题目,控制矩阵键盘的第七个按键,从而实现蜂鸣器的鸣叫,再次按下第七个按键,实现蜂鸣器的关闭。
蜂鸣器这里补充一些基础知识,蜂鸣器,我的理解就是不断的在一定的振幅改变下才去鸣叫,所以可以利用一个for
循环来触发蜂鸣器的鸣叫
这里给出代码:
if(KeyNum == 7)
{
KeyNum = 0;
while(1)
{
BuzzerTime();
Delay(1);
KeyNum = MatriXie();
if(KeyNum == 7)
{
BuzzerTime();
break;
}
}
}
51单片机之DS1302时钟设置
这个操作是我们学校选拔赛的第八道题目,控制矩阵键盘的第八个按键,从而实现DS1302时钟功能,让数码管显示时钟,并且秒是可以动的,可以进位到分钟,小时,所以这道题目是很困难的,也是江科大UP主讲了好长时间的课程,一节课1.5h总共两节课,给我学的很困哈哈哈哈不过多学的话就会了。
这里给出代码:
//main函数
if(KeyNum == 8)
{
DS1302_SetTime();
KeyNum = 0;
while(1)
{
DS1302_ReadTime();
NiXie(1,DS1302_Time[0]/10);
NiXie(2,DS1302_Time[0]%10);
NiXie(3,10);
NiXie(4,DS1302_Time[1]/10);
NiXie(5,DS1302_Time[1]%10);
NiXie(6,10);
NiXie(7,DS1302_Time[2]/10);
NiXie(8,DS1302_Time[2]%10);
KeyNum = MatriXie();
if(KeyNum == 8)
{
P2_2 = 1;
P2_3 = 1;
P2_4 = 1;
P0 = 0xFF;
break;
}
}
}
51单片机之读出温度传感器温度
这个操作是我们学校选拔赛的第九道题目,控制矩阵键盘的第九个按键,从而实现温度传感器读取温度的功能,这道题我当时没有写出来是因为这里我学的不够扎实,当时并没有思路去写出来这个题目。。。。看看小伙伴谁会写的话可以给大家讲出来。
代码模块化汇总
主函数
main.c
#include <REGX52.H>
#include "Delay.h"
#include "MatriXie.h"
#include "NiXie.h"
#include "BuzzerTime.h"
#include "DS1302.h"
//定义LED
sbit LED_1 = P2^0;
sbit LED_2 = P2^1;
sbit LED_3 = P2^2;
sbit LED_4 = P2^3;
sbit LED_5 = P2^4;
sbit LED_6 = P2^5;
sbit LED_7 = P2^6;
sbit LED_8 = P2^7;
//定义独立按键
sbit K_3 = P3^2;
sbit K_4 = P3^3;
sbit K_2 = P3^0;
sbit K1 = P3^1;
unsigned char KeyNum,flag=0;
void main()
{
//P2 = 0xFE; // 1111 0111
while(1)
{
KeyNum = MatriXie();
if(KeyNum == 1)
{
LED_1=~LED_1;
}
if(KeyNum == 2)
{
KeyNum = 0;
while(1)
{
LED_1 = 0;
Delay(100);
LED_1 = 1;
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 2)
{
LED_1 = 1;
break;
}
}
}
if(KeyNum == 3)
{
while(1)
{
P2 = 0xFE; // 1111 1110
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xFD; // 1111 1101
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xFB; // 1111 1011
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xF7; // 1111 0111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xEF; // 1110 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xDF; // 1101 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0xBF; // 1011 1111
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
P2 = 0x7F; // 0111 1111
Delay(100);
//flag=1;
KeyNum = MatriXie();
if(KeyNum == 3)
{
P2 = 0xFF;
break;
}
}
}
if(KeyNum == 4)
{
KeyNum = 0;
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
while(1)
{
P0 = 0x66; // 0111 1101
KeyNum = MatriXie();
if(KeyNum == 4)
{
P0 = 0xFF;
break;
}
}
}
if(KeyNum == 5)
{
KeyNum = 0;
while(1)
{
NiXie(1,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(2,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(3,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(4,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(5,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(6,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(7,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
NiXie(8,4);
Delay(100);
KeyNum = MatriXie();
if(KeyNum == 5)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
}
}
if(KeyNum == 6)
{
KeyNum = 0;
while(1)
{
NiXie(1,0);
NiXie(2,1);
NiXie(3,2);
NiXie(4,3);
NiXie(5,4);
NiXie(6,5);
NiXie(7,6);
NiXie(8,7);
KeyNum = MatriXie();
if(KeyNum == 6)
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0xFF;
break;
}
}
}
if(KeyNum == 7)
{
KeyNum = 0;
while(1)
{
BuzzerTime();
Delay(1);
KeyNum = MatriXie();
if(KeyNum == 7)
{
BuzzerTime();
break;
}
}
}
if(KeyNum == 8)
{
DS1302_SetTime();
KeyNum = 0;
while(1)
{
DS1302_ReadTime();
NiXie(1,DS1302_Time[0]/10);
NiXie(2,DS1302_Time[0]%10);
NiXie(3,10);
NiXie(4,DS1302_Time[1]/10);
NiXie(5,DS1302_Time[1]%10);
NiXie(6,10);
NiXie(7,DS1302_Time[2]/10);
NiXie(8,DS1302_Time[2]%10);
KeyNum = MatriXie();
if(KeyNum == 8)
{
P2_2 = 1;
P2_3 = 1;
P2_4 = 1;
P0 = 0xFF;
break;
}
}
}
}
}
延时函数Delay
Delay.c
void Delay1ms(void) //@12.000MHz
{
unsigned char data i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
void Delay(unsigned int x)
{
while(x--)
{
Delay1ms();
}
}
Delay.h
void Delay1ms(void);
void Delay(unsigned int x);
矩阵键盘MatriXKey
MatriXKey.c
#include <REGX52.H>
#include "Delay.h"
unsigned int MatriXie()
{
unsigned char KeyNumber = 0;
P1 = 0xFF;
P1_7 = 0;
if(P1_3 == 0) {Delay(20);while(P1_3==0);Delay(20);KeyNumber=1;}
if(P1_2 == 0) {Delay(20);while(P1_2==0);Delay(20);KeyNumber=2;}
if(P1_1 == 0) {Delay(20);while(P1_1==0);Delay(20);KeyNumber=3;}
if(P1_0 == 0) {Delay(20);while(P1_0==0);Delay(20);KeyNumber=4;}
P1 = 0xFF;
P1_6 = 0;
if(P1_3 == 0) {Delay(20);while(P1_3==0);Delay(20);KeyNumber=5;}
if(P1_2 == 0) {Delay(20);while(P1_2==0);Delay(20);KeyNumber=6;}
if(P1_1 == 0) {Delay(20);while(P1_1==0);Delay(20);KeyNumber=7;}
if(P1_0 == 0) {Delay(20);while(P1_0==0);Delay(20);KeyNumber=8;}
P1 = 0xFF;
P1_5 = 0;
if(P1_3 == 0) {Delay(20);while(P1_3==0);Delay(20);KeyNumber=9;}
if(P1_2 == 0) {Delay(20);while(P1_2==0);Delay(20);KeyNumber=10;}
if(P1_1 == 0) {Delay(20);while(P1_1==0);Delay(20);KeyNumber=11;}
if(P1_0 == 0) {Delay(20);while(P1_0==0);Delay(20);KeyNumber=12;}
P1 = 0xFF;
P1_4 = 0;
if(P1_3 == 0) {Delay(20);while(P1_3==0);Delay(20);KeyNumber=13;}
if(P1_2 == 0) {Delay(20);while(P1_2==0);Delay(20);KeyNumber=14;}
if(P1_1 == 0) {Delay(20);while(P1_1==0);Delay(20);KeyNumber=15;}
if(P1_0 == 0) {Delay(20);while(P1_0==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
MatriXKey.h
unsigned int MatriXie(void);
数码管NiXie
NiXie.c
#include <REGX52.H>
#include "Delay.h"
#include "MatriXie.h"
#include "NiXie.h"
unsigned char NiXieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
void NiXie(unsigned char pos,unsigned char number)
{
switch(pos)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0 = NiXieTable[number];
Delay(1);//显示一段时间//消影
//P0 = 0x00;
}
NiXie.h
void NiXie(unsigned char pos,unsigned char number);
时钟DS1302
DS1302.c
#include <REGX52.H>
//引脚定义
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
//寄存器写入地址/指令定义
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_WP 0x8E
//时间数组,索引0~6分别为年、月、日、时、分、秒、星期
unsigned char DS1302_Time[]={15,22,00};
/**
* @brief DS1302初始化
* @param 无
* @retval 无
*/
void DS1302_Init(void)
{
DS1302_CE=0;
DS1302_SCLK=0;
}
/**
* @brief DS1302写一个字节
* @param Command 命令字/地址
* @param Data 要写入的数据
* @retval 无
*/
void DS1302_WriteByte(unsigned char Command,Data)
{
unsigned char i;
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<<i);
DS1302_SCLK=1;
DS1302_SCLK=0;
}
for(i=0;i<8;i++)
{
DS1302_IO=Data&(0x01<<i);
DS1302_SCLK=1;
DS1302_SCLK=0;
}
DS1302_CE=0;
}
/**
* @brief DS1302读一个字节
* @param Command 命令字/地址
* @retval 读出的数据
*/
unsigned char DS1302_ReadByte(unsigned char Command)
{
unsigned char i,Data=0x00;
Command|=0x01; //将指令转换为读指令
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<<i);
DS1302_SCLK=0;
DS1302_SCLK=1;
}
for(i=0;i<8;i++)
{
DS1302_SCLK=1;
DS1302_SCLK=0;
if(DS1302_IO){Data|=(0x01<<i);}
}
DS1302_CE=0;
DS1302_IO=0; //读取后将IO设置为0,否则读出的数据会出错
return Data;
}
/**
* @brief DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中
* @param 无
* @retval 无
*/
void DS1302_SetTime(void)
{
DS1302_WriteByte(DS1302_WP,0x00);
DS1302_WriteByte(DS1302_HOUR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);
DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
DS1302_WriteByte(DS1302_SECOND,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
DS1302_WriteByte(DS1302_WP,0x80);
}
/**
* @brief DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中
* @param 无
* @retval 无
*/
void DS1302_ReadTime(void)
{
unsigned char Temp;;
Temp=DS1302_ReadByte(DS1302_HOUR);
DS1302_Time[0]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_MINUTE);
DS1302_Time[1]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_SECOND);
DS1302_Time[2]=Temp/16*10+Temp%16;
}
DS1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
//外部可调用时间数组,索引0~6分别为年、月、日、时、分、秒、星期
extern unsigned char DS1302_Time[];
void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command,Data);
unsigned char DS1302_ReadByte(unsigned char Command);
void DS1302_SetTime(void);
void DS1302_ReadTime(void);
#endif
📌 [ 笔者 ] 夏目浅石.
📃 [ 更新 ] 2023.11
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!
📜 参考文献:
B站江科大51单片机入门视频
AYIT嵌入式实验室出题
CSDN嵌入式领域博主:謓泽(学习笔记超级建议看这位大佬的博客,复习很快,学习视频的成本也会低)
如果侵权,请联系作者夏目浅石,立刻删除