Skip to content

代码参考


0 数码管

c
unsigned char Number[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x40, 0x00};

// 数码管显示子函数
void Display(unsigned char Location, Num)
{
	switch (Location)
	{
	case 1: P2_2=0; P2_1=0; P2_0=0; break;
	case 2: P2_2=0; P2_1=0; P2_0=1; break;
	case 3: P2_2=0; P2_1=1; P2_0=0; break;
	case 4: P2_2=0; P2_1=1; P2_0=1; break;
	case 5: P2_2=1; P2_1=0; P2_0=0; break;
	case 6: P2_2=1; P2_1=0; P2_0=1; break;
	case 7: P2_2=1; P2_1=1; P2_0=0; break;
	case 8: P2_2=1; P2_1=1; P2_0=1; break;
	}
	P0 = Number[Num]; // 段码输出
    //静态没有下面两个
	Delay(1);				 // 显示一段时间
	P0 = 0x00;				 // 段码清0,消影
}

1、并行口与 if 语句 — 按键切换 LED

P1 口接 8 个发光二极管,P3.0 接一个按键。按下时左边 4 个亮,弹开时右边 4 个亮。

c
#include <reg52.h>
#define uchar unsigned char

sbit S1 = P3^0;

void main(void)
{
    while(1)
    {
        if(S1 == 0)
            P1 = 0xF0;    // 左边 4 个亮
        else
            P1 = 0x0F;    // 右边 4 个亮
    }
}

2、按键控制流水灯方向切换

P1 口接 8 只发光二极管,P3.0 接 S1。按一次 S1,流水灯方向改变一次。

c
#include <reg52.h>
#define uchar unsigned char

sbit S1 = P3^0;
bit flag = 0;       // 方向标志
bit kp   = 0;       // 按键按下标志

void delayms(uchar ms)
{
    uchar i;
    while(ms--)
        for(i = 1; i < 123; i++);
}

void key(void)
{
    if(S1 == 0)
    {
        delayms(10);             // 消抖
        if((S1 == 0) && (kp == 0))
        {
            kp = 1;
            flag = ~flag;        // 切换方向
        }
    }
    else
        kp = 0;                  // 按键释放
}

void main(void)
{
    P1 = 0xFE;                   // D1 亮(最低位)
    while(1)
    {
        key();
        if(flag == 0)            // 方向 0:左移
        {
            delayms(100);
            P1 = (P1 << 1) | (P1 >> 7);
        }
        else                     // 方向 1:右移
        {
            delayms(100);
            P1 = (P1 >> 1) | (P1 << 7);
        }
    }
}

3、外部中断实验 — INT0/INT1 嵌套

P1 接 8 个 LED,P3.2(S3) 触发 INT0 左移 16 次,P3.3(S4) 触发 INT1 右移 8 次。INT1 可嵌套 INT0。

c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

void delayms(uint ms)
{
    uchar i;
    while(ms--)
        for(i = 1; i < 123; i++);
}

// INT0:左移 16 次,间隔 100ms
void LED1(void) interrupt 0
{
    uchar i;
    P1 = 0xFE;
    for(i = 0; i < 16; i++)
    {
        delayms(100);
        P1 = (P1 << 1) | (P1 >> 7);
    }
}

// INT1:右移 8 次,间隔 200ms
void LED2(void) interrupt 2
{
    uchar i;
    P1 = 0xFE;
    for(i = 0; i < 8; i++)
    {
        delayms(200);
        P1 = (P1 >> 1) | (P1 << 7);
    }
}

void main(void)
{
    EA = 1;          // 开总中断
    EX0 = 1; EX1 = 1;
    IT0 = 1; IT1 = 1;  // 下降沿触发
    PX0 = 0; PX1 = 1;  // INT1 优先级 > INT0(可嵌套)

    while(1)            // 无按键时全亮全灭交替 200ms
    {
        P1 = 0x00;  delayms(200);
        P1 = 0xFF;  delayms(200);
    }
}

