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

用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推挽输出-CSDN博客

STM32F103C8T6是一款常用的STM32系列微控制器芯片。针对该芯片的仿真,可以使用Keil软件进行仿真。Keil具有强大的软件仿真功能,通过仿真可以发现将要出现的问题,并观察硬件相关的寄存器值的变化,以判断代码是否正常运行。使用Keil进行软件仿真可以避免频繁下载程序,从而延长单片机Flash寿命。 在Keil中进行STM32F103C8T6的仿真,可以按照以下步骤进行设置: . 在“Debug”选项卡中选择“Use Simulator”,表示使用软件仿真。 2. 选择“Run to main()”,表示跳过汇编代码,直接跳转到main函数开始仿真。 3. 设置“Dialog DLL”项为“DARMSTM.DLL”和“TARMSTM.DLL”。 4. 设置parameter项为“-pSTM32F103C8”,用于设置支持STM32F103C8的软硬件仿真。 除了Keil软件,还可以使用Proteus进行仿真。在Proteus中进行STM32F103C8T6的仿真,可以按照以下步骤进行设置: 1. 打开Proteus软件。 2. 双击芯片,选择STM32F103C8T6芯片。 3. 在“Program File”的路径中选择生成的.hex文件进行打开。 4. 运行仿真,观察仿真结果。 通过以上步骤,你可以进行STM32F103C8T6的仿真,以验证代码的正确性和功能的正常运行。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Keil5进行STM32F103C8T6的软件仿真](https://blog.csdn.net/weixin_64449928/article/details/127690607)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Stm32f103c8t6(proteus仿真)学习——1.点亮LED流水灯](https://blog.csdn.net/weixin_53405696/article/details/131818153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值