一、代码和思路分析
代码:
#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 SystemIni(){
// 配置PC13为推挽输出模式
GPIOC_CRH &= 0xFFF0FFFF; // 保留原来的设置
GPIOC_CRH |= 0x00300000; // 设置 PC13 为推挽输出模式
// PC13初始化为亮(即高电平)
GPIOC_ODR |= (1<<13); // 设置PC13引脚输出高电平
}
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);
SystemIni();
while(j){
B_LED_LIGHT();
Delay_ms(100);
C_LED_LIGHT();
Delay_ms(100);
A_LED_LIGHT();
Delay_ms(100);
}
}
void SystemInit(){
}
思路分析:
这段代码是用于STM32微控制器的C语言程序,主要功能是控制三个LED灯以不同的顺序点亮。程序设计思路如下:
- 定义基础地址和寄存器:
GPIOB_BASE、GPIOC_BASE和GPIOA_BASE定义了GPIOB、GPIOC和GPIOA的基础地址。
RCC_APB2ENR定义了APB2外设时钟使能寄存器的地址。
GPIOB_CRH、GPIOC_CRH和GPIOA_CRL定义了GPIOB、GPIOC和GPIOA的端口配置高/低寄存器。
GPIOB_ODR、GPIOC_ODR和GPIOA_ODR定义了GPIOB、GPIOC和GPIOA的端口输出数据寄存器。 - 系统初始化:
SystemInit():此函数为空,可能需要在其他地方定义。
SystemIni():配置PC13为推挽输出模式,并初始化为高电平(亮)。 - LED控制函数:
A_LED_LIGHT():将PA4设置为低电平,PB9和PC15设置为高电平。
B_LED_LIGHT():将PA4设置为高电平,PB9设置为低电平,PC15设置为高电平。
C_LED_LIGHT():将PA4和PB9设置为高电平,PC15设置为低电平。 - 延时函数:
Delay_ms():通过一个简单的循环实现毫秒级延时。 - 主函数(main):
配置RCC_APB2ENR来开启GPIOB、GPIOC和GPIOA的时钟。
配置GPIOB、GPIOC和GPIOA的端口配置寄存器,将相关引脚设置为推挽输出模式。
初始化三个LED灯为高电平(不亮)。
在一个循环中,依次调用B_LED_LIGHT()、C_LED_LIGHT()和A_LED_LIGHT(),并使用Delay_ms()实现闪烁效果。 - GPIOx端口的各寄存器地址和详细参数:
GPIOx_BASE:GPIO端口的基础地址。
GPIOx_CRH/CRL:端口配置高/低寄存器,用于配置每个引脚的工作模式和输出类型。
GPIOx_ODR:端口输出数据寄存器,用于控制引脚输出高或低电平。
RCC_APB2ENR:APB2外设时钟使能寄存器,用于开启GPIO端口的时钟。
二、Proteus仿真
电路图及仿真效果:
STM32最小系统核心板子出厂时已经焊接好了1个led灯(标注了PC13处),一般可通过此灯的点亮让编程者验证自己烧录的代码是否正常运行了。
三、实物仿真
实际上是在循环点亮的,不放动图了,pc13接口也顺利点亮用于验证