提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、笔记主题;
51单片机基础知识学习
二、具体操作;
1.原理;
CPU驱动寄存器,寄存器驱动驱动器来控制引脚电流大小,驱动器起到扩大效果的作用,从而达到控制单片机的目的
2.点亮LED
2.1原理
首先需要知道对应LED的输出引脚,从而控制电流
“0”为底电频,“1”为高电频
当给与的电压为0,电压较小,电压差较大,此时有电流流过,LED被点亮
2.2进制转换
我们需要对相应的寄存器赋值,但c语言在编译时不能直接打二进制数字,最好转化为十六进制
代码如下:
p2=0*fe;//11111110
2.3头文件
此时编译器还不能识别p2口,因此要先添加头文件
代码如下:
#include <REGX52.H>
2.4代码示例
#include <REGX52.H>
void main()
{
P2=0x55;//0101 0101
while(1)
{
}
}
3.闪烁
在之前的基础上加入一个延时器来使其闪烁
代码示例;
#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 205;
k = 187;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2=0xfe;
Delay500ms();
P2=0xff;
Delay500ms();
}
}
4.流水灯
在之前的基础上不断调节亮的LED位置
void main()
{
while(1)
{
P2=0xfe;
Delay500ms();
P2=0xfd;
Delay500ms();
P2=0xfb;
Delay500ms();
P2=0xf7;
Delay500ms();
P2=0xef;
Delay500ms();
P2=0xdf;
Delay500ms();
P2=0xbf;
Delay500ms();
P2=0x7f;
Delay500ms();
}
}
5.延时器进阶
写一个1ms的延时器,需要延时多少就循环多少次
void Delay1ms(unsigned int xms) //@12.000MHz
{
while(xms>0){
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
6.独立按键
6.1位置
在51单片机的左下方有4个独立按键
6.2控制LED
可以在头文件里找到单独的灯所处的寄存器单元,通过修改其值来控制单独的LED
P2_0=0;
6.3控制原理
按钮会改变对应位置的电频状态,通过寄存器对其状态的检测和判断语句来达到控制电路的目的
while(1)
{
if(P3_1==0)
{
P2_0=0;
}
else{
P2_0=1;
}
}
6.4按钮控制亮灭与按键消抖
6.4.1消抖
按键在按下和松开时都会发生抖动,影响单片机的程序运行,因此需要消抖
6.4.2控制
在检测到按键按下和LED原本状态的两个条件后,进行20ms的延迟进行消抖,随后利用循环检测按键是否松开,松开后再进行20ms延迟进行消抖
if(P3_1==0 && P2_0==1)
{
Delay(20);//按下消抖
while(P3_1==0);
Delay(20);//松开消抖
P2_0=0;
}
else if(P3_1==0 && P2_0==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
P2_0=1;
}
6.5二进制控制和取反字符
"~"为取反字符,将寄存器里的数据取反
二进制控制的初始如果是1111 1111
那么要想让其正常工作,则应该进行取反,毕竟1代表灭,0代表亮
unsigned char LED=0;
while(1)
{
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
LED++;
P2=~LED;
}
}
6.6控制LED左右
这里需要用到“<<”来进行移位,同时需要考虑到临界状态,到达最左或者最右之后复位
unsigned char num;
void main()
{
P2=~0x01;
while(1)
{
if(P3_0==0)
{
Delay(20);//°´ÏÂÏû¶¶
while(P3_0==0);
Delay(20);//ËÉ¿ªÏû¶¶
num++;
if(num>=8)
num=0;
P2=~(0x01<<num);
}
if(P3_1==0)
{
Delay(20);//°´ÏÂÏû¶¶
while(P3_1==0);
Delay(20);//ËÉ¿ªÏû¶¶
if(num==0)
num=7;
else
num--;
P2=~(0x01<<num);
}
}
}
7.静态数码管显示
7.1普通版本
先通过译码器将二进制数转化为十进制数,通过转化后的十进制数来选择点亮哪一位数码管,然后再输入一个二进制数,再放大之后调控选择某一位数码管的哪几个亮,从而显示出数字
7.2封装
将数码管显示代码进行封装,利用switch case来进行数位的选择,然后将显示不同东西的二进制数放在一个数组里,再进行调用。
unsigned char nixietable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void nixie(unsigned char location,num)
{
switch(location){
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[num];
}
7.动态数码管显示
动态数码管显示是利用了人眼无法识别过快变化的特点,不断地进行扫描,以达到同时显示多个数字的功能。
需要应用循环进行重复,但为了显示更清楚,需要在各循环数字之间添加1ms的延迟和清零,这里用额外的connect函数来实现这个效果。
void connect()
{
Delay(1);
P0=0x00;
}
while(1)
{
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
while(1){
nixie(1,1);
connect();
nixie(2,3);
connect();
nixie(3,2);
connect();
}
}
}
8.矩阵键盘
需要对矩阵键盘进行扫描判定,先列再行,判断其电压变化,然后打出相应的数字
P1=0xFf;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=1;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=5;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=9;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=13;}
P1=0xFf;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=2;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=6;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=10;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=14;}
P1=0xFf;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=3;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=7;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=11;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=15;}
P1=0xFf;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=4;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=8;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=12;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=16;}
9.定时器
9.1原理
9.2逻辑运算
9.2.1按位与
按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位都为1时,结果位才为1。参与运算的两个数均以补码出现。
9.2.1按位或
按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。当参与运算的是负数时,参与两个数均以补码出现。
9.3定时器的初始准备
定时器需要进行初始的准备,包括调整好模式,对tmod进行清零,打开计时器启动项,打开中断允许位,打开cpu接收,调整中断优先级。
然而,在清零的过程中需要进行循环清零,这时就需要逻辑运算了
void Timer0_Init()
{
//TMOD=0X01;//ģʽ£»¶¨Ê±Æ÷
TMOD=TMOD&0xF0;//°ÑtmodµÄµÍËÄλÇåÁ㣬¸ßËÄλ²»±ä
TMOD=TMOD|0x01;//°ÑtmodµÄµÍËÄλÖÃ1£¬¸ßËÄλ²»±ä
TF0=0;//´ò¿ªzhongduanqiÆ÷£¬ÂúÁ˶Á1
TR0=1;//¿ØÖƶ¨Ê±»òÕß¼ÆÊýÆ÷µÄÆô¶¯Í£Ö¹£¬1ΪÆô¶¯
TH0=0X66;
TL0=0XFC;
ET0=1;//T0µÄÖжÏÔÊÐíλ
EA=1;//cpu×Ü¿ª¹Ø
PT0=0;//ÖжÏÓÅÏȼ¶
}