【蓝桥杯】单片机学习(3)——数码管的显示+定时器+中断

2023-05-16

数码管+定时+中断

    • 一、定时器
      • 1、定时器基础知识
      • 2、定时器的寄存器(TCON&TMOD)
        • 3、定时器的应用
    • 二、中断
      • 1、中断的概念
      • 2、51单片机内与中断控制有关的寄存器
      • 3、中断的响应条件及应用
    • 三、数码管
      • 1、数码管的原理介绍
      • 2、数码管的真值表(code关键字介绍)
      • 3、数码管的静态显示
        • (1)以普中科技的开发板为例(共阴极数码管)
        • (2)以CT107D开发板为例(共阳级数码管)
      • 4、数码管的动态显示
        • (1)原理分析
        • (2)数码管动态扫描的一般步骤。
        • (3)例程(普中·共阴)
        • (4)例程(CT107D·共阳)

一、定时器

1、定时器基础知识

实现定时/计数,有3种主要方法:软件延时数字电路硬件定时可编程定时/计数器

  • 软件定时:让机器执行一个程序段,这个程序段本身没有具体的目的,通过挑选适当的指令和设置合适的循坏次数来实现软件延时,由于执行每条指令都需要时间,执行这个程序段所需要的时间就是延时时间。常见的指令有for循环,通过改过循环次数来改变延时的时间。缺点:软件延时占用CPU,降低CPU的利用率。

  • 数字电路硬件定时:采用小规模集成电路器件,外接定时部件(电阻和电容)。通过改变电阻和电容的值来改变定时范围。缺点:硬件电路连接好之后,不方便修改。

  • 可编程定时/计数器:硬件定时,同时可以通过软件来确定和改变它的定时值,通过初始化编程,能够满足各种定时和计数需求,也是应用较多的一种方式。

时钟周期,即时钟源频率频率(晶振)分之一,一个机器周期为12个时钟周期。机器周期就是定时器的计数周期,在我们设定好初值之后,每经过一个机器周期,定时器自动加1,加到一定数值之后就会溢出。对于8位的定时器,加到255后再加1溢出;对于16位的定时器,加到65535后再加1溢出。

定时器既可以工作在定时方式也可以工作在计数方式。这两种方式本质都是对脉冲进行计数,不过所计脉冲的来源不同。常用的是定时方式,(以T0为例)每过一个机器周期,计数器的初值加1,直至计满预设的个数,TH0和TL0回零,溢出中断标志位TF0置1,产生溢出中断。当我们设定了定时器的工作方式并启动后,定时器就按照规定的方式工作,不占用CPU的操作时间,此时CPU可以执行其他其他程序,除非定时器溢出,才会中断CPU正在执行的程序(类似于人在工作或者睡觉的时候,手表依然滴滴滴滴在走,到了设定的时间,闹钟会响)。

2、定时器的寄存器(TCON&TMOD)

标准的51单片机内,常用的定时器有T0和T1。TH0和TL0分别用于存储定时器T0定时初值的高八位和低八位;TH1和TL1用于存储定时器T1定时初值的高八位和低八位。

  • 定时器控制寄存器——TCON(定时器控制只用高四位)
76543210
符号TF1TR1TF0TR0IE1IT1IE0IT0

TF1:T1溢出中断请求标志。T1有溢出中断请求,TF1硬件置 1;T1无溢出中断请求,TF1 =0。有两种清零方式,软件清零和进入定时器中断时硬件清零。

TR1:T1运行控制位。TR1=1,启动T1工作;TR1=0,停止T1工作。
TF0:T0溢出中断请求标志。T1有溢出中断请求,TF0硬件置1;T0无溢出中断请求,TF0 =0。有两种清零方式,软件清零和进入定时器中断时硬件清零。
TR0:T0运行控制位。TR0=1,启动T1工作;TR0=0,停止T0工作。

注:硬件置1或清零是指符合条件后,单片机自动完成;软件置1或清零是指需要通过编写程序实现。

  • 定时器模式寄存器——TMOD
76543210
符号GATE(T1)C/T(T1)M1(T1)M0(T1)GATE(T0)C/T(T0)M1(T0)M0(T0)

GATE:门控信号。GATE=0, TRx=1时,可启动定时器工作;GATE=1,除TRx=1外,还需INTx= 1才可启动定时器工作。

C /T:定时/计数器选择控制位。置1为计数器,置0为定时器。

