用STM32F103C8T6点亮一组由3个不同色的LED组成的流水灯(寄存器地址方式)【Proteus】【STM32开发板】

本文介绍了如何使用STM32F103C8T6开发板,配合Proteus软件,通过GPIOA、GPIOB和GPIOC控制3个LED实现流水灯效果,涉及时钟设置、GPIO初始化和寄存器编程。作者详细展示了如何配置GPIO模式和控制LED灯的亮灭状态,以实现定时闪烁效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用STM32F103C8T6点亮一组由3个不同色的LED组成的流水灯(寄存器地址方式)【Proteus】【STM32开发板】

实验要求

  1. 用Proteus设计一个STM32最小系统板+LED流水灯实验原理图,仿真运行。

  2. 以STM32最小系统核心板(STM32F103C8T6)+面包板+3只(或更多)红绿蓝LED搭建电路,使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长1秒。

    1. 写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;

    2. 用C语言寄存器方式编程实现,代码须有详细注解。

    3. STM32最小系统核心板子出厂时已经焊接好了1个led灯(标注了PC13处),一般可通过此灯的点亮让编程者验证自己烧录的代码是否正常运行了。请查阅最小版电路原理图和相关资料,将这个灯也用在流水灯中,重编新程序。

项目编写

GPIO端口的初始化设置

GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,STM32 芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。STM32 芯片的 GPIO 被分成很多组,每组有 16 个引脚,如型号为 STM32F103VET6 型号芯片有 GPIOA、GPIOB、GPIOC至 GPIOE共 5组 GPIO,芯片一共 100个引脚,其中 GPIO就占了一大部分,所有的 GPIO 引脚都有基本的输入输出功能。

点亮LED灯,实现流水灯效果需要用到GPIO端口。为了点亮LED灯,进行以下三个步骤:

1. 打开GPIO口的时钟

GPIO的地址:

在这里插入图片描述

时钟的地址:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

即时钟的地址为0x40021018,打开三个I/O口的时钟需要将三个位都置1:

#define RCC_APB2ENR (*(unsigned int *)0x40021018)
 
// 打开时钟
RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟
RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟

2. 初始化GPIO口(选择推挽输出)

GPIO口有输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽式输出、推挽式复用、开漏服用八种模式。本次实验使用推挽输出。

在这里插入图片描述

在这里插入图片描述

端口1-7为低,端口8-15为高。每个引脚由四个位控制。

对于本次实验用到的GPIOB的B9、GPIOC的C15、GPIOA的A4,设置如下:

#define GPIOB_CRH (*(unsigned int *)0x40010C04)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)
 
GPIOB_CRH&= 0xffffff0f;		
GPIOB_CRH|=0x00000020;
 
GPIOC_CRH &= 0x0fffffff; 
GPIOC_CRH|=0x30000000;
 
GPIOA_CRL &= 0xfff0ffff; 
GPIOA_CRL|=0x00010000;
3. 设置低电平

在这里插入图片描述

输出高电平为1,低电平为0。

对于本次实验用到的GPIOB的B9、GPIOC的C15、GPIOA的A4,设置如下:

#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
 
GPIOB_ODR &= ~(1<<9);  
GPIOC_ODR &= ~(1<<15); 
GPIOA_ODR &= ~(1<<4);  

完整代码

在Keil中编写以下代码,保存并编译。编译时选择生成hex文件,用于Proteus仿真。

#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(1000);
 
		C_LED_LIGHT();
		Delay_ms(1000);
 
		A_LED_LIGHT();
		Delay_ms(1000);
	}
	
}
 
 
void SystemInit(){
	
}

对于第二问的第三小问,只需将以上代码中的所有PC15改为PC13,将PC15推挽输出的地址0x30000000改为PC13推挽输出的地址0x00300000即可。

Proteus仿真

Proteus电路图如下:

(建立工程时,固件系列为Cortex-M3,控制器为STM32F103C8。若没有STM32F103C8固件,可用STM32F103C6代替,如图)

在这里插入图片描述

将Keil编译生成的hex文件导入单片机,运行,结果如下。

在这里插入图片描述

STM32开发板实现

如下图所示,将STM32开发板插入面包板并与ST-link连接(相接的两接口应同名),分别用导线将开发板两侧的3.3V输出接至面包板两侧的正极槽、接地输入接至面包板两侧的负极槽。将一个红色LED接在开发板的B9接口上,具体做法是将正极(长管脚)接至正极槽,负极(短管脚)接至开发板B9接口所接在的一槽。用同样的方法将一个绿色LED接在开发板的C15接口上,将一个蓝色LED接在开发板的A4接口上。

在这里插入图片描述

代码在Keil中编译完成后,点击“下载”,即可将代码载入STM32单片机中并开始运行。运行结果如下。

在这里插入图片描述

第二问的第三小问的运行结果如下。

在这里插入图片描述

总结

本次实验在用STM32点亮一个LED灯的基础上拓展,了解了STM32时钟的控制方式,提高了我利用寄存器编写程序的能力。

