Skip to content

单片机分类

分类

  1. 单片机由 内核、内存、IO 接口 组成。
  2. 单片机可根据 内核、位数、品牌 进行分类。
  3. 主流位数:8位、16位、32位
  4. 内核
    • Intel —— 51 内核
    • Ateml —— AVR 内核
    • ARM —— ARM 内核
  5. 开发方式分类:库开发、底层开发
  6. 什么是微型计算机:以微处理器为核心的计算机称为微型计算机

工作条件

  1. 单片机工作条件
    • 供电(4.5V ~ 5.5V 直流电)
    • 时钟(晶振)
    • 复位:手动复位、上电复位
    • 程序
  2. 计算机工作条件:供电、时钟、复位、reday

电路图

  1. 电路原理图
    • 电源
    • 负载:耗电的元件(元件三要素:标识、符号、参数
    • 控制:单片机、开关
  2. PCB 图

电流与电路

  1. 串联:电流相等,电压不同。
  2. 并联:电压相等,电流不同。
  3. 串联分压,并联分流。
  4. 交流变直流的过程称为:整流
  5. 直流遍交流的过程称为:逆变
  6. 欧姆定律及演变公式

51单片机内部结构

组成部分

  1. 中央处理单元:51 内核、CPU
  2. 内存:见下文
  3. IO口:见下文
  4. 中断控制器:5 种中断源(见下文)
  5. 定时/计数器:2 个 16 位的定时/计数器(见下文)
  6. 振荡器:内部振荡器(时钟 IC) + 外部时钟电路(晶振、电容)
  7. 总线控制器(略)

内存

  1. ROM:只读存储器,用于存储程序,断电数据不丢失。
  2. RAM:随机存储器,用于存储数据,断电数据清空。
  3. 标准 51 单片机 ROM(4KB)RAM(128B)
  4. 60S2 的 ROM(60KB)RAM(1280B)
  5. 存储器结构:哈佛结构、冯诺依曼结构
  6. 51单片机所有存储器均是 8位 的。

IO口

  1. 并行口:P0、P1、P2、P3
  2. 串行口:RxD、TxD

可编程芯片的开发框架

  1. 内部编程结构
  2. 外部引脚定义
  3. 系统组成
  4. 编程方法

外部引脚

  1. 灌电流:从外部流入单片机。

  2. 拉电流:从单片机流入外设。

  3. 每个 IO 引脚最大可接受灌电流为 20mA

  4. 整个单片机最大可接受灌电流为 120mA

  5. 单片机直驱:仅有单片机提供电流,不需要其他的驱动电路。

  6. 驱动电路:有些外设 > 120mA,可以使用驱动电路辅助单片机供电。

  7. 一个引脚实现多个功能:引脚复用

最小系统电路

  1. 供电电路
  2. 时钟电路
  3. 复位电路
  4. 最小系统电路的作用:为单片机提供基本工作条件的电路
  5. 如何判断单片机正常工作了?单片机执行了内部程序

工作模式

模式

  1. 标准双向口
  2. 强推挽输出(强推):提高了单片机的 IO 扣的拉电流
  3. 开漏模式(略)
  4. 高阻模式(略)

模式参数(第一个值:M1,第二个值:M0)

  1. 00:标准双向口,灌电流

  2. 01:强推模式,拉电流

  3. 10:开漏模式

  4. 11:高阻模式

  5. 例:给 P1.0 设置成强推模式

    c
    P1M1 = 0x00;	// 0b 0000 0000
    P1M0 = 0x01;	// 0b 0000 0001

LED

外形

长正短负,箭头方向即为电流方向。

欧姆定律

  1. R = U/I
  2. I = U/R
  3. U = IR

逻辑运算

  1. 指定位清零,其他位不变:与运算,指定位和 0 相与,其他位和 1 相与。
  2. 指定位置 1,其他位不变:或运算,指定位和 1 相或,其他位和 0 相或。
  3. 指定位取反,其他位不变:异或,指定位和 1 异或,其他位和 0 异或。

按键

动态扫描步骤

c
unsigned char key_scan() {
  	unsigned char key_num = 0;
    if (!K1 || !K2) {
      	delay(10);
				if (!K1) key_num = 1;
      	if (!K2) key_num = 2;
      	while(!K1 || !K2);
      	delay(10);
    }
  	return key_num;
}

时间碎片

c
// 拆碎前
void test1() {
		int i = 100;
  	while(i) {
      printf("%d",i);
      i--;
    }
}

// 拆碎后
void test2() {
		static int i = 100;
  	printf("%d",i);
  	i--;
  	i %= 100;
}

void mian() {
  	while(1) {
      	test2();
      	printf("Hello");
    }
}

数码管与点阵屏

  1. 共阴:公共的负极
  2. 共阳:公共的正极

动态扫描

  1. 选位|选列
  2. 送段|送行
  3. 延时|延时
  4. 灭段|灭行

选位送段

  1. 数码管:高选位,低送段
  2. 点阵屏:高选列,低送行

sizeof

  1. 计算数组所占内存的大小。

  2. 计算数组元素个数:n = sizeof(arr) / sizeof(type for arr)

    c
    int arr[] = {1,2,3,4,5};
    int n = sizeof(arr) / sizeof(int);

蜂鸣器

  1. 发声原理:不断切换高低电平。

  2. 有源/无源:是否有震荡源。

  3. 给定频率输出声音:

    • 给定频率求周期:5Hz,200ms
    • 给定周期求频率:20ms,50Hz
    • GMK:1GHz = 1000MHz,1MHz = 1000KHz,1KHz = 1000Hz
    • smu:1s = 1000ms,1ms = 1000 us(1m = 1kms = 1mus)
  4. 人耳可听见的声音频率范围:5 Hz ~ 20 KHz(200ms ~ 50us)

  5. 例题:用蜂鸣器发出一个 440Hz 的声音,写出 TH0 和 TL0 的值。

    c
    TH0 = (65536 - 1000000 / 440 / 2) / 256;
    TL0 = (65536 - 500000 / 440) % 256;

中断

定义

  1. 中断定义:打断 CPU 当前工作的一个事件。事件的集合称为中断源。
  2. 5 个中断源
    • 外部中断类
      • 外部中断 0
      • 外部中断 1
    • 定时计数器类
      • 定时计数器 0 中断
      • 定时计数器 1 中断
    • 串行类:串行中断
  3. 数字信号
    • 高电平
    • 低电平
    • 上升沿
    • 下降沿
  4. 51 单片机里只支持低电平、下降沿的外部中断。

外部中断

  1. 步骤

    • 开中断
    • 设置中断请求模式
    • 中断处理子函数
  2. 开外部中断

    • IE 寄存器:可以位寻址

    • | 位 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | 名称 | EA | | | ES | ET1 | EX1 | ET0 | EX0 |

    • 0-关,1-开

  3. 设置外部中断请求类型

    • TCON:可以位寻址

    • | 位 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | 名称 | | | | | IE1 | IT1 | IE0 | IT0 |

    • IT0/IT1:设置请求信号类型。0-低电平 1-下降沿。

    • IE0/IE1:使能信号。

  4. 中断处理子函数

    • 特点
      • 无带入值、无返回值。
      • 中断处理子函数不可被其他函数调用,由 CPU 自动调用。
      • 无需声明,直接使用。
      • 必须要有中断向量号。
    • 中断向量号
      • 中断向量和中断向量号不是同一个东西,中断向量是地址,中断向量号是地址别名。
      • 中断向量用于标识中断源类型。
      • 关键字:interrupt
      • 中断向量号
        • 0 - 外部中断 0
        • 1 - 定时计数器 0 中断
        • 2 - 外部中断 1
        • 3 - 定时计数器 1 中断
        • 4 - 串行口
  5. 例题:设计一个是用外部中断 0 下降沿触发的程序。

    c
    #include <STC12C5A60S2.H>
    bit flag = 0;
    
    void init() {
      	EA = EX1 = IT0 = 1;
    }
    
    void main() {
      	init();
    		while(1) {
          	if (flag) {
              	flag = 0;
              	// 1000 行代码
            }
        }
    }
    
    void inter() interrupt 0 {
      	EX0 = 0;
      	flag = 1;
      	EX0 = 1;
    }

定时计数器

知识点

  1. 51 单片机里有两个 16 位的定时计数器。
  2. 16 位定时计数器最大计算能力:65536(0~65535)
  3. 分类
    • 加法计数器(51):计数初值 = 最大计数值 - 计数值。
    • 减法计数器:计数初值 = 计数值
  4. 工作模式
    • 定时模式
    • 计数模式
  5. 工作方式:方式0 ~ 方式3(方式1最常用)
    • 方式 0:13 位。
    • 方式 1:16 位。
    • 方式 2:8 位,有 8 位自动装载。
    • 方式 3(略)

步骤

  1. 模式方式设置

    • TMOD 寄存器:不可进行位寻址

    • | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ---- | ----- | ---- | ---- | ---- | ----- | ---- | ---- | | GATE | C/~T | M1 | M0 | GATE | C/~T | M1 | M0 |

    • GATE:门控信。0-软件开启,1-硬件开启。

    • C/~T:工作模式。0-定时模式,1-计数模式。

    • M1M0:工作方式

      • 00-方式0
      • 01-方式1(常用)
      • 10-方式2
      • 11-方式3
  2. 写入计数初值

    • 寄存器:TH0、TH1、TL0、TL1

    • | T1高 8 位 | T1低 8 位 | T0高 8 位 | T0低 8 位 | | --------- | --------- | --------- | --------- | | TH1 | TL1 | TH0 | TL0 |

    • 计算高 8 位:计数初值 / 256

    • 计算低 8 位:计数初值 % 256

  3. 开启定时计数器

    • 寄存器:TCON

    • | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |

    • TF1/TF0:溢出标志位

    • TR1/TR0:定时计数器开关 0-关 1-开

  4. 查询法:设置一个计数器 T0,计数 3 次为一个周期,每个周期切换一次 LED(P1.0) 的亮灭状态。

    c
    #include <STC12C5A60S2.H>
    sbit LED = P1 ^ 0;
    
    void init() {
    		LED = 1;
      	TMOD = 0x05;
      	TH0 = (65536 - 3) / 256;
      	TL0 = (65536 - 3) % 256;
      	TR0 = 1;
    }
    
    void main() {
    		init();
      	while(1) {
          	if (TF0) {
              	TR0 = TF0 = 0;
              	TH0 = (65536 - 3) / 256;
      					TL0 = (65536 - 3) % 256;
              	LED = ~LED;
              	TR0 = 1;
            }
        }
    }
  5. 定时计数器中断

    • 开中断:IE

    • 中断处理子函数

    • 程序1:设置一个定时器 T0,每隔 3 秒切换一次 LED(P1.0) 的亮灭状态。

      c
      #include <STC12C5A60S2.H>
      sbit LED = P1 ^ 0;
      
      void init() {
      		LED = 1;
        	TMOD = 0x01;
        	TH0 = (65536 - 50000) / 256;
        	TL0 = (65536 - 50000) % 256;
        	EA = ET0 = TR0 = 1;
      }
      
      void main() {
      		init();
        	while(1);
      }
      
      // 马
      void timer() interrupt 1 {
        	static unsigned char c = 0;
        	c = ++c % 60;
        	if (!c) LED = ~LED;
        	else {
            	TR0 = 0;
            	TH0 = (65536 - 50000) / 256;
            	TL0 = (65536 - 50000) % 256;
            	TR0 = 1;
          }
      }
      
      // 刘
      void timer() interrupt 1 {
        	static unsigned char c = 0;
        	TR0 = 0;
          TH0 = (65536 - 50000) / 256;
          TL0 = (65536 - 50000) % 256;
        	if (++c == 60) {
            	c = 0;
            	LED = ~LED;
          }
          TR0 = 1;
      }
    • 程序2:设置一个定时器 T0,每隔 2 秒切换一次 LED_BLUE(P1.0) 的亮灭状态。每隔 3 秒切换一次 LED_RED(P1.1) 的亮灭状态。

      c
      #include <STC12C5A60S2.H>
      sbit LED_BLUE = P1 ^ 0;
      sbit LED_RED = P1 ^ 1;
      bit F2 = F3 = 0;
      
      void init() {
      		LED_BLUE = LED_RED = 1;
        	TMOD = 0x01;
        	TH0 = (65536 - 50000) / 256;
        	TL0 = (65536 - 50000) % 256;
        	EA = ET0 = TR0 = 1;
      }
      
      void main() {
      		init();
        	while(1);
      }
      
      void timer() interrupt 1 {
        	static unsigned char c = 0;
        	c = ++c % 120;
        	if (!(c % 40)) LED_BLUE = ~LED_BLUE;
        	else if (!(c % 60)) LED_RED = ~LED_RED;
        	else {
            	TR0 = 0;
              TH0 = (65536 - 50000) / 256;
              TL0 = (65536 - 50000) % 256;
              TR0 = 1;
          }
      }
      
      void timer() interrupt 1 {
        	static unsigned char c = 0,k = 0;
        	TR0 = 0;
          TH0 = (65536 - 50000) / 256;
          TL0 = (65536 - 50000) % 256;
        	if (++k == 40) {
            	k = 0;
            	LED_BLUE = ~LED_BLUE;
          }
        	if (++c == 60) {
            	c = 0;
            	LED_RED = ~LED_RED;
          }
          TR0 = 1;
      }

频率与周期

考点

  1. 给定频率求周期:5Hz,200ms
  2. 给定周期求频率:20ms,50Hz

时钟周期

  1. 时钟电路中晶振的周期即为时钟周期。
  2. 晶振频率 12MHz,时钟周期是:1s/12MHz = 1ms/12KHz = 1us/12Hz = 1/12us

机器周期

  1. 一个机器周期 = 12个时钟周期
  2. 晶振频率 12MHz,机器周期是:1us

基于 MIT 许可发布