1 - 01单片机原理图和开发板设计图

2 - 02点亮LED

LED

1. 原理图

LED原理图

2. 描述

流水灯模块使用P1 进行IO操作。并使用共地。默认高电平 所以需要点亮LED等, 就是将P1口 地线接通即可。

3. 点亮LED

第一个LED

P1引脚一共8位。此处变量LED设置P1.0(即P1引脚第0位)

#include <reg52.h>

sbit LED = P1^0;  // 定义P1.0为LED引脚

void main() {
    LED = 0;  // 输出低电平,点亮LED(共地接法)
    while (1);  // 保持程序运行
}

同时点亮1 3 5 led

#include <reg52.h>

sbit LED1 = P1^0;
sbit LED3 = P1^2;
sbit LED5 = P1^4;
void main() {
    LED1 = 0;
    LED3 = 0;
    LED5 = 0;
    while (1);
}
#include <reg52.h>

void main() {
    // 0xEA 在二进制表示为  11101010
    P1 = 0xEA; 
    while (1);
}

轮流点亮每一个LED

#include <reg52.h>

unsigned char a;
void delay();

void main() {
    while(1) {
        delay();
        for(a = 0; a < 8; a++) {
            P1 = P1 << 1;
            delay();
        }
        P1 = 0xFF;
    }
}

void delay() {
    int i = 65535;
    while(i--);
}

轮流点亮每一个LED,每次只点亮一个 从左向右

这里要用到一个 intrins 的 corl 循环左移 corr 循环右移 nop 空指令

#include <reg52.h>
#include <intrins.h>

unsigned char a;
unsigned char temp;
void delay();

void main() {
    temp = 0xFE;
    P1 = temp;
    while(1) {
        delay();
        temp = _crol_(temp, 1);
        P1 = temp;
    }
}

void delay() {
    int i = 65535;
    while(i--);
}

轮流点亮每一个LED,每次只点亮一个 从右向左

#include <reg52.h>
#include <intrins.h>

unsigned char a;
unsigned char temp;
void delay(unsigned int z);

void main() {
    temp = 0x7F;
    P1 = temp;
    while(1) {
        delay(1000);
        temp = _cror_(temp, 1);
        P1 = temp;
    }
}
// 改进了延时函数
void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
        for(y=0; y<125; y++);
}

发光二极管 2-4-6-8 闪烁间隔1s

#include <reg52.h>
#include <intrins.h>

unsigned char a;
unsigned char temp;
void delay(unsigned int z);

void main() {
    temp = 0xFD;
    P1 = temp;
    while(1) {
        delay(1000);
        temp = _crol_(temp, 2);
        P1 = temp;
    }
}

void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
        for(y=0; y<125; y++);
}

从右向左循环点亮间隔500ms

引用 轮流点亮每一个LED,每次只点亮一个 从右向左

3 - 03数码管

数码管

静态显示

根据开发板原理图 数码管由两个锁存器共同控制 数码管锁存器模块

型号为74HC573, 接下来看锁存器说明 数码管锁存器模块说明

带上划线的OE, 表示低电平有效

所以看表当OE为高电平时,不论LE D 如何 输出都是高阻态(用Z表示)

当OE为底电平时,LE为低电平时, 此时就锁住了输出值(用Q0 表示) 当OE为底电平时,LE为高电平时, 此时输出随D口变化而变化也就是连通状态

回到我们的锁存器电路图,OE均接地,所以已经是低电平有效。所以我们要控制的就是LE 让她为高电平就变化锁存器里面的值。之后改成低电平来锁住值。

我们的单片机数码管是8位共阴极数码管 8位共阴极数码管 U8锁存器是作为位选,U9 锁存器是段选

段选是表示 数码管要显示什么数字 位选(位置选择)是表示 一个8段数码管(每一个8. 作为一段)那些需要点亮

例如我们要显示 从右侧开始 1357段数码管显示数字5

#include <reg52.h>
#include <intrins.h>

void delay(unsigned int z);

sbit DULA = P2^6; // 段选LE控制
sbit WELA = P2^7; // 位选LE控制
unsigned char code leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F  //"9"

};

void main() {
  DULA = 1;
  P0 = leddata[5];
  DULA = 0;
  
  delay(10);
  WELA = 1;
  P0 = 0x55;
  WELA = 0;
  
  while(1);
}

void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
      for(y=0; y<125; y++);
}

另一个例子 从0-9 循环显示 每次间隔1s

#include <reg52.h>
#include <intrins.h>

void delay(unsigned int z);
  
sbit DULA = P2^6;
sbit WELA = P2^7;
unsigned char code leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F  //"9"

};

void main() {
  unsigned int i;
  
  delay(10);
  WELA = 1;
  P0 = 0x00;
  WELA = 0;
  
  while(1){
    for(i = 0; i <= 9; i++) {
      DULA = 1;
      P0 = leddata[i];
      DULA = 0;
      delay(1000);
    }
  }
}

void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
      for(y=0; y<125; y++);
}

动态显示

所谓的动态显示就是利用人眼的视觉 延时误差来让数码管看起来保持不变 例如我们要让左侧 第一个显示1 第二个显示2 在数码管实例图中 WE1 口对应Q0, Q0对应D0,所以将位选的D0 置为0(二进制(大端表示)表示1111 1110),段选设置为1 WE2 对应Q1 Q1对应D1,所以将位选的D1 置为1(二进制(大端表示)表示 1111 1101),段选设置为2 如此快速的往复,即可实现数码管显示1和2。代码如下

#include <reg52.h>
#include <intrins.h>

void delay(unsigned int z);
  
sbit DULA = P2^6;
sbit WELA = P2^7;
unsigned char code leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F  //"9"
};

void main() {

  while(1){
    
    WELA = 1;
    P0 = 0xFE;
    WELA = 0;
    
    DULA = 1;
    P0 = leddata[1];
    DULA = 0;
    
    delay(5);
    
    WELA = 1;
    P0 = 0xFD;
    WELA = 0;
    
    DULA = 1;
    P0 = leddata[2];
    DULA = 0;
    delay(5);

  }
}

void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
      for(y=0; y<125; y++);
}

下一个例子, 在八个数码管从左到右 一次显示 1 2 3 4 5 6 7 8

#include <reg52.h>
#include <intrins.h>

void delay(unsigned int z);
  
sbit DULA = P2^6;
sbit WELA = P2^7;
unsigned char code leddata[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
};
unsigned char code dudata[] = {
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
};

void main() {
  unsigned char i = 0;
  while(1){
    
    WELA = 1;
    P0 = dudata[i];
    WELA = 0;
    
    DULA = 1;
    P0 = leddata[i+1];
    DULA = 0;
    i++;
    
    delay(1);
    if (i == 8) {
      i = 0;
    }
  }
}

void delay(unsigned int z) {
    unsigned int x,y;
    for(x = z; x > 0; x--) 
      for(y=0; y<125; y++);
}