4、定时器 T1 方式 1 + T0 方式 2

T1 方式 1 定时 1s,P1.0 LED 亮灭交替;T0 方式 2 定时 0.5s,P1.7 LED 亮灭交替。

c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit P10 = P1^0;     // T1 控制,1s 交替
sbit P17 = P1^7;     // T0 控制,0.5s 交替

uint con0 = 0;       // T0 计数
uint con1 = 0;       // T1 计数

// T1 中断(方式 1,50ms × 20 = 1s)
void LED1(void) interrupt 3
{
    TH1 = 15536 / 256;           // 50ms 初值 = 65536 − 50000
    TL1 = 15536 % 256;
    if(++con1 == 20)
    {
        con1 = 0;
        P10 = ~P10;
    }
}

// T0 中断(方式 2,250μs × 2000 = 0.5s,TH=TL=6)
void LED2(void) interrupt 1
{
    if(++con0 == 2000)
    {
        con0 = 0;
        P17 = ~P17;
    }
}

void main(void)
{
    TMOD |= 0x12;    // T1 方式 1(0x10) + T0 方式 2(0x02)
    TH1 = 15536 / 256; TL1 = 15536 % 256;
    TH0 = 6; TL0 = 6;           // 256 − 250 = 6,定时 250μs
    EA = 1;
    ET0 = 1; TR0 = 1;
    ET1 = 1; TR1 = 1;
    P10 = 0; P17 = 0;           // 初始点亮
    while(1);
}

5、数码管动态显示 — "15-35-00"

共阴数码管,P0 段码 + P2 位选,显示 "15-35-00"(- 用 0x40)。

c
#include <reg52.h>
#define uchar unsigned char

// 段码:0~9 以及 "-" (0x40)
uchar code seg[] =
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};

uchar dis[] = {1,2,3,4,5,6,7,8};

void delayms(uchar ms)
{
    uchar i;
    while(ms--)
        for(i = 0; i < 123; i++);
}

void display(void)
{
    uchar i;
    for(i = 0; i < 8; i++)
    {
        P0 = seg[dis[i]];    // 送段码
        P2 = i;              // 位选
        delayms(1);
    }
}

void main(void)
{
    while(1)
    {
        dis[0]=1; dis[1]=5; dis[2]=10; dis[3]=3;
        dis[4]=5; dis[5]=10; dis[6]=0;  dis[7]=0;
        display();
    }
}

6、数码管时钟 — 12:30:00

T1 方式 1 定时 50ms,共阴数码管显示 HH-MM-SS,冒号闪烁。

c
#include <reg52.h>
#define uchar unsigned char

// 段码:0~9, -, 空(0x00)
uchar code seg[] =
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00};

uchar dis[8];
uchar aa = 0;                     // 冒号闪烁标志
uchar hour = 12, min = 30, sec = 0;
uchar t1_counter = 0;

void delayms(uchar ms)
{
    uchar i;
    while(ms--)
        for(i = 0; i < 123; i++);
}

void display(void)
{
    uchar i;
    for(i = 0; i < 8; i++)
    {
        P0 = seg[dis[i]];
        P2 = i;
        delayms(1);
    }
}

// T1 中断:50ms 定时
void t1_int(void) interrupt 3
{
    TH1 = 15529 / 256;           // 50ms 初值
    TL1 = 15529 % 256;

    if(t1_counter == 0) aa = 1;       // 冒号亮
    if(t1_counter == 10) aa = 0;      // 冒号灭

    if(++t1_counter == 20)            // 1s 到
    {
        t1_counter = 0;
        if(++sec == 60)
        {
            sec = 0;
            if(++min == 60)
            {
                min = 0;
                if(++hour == 24)
                    hour = 0;
            }
        }
    }
}

