• 51单片机 第二节 点亮LED


    本笔记默认学习者已拥有:
    1.Keil5和stc烧写工具 等各种软件、驱动、环境;
    2.有一个属于自己的 51单片机开发板及相关零件 ;
    3.认识C语言的语法;
    本人使用的51开发板为 郭天祥C51 TX-1C增强版开发板
    本笔记根据B站up主:江科大自化协的教学视频 整理得到ヾ(•ω•)
    虽然上来就是原理图,但千里之行始于足下,望能怀沉稳之心看到最后




    2-1 点亮一个LED



    原理分析

    上图为TX-1C的LED模板的原理图,其 IO口 均为 P1口,视频中为P2,以下P2在TX-1C中均对P1!!!

    LED模板原理图

    1.VCC 可视为电源的正极,GND为接地线(可视为电源的负极),P20、P21 等均为单片机的P2口引脚;

    TX-1C 是用 排阻 和 LED 相连的;

    2.电阻的作用为 限流 ,因为 VCC 的电压为5V,直接 接VCC 可能使 LED 烧毁;
    3.单片机通过从引脚输出高、低电平(高为5V,低为0V,为TTL电平,可分别视为正、负极):

    \[(一种电平规范)TTL \begin{cases} 5V,视为正极+,等价逻辑"1"\\ 0V,视为负极-,等价逻辑"0" \end{cases}\]

    4.让LED亮灭的问题 转化为 单片机引脚给高低电平的问题
    (引脚给高电平,两端都是高电平,LED不亮;引脚给低电平,形成电平差,LED亮)

    图1

    4.单片机(MCU)内有CPU,而MCU中有很多 寄存器(一种存储器),寄存器以8个为一组,每个寄存器通过导线,经过驱动器 增大电流,然后连接到 IO口 端口上;
    5.CPU可以通过直接访问寄存器(在寄存器中写值);
    6.寄存器以8个为一组,P2口也是以8个为一组;

    7.给高低电平的问题 转化为 配置P2口寄存器问题
    CPU通过控制 寄存器 来控制 硬件电路,硬件电路来执行我们想要完成的功能




    实践代码

    图2

    1.给P20口 赋值 0(给低电平),其他口 赋值 1(给高电平),这样就只有D1 一个LED亮,剩下的都不亮;
    2.赋值是由 P2寄存器 确定的,要给P2寄存器 赋值 1111 1110 这一数字;

    注意这里 寄存器 和 LED 顺序关系,
    \(P20 \to D1 \to P2寄存器最后一位\)
    \(P27 \to D8 \to P2寄存器第一位\)



    点亮一个LED.c

    #include<reg51.h>
    //#include<REGX52.H>与其在某些 表达 上有所不同,但功能基本相似
    void main(){
    	P1=0xFE;//1111 1110
    	//原视频为 P2=0xFE,而我的开发板对应端口为P1 
    	while(1);
    	/*
    	单片机 会 优先执行 主函数main, 
    	主函数执行结束后,会从头执行主函数,不断执行
    	这显然是会损坏单片机的, 使用while(1)语句可以避免这种情况
    	使程序停止 
    	*/ 
    }
    

    运行结果如下:

    点亮一个LED




    使LED间隔点亮.c

    #include<reg51.h>
    void main(){
    	P1=0x55;//0101 0101
    	while(1);
    }
    

    运行结果如下:

    点亮LED2




    2-2 LED闪烁

    1.让LED闪烁,写下了如下的代码:

    #include<reg51.h>
    void main(){
    	while(1){
    		P1=0xFE;//1111 1110
    		P1=0xFF;//1111 1111
    	}
    }
    

    2.发现LED并没有闪烁,但亮度比点亮LED时暗淡不少
    (图左为当前代码的运行结果,图右为 点亮一个LED.c 的运行结果)

    LED闪烁1

    3.亮度变暗,是单片机速度的问题,单片机的速度是MHZ的等级,1MHZ就是每秒运行一百万次
    所以LED是由于闪的特别快,所以才显得暗;
    4.所以要想看到闪烁效果,要让其以一秒为周期闪烁

    LED2

    5.stc烧录工具中的软件延时计算器可以自动生成延迟函数,但同时要注意8051指令集项不要选错



    LED闪烁.c

    #include<reg51.h>
    #include<intrins.h>//_nop_();需要 该头文件 
    void Delay500ms()		//@11.0592MHz,我的晶振规模和视频中不同
    {
    	unsigned char i, j, k;
    
    	_nop_();//_nop_();为空语句函数,什么也不会执行 
    	i = 4;
    	j = 129;
    	k = 119;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    /*
    void Delay500ms(){
    	uint unsigned int i,j;
    	for(i=500;i>0;i--) 
    		for(j=110;j>0;--j);
    }
    此为一种可视为等价的 函数写法 
    */
    void main(){
    	while(1){
    		P1=0xFE;//1111 1110
    		Delay500ms();
    		P1=0xFF;//1111 1111
    		Delay500ms();
    		//以1秒为一个周期,即每隔500ms闪烁一次 
    		//1s=1000ms
    	}
    }
    
    

    运行结果如下:

    IMG_4224




    2-3 LED流水灯

    这里考虑到读者,直接使用了位运算

    LED流水灯.c

    #include<reg51.h>
    #include<intrins.h>
    #define uint unsigned int 
    //这里 定义了一个 x ms 的函数 
    void Delayms(uint x)		//@11.0592MHz
    {
    	unsigned char i, j;
    	while(x--){
    		i = 2;
    		j = 199;
    		do
    		{
    			while (--j);
    		} while (--i);
    	}
    }
    void main(){
    	P1=0xFE;
    	while(1){
    		Delayms(500);
    		P1<<=1; P1+=1;
    		//使用位运算将指令位移,并且补1 保证流水灯效果 
    		if(P1==0xFF) P1=0xFE;
    		//当P1变为 1111 1111 时,需要进行 类似复位的操作,体现循环流水效果 
    	}
    }
    
    

    运行结果如下:

    IMG_4225.GIF




    相关知识

    电阻

    1.有些电阻上会有数字,例如102代表了\(10*10^2=1000=1K\)阻值的电阻;
    2.类似的,474代表了\(47*10^4=470000=470K\)阻值的电阻;
    3.即前两位为有效数字,后一位为倍率,若\(X\)代表前几位数字,\(Y\)代表最后一位数字有(\(X\)不一定只是两位,也可能是一位或者更多位)

    \[阻值=X*10^Y \]

  • 相关阅读:
    [考试]20150811
    [考试]20150810
    [随笔]暑假过了,暑假来了
    [考试]20150808
    动态规划大合集II
    [知识点][旧版]C++中的运算符
    NOIP动态规划大合集
    [考试]20150729
    [考试]20150728
    /=============分隔线=============/
  • 原文地址:https://www.cnblogs.com/Potrem/p/51_2.html
Copyright © 2020-2023  润新知