IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【嵌入式04.2】STM32F103C8T6的简易流水灯仿真(寄存器实现+STM32CubeMX实现) -> 正文阅读

[嵌入式]【嵌入式04.2】STM32F103C8T6的简易流水灯仿真(寄存器实现+STM32CubeMX实现)

题目要求:假设你手中已有 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。

一、程序设计

stm32点灯是通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,从而实现各种功能。其过程大致如下:
CPU给指令→GPIO收到指令→配置内部寄存器→配置IO口模式→控制LED灯亮灭

(一)配置时钟效能

因为默认的时钟都是关闭的,所以在配置STM32之前必须先配置时钟。
时钟控制叫做RCC,是属于AHB总线的,我们使用的GPIOA/B/C端口都是属于APB2。
在这里插入图片描述
在这里插入图片描述

以GPIOA口为例,GPIO端口A的地址从0x4001 0800开始,从手册中可以得知复位和时钟控制RCC的地址从0x4002 1000开始,再找到APB2的外设时钟使能寄存器,可以看出其偏移地址为0x18,所以APB2的地址就是0x4002 1018。
根据手册可以知道IO端口B时钟使能是RCC_APB2ENR的位2,将RCC_APB2ENR位的2赋值为1,就能开启GPIOA时钟

#define RCC_AP2ENR ((unsigned volatile int)0x40021018)
RCC_AP2ENR|=1<<2; //APB2-GPIOA外设时钟使能

在这里插入图片描述

(二)配置为通用输出