参考资料

STM32F103的流水灯点亮版本1(寄存器地址操作)_pc13推挽输出-优快云博客

<think>好的,我需要帮助用户找到关于如何在Proteus中使用STM32F103C8T6实现按键控制LED的仿真和示例代码。首先,用户已经提供了几个相关的引用,我需要仔细看看这些引用是否有帮助。 引用1提到在Proteus中仿真STM32F103C8T6时,串口发送小数会导致卡死,但用户的问题是关于按键控制LED,可能关联不大。不过,里面提到的仿真配置可能有参考价值,比如使用USART1的引脚,但暂时记下这个信息。 引用2提到了基于ProteusSTM32CubeMX仿真STM32F103C8T6结合FreeRTOS,其中PC13和PC14控制LED,PA0作为按键输入,PA9和PA10用于USART。这直接关联到用户的请求,因为提到了LED和按键的引脚配置,可能可以作为示例的基础。需要确认是否使用了FreeRTOS,但用户可能只需要基础代码,不需要操作系统。不过,这里提供了引脚分配,PC13和PC14作为LED,PA0作为KEY1,这可能是一个关键点。 引用3是关于如何在Proteus中配置STM32F103C8T6以及使用Keil5开发,提到了需要Proteus 8.15以上版本才能找到该型号。这可能对用户的环境配置有帮助,需要提醒用户检查Proteus版本是否足够高。 接下来,用户需要具体的教程或示例代码。根据引用2的信息,可以构建一个基本的按键控制LED的代码结构。需要确定按键是输入模式,LED是输出模式,并且编写相应的GPIO读取和控制的代码。同时,需要配置Proteus的原理图,连接按键到PA0,LED到PC13或PC14。 可能还需要考虑按键的去抖动处理,这在硬件仿真中是否需要软件去抖。此外,STM32CubeMX可以生成初始化代码,简化配置过程,用户可能需要使用这个工具来生成GPIO的初始化代码,然后在Keil中编写主循环逻辑。 另外,需要确保在Proteus中正确添加STM32F103C8T6元件,并连接外部晶振(如引用2提到的PD0和PD1接8MHz晶振),以及可能的复位电路。不过,对于简单的按键和LED控制,可能不需要外部晶振,使用内部时钟即可,但引用2提到了外接晶振,可能需要配置时钟树。 综上,步骤可能包括: 1. 使用STM32CubeMX配置GPIO引脚:PA0输入,PC13输出。 2. 生成初始化代码。 3. 在Keil中编写主循环,检测按键状态并控制LED。 4. 在Proteus中搭建电路,连接按键和LED到对应引脚。 5. 进行仿真测试。 需要检查引用中的信息是否有示例代码片段,但引用中没有提供具体的代码,可能需要根据常规方法构建。此外,提醒用户注意Proteus版本,并参考引用3中的配置步骤选择正确的单片机型号。 最后,生成相关问题,可能涉及仿真配置问题、代码优化、扩展功能等。</think>### 使用Proteus仿真STM32F103C8T6按键控制LED的实现步骤 #### 1. **环境准备** - 确保Proteus版本≥8.15(否则可能无法找到STM32F103C8T6型号)[^3]。 - 安装Keil MDK-ARM和STM32CubeMX。 #### 2. **STM32CubeMX配置** 1. **创建项目**:选择STM32F103C8Tx型号。 2. **配置时钟源**:若需外部晶振,在`RCC`中启用`High Speed Clock (HSE)`并连接PD0/PD1(参考引用2的硬件设计)[^2]。 3. **GPIO设置**: - **PA0**:设为`GPIO_Input`模式(按键输入)。 - **PC13**:设为`GPIO_Output`模式(LED控制)。 4. **生成代码**:选择IDE为Keil,生成初始化代码。 #### 3. **Keil代码编写** ```c // main.c 主循环中添加以下逻辑 while (1) { if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { // 检测按键按下(假设按键接地) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // LED亮 } else { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // LED灭 } HAL_Delay(10); // 简单延时去抖 } ``` #### 4. **Proteus电路搭建** 1. **添加元件**: - STM32F103C8T6(微控制器) - LED(连接至PC13,阴极接地) - 按钮(连接至PA0,另一端接地) - 电阻(LED限流,例如220Ω) 2. **电路连接**: - PA0 → 按钮 → GND - PC13 → 电阻 → LED阳极 → GND #### 5. **仿真运行** 1. 将Keil生成的`.hex`文件加载到ProteusSTM32中。 2. 启动仿真,按下按钮观察LED状态变化。 --- ### 关键问题说明 - **按键去抖动**:示例代码使用`HAL_Delay(10)`简单去抖,实际可优化为硬件滤波或状态机。 - **引脚电平逻辑**:若按键设计为上拉模式(默认高电平,按下为低电平),代码需对应调整输入检测逻辑。 - **外部晶振**:若需高精度时钟,按引用2配置PD0/PD1外接8MHz晶振。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值