Featured image of post 国信长天单片机

国信长天单片机

   
AI 摘要
AI 摘要接口暂时失联……

准备

本源码需要配合Clion使用,keil等代码编辑器可能存在语法错误

代码中注释了部分功能,可以自行尝试

环境配置

  1. 下载安装Clion

  2. 安装 PlatformIO 插件

  3. 在clion中新建一个项目,根据提示配置环境

  4. 编写一个简单的代码测试环境是否配置成功

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <mcs51/8052.h>

void main()

{
    while(1)
    {
        P1 = 0xfe;
    }
}

环境配置文件(以stc89c52rc为例)

1
2
3
4
5
6
[env:STC89C52RC]
platform = intel_mcs51
board = STC89C52RC

lib_deps = C:\Users\Night\.platformio\packages\toolchain-sdcc\include 
// 这里配置环境安装路径

原理图

led电路图

202411182015900.jpg

蜂鸣器

202411182015900.jpg

202411182015900.jpg

7Ch138译码器

202411182015900.jpg

或非门

202411182015900.jpg

数码管

202411182015900.jpg

延时函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 延时函数
void Delay(unsigned int time) {
  while (time--) {
    DisplaySMG_Dynamic();
  }
}

// 延时函数
void DelaySMG(unsigned int time) {
  while (time--)
    ;
}

定时器函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Timer 0 interrupt service routine
void timer0_ISR() __interrupt(1) {
    TH0 = 0xFC; // Reload high byte for 1ms
    TL0 = 0x66; // Reload low byte for 1ms
    }
}

// Initialize Timer 0
void Timer0_Init() {
    TMOD |= 0x01; // Set Timer 0 in mode 1 (16-bit timer mode)
    TH0 = 0xFC;   // Load initial value for 1ms delay
    TL0 = 0x66;
    ET0 = 1;      // Enable Timer 0 interrupt
    EA = 1;       // Enable global interrupts
    TR0 = 1;      // Start Timer 0
}

数码管位选和段选函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 选择位
void SelectBit(unsigned char pos) {
 Init74HC138(6); // Open COM end
 P0 = 0x00;      // Turn off all segments
 DelaySMG(10);   // Short delay to eliminate shadow
 P0 = (0x01 << pos);
}

// 选择段
void SelectSegment(unsigned char value) {
 Init74HC138(7); // 打开段选端
 P0 = value;
}

74HC573锁存器函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void int74h573(unsigned int n) {
  switch (n) {
  case 4:
    P2 = (P2 & 0x1f) | 0x80;
    break;
  case 5:
    P2 = (P2 & 0x1f) | 0xa0;
    break;
  case 6:
    P2 = (P2 & 0x1f) | 0xc0;
    break;
  case 7:
    P2 = (P2 & 0x1f) | 0xe0;
    break;
  }
}

动态显示数码管

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 动态显示数码管
void DisplaySMG_Dynamic() {
  SelectBit(0);
  SelectSegment(SMG_NoDot[hour / 10]);
  DelaySMG(500);

  SelectBit(1);
  SelectSegment(SMG_NoDot[hour % 10]);
  DelaySMG(500);

  SelectBit(2);
  SelectSegment(SMG_NoDot[16]);
  DelaySMG(500);

  SelectBit(3);
  SelectSegment(SMG_NoDot[minute / 10]);
  DelaySMG(500);

  SelectBit(4);
  SelectSegment(SMG_NoDot[minute % 10]);
  DelaySMG(500);

  SelectBit(5);
  SelectSegment(SMG_NoDot[16]);
  DelaySMG(500);

  SelectBit(6);
  SelectSegment(SMG_NoDot[second / 10]);
  DelaySMG(500);

  SelectBit(7);
  SelectSegment(SMG_NoDot[second % 10]);
  DelaySMG(500);
}

完整代码 mian.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "mcs51/8052.h"
#include "tool.h"

typedef unsigned int u16;
unsigned int ms_count = 0; // Millisecond counter

// Timer 0 interrupt service routine
void timer0_ISR() __interrupt(1) {
  TH0 = 0xFC; // Reload high byte for 1ms
  TL0 = 0x66; // Reload low byte for 1ms
  ms_count++;
  if (ms_count >= 1000) { // 1000ms = 1 second
    ms_count = 0;
    time_increase();
    DisplaySMG_Dynamic();
  }
}

