嵌入式基本概念

  • 嵌入式系统
    嵌入式系统是一种专门设计用于执行特定任务或控制特定设备的计算机系统。它通常包括硬件和软件两个部分,被嵌入到目标设备中,以实现特定的功能。

  • RTOS(Real-Time OS)

    一种专门设计用于嵌入式系统的操作系统。RTOS的主要特点是能够保证任务在预定的时间内得到及时处理,具有良好的实时性。

1. STM32和51

1. 51的优缺点

1. 51 的优点

  • 硬件层面
  1. 结构简单,8位
  2. 硬件到软件有一套按位操作系统。(进行位的操作:传送、置位、清零、测试,逻辑运算)
  3. 包含乘除法指令
  • 软件层面
  1. 可以使用C进行编程

2. 51的缺点

  • 硬件层面
  1. 功能少,运行速度慢
  2. I/O高电平无输出能力
  3. 保护能力差

2.stm32的简介

​ 由ST厂商推出的STM32系列单片机,行业的朋友都知道,这是一款性价比超高的系列单片机,应该没有之一,功能及其强大。其基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M内核,同时具有一流的外设:1μs的双12位ADC,4兆位/秒的UART,18兆位/秒的SPI等等,在功耗和集成度方面也有不俗的表现,当然和MSP430的功耗比起来是稍微逊色的一些,但这并不影响工程师们对它的热捧程度,由于其简单的结构和易用的工具再配合其强大的功能在行业中赫赫有名。

  • 强大功能体现
  1. 内核
    STM32 系列采用了多种 ARM Cortex-M 内核,包括 Cortex-M0、Cortex-M3、Cortex-M4 等,具有不同的性能和功能特点,可根据应用场景的需求进行选择。

  2. 时钟
    STM32 系列支持多种时钟源,包括内部 RC 振荡器、内部晶体振荡器、外部晶体振荡器等,可根据应用场景的需求进行选择。同时还支持多种时钟分频和时钟输出等功能。

  3. 存储器
    STM32 系列支持多种存储器类型,包括 Flash 存储器、RAM 存储器、EEPROM 存储器等,可以根据应用场景的需求进行选择。同时还支持多种存储器保护和存储器映射等功能。

  4. 支持多种通讯

    STM32 系列还支持多种通信协议,如 SPI、I2C、CAN、USART 等。这使得 STM32 系列非常适合各种应用,特别是需要与其他设备或模块进行通信的应用。

3.STM32F103C8T6 最小系统制作

1.供电电路

1.芯片特性

  • 操作定压Vdd=2.0~3.6v
  • Vdd关闭后,RTC和备用寄存器可以从Vbat供电

2.电源转换电路

  • USB供电(5v)转3.3v供电

​ 采用AMS1117芯片

  • AMS1117
    • 特点:

Three Terminal Adjustable or Fixed Voltages*

• High Efficiency Linear Regulators 1.5V, 1.8V, 2.5V, 2.85V, 3.3V and 5.0V

• Post Regulators for Switching Supplies • Output Current of 1A

• 5V to 3.3V Linear Regulator

• Operates Down to 1V Dropout

• Line Regulation: 0.2% Max.

• Active SCSI Terminators

• Load Regulation: 0.4% Max.

• SOT-223, TO-252 and SO-8 package

3.SWD下载电路

  • PA13和PA14为STM32F103C8T6芯片的SWD下载调试引脚

4.时钟电路

  • 时钟源

三个不同的时钟源可以用来驱动系统时钟(SYSCLK):

● HSI晶振时钟(高速内部时钟信号)

● HSE晶振时钟(高速外部时钟信号)

● PLL时钟

STM32有两个二级时钟源:

● 40kHz的低速内部RC,它可以驱动独立看门狗,还可选择地通过程序选择驱动RTC。RTC 用于从停机/待机模式下自动唤醒系统。

● 32.768kHz的低速外部晶振,可选择它用来驱动RTC(RTCCLK)。

  • 时钟电路(晶振电路)

5.复位电路

  • 复位条件:

    • NRST引脚上出现低电平(外部复位)
    • 窗口看门狗计数终止(WWDG复位)
    • 独立看门狗计数终止(IWDG复位)
    • 软件复位(SW复位)
    • 低功耗管理复位
  • 复位电路

6.外围测试电路

  • LED测试电路
  1. 电源指示灯
  2. 烧录指示灯
  3. blink程序测试用灯
  • 引脚引出

STM32的GPIO(待补充)