M1M0:定时器的工作模式选择位。
定时器工作模式选择位
定时器初值的计算:(设定时时间为T)
①方式0:13位定时器。T=(2^13-T0初值)* 12 / fosc
TH0 = (2^13-T * fosc/12) / 32
TL0 = (2^13-T * fosc/12) / 32;
②方式1:16位定时器。T=(2^16-T0初值)* 12 / fosc
TH0 = (2^16-T * fosc/12) /256,
TL0 = (2^16-T * fosc/12) / 256;
③方式2:8位自动重载定时器。T=(2^8-T0初值)* 12 / fosc
TH0 = TL0 = T=(2^8-T0初值)* 12 / fosc

3、定时器的应用

定时器应用可以按照以下四个步骤:
①设置特殊功能寄存器TMOD,配置好工作模式。
②设置计数寄存器THO和TL0的初值。
③设置TCON,通过TRO置1来让定时器开始计数。
④判断TCON寄存器的TF0位,监测定时器溢出情况。

二、中断

1、中断的概念

  • 中断的发生:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理。
  • 中断响应和中断服务:CPU暂时中断当前的工作,转去处理事件B
  • 中断返回:CPU将事件B处理完成后,再回到原来事件A被中断的地方继续处理事件A。

以上整个过程即为中断。8XX51有5个中断源,3个在片内,2个在片外(如下图)。它们在程序存储器中有固定的中断入口地址,当CPU响应中断时,硬件自动形成这些地址,由此进入中断服务程序;5个中断源有两级中断优先级,可形成中断嵌套。
51单片机中断源
使用定时器时一般也会用到中断,但要注意定时器和中断不是一个概念,定时器是单片机模块的一个资源,而中断只是单片机的一种中断机制

2、51单片机内与中断控制有关的寄存器

  • 中断控制寄存器——IE
76543210
符号EAET 2ESET1EX1ET0EX0

IE寄存器的各位对应相应的中断源,如果允许该中断源中断,则该位置1,禁止中断则该位为0。其中EA中断总控开关,是CPU是否响应中断的前提。ES串行口中断允许位,ET2为定时器T2中断允许位,ET1定时器T1中断允许位,ET0定时器T0中断允许位,EX0外部中断INT0允许位,EX1外部中断INT1允许位。

  • 定时器控制寄存器——TCON(低四位)
76543210
符号TF1TR1TF0TR0IE1IT1IE0IT0

IE1:外部中断1(INT1)运行控制位。IE1=1.启动INT1控制;
IE1=0,停止INT1控制。
IT1:外部中断1(INT1)触发方式控制位。IT1=1,下降沿触发;IT1=0,低电平触发。
IE0:外部中断0(INT0)运行控制位。IE0=1.启动INT1控制;
IE0=0,停止INT1控制。
IT0:外部中断0(INT0)触发方式控制位。IT0=1,下降沿触发;IT0=0,低电平触发。

  • 中断优先级管理寄存器——IP
76543210
符号PT2PSPT1PX1PT0PX0

当某几个中断源同时发出中断请求时,由内部查询确定优先级,查询的顺序为:(INT0的优先级最高)
INT0——T0——INT1——T1——串行口 ——T2

中断查询序列如下:
中断查询序列

3、中断的响应条件及应用

响应条件:

  • 中断源有中断请求
  • 此中断源的中断允许位为1
  • 总中断打开(允许),即EA=1

中断的应用:

void timer() interrupt n
   {

   }

注:timer()为函数名,自己随意取;interrupt为关键字,不能更改,n为中断函数序列编号。

三、数码管

1、数码管的原理介绍

数码管的原理图如图3-1,本质就是把8段LED小灯组合在一起。
数码管原理图
数码管可以分为共阴极和共阳极,内部结构如下图3-2所示:

共阴极数码管,即把8只LED灯的阴极连接在一起,由阳极来控制单个小灯的亮灭(1亮0灭);同理,共阳数码管就是阳极连接在一起,通过阴极来控制小灯的亮灭(1灭0亮)。

2、数码管的真值表(code关键字介绍)

将数码管的8个段当成8个LED小灯来控制,即a、b、c、d. e、f、g、dp- -共8个LED小灯。以图3-1,如果点亮b和c这两个LED小灯,也就是数码管的b段和c段,其他的所有的段都熄灭的话,就可以让数码管显示出一个数字1,以共阳极数码管为例,二进制数字为0b11111001,十六进制为0xF9。同理可得其他数字多对应的数码管的真值,如下:

  • 共阳极数码管的真值表:
字符01234567
数值0XC00XF90XA40XB00X990X920X820XF8
字符89ABCDEF
数值0X800X900X880X830XC60XA10X860X8E
unsigned char code LEDchar[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 
       0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};  
                    //共阳极数码管从0到F的真值
  • 共阴极数码管的真值表
字符01234567
数值0X3F0X060X5B0X4F0X660X6D0X7D0X07
字符89ABCDEF
数值0X7F0X6F0X770X7C0X390X5E0X790X71
unsigned char code LEDchar[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 
         0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; 
          //共阴极数码管从0到F的真值
  • code关键字:C51单片机中,使用关键字unsigned char或者 unsigned int定义的变量都是放在单片机的RAM中,这些变量的值可以通过程序改变。而在定义时使用code修饰的变量是存储到存储空间FLASH里的,这样可以大大的节省的RAM的空间,但是这些变量的值在程序中不可以修改,所以我们在定义一些程序中不需要修改的变量时,可以使用code关键字,例如上面提到的数码管的真值的定义:unsigned char code LEDchar[]={};

3、数码管的静态显示

(1)以普中科技的开发板为例(共阴极数码管)

原理图如下:
普科技开发版原理图(部分)代码功能:一位数码管静态显示0到F,数字(字母)切换时间为1秒。

//数码管静态显示,0到F

#include<reg52.h>

sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

typedef unsigned char u8;

unsigned char code LEDchar[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 
         0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};  //共阴极数码管从0到F的真值

void TimeInit();   //定时器初始化函数
void main()
{
	u8 cnt = 0;    //记录T0中断次数
	u8 sec =0;     //记录经过的秒数

    LSA = 0;       //数码管的位选
	LSB = 0;
	LSC = 0;

    TimeInit();    //定时器初始化

	while(1)
	{
	      if(TF0 == 1)                       //判断T0是否溢出
		  {
		      TF0 = 0;                       //T0溢出后,清楚中断标志
			  TH0 = (65536-2*110592/12)/256; //0xB8,定时20ms 0.02秒*11059200 
              TL0 = (65536-2*110592/12)%256; //0x00
			  cnt++;
			  if(cnt>=50)                    //判断是否达到50次,即一秒钟
			  {
			      cnt = 0;                   //清零
			      P0 = LEDchar[sec];         //当前秒数对应的真值表中的真值送到P0口
			      sec++;                     //秒数记录加1
			      if(sec>=16)                //秒数达到0x0F后,重新从0开始
			        {
			            sec = 0;
			        }
			  }
		  }
	}
}

void TimeInit()
{
    TMOD = (TMOD & 0xf0)|0x01;     //设置定时器工作在模式1
    TH0 = (65536-2*110592/12)/256; //0xB8,定时20ms  
    TL0 = (65536-2*110592/12)%256; //0x00
    TR0 = 1;                       //允许定时器T0工作
}

(2)以CT107D开发板为例(共阳级数码管)

CT107D开发板是蓝桥比赛用开发板,原理图如下:
CT107原理图(部分)代码如下:

//数码管静态显示,0到F

#include<reg52.h>

typedef unsigned char u8;

unsigned char code LEDchar[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                    0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
                    0xbf,0x7f};  //共阳极数码管从0到F的真值

void TimeInit();   //定时器初始化函数
void HC138(u8 channel);            //138译码器通道选择函数
void ShowSMG_Bit(u8 date,u8 pos);  //数码管显示函数

void main()
{
	u8 cnt = 0;    //记录T0中断次数
	u8 sec =0;     //记录经过的秒数

    TimeInit();    //定时器初始化

	while(1)
	{
	      if(TF0 == 1)                          //判断T0是否溢出
		  {
		      TF0 = 0;                          //T0溢出后,清楚中断标志
			  TH0 = (65536-2*110592/12)/256;    //重新加载初值
              TL0 = (65536-2*110592/12)%256;    
			  cnt++;
			  if(cnt>=50)                       //判断是否达到50次,即一秒钟
			  {
			      cnt = 0;                      //清零
			      ShowSMG_Bit(LEDchar[sec],7);  //数码管显示对应的秒数
			      sec++;                        //秒数记录加1
			      if(sec>=16)                   //秒数达到0x0F后,重新从0开始
			        {
			            sec = 0;
			        }
			  }
		  }
	}
}

void HC138(u8 channel)
{
    switch(channel)
    {
        case 4:
            P2 = (P2&0x1f)|0x80;   //选择Y4对应模块(LED小灯) ,运算结果为P2高三位为100
        break;
        case 5:
            P2 = (P2&0x1f)|0xa0;   //选择Y5对应模块(蜂鸣器),运算结果为P2高三位为101
        break;
        case 6:
            P2 = (P2&0x1f)|0xc0;   //选择Y6对应模块(数码管的位选),运算结果为P2高三位为110
        break;
        case 7:
            P2 = (P2&0x1f)|0xe0;   //选择Y7对应模块(数码管的段选),运算结果为P2高三位为111
        break;
    }
}

void ShowSMG_Bit(u8 date,u8 pos)
{
    HC138(6);                       //Y6模块工作,数码管进行位选
    P0 = 0x01<<pos;                 //数码管的位选传到P0口
    HC138(7);                       //Y7模块工作,数码管进行段选
    P0 = date;                      //当前数码管要显示数值对应的真值传到P0口
}

void TimeInit()
{
    TMOD = (TMOD & 0xf0)|0x01;     //设置定时器工作在模式1
    TH0 = (65536-2*110592/12)/256; //0xB8,定时20ms 0.02秒*11059200 
    TL0 = (65536-2*110592/12)%256; //0x00
    TR0 = 1;                       //允许定时器T0工作
}

4、数码管的动态显示

(1)原理分析

动态数码管,即同时有多个数码管显示数字,实际上是轮流点亮各个数码管(同一时刻只有一个数码管被点亮),利用人眼的视觉暂留现象(余晖效应),使我们看到多个数码管同时点亮的效果。就像我们看到的电影也是由一帧一帧的画面组成的,但因为速度足够快,我们看到它就是动态的。刷新时间小于10毫秒时,对于人眼来说就是无闪烁的。

(2)数码管动态扫描的一般步骤。

  • 给对应的IO口赋值,位选编码选择哪一位亮
  • 给选中的数码管段选赋值,让其显示对应的数字或字母
  • 适当延时使其稳定(延时不易过长)
  • 消隐,避免上一次IO口确定的段码对本次段码产生影响

注:数码管的显示涉及段选和位选。段选即选择数码管的哪一段 (a、b、c、d、e、f、g、dp),位选即选择哪一个数码管。

(3)例程(普中·共阴)

以普中科技的开发板为例(共阴极数码管),原理图如下:
普中科技开发板代码功能:电子钟,从右到左,1、2位为秒,3、4位为分,5、6位为时,7、8位为天。

#include<reg52.h>

sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

typedef unsigned char u8;
typedef unsigned int u16;

u8 LedChar[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //共阴极数码管从0到9的真值
u8 LedBuff[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};  //数码管显示缓冲区,初值0xFF确保启动时都不亮
u8 flags = 1; //1秒定时标志

void TimeInit(); //定时器中断初始化函数

int main()
{
    u8 sec = 0, minutes = 0, hours = 0, days = 0; //定义记录秒,分,时,天的变量
    TimeInit(); //定时器中断初始化
    while(1)
    {
        if(flags == 1)            //判断1秒定时标志
        {
            flags = 0;            //标志位清零
            sec++;                //秒加1
            if(sec == 60)         //判断秒变量到达60秒
            {
                sec = 0;          //清0零
                minutes++;        //分钟位加1
            }
            if(minutes == 60)     //判断达到60分
            {
                minutes = 0;      //清零
                hours++;          //小时位加1
            }
            if(hours == 24)       //判断达到24小时
            {
                hours =0;         //清零
                days++;           //天数加1
            }
            LedBuff[0]= LedChar[sec%10];        //秒的低位
            LedBuff[1]= LedChar[sec/10%10];     //秒的高位
            LedBuff[2]= LedChar[minutes%10];    //分钟的低位
            LedBuff[3]= LedChar[minutes/10%10]; //分钟的高位
            LedBuff[4]= LedChar[hours%10];      //小时的低位
            LedBuff[5]= LedChar[hours/10%10];   //小时的高位
            LedBuff[6]= LedChar[days%10];       //天数的低位
            LedBuff[7]= LedChar[days/10%10];    //天数的高位
        }
    }
}

void TimeInit()
{
    EA = 1;                       //打开中断总开关
    ET0 = 1;                      //打开T0中断开关
    TMOD = (TMOD & 0xf0)|0x01;    //设置定时器工作在模式1
    TH0 = (65536-1*11059/12)/256; //0xFC,定时1ms  0.001秒*11059200 
    TL0 = (65536-1*11059/12)%256; //0x67
    TR0 = 1;                      //允许定时器T0工作
}

void InterruptTimer0() interrupt 1
{
    static u8 i = 0;                            //动态扫描的索引
    static u16 cnt = 0;  //用来记录中断次数,设置的中断定时为1ms,中断1000次即一秒钟

    TH0 = (65536-1*11059/12)/256;               //重新加载初值 
    TL0 = (65536-1*11059/12)%256;
    cnt++;                                      //中断次数计数值加1
    if(cnt>=1000)                                  //中断次数达到1000次即为1秒
    {
        cnt = 0;                                //清零,重新记录中断次数
        flags = 1;                              //设置1秒定时标志位1
    }

    P0 = 0xff;                                  //消隐
    switch(i)                                   //根据动态索引i的值进行位选,依次点亮八个数码管
    {
        case 0 :LSA = 0; LSB = 0; LSC = 0;i++; P0 = LedBuff[0];break;
        case 1 :LSA = 1; LSB = 0; LSC = 0;i++; P0 = LedBuff[1];break;
        case 2 :LSA = 0; LSB = 1; LSC = 0;i++; P0 = LedBuff[2];break;
        case 3 :LSA = 1; LSB = 1; LSC = 0;i++; P0 = LedBuff[3];break;
        case 4 :LSA = 0; LSB = 0; LSC = 1;i++; P0 = LedBuff[4];break;
        case 5 :LSA = 1; LSB = 0; LSC = 1;i++; P0 = LedBuff[5];break;
        case 6 :LSA = 0; LSB = 1; LSC = 1;i++; P0 = LedBuff[6];break;
        case 7 :LSA = 1; LSB = 1; LSC = 1;i=0; P0 = LedBuff[7];break;
        default:break;
    }
} 

(4)例程(CT107D·共阳)

以CT107D开发板为例(共阳极数码管),原理图如下:
CT107D开发板原理图(部分)功能同上,代码如下:

#include<reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;

u8 LedChar[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管从0到9的真值
u8 LedBuff[] = {0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF};    //数码管显示缓冲区,初值0xFF确保启动时都不亮
u8 flags = 1; //1秒定时标志

void TimeInit();                   //定时器中断初始化函数
void HC138(u8 channel);            //138译码器通道选择函数
void ShowSMG_Bit(u8 date,u8 pos);  //数码管显示函数

int main()
{
    u8 sec = 0, minutes = 0, hours = 0, days = 0; //定义记录秒,分,时,天的变量
    TimeInit();                   //定时器中断初始化
    while(1)
    {
        if(flags == 1)            //判断1秒定时标志
        {
            flags = 0;            //标志位清零
            sec++;                //秒加1
            if(sec == 60)         //判断秒变量到达60秒
            {
                sec = 0;          //清0零
                minutes++;        //分钟位加1
            }
            if(minutes == 60)     //判断达到60分
            {
                minutes = 0;      //清零
                hours++;          //小时位加1
            }
            if(hours == 24)       //判断达到24小时
            {
                hours = 0;        //清零
                days++;           //天数加1
            }
            LedBuff[0]= LedChar[sec%10];        //秒的低位
            LedBuff[1]= LedChar[sec/10%10];     //秒的高位
            LedBuff[2]= LedChar[minutes%10];    //分钟的低位
            LedBuff[3]= LedChar[minutes/10%10]; //分钟的高位
            LedBuff[4]= LedChar[hours%10];      //小时的低位
            LedBuff[5]= LedChar[hours/10%10];   //小时的高位
            LedBuff[6]= LedChar[days%10];       //天数的低位
            LedBuff[7]= LedChar[days/10%10];    //天数的高位
        }
    }
}

void TimeInit()
{
    EA = 1;                       //打开中断总开关
    ET0 = 1;                      //打开T0中断开关
    TMOD = (TMOD & 0xf0)|0x01;    //设置定时器工作在模式1
    TH0 = (65536-1*11059/12)/256; //0xFC,定时1ms  0.001秒*11059200 
    TL0 = (65536-1*11059/12)%256; //0x67
    TR0 = 1;                      //允许定时器T0工作
}

void HC138(u8 channel)
{
    switch(channel)
    {
        case 4:
            P2 = (P2&0x1f)|0x80;   //选择Y4对应模块(LED小灯) ,运算结果为P2高三位为100
        break;
        case 5:
            P2 = (P2&0x1f)|0xa0;   //选择Y5对应模块(蜂鸣器),运算结果为P2高三位为101
        break;
        case 6:
            P2 = (P2&0x1f)|0xc0;   //选择Y6对应模块(数码管的位选),运算结果为P2高三位为110
        break;
        case 7:
            P2 = (P2&0x1f)|0xe0;   //选择Y7对应模块(数码管的段选),运算结果为P2高三位为111
        break;
    }
}

void ShowSMG_Bit(u8 date,u8 pos)
{
    HC138(6);                       //Y6模块工作,数码管进行位选
    P0 = 0x01<<pos;                 //数码管的位选传到P0口
    HC138(7);                       //Y7模块工作,数码管进行段选
    P0 = date;                      //当前数码管要显示数值对应的真值传到P0口
}

void InterruptTimer0() interrupt 1
{
    static u8 i = 0;                           //动态扫描的索引
    static u16 cnt = 0;  //用来记录中断次数,设置的中断定时为1ms,中断1000次即一秒钟

    TH0 = (65536-1*11059/12)/256;              //重新加载初值 
    TL0 = (65536-1*11059/12)%256;
    cnt++;                                     //中断次数计数值加1
    if(cnt>=1000)                                 //中断次数达到1000次即为1秒
    {
        cnt = 0;                               //清零,重新记录中断次数
        flags = 1;                             //设置1秒定时标志位1
    }

    P0 = 0xff;                                 //消隐
    switch(i)                                  //根据动态索引i的值进行位选,依次点亮八个数码管
    {
        case 0 : i++; ShowSMG_Bit(LedBuff[0],7); break; //最右边一位数码管(com8)对应P0^7口
        case 1 : i++; ShowSMG_Bit(LedBuff[1],6); break;
        case 2 : i++; ShowSMG_Bit(LedBuff[2],5); break;
        case 3 : i++; ShowSMG_Bit(LedBuff[3],4); break;
        case 4 : i++; ShowSMG_Bit(LedBuff[4],3); break;
        case 5 : i++; ShowSMG_Bit(LedBuff[5],2); break;
        case 6 : i++; ShowSMG_Bit(LedBuff[6],1); break;
        case 7 : i=0; ShowSMG_Bit(LedBuff[7],0); break;
        default:break;
    }
} 

前一篇: 单片机学习(2)——点亮LED小灯

下一篇: 单片机学习(4)——点阵LED

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【蓝桥杯】单片机学习(3)——数码管的显示+定时器+中断 的相关文章

  • 【Mysql第十期 数据类型】

    文章目录 1 MySQL中的数据类型2 类型介绍2 2 可选属性2 2 2 UNSIGNED2 2 3 ZEROFILL2 3 适用场景2 4 如何选择 xff1f 3 浮点类型3 2 数据精度说明3 3 精度误差说明 4 定点数类型4 1
  • 【Mysql第十一期 约束】

    文章目录 1 约束 constraint 概述1 1 为什么需要约束1 2 什么是约束1 3 约束的分类 2 非空约束2 1 作用2 2 关键字2 3 特点2 4 添加非空约束2 5 删除非空约束 3 唯一性约束3 1 作用3 2 关键字3
  • 【Mysql第十二期 视图】

    文章目录 1 常见的数据库对象2 视图概述2 1 为什么使用视图 xff1f 2 2 视图的理解 3 大白话理解3 1 创建单表视图3 2 创建多表联合视图 4 查看视图5 更新视图的数据5 1 一般情况 6 修改 删除视图6 1 修改视图
  • 【presto sql】presto sql 如何通过 计算当前日期(年月日,时分秒) 来计算当前是星期几?

    文章目录 原因解析常见的日期处理方式拓展 原因 presto没有直接的日期转星期几的方式 xff0c 但是可以通过函数mod xff0c date diff多种函数进行求模转换成我们想要的星期几 span class token keywo
  • 【presto】presto如何对字段换行处理?chr(10)

    文章目录 问题描述问题分析什么是ASCII码presto sql逻辑 问题描述 需要对当前日期格式如 xff1a 2023 02 23 当遇到 的时候进行换行处理 其他的文本描述字段同理 问题分析 通过查找presto的函数 xff0c 换
  • Qt扫盲-QMenu理论总结

    QMenu理论总结 一 概述二 常用操作1 添加Action2 信号槽3 可撕下菜单4 展示菜单 一 概述 QMenu其实就是菜单控件 xff0c 菜单控件本质上就是一个选择项目 它可以是菜单栏中的下拉菜单 xff0c 也可以是独立的上下文
  • c++: internal compiler error: Segmentation fault (program cc1plus) 解决

    在ubuntu中编译很多库 xff0c 尤其是很大的一些中间件 xff0c 常常会c 43 43 internal compiler error Segmentation fault program cc1plus 这个错误 xff0c 看
  • Windows 远程桌面连接 Jetson Nx (Linux)Ubuntu 18.04

    一 Windows打开远程桌面工具 采取Windows自带远程桌面工具 xff0c 使用win 43 r输入打开mstsc 输入目标ip xff0c 以及用户名 xff08 在显示选项中打开输入用户名 xff09 二 Linux配置 安装x
  • Android studio更换阿里源

    对特定项目生效 xff0c 在项目中的build gradle修改内容 buildscript span class token punctuation span repositories span class token punctuat
  • docker 服务与调用

    docker file ROM tensorflow1 span class token punctuation span 14 python3 span class token punctuation span 5 20210111 sp
  • CTC loss原理详解大全

    ctc本质是损失函数 xff0c 在我的学习过程中浏览了一些博客 xff0c 下面整理了一些写的较好 较详细的 xff1a 1 过程详细 xff0c 全英文 2 博主参照原文讲解的 3 有伪代码 xff0c 帮助理解 4 中文解释 xff0
  • Python 对象、类、实例的联系与区别

    Python 中的对象 类 实例 本文讲述Python 中对象 类 实例的联系与区别 来源 xff1a 笨办法学 Python xff08 Learn Python The Hard Way xff09 作者 xff1a Zed Shaw
  • linux安装tailf 命令

    1 复制如下代码到一个新建的tailf c文件里 span class token comment tailf c tail a log file and then follow it Created Tue Jan 9 15 49 21
  • DBNet学习笔记

    1 网络结构 xff1a 1 网络流程 输入一张图片 xff0c 经过卷积操作 gt 1 2 gt 1 4 gt 1 8 gt 1 16 gt 1 32进行特征的提取 xff0c 然后进行上采样操作 xff0c 上采样的过程是把1 32的特
  • ubuntu18.04 安装PCL1.8.1

    ubuntu18 04 安装PCL1 8 1 注意版本匹配 xff1a PCL1 8 1 43 VTK7 1 1 43 QT5 14 2 1 PCL github 地址 xff1a https github com PointCloudLi
  • ubuntu 18.04 docker 安装

    docker 官网 xff1a https docs docker com engine install ubuntu xff08 1 xff09 按照官网安装教程 xff1a 我选择的是Install from a package安装方法
  • C++函数返回多个值:结构体、tuple

    C 43 43 函数一般可以返回一个值 xff0c 但是在使用中常常需要一个函数返回多个值 xff0c 因此可以使用结构体或tuple来进行实现 注意看代码里的注释 xff01 xff01 xff01 1 使用结构体返回多个值 实现步骤 x
  • 【GStreamer 】1-扫盲介绍

    从历史的角度来看 xff0c Linux 在多媒体方面已经远远落后于其它的操作系统 微软的Windows和苹果的MacOS它们对多媒体设备 多媒体创作 播放和实时处理等方面已经有了很好的支持 另一方面 xff0c Linux对多媒体应用的综
  • C++判断文件是否存在

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • PCL编译完成后找不到库

    使用执行命令L g 43 43 std 61 c 43 43 14 I usr local include pcl 1 8 I usr local include eigen3 main cpp o test111 其中 std 61 c

随机推荐

  • docker安装及使用,常用命令总结

    1 安装 参考官方教程 xff1a https docs docker com engine install ubuntu 有三种安装方法 xff1a Install using the repository Install from a
  • CMakeLists.txt中相关指令和含义

    语法格式 xff1a 指令 xff08 参数1 参数2 xff09 参数使用括号括起来 参数之间使用空格或分号分开 指令大小写无关 xff0c 参数和变量大小写有影响 重要指令 1 cmake minimum required xff1a
  • ubuntu 18.04安装nvidia驱动后,电脑开机失败

    安装驱动后电脑开机失败 xff0c 恢复到安装驱动之前的状态 xff1a 在nvidia 官网 https www nvidia com Download index aspx 下载显卡驱动 xff0c 并安装成功后重启电脑发现电脑重启失败
  • c++ CUDA nvcc编译问题

    安装了cuda10 1 xff0c 使用cuda编译代码时 xff0c 显示 xff1a Cannot get compiler information span class token operator span Compiler exi
  • PCL库点云小知识

    1 计算极值点 include lt pcl io pcd io h gt include lt pcl point types h gt include lt pcl common common h gt pcl PointCloud l
  • PCL Windows 安装

    参考文章 xff1a https blog csdn net weixin 44244190 article details 124324121 我的环境为 xff1a python3 6 xff0c visual studio 2019
  • 使用mmdetection3d预测自己采集的数据遇到的问题

    预测结果是这样的 xff1a 点云数据原图是这样的 xff1a 红色框出的为真实的car类别 xff1a 已解决 xff0c 请查看mmdetection3d issue
  • ubuntu18.04 cuda卸载及安装

    1 若电脑上已经安装了其他版本的cuda及显卡驱动 xff0c 需要完全卸载并删除相关文件 xff0c 否则会导致安装不成功 xff0c 执行如下 xff1a 1 1卸载cuda 步骤如下 cd usr local cuda xx x bi
  • 【GStreamer 】2-ubuntu v4l2-ctl 查看USB 相机基本参数

    v4l2是Video4linux2的简称 xff0c 是linux中关于视频设备的内核驱动 xff0c 在Linux中 xff0c 视频设备是设备文件 xff0c 可以像访问普通文件一样对其进行读写 xff0c 摄像头设备文件位置是 dev
  • 使用conda安装Paddle3D时出现的报错及解决方式

    1 cmake时 usr bin ld cannot find lxxx问题 如 xff1a usr bin ld cannot find lleveldb usr bin ld cannot find lsnappy 解决方法 xff1a
  • git安装及使用常用命令

    1 安装 Ubuntu xff1a apt get install git Windows xff1a 官网下载地址 xff1a https gitforwindows org xff0c 也可以用国内镜像 xff1a https npm
  • 如何设置才能提升VMware虚拟机的显卡性能

    将本机的intel和NVIDIA显卡驱动更新为最新版本 使用最新的VMware Workstation pro 12 5 处理器中 xff0c 选择8个核心 xff0c 勾选下面两个虚拟化
  • 程序设计思维与实践 CSP-M3 补题 (3/4/数据班)

    程序设计思维与实践 CSP M3 A csp m3 t1题目分析代码 B csp m3 t2题意分析代码 T4 咕咕东学英语题意 分析代码 A csp m3 t1 题目 瑞神的数学一向是最好的 xff0c 连强大的咕咕东都要拜倒在瑞神的数学
  • Centos7搭建Samba文件共享服务

    编辑本地yum源 root 64 localhost vim etc yum repos d local repo Centos7 name 61 CentOS Local baseurl 61 file mnt gpgcheck 61 0
  • IS-IS协议原理与配置

    IS IS 中间系统到中间系统协议 xff1a 基于链路状态并使用最短路径优先算法进行路由计算的一种IGP协议 基于802 3封装 IS IS最初是国际化标准组织ISO为它的无连接网络协议CLNP设计的一种动态路由协议 为了提供对IP的路由
  • 数据库关系代数表达式学习

    一 关系代数的9种操作 xff1a 关系代数中包括了 xff1a 并 交 差 乘 选择 投影 联接 除 自然联接等操作 五个基本操作 xff1a 并 差 笛卡尔积 投影 选择 四个组合操作 xff1a 交 联接 等值联接 自然联接 RS 除
  • 手把手教你从阿里云到idea的短信服务怎么玩.给你女朋友发一条是不是贼帅?

    短信服务 1 1打开阿里云 创建成功就会有 总结阿里云 1 开启子用户 2 新建用户组 设置添加权限 3 创建一个用户 具体用来操作的账号 4 得到AccessKey id 密码 61 61 注意 保存账号 61 61 如果泄露 用户组下禁
  • week16——实验(csp_m4)

    目录 TT数鸭子 xff1a 问题描述题目简述输入 输出格式样例 问题分析解题思路参考代码 心得体会 ZJM要抵御宇宙射线 xff1a 问题描述题目简述输入 输出格式样例 问题分析解题思路参考代码 心得体会 宇宙狗的危机 xff1a 问题描
  • Gstreamer 应用开发:1-基础介绍

    我们之前的系列 xff0c 正式的介绍了Gstreamer xff0c 并且围绕如何使用USB相机推流实现RTSP服务器来做了介绍 xff0c 并在Jeston TX1 平台上做了优化急速的一些探索 今天我们开始围绕如何用命令实现一个音视频
  • 【蓝桥杯】单片机学习(3)——数码管的显示+定时器+中断

    数码管 43 定时 43 中断 一 定时器1 定时器基础知识2 定时器的寄存器 xff08 TCON amp TMOD xff09 3 定时器的应用 二 中断1 中断的概念2 51单片机内与中断控制有关的寄存器3 中断的响应条件及应用 三