// Initialize Timer 0
void Timer0_Init() {
  TMOD |= 0x01; // Set Timer 0 in mode 1 (16-bit timer mode)
  TH0 = 0xFC;   // Load initial value for 1ms delay
  TL0 = 0x66;
  ET0 = 1;      // Enable Timer 0 interrupt
  EA = 1;       // Enable global interrupts
  TR0 = 1;      // Start Timer 0
}


// Main function
int main() {
    Timer0_Init(); // Initialize Timer 0
    while (1) {
        DisplaySMG_Dynamic(); // Display dynamic SMG
    }
}

tool.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//
// Created by NightRain on 2024/11/18.
//

#ifndef UNTITLED1_TOOL_H
#define UNTITLED1_TOOL_H

void DisplaySMG_Dynamic();
void Delay(unsigned int time);
void DelaySMG(unsigned int time);
void Init74HC138(unsigned char n);
void SelectBit(unsigned char pos);
void SelectSegment(unsigned char value);
void time_increase();
#endif // UNTITLED1_TOOL_H

tool.c

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
// Created by NightRain on 2024/11/18.
//

#include "tool.h"
#include "mcs51/8052.h"

// 共阳4位数码管的段码数组
unsigned char SMG_NoDot[18] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92,
                               0x82, 0xf8, 0x80, 0x90, 0x88, 0x80,
                               0xc6, 0xc0, 0x86, 0x8e, 0xbf, 0x7f};

unsigned int hour = 0;
unsigned int minute = 0;
unsigned int second = 0;

void DisplaySMG_Dynamic();
void Delay(unsigned int time);
void DelaySMG(unsigned int time);
void Init74HC138(unsigned char n);
void SelectBit(unsigned char pos);
void SelectSegment(unsigned char value);

// 延时函数
void Delay(unsigned int time) {
  while (time--) {
    DisplaySMG_Dynamic();
  }
}

// 延时函数
void DelaySMG(unsigned int time) {
  while (time--)
    ;
}

// 选择通道,即具体选择哪个锁存器
void Init74HC138(unsigned char n) {
  switch (n) {
  case 4:
    P2 = (P2 & 0x1f) | 0x80;
    break;
  case 5:
    P2 = (P2 & 0x1f) | 0xa0;
    break;
  case 6:
    P2 = (P2 & 0x1f) | 0xc0;
    break;
  case 7:
    P2 = (P2 & 0x1f) | 0xe0;
    break;
  }
}

void int74h573(unsigned int n) {
  switch (n) {
  case 4:
    P2 = (P2 & 0x1f) | 0x80;
    break;
  case 5:
    P2 = (P2 & 0x1f) | 0xa0;
    break;
  case 6:
    P2 = (P2 & 0x1f) | 0xc0;
    break;
  case 7:
    P2 = (P2 & 0x1f) | 0xe0;
    break;
  }
}

// 选择位
void SelectBit(unsigned char pos) {
  Init74HC138(6); // Open COM end
  P0 = 0x00;      // Turn off all segments
  DelaySMG(10);   // Short delay to eliminate shadow
  P0 = (0x01 << pos);
}

// 选择段
void SelectSegment(unsigned char value) {
  Init74HC138(7); // 打开段选端
  P0 = value;
}

void time_increase() {
  second++;
  if (second == 60) {
    second = 0;
    minute++;
    if (minute == 60) {
      minute = 0;
      hour++;
      if (hour == 24) {
        hour = 0;
      }
    }
  }
}

// 动态显示数码管
void DisplaySMG_Dynamic() {
  SelectBit(0);
  SelectSegment(SMG_NoDot[hour / 10]);
  DelaySMG(500);

  SelectBit(1);
  SelectSegment(SMG_NoDot[hour % 10]);
  DelaySMG(500);

  SelectBit(2);
  SelectSegment(SMG_NoDot[16]);
  DelaySMG(500);

  SelectBit(3);
  SelectSegment(SMG_NoDot[minute / 10]);
  DelaySMG(500);

  SelectBit(4);
  SelectSegment(SMG_NoDot[minute % 10]);
  DelaySMG(500);

  SelectBit(5);
  SelectSegment(SMG_NoDot[16]);
  DelaySMG(500);

  SelectBit(6);
  SelectSegment(SMG_NoDot[second / 10]);
  DelaySMG(500);

  SelectBit(7);
  SelectSegment(SMG_NoDot[second % 10]);
  DelaySMG(500);
}
本博客已运行
发表了11篇文章,共计11992字 总计11.99k字
载入天数... 载入时分秒... 载入旅行者一号离地球距离信息...
梦——それは现実の続き;现実——それは梦の终わり
使用 Hugo 构建
主题 StackJimmy 设计