正点原子miniStm32F103
alientek miniSTM32 v3版开发板MCU为STM32F103RCT6,主频72MHz,48KB SRAM,256KB Flash,2个基本定时器、4个通用定时器、2个高级定时器、2个DMA控制器(共12个通道)、3个SPI、2个IIC、5个串口、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO接口和51个通用IO口。
注:正点原子精英版和战舰版的芯片都为STM32F103ZET6,144Pin,512KB Flash,64KB SRAM,主频72MHz。
注:ST定义的Flash大小规格:小容量(FLASH<=32K),中容量(64K<=FLASH<=128K),大容量(256K<=FLASH)

BOOT0、BOOT1用于设置stm32启动方式:
BOOT0
|
BOOT1
|
启动模式
|
说明
|
0
|
X
|
用户闪存存储器
|
Flash启动
|
1
|
0
|
系统存储器
|
系统存储器启动,用于串口下载
|
1
|
1
|
SRAM启动
|
SRAM启动,用于SRAM中调试代码
|
一般情况下(即标准的 ISP 下载步骤) 如果我们想用用串口下载代码,则必须先配置 BOOT0 为 1, BOOT1 为 0, 然后按复位键,最后再通过程序下载代码,下载完以后又需要将 BOOT0 设置为 GND,以便每次复位后都可以运行用户代码。可以看到,这个标准的 ISP 步骤还是很繁琐的,跳线帽跳来跳去,还要手动复位,所以 ALIENTEK 为 STM32 的串口下载专门设计了一键下载电路,通过串口的 DTR 和 RTS 信号,来自动控制 RST(复位)和BOOT0,因此不需要用户来手动切换状态,直接串口下载软件自动控制,可以非常方便的下载代码。

重点关注:时钟、GPIO、中断、DMA、串口、ADC
一、基础
AHB:Advanced High-performance Bus,高速总线,用来接高速外设的。
APB:Advanced Peripheral Bus,低速总线,连接低速外设。
AHB和APB通过bridge连接,bridge相当于一个高速的AHB slave。
二、工具使用
2.1 STLink使用
先连接USB_232给板卡供电,之后再连接STLink,设置MDK调试。
三、时钟

STM32有5个时钟源:HSI,HSE,LSI,LSE,PLL
①HSI(High speed internal oscillator clock)是高速内部时钟, RC振荡器, 频率为8MHz。
②HSE(High speed inexternal oscillator clock)是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz。开发板接的是8M的晶振。
③LSI是低速内部时钟, RC 振荡器,频率为 40kHz。 独立看门狗的时钟源只能是 LSI,同时 LSI 还可以作为 RTC 的时钟源。
④LSE是低速外部时钟,接频率为 32.768kHz 的石英晶体。 这个主要是 RTC 的时钟源。
⑤PLL(Phase Locked Loop)为锁相环倍频输出,其时钟输入源可选择为 HSI/2、 HSE 或者 HSE/2。倍频可选择为2~16 倍,但是其输出频率最大不得超过 72MHz。
系统时钟SYSCLK可来源于三个时钟源:
1)HSI振荡器时钟;
2)HSE振荡器时钟;
3)PLL时钟。 注:任何一个外设在使用前,必须首先使能其相应的时钟。
四、GPIO
STM32F103RCT6,一共有4组IO口,一共16x3 + 3 = 51个IO,GPIOA0~A15,GPIOB0~B15,GPIOC0~C15,GPIOD0~D2。
每组GPIO端口的寄存器包括:
- 两个32位配置寄存器(GPIOx_CRL ,GPIOx_CRH) ,
- 两个32位数据寄存器 (GPIOx_IDR端口输入数据寄存器和GPIOx_ODR端口输出数据寄存器),
- 一个32位置位/ 清除寄存器(GPIOx_BSRR),
- 一个16位清除寄存器(GPIOx_BRR),
- 一个32位锁定寄存器(GPIOx_LCKR)。
五、中断
NVIC:Nested Vectored Interrupt Controller,内嵌向量中断控制器。
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。STM32F103 系列只有60个可屏蔽中断,16级可编程的中断优先级。
注:一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。
中断优先级设置的步骤:
1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
2. 设置所用到的中断的中断优先级别。对每个中断调用函数为 NVIC_Init();
外部中断
STM32的每个IO都可以作为外部中断输入。STM32的中断控制器支持19个外部中断/事件请求:
线0~15:对应外部IO口的输入中断,线16:连接到PVD输出,线17:连接到RTC闹钟事件,线18:连接到USB唤醒事件。
六、串口
串口配置的一般步骤:
1)串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
2)串口复位:USART_Deinit();这一步不是必须的
3)GPIO端口模式设置:GPIO_Init();
4)串口参数初始化:USART_Init();
5)开启中断并且初始化NVIC_Init();USART_ITConfig(); (如果需要开启中断才需要这个步骤)。
6)使能串口:USART_Cmd()
7)编写中断处理函数:USARTx_IRQHandler()
8)串口数据收发:void USART_SendData() uint16_t USART_ReceiveData();
9)串口传输状态获取:FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearTPendingBit(USART_Typedef* USARTx, uint16_t USART_IT);
#include "sys.h" void uart_init(u32 band) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); USART_DeInit(USART1); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); USART_InitStruct.USART_BaudRate = band; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStruct.USART_Parity =USART_Parity_No; USART_InitStruct.USART_StopBits=USART_StopBits_1; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1, &USART_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; NVIC_Init(&NVIC_InitStruct); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); } void USART1_IRQHandler() { u8 res; if(USART_GetITStatus(USART1, USART_IT_RXNE)){ res = USART_ReceiveData(USART1); USART_SendData(USART1, res); } } int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); while(1); return 0; }
七、DMA
STM32最多有2个DMA控制器,DMA1有7个通道,DMA2有5个通道。每个通道专门用来管理来自于一个或多个外设对寄存器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。
配置DMA通道x的过程(x代表通道号):
1) 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
2) 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
3) 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
4) 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
5) 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
6) 设置DMA_CCRx寄存器的ENABLE位,启动该通道。
一旦启动了DMA通道,它即可响应连到该通道上的外设的DMA请求。当传输一半的数据后,半传输标志(HTIF)被置1,当设置了允许半传输中断位(HTIE)时,将产生一个中断请求。在数据传输结束后,传输完成标志(TCIF)被置1,当设置了允许传输完成中断位(TCIE)时,将产生一个中断请求。
DMA寄存器
DMA中断状态寄存器(DMA_ISR)
DMA中断标志清除寄存器(DMA_IFCR)
DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)
DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7) Number of data to transfer
DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7)
DMA通道x存储器地址寄存器(DMA_CMARx)(x = 1…7)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具