由于STM32的每个IO端口都需要4个位来配置,所以一个32位的寄存器最大只能配置8个IO端口。STM32中,用端口配置低寄存器(GPIOx_CRL)来配置引脚Px0-Px7,用端口配置高寄存器(GPIOx_CRH)来配置引脚Px8-Px15。
以本次实验用到的PA5为例,使用的寄存器为GPIOA_CRL。
如下图所示,偏移地址为0x00,意思是在基地址的基础上再加0x00,所以对于GPIOA来说就是0x4001 0800。配置PA5需要的寄存器是低位的寄存器GPIOA_CRL,其地址是0x4001 0800,找到需要操作的寄存器后,将其配置为通用输出。
将LED灯点亮需要输出低电平,所以我们需要找到端口输出数据寄存器,将第5位输出为0。(此处中文版端口输出数据寄存器地址偏移为0Ch,而英文版为0x0C

#define GPIOA_CRL * ((unsigned volatile int*)0x40010800)
#define GPIOA_ODR * ((unsigned volatile int*)0x4001080C)
GPIOA_CRL&=0xFF0FFFFF; //设置位清零
GPIOA_CRL|=0X00200000; //PA5推挽输出
GPIOA_ODR|=1<<5; //设置PA5初始灯为灭

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
GPIOA的基本配置如上,其它口的配置可查询手册如上即可,再加上延迟函数即可实现流水灯。

二、C语言 寄存器方式实现编程

(一)启动文件

1.启动文件简介

启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:

1、初始化堆栈指针SP=_initial_sp
2、初始化PC 指针=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界

2.启动文件的选择

ST提供的3个启动文件,分别适用于不同容量的STM32芯片。
这三个文件为:
startup_stm32f10x_ld.s
startup_stm32f10x_md.s
startup_stm32f10x_hd.s
其中,ld.s适用于小容量 产品;md.s适用于中等容量产品;hd适用于大容量产品;
这里的容量是指FLASH的大小判断方法如下:
小容量:FLASH≤32K
中容量:64K≤FLASH≤128K
大容量:256K≤FLASH
所以,大家需要根据自己所用的STM32芯片选择不同的.s文件。
此处查阅《STM32F103中文教程及参考手册》可知,C8T6的Flash容量为128K,属于中容量,因此这里采用 startup_stm32f10x_md.s作为启动文件。
在这里插入图片描述

(二)创建项目

1.打开Keil,创建项目:
在这里插入图片描述

在这里插入图片描述

2.选择STM32F103C8开发板,点击"OK":
在这里插入图片描述
3.右键点击Source Group1,然后选中Add New item to ‘Group…’,添加"C File (.c)"文件Text1:

在这里插入图片描述在这里插入图片描述

5.添加启动文件
在这里插入图片描述

(三)代码编写

//--------------APB2使能时钟寄存器------------------------
#define RCC_AP2ENR	*((unsigned volatile int*)0x40021018)
	//----------------GPIOA配置寄存器 ------------------------
#define GPIOA_CRL	*((unsigned volatile int*)0x40010800)
#define	GPIOA_ODR	*((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 ------------------------
#define GPIOB_CRH	*((unsigned volatile int*)0x40010C04)
#define	GPIOB_ODR	*((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 ------------------------
#define GPIOC_CRH	*((unsigned volatile int*)0x40011004)
#define	GPIOC_ODR	*((unsigned volatile int*)0x4001100C)
//-------------------简单的延时函数-----------------------
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<<5;		//PA5低电平
	GPIOB_ODR=0x1<<9;		//PB9高电平
	GPIOC_ODR=0x1<<14;		//PC14高电平
}
void B_LED_LIGHT(){
	GPIOA_ODR=0x1<<5;		//PA5高电平
	GPIOB_ODR=0x0<<9;		//PB9低电平
	GPIOC_ODR=0x1<<14;		//PC14高电平
}
void C_LED_LIGHT(){
	GPIOA_ODR=0x1<<5;		//PA5高电平
	GPIOB_ODR=0x1<<9;		//PB9高电平
	GPIOC_ODR=0x0<<14;		//PC14低电平	
}
//------------------------主函数--------------------------
int main()
{
	int j=100;
	RCC_AP2ENR|=1<<2;			//APB2-GPIOA外设时钟使能
	RCC_AP2ENR|=1<<3;			//APB2-GPIOB外设时钟使能	
	RCC_AP2ENR|=1<<4;			//APB2-GPIOC外设时钟使能
	//这两行代码可以合为 RCC_AP2ENR|=1<<3|1<<4;
	GPIOA_CRL&=0xFF0FFFFF;		//设置位 清零	
	GPIOA_CRL|=0X00200000;		//PA5推挽输出
	GPIOA_ODR|=1<<5;			//设置PA5初始灯为灭
	
	GPIOB_CRH&=0xFFFFFF0F;		//设置位 清零	
	GPIOB_CRH|=0x00000020;		//PB9推挽输出
	GPIOB_ODR|=0x1<<9;			//设置初始灯为灭
	
	GPIOC_CRH&=0xF0FFFFFF;		//设置位 清零
	GPIOC_CRH|=0x02000000;   	//PC14推挽输出
	GPIOC_ODR|=0x1<<14;			//设置初始灯为灭	
	while(j)
	{	
		A_LED_LIGHT();	
		Delay_ms(1000000);
		B_LED_LIGHT();
		Delay_ms(1000000);
		C_LED_LIGHT();
		Delay_ms(1000000);
	}
}
void SystemInit(){
	
}

(四)修改参数

1.生成HEX文件,运行程序时生成的相关的hex文件用于烧录到开发板上
在这里插入图片描述

2.改为相关芯片
在这里插入图片描述

(五)编译调试

1.进行编译时出现了以下错误:
在这里插入图片描述
出现该错误的原因是因为工程中包含了不止一个启动文件导致的。
这时需要在工程环境里找到Startup的驱动,将该驱动的去掉,具体步骤如下图所示:

在这里插入图片描述
修改后重新编译即可:在这里插入图片描述
2.调试时出现以下问题:
在这里插入图片描述
在这里插入图片描述
解决方法如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重新调试即可:
在这里插入图片描述

(六)波形图观察

1.在上述步骤调试过程中,点击下图图标后,点击Logic Analyzer
在这里插入图片描述

2.添加要观察的引脚,Display Type需要修改为Bit,输入引脚有三种方法,以PA5口为例:
①观测PA5口输入(PORTA&0x00000020)>>5;
②直接输入PORTA.5回车即可得到上述格式;
③输入PORTA回车后,点击Current Logic Analyzer Signals后在Shift Right中输入5。
在这里插入图片描述
3.相关设置
在这里插入图片描述

4.运行程序,观察波形图在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
引脚为低电平的灯亮,高电平的不亮。根据上面两个图可以观察到,PB9端口的灯在1.125159秒开始亮,在2.250163秒的时候熄灭,LED灯闪烁周期约为1秒。