void main(void)
{
    TMOD |= 0x10;
    TH1 = 15529 / 256;
    TL1 = 15529 % 256;
    TR1 = 1; EA = 1; ET1 = 1;

    while(1)
    {
        dis[0] = hour / 10;
        dis[1] = hour % 10;

        if(aa == 0)                    // 冒号灭
        {
            dis[2] = 10;               // "-"
            dis[5] = 10;
        }
        else                           // 冒号亮
        {
            dis[2] = 11;               // 空(灭)
            dis[5] = 11;
        }

        dis[3] = min / 10;
        dis[4] = min % 10;
        dis[6] = sec / 10;
        dis[7] = sec % 10;

        display();
    }
}

7、LCD1602 数字钟

利用 LCD1602 显示时钟,P2.4/P2.5/P2.6 为 RS/RW/E,P0 为数据口。

c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit RS = P2^4;
sbit RW = P2^5;
sbit E  = P2^6;

uchar code str[] = {"welcome "};
uchar sec = 0;
uchar con = 0;

void delayms(uchar ms)
{
    uchar i;
    while(ms--)
        for(i = 0; i < 123; i++);
}

// 写指令
void w_com(uchar com)
{
    RS = 0; RW = 0;
    E = 1; P0 = com; E = 0;
    delayms(1);
}

// 写数据
void w_dat(uchar dat)
{
    RS = 1; RW = 0;
    E = 1; P0 = dat; E = 0;
    delayms(1);
}

// LCD 初始化
void lcd_ini(void)
{
    delayms(10);
    w_com(0x38);    // 8 位口,2 行,5×7 点阵
    delayms(10);
    w_com(0x0C);    // 开显示,关光标
    delayms(10);
    w_com(0x06);    // 右移,地址加 1
    delayms(10);
    w_com(0x01);    // 清屏
    delayms(10);
    w_com(0x38);
    delayms(10);
}

void main(void)
{
    uchar i, num;
    lcd_ini();

    // 第一行显示 "welcome"
    w_com(0x80);
    for(i = 0; str[i] != '\0'; i++)
        w_dat(str[i]);

    while(1)
    {
        w_com(0xC7);    // 第二行第7位
        // …(时钟显示逻辑)
    }
}

8、带按键调整的 LCD1602 时钟

LCD1602 显示时钟,S1=小时+1,S2=小时−1,S3=分钟+1,S4=分钟−1。

c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit RS = P2^4;
sbit RW = P2^5;
sbit E  = P2^6;

sbit S1 = P3^0;    // 小时+1
sbit S2 = P3^1;    // 小时−1
sbit S3 = P3^2;    // 分钟+1
sbit S4 = P3^3;    // 分钟−1

uchar hour = 12, min = 30, sec = 0;
uchar t1_count = 0;

void delayms(uchar ms)
{
    uchar i;
    while(ms--)
        for(i = 0; i < 123; i++);
}

void w_com(uchar com)
{ RS = 0; RW = 0; E = 1; P0 = com; E = 0; delayms(1); }

void w_dat(uchar dat)
{ RS = 1; RW = 0; E = 1; P0 = dat; E = 0; delayms(1); }

void lcd_ini(void)
{
    delayms(10);
    w_com(0x38); w_com(0x0C); w_com(0x06);
    w_com(0x01); w_com(0x38);
    delayms(10);
}

// 按键调整
void key_adj(void)
{
    if(S1 == 0) { delayms(10); if(S1 == 0)
    { hour = (hour + 1) % 24; while(S1 == 0); } }

    if(S2 == 0) { delayms(10); if(S2 == 0)
    { hour = (hour == 0) ? 23 : hour - 1; while(S2 == 0); } }

    if(S3 == 0) { delayms(10); if(S3 == 0)
    { min = (min + 1) % 60; while(S3 == 0); } }

    if(S4 == 0) { delayms(10); if(S4 == 0)
    { min = (min == 0) ? 59 : min - 1; while(S4 == 0); } }
}

void main(void)
{
    lcd_ini();
    TMOD |= 0x10;   // T1 方式 1
    // …(定时器 + 显示循环)
}

Copyright © 2026