​ STM32的I/O 端口有8种模式(4种输入模式和4种输出模式)。

  • GPIO工作模式—–输入

    1.浮空输入模式

    2.上拉输入模式

    3.下拉输入模式

    4.模拟输入模式

  • GPIO工作模式—–输出

    1.开漏输出模式

    2.推挽输出模式

    3.复用开漏输出

    4.复用推挽输出

输入模式

1. 输入浮空

  • 特性
  1. I/O端口的电平信号直接进入输入数据寄存器。
  2. 引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的·
  • 使用案例

2. 输入上拉

  • 特性
  1. IO内部接上拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平
  2. STM32 内部上拉输出的电流很弱的,需要大电流还是得外部上拉。
  • 使用案例

3. 输入下拉

  • 特性
  1. IO内部接下拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平
  • 使用案例

4. 模拟输入

  • 特点
  1. 信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态
  2. 没有连接TTL触发器,这样保留最原始的电压值,不是转换过后的0和1信号
  3. 数据直接送到片上外设,一般是ADC模数转换器(Analog-to-Digital Converter)
  • 使用案例

用于连接模拟传感器或信号源,如温度传感器或光线传感器,可以通过ADC模块读取模拟电压值。

输出模式(一知半解,待补充)

1. 开漏输出

  • 特征
  1. 引脚可以输出低电平(逻辑0),但不能输出高电平,而是通过外部上拉电阻实现。
  • 使用案例

​ 适用于实现多个引脚共享一个信号线的情况,如I2C总线或SPI总线。开漏输出模式允许多个设备通过外部上拉电阻共享同一条信号线,并且可以实现更高的灵活性和可靠性。

2. 推挽输出

  • 特征

​ 这意味着引脚可以输出高电平(逻辑1)或低电平(逻辑0),且能够提供或接受相对较高的电流。

  • 使用案例

​ 适用于驱动外部负载,如LED、继电器、蜂鸣器等。推挽输出模式在输出高电平时提供的电流较大,可以有效地驱动各种类型的负载。

3. 复用功能推挽输出

  • 特征

在复用推挽输出模式下,GPIO引脚被配置为复用推挽输出,同时具有其他功能,如串行通信、定时器等。

  • 使用案例

​ 适用于需要在GPIO引脚上实现数字输出以及其他功能的应用场景。例如,将引脚配置为UART串行通信的TX引脚,同时可用于输出数字信号。

4. 复用功能开漏输出

  • 特征

  • 使用案例

STM32 HAL库和标准库的比较

  • 抽象层级:
    标准库:标准外设库提供了对STM32外设的低层次的直接访问,开发者需要直接操作外设的寄存器来配置和控制外设。
    HAL库:HAL库提供了对STM32外设的高层次的抽象,通过一组统一的API接口,开发者可以更方便地配置和控制外设,而不必直接操作底层寄存器。
  • 可移植性:
    标准库:标准外设库的代码通常直接与特定型号的STM32微控制器相关联,因此在不同型号的微控制器之间的移植性较差。
    HAL库:HAL库设计为具有一定的可移植性,可以在不同型号的STM32微控制器之间进行较为简单的移植。
  • 易用性:
    标准库:标准外设库需要开发者具有一定的硬件知识和对STM32微控制器的了解,操作相对复杂,学习曲线较陡。
    HAL库:HAL库提供了一套统一的API接口,使得操作外设更加简单直观,适合初学者或者对硬件了解较少的开发者使用。
  • 功能支持:
    标准库:标准外设库通常提供了丰富的外设驱动程序,但功能相对较为基础,不支持一些高级特性。
    HAL库:HAL库不仅提供了基础的外设驱动程序,还支持一些高级特性,如DMA、中断优先级管理、时钟配置等,能够满足更复杂的应用需求。

总的来说,标准库更加接近硬件,直接操作寄存器,适合对硬件较为了解的开发者;而HAL库提供了更高层次的抽象,操作更加简便,适合快速开发应用程序。选择使用哪种库取决于开发者的具体需求和技术水平。

