一、了解STM32F103C8T6
1、STM32F103C8T6的电路原理
STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,广泛应用于各种嵌入式系统
中。其电路原理涉及多个关键部分,包括电源电路、时钟电路、复位电路、GPIO(通用输入输出)电路以及通信接口电路等。
STM32F103C8T6的电源电路负责为整个微控制器提供稳定的工作电压。一般来说,
STM32F103C8T6的工作电压范围是2V到3.6V。
时钟电路是STM32F103C8T6微控制器的核心部分之一,它负责为微控制器的各个部分提供精确的
时钟信号。STM32F103C8T6内置了多个振荡器,包括HSI、LSI和HSE等。
复位电路用于在微控制器出现错误或需要重启时将其恢复到初始状态。STM32F103C8T6的复位电
路通常包括一个复位按钮和一个上拉电阻。当复位按钮被按下时,微控制器会接收到一个低电平信号,从而触发复位操作。
GPIO电路是STM32F103C8T6与外部世界进行交互的重要接口。STM32F103C8T6提供了多个GPIO
端口,每个端口都可以配置为输入或输出模式。
STM32F103C8T6支持多种通信接口,如UART(通用异步收发传输器)、SPI(串行外设接口)、
I2C(两线式串行接口)等。这些通信接口电路用于实现微控制器与其他设备之间的数据交换。
2.电路原理图
3.寄存器
寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指
令、数据和地址。
简单来说,寄存器就是存放东西的东西。寄存器存放的是指令、数据或地址。
存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来
问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的
寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。
指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机
器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。
4.最小系统板的引脚原理图
二、LED流水灯实验
1.proteus仿真
2.代码
#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOB_CRH (*(unsigned int )0x40010C04)
#define GPIOC_CRH ((unsigned int )0x40011004)
#define GPIOA_CRL ((unsigned int *)0x40010800)
#define GPIOB_ODR (*(unsigned int )0x40010C0C)
#define GPIOC_ODR ((unsigned int )0x4001100C)
#define GPIOA_ODR ((unsigned int *)0x4001080C)
void SystemInit(void);
void Delay_ms(volatile unsigned int);
void A_LED_LIGHT(void);
void B_LED_LIGHT(void);
void C_LED_LIGHT(void);
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t–)
for (i=0;i<800;i++);
}
void A_LED_LIGHT(){
GPIOA_ODR=0x0<<4; //PA4低电平
GPIOB_ODR=0x1<<9; //PB9高电平
GPIOC_ODR=0x1<<15; //PC15高电平
}
void B_LED_LIGHT(){
GPIOA_ODR=0x1<<4; //PA4高电平
GPIOB_ODR=0x0<<9; //PB9低电平
GPIOC_ODR=0x1<<15; //PC15高电平
}
void C_LED_LIGHT(){
GPIOA_ODR=0x1<<4; //PA4高电平
GPIOB_ODR=0x1<<9; //PB9高电平
GPIOC_ODR=0x0<<15; //PC15低电平
}
int main(){
int j=100;
// 开启时钟
RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
// 设置 GPIO 为推挽输出
GPIOB_CRH&= 0xffffff0f; //设置位 清零
GPIOB_CRH|=0x00000020; //PB9推挽输出
GPIOC_CRH &= 0x0fffffff; //设置位 清零
GPIOC_CRH|=0x30000000; //PC15推挽输出
GPIOA_CRL &= 0xfff0ffff; //设置位 清零
GPIOA_CRL|=0x00010000; //PA4推挽输出
// 3个LED初始化为不亮(即高点位)
GPIOB_ODR |= (1<<9);
GPIOC_ODR |= (1<<15);
GPIOA_ODR |= (1<<4);
while(j){
B_LED_LIGHT();
Delay_ms(100);
C_LED_LIGHT();
Delay_ms(100);
A_LED_LIGHT();
Delay_ms(100);
}
}
void SystemInit(){
}
3.程序设计思路
地址定义(寄存器映射):使用#define指令定义了各个GPIO和RCC(Reset and Clock Control)
寄存器的基地址。通过这些基地址,进一步定义了各个控制寄存器(如GPIO的CRH/CRL和ODR)的指针。
函数声明:声明了Delay_ms(延时函数)、A_LED_LIGHT、B_LED_LIGHT和C_LED_LIGHT(控制三
个LED的亮灭)。
延时函数Delay_ms:使用一个嵌套的循环来实现毫秒级的延时。延时时间与CPU的时钟频率有
关。
LED控制函数:A_LED_LIGHT、B_LED_LIGHT和C_LED_LIGHT分别用于设置三个LED的状态。使用的
是直接操作GPIO的ODR(Output Data Register)寄存器的方法。
主函数main:首先,通过操作RCC寄存器,开启GPIOA、GPIOB和GPIOC的时钟。然后,配置这三
个GPIO的特定引脚(PA4、PB9和PC15)为推挽输出模式。初始状态下,三个LED都处于熄灭状态(高电平)。接下来,通过一个无限循环,不断改变三个LED的状态。每个LED状态保持100毫秒,然后切换到下一个LED。