三、安装STM32CubeMX软件+HAL库实现编程

(一)安装JRE、STM32CubeMX、HAL库

1.安装JRE
由于STM32CubeMX软件是基于JAVA环境运行的,所以需要安装JRE(Java Runtime Environment)才能使用,安装链接如下:
https://www.java.com/en/download/manual.jsp
在这里插入图片描述
点击安装:
在这里插入图片描述
安装完成点击关闭:
在这里插入图片描述
2.安装STM32CubeMX
下载地址(官网中文):
https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html#get-software
在这里插入图片描述
选择版本进行下载(需要提供邮箱账号,根据邮件的网址进行下载):

在这里插入图片描述
点击“NEXT”:
在这里插入图片描述

勾选“I accept the……”然后点击“NEXT”:
在这里插入图片描述

勾选"I have read ……",点击“NEXT”:
在这里插入图片描述

点击“NEXT”:
在这里插入图片描述

点击“Done":
在这里插入图片描述
3.安装HAL库

①打开STM32CubeMX.exe
在这里插入图片描述
②点击"Help"打开“Manage embedded software packages"(打开以后未出现安第三步骤的内容时,点击“Refresh”等待即可):
在这里插入图片描述
③根据持有的芯片类型选择对应芯片类型、对应固件类型版本,然后点击"Install"等待即可:
在这里插入图片描述

(二)完成初始化实现编程

1.在STM32CubeMX中新建项目
在这里插入图片描述
2.在Commercial Part Number中选择芯片类型,然后点击 Start Project,具体步骤如下所示:
在这里插入图片描述
3.点击System Core,进入SYS,在Debug下选择serial wire:
在这里插入图片描述
4.配置时钟,在Clock Configuration中选中PLLCLK
在这里插入图片描述
进入RCC中,在HSE中设置为Crystal/…
在这里插入图片描述
5.接下来就是点击相应的引脚设置输出寄存器,即output那一项,一共选择3个,为PA5、PB9、PC14
在这里插入图片描述
在这里插入图片描述
6.点击project manager,配置好自己的路径(注意:不要出现中文和空格否则后续步骤中将出现报错,如第七步)和项目名,然后IDE改为MDK-ARM
在这里插入图片描述
7.进入code generate界面,选择初始化.c/.h文件,然后点击generate code
在这里插入图片描述
在点击generate code后出现以下报错,原因是因为上述步骤中路径中出现了中文(空格也不行),重新修改路径即可
在这里插入图片描述
在这里插入图片描述
此处直接修改路径但未成功,因此重新操作上述步骤,最终成功,点击Open Project,然后就会进入KEIL
在这里插入图片描述
8.添加代码,代替在main.c文件中主函数内容:

SystemClock_Config();//系统时钟初始化
MX_GPIO_Init();//gpio初始化
while (1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//PA5亮灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);//PC14熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);//PA5熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//PB9亮灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);//PC14熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);//PA5熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);//PC14亮灯
HAL_Delay(1000);//延时1s
}

(三)观察GPIO端口的输出波形

1.在Target界面中选择正确的晶振大小,如果选择错误,则波形错误,时间不准确
在这里插入图片描述
2.Debug页设置:
在这里插入图片描述
3.编译
在这里插入图片描述
4.调试
在这里插入图片描述
5.观察GPIO端口的输出波形(操作可参考本文上述寄存器实现编程的波形图观察步骤)
在这里插入图片描述
引脚为低电平时灯亮,高电平时灯不亮,上图以端口PA5为例,可以看出LED灯闪烁周期为1秒

四、总结

对比寄存器方式实现流水灯和STM32CubeMX+KEIL+HAL库实现流水灯的代码编写部分,可以明显看出后者代码编写的少一点,运用后者更容易实现流水灯仿真。运用STM32CubeMX+KEIL+HAL库能自动生成代码,只需要加入主函数代码即可,能够有效减少代码编写的烦恼。

五、参考文献

http://t.csdn.cn/rBbz4
https://blog.csdn.net/weixin_43778388/article/details/122136509
https://blog.csdn.net/Hxm1998/article/details/113066766
https://blog.csdn.net/darkchipman0/article/details/115455332
http://t.csdn.cn/SLkcJ

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:50:48  更:2022-10-17 12:54:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 1:56:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计