标准库的功能

  • 外设驱动支持:
    STM32标准库提供了丰富的外设驱动程序,包括GPIO、定时器、串口、SPI、I2C、ADC等,开发者可以直接调用这些函数来配置和控制外设,实现各种功能。
  • 中断支持:
    标准库支持外部中断和定时器中断,在外设产生中断时能够及时响应,并执行相应的中断服务程序。开发者可以通过注册中断处理函数来实现自定义的中断处理逻辑。
  • 时钟控制:
    STM32标准库提供了时钟配置功能,包括系统时钟和外设时钟的配置。开发者可以根据实际需求设置时钟源、时钟分频等参数,以满足系统的性能和功耗要求。
  • 低功耗模式:
    标准库支持STM32微控制器的低功耗模式,包括停机模式、睡眠模式、待机模式等,开发者可以根据需要选择合适的低功耗模式来降低系统的功耗。
  • 系统初始化和配置:
    标准库提供了系统初始化和配置函数,包括时钟初始化、外设初始化等,开发者可以在程序的启动阶段调用这些函数来配置系统的基本参数。
  • 调试支持:
    标准库提供了一些调试功能,如串口打印输出、断言功能等,帮助开发者在调试和验证程序时更加方便。
    定时器和计数器: 标准库提供了定时器和计数器的功能支持,包括定时器的初始化、启动、停止等操作,以及定时器中断的配置和处理。
  • PWM输出:
    标准库支持PWM输出功能,开发者可以通过配置定时器和GPIO来生成PWM信号,用于控制电机、LED等外部设备。

案例程序

STM32的中断

概念解释

中断向量

中断向量是指用于唤醒处理器并跳转到相应中断服务程序(ISR)的特定地址。在中断发生时,处理器会根据中断类型查找相应的中断向量,并跳转到相应的中断服务程序开始执行中断处理。中断向量通常是固定的,由处理器或芯片设计者确定,因为它们对应于具体的中断类型。例如,某个中断类型可能对应到内存中的特定地址,而另一个中断类型可能对应到另一个地址。

中断向量表

中断向量表是一张表格,存储着所有中断类型对应的中断向量。每个中断向量都包含了中断发生时处理器应该跳转到的地址。在许多嵌入式系统中,中断向量表通常存储在固定的内存位置,处理器在发生中断时会根据中断类型找到相应的中断向量,并跳转到相应的中断服务程序。中断向量表的大小通常由中断类型的数量决定。

NVIC

NVIC是ARM Cortex-M系列微控制器中的一个重要组件,用于管理和控制中断

AFIO

AFIO代表Alternate Function Input Output(备用功能输入输出),是STM32系列微控制器中的一个模块。AFIO模块允许用户配置GPIO引脚的备用功能,包括串行通信、定时器、中断控制等。

硬件特性

  1. 68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设
  2. 使用NVICNVIC代表Nested Vectored Interrupt Controller(嵌套向量中断控制器)。NVIC是ARM Cortex-M系列微控制器中的一个重要组件,用于管理和控制中断。统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级
  3. 优先级分组
    1. 抢占优先级:越高可以中断嵌套
    2. 响应优先级:越高可以优先排队

外部中断( E X T I )

硬件特性:

  1. 触发方式:上升沿/下降沿/双边沿/软件触发
  2. 支持所有GPIO口,但相同的Pin不能同时触发中断
  3. 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒

结构体初始化配置过程

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
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟,外部中断必须开启AFIO的时钟

/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB14引脚初始化为上拉输入

/*AFIO选择中断引脚*/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚

/*EXTI初始化*/
EXTI_InitTypeDef EXTI_InitStructure; //定义结构体变量
EXTI_InitStructure.EXTI_Line = EXTI_Line14; //选择配置外部中断的14号线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定外部中断线使能
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定外部中断线为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //指定外部中断线为下降沿触发
EXTI_Init(&EXTI_InitStructure); //将结构体变量交给EXTI_Init,配置EXTI外设

/*NVIC中断分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2
//即抢占优先级范围:0~3,响应优先级范围:0~3
//此分组配置在整个工程中仅需调用一次
//若有多个中断,可以把此代码放在main函数内,while循环之前
//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置

/*NVIC配置*/
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择配置NVIC的EXTI15_10线
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1

遇到问题

OLED屏幕不显示(未解决)

​ 使用 STM32以IIC的协议进行通信来在0.96寸OLED屏幕显示失败。但是使用arduino uno时显示正常。

​ 经过检验,发现使用的芯片为STM32f103c6t6 默认i2c输出引脚为PB6(SCL) PB7(SDA)STM32f103c8t6有两组I2C引脚,分别是{ PB6(SCL) PB7(SDA) } 和{ PB8(SCL) PB9(SDA)}

​ 多看看技术手册!!!

不同芯片功能对比

  1. C6T6没有串口3(及USART3);

  2. C6T6没有通用定时器TIM4;

  3. C6T6没有串行外设接口SPI2;

  4. C6T6没有I2C2

  5. C6T6的flash为32K, C8T6为64K;

  6. C6T6的RAM为10K,C8T6为20K。

    总结就是C8T6比C6T6多了一个串口、一个定时器、一个串行外设接口、一个I2C、内存大一点!

  • IIC协议的上拉电阻已考虑
  • 电压大小已考虑
  • 芯片引脚特性