STM32最小系统核心板(STM32F103C8T6)实现流水灯
文章目录
- 一.题目要求
- 二.STM32简介
- 三.GPIO初始化
- 1.输入输出模式和输出速率设置
- (1)找到GPIOA、GPIOB、GPIOC的地址
- (2)配置对应引脚寄存器,基地址+偏移量
- (3)设置输出模式为推挽输出,输出速度为2Mhz
- 2.时钟地址
- 三.工程文件模板的建立
- 1.所需文件
- 2.创建工程
- 3.启动代码
- 3.1启动代码介绍
- 3.2使用启动代码
- 3.3完善项目创建
- 四.代码的书写
- 1.led.c
- 2.led.h
- 3.test.c
- 五.调试问题
- 六.总结
一.题目要求
假设你手中已有 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒:
1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数
2)用C语言 寄存器方式编程实现
二.STM32简介
关于单片机外设的功能都是完全不同的,但初始化都是大同小异的,点灯是所有学单片机的人都应该学会的第一项技能,这样子才算入门。
51单片机的点灯是,通过控制寄存器将片外引脚(我们称之为IO口)拉低拉高,输出高低电平,以控制LED亮灭,过程为:
单片机给指令->控制寄存器->给IO口电平->控制LED亮灭
stm32的点灯则是,通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,让其实现各种功能,过程为:
CPU给指令->GPIO收到指令->配置内部寄存器->配置IO口模式(注意是模式)->控制LED亮灭
STM32
STM32,从字面上来理解,ST 是意法半导体,M 是 Microelectronics 的缩写,32 表示32 位,合起来理解STM32就是指 ST 公司开发的 32 位微控制器。
STM32 属于一个微控制器,自带了各种常用通信接口,比如 USART、I2C、SPI 等,可连接非常多的传感器,可以控制很多的设备。现实生活中,我们接触到的很多电器产品都有 STM32 的身影,比如智能手环,微型四轴飞行器,平衡车、移动 POST 机,智能电饭锅,3D 打印机等等。
STM32 有很多系列,可以满足市场的各种需求,从内核上分有 Cortex-M0、M3、M4和 M7 这几种,每个内核又大致分为主流、高性能和低功耗。
单纯从学习的角度出发,可以选择 F1和 F4,F1代表了基础型,基于 Cortex-M3内核,主频为 72MHZ,F4 代表了高性能,基于 Cortex-M4 内核,主频 180M。
三.GPIO初始化
1.输入输出模式和输出速率设置
首先需要知道的是,STM32中对于GPIO口的操作,无非就是操作下面的寄存器而已,所谓的标准库也好,HAL库也好,它们都只是对操作寄存器的过程进行了封装,目的是为了减轻编程时的工作负担:
两个32位的配置寄存器:GPIOx_CRL、GPIOx_CRH两个32位数据寄存器:GPIOx_IDR、GPIOx_ODR一个32位的置位/复位寄存器:GPIOx_BSRR一个16位复位寄存器:GPIOx_BRR一个32位锁定寄存器:GPIOx_LCKR
- 本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A5、B9、C14三个引脚。其中A5属于端口配置低寄存器偏移地址为0x00,B9、C13属于端口配置高寄存器偏移地址为0x04。
(1)找到GPIOA、GPIOB、GPIOC的地址
查询数据手册找到GPIOA、GPIOB、GPIOC的地址,可发现本次实验采用GPIOA、B、C三个端口,该三个端口都属于APB2总线
(2)配置对应引脚寄存器,基地址+偏移量
故而配置如下
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C04)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
(3)设置输出模式为推挽输出,输出速度为2Mhz
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; //设置初始灯为灭
例:将GPIOB9配置成推挽输出模式,且最大速度为2MHz
首先,其为GPIOB9端口,其属于端口配置高寄存器模块,则由图8.2.2可知,CNF9和MODE9位为0,其余位为F,即:GPIOB_CRH&=0xFFFFFF0F;又因其为推挽输出模式,且最大速度为2MHz,所以4位寄存器的配置就是CNF9【00】MODE9【10】,0010换成十进制数就是2,即:GPIOB_CRH|=0x00000020
2.时钟地址
时钟控制名字叫做RCC,属于AHB总线。
查询数据手册可发现,外设时钟使能寄存器,设偏移量为0x18
,起始地址0x4002 1000
,该寄存器地址为0x4002 1018
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018) #时钟使能寄存器
手册RCC_APB2ENR,位3是IOPBEN,名字是IO端口B时钟使能,就是我们想要的。把RCC_APB2ENR的位3赋值为1,就是开启GPIOB时钟
RCC->APB2ENR|=1<<2; //APB2-GPIOA外设时钟使能RCC->APB2ENR|=1<<3; //APB2-GPIOB外设时钟使能 RCC->APB2ENR|=1<<4; //APB2-GPIOC外设时钟使能//这两行代码可以合为 RCC_APB2ENR|=1<<3|1<<4;
- 关于STM32F103系列芯片的地址映射和寄存器映射原理,GPIO端口的初始化设置步骤可以参考笔者的上一篇博客:地址和寄存器映射原理讲解与GPIO端口的初始化设置
三.工程文件模板的建立
1.所需文件
- 建立模板要用到的SYSTEM文件及启动文件,包括点灯时需要的C8T6数据手册,以及烧录用到的FlyMcu,网盘自取。
链接:https://pan.baidu.com/s/1jxbVCa_filfR9ZRlmP6SMw
提取码:k4lv
2.创建工程
新建工程work4
文件,工程名为led
,因为之后实验采用C8T6板,因此这里选择STM32F103C8
之后弹出的添加库文件窗口Manage Run-Time Environment
,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不做介绍。选择Cancel即可。至此为止我们还只是建了一个框架,还需要添加启动代码,以及.c 文件等。
3.启动代码
3.1启动代码介绍
启动代码是一段和硬件相关的汇编代码
主要作用
如下:
1、堆栈(SP)的初始化
2、初始化程序计数器(PC)
3、设置向量表异常事件的入口地址
4、调用 main 函数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
查阅C8T8的数据手册,可知C8T6的Flash容量为128K,属于中容量,因此这里采用startup_stm32f10x_md.s
作为启动文件
3.2使用启动代码
STM32F103C8T6核心板启动文件下载链接:
链接:https://pan.baidu.com/s/1Elgc4nvxXjiHLSZ2nXnSCQ
提取码:bmba将启动文件拷贝到work4工程文件夹下:
我们找到
Target1→Source Group1
→双击→设置打开文件类型为Asm Source file
→选择startup_stm32f10x_hd.s
→点击Add
,如下图所示
下列两个文件Listings
和Objects
,是 KEIL 自行创建的,用于保存编译过程中生成的一些文件。而后我们创建
USER文件夹
存放存放启动文件(startup_stm32f10x_md.s)、工程文件(test.uvprojx)等不可缺少的文件;创建OBJ文件夹
存放这些编译过程中产生的中间文件(包括.hex文件也将存放在这个文件夹里面)。然后我们将把Listings 和Objects 文件夹里面的东西全部移到 OBJ 文件夹下。我们将系统代码 copy 过来放在我们的
work4
里面(即SYSTEM
文件夹,该文件夹由 ALIENTEK 提供,这些代码在任何 STM32F10x 的芯片上都是通用的,可以用于快速构建自己的工程。注意是寄存器版本
3.3完善项目创建
(1)在USER
文件夹下面找到 led
,打开它,然后在 Target
目录树上点击右键→Manage Project Items
,弹出对话框。
(2)在上面对话框的中间栏,点新建
按钮(也可以通过双击下面的空白处实现),新建 USER
和 SYSTEM
两个组。然后点击 Add Files
按钮,把 SYSTEM 文件夹三个子文件夹里面的:sys.c、usart.c、delay.c
加入到 SYSTEM 组中。然后OK,返回界面
(3)点击新建文件,新建test.c
文件,保存在USER
中,然后双击USER
,会弹出加载文件的对话框,此时我们在 USER 目录下选择test.c
文件,加入到 USER 组下。
(4)设置路径,点击魔法棒,弹出 Options for Target’Target 1’
对话框,选择 Output 选项卡
→选中 Create Hex File
(用于生成 Hex 文件,后面会用到)→点击 Select Folder for Objects
→找到 OBJ 文件夹→点击 OK
(5)再设置 Listings
文件路径,在上述基础上,打开 Listing
选项卡→点击 Select Folder for Listings
→找到 OBJ
文件夹→点击 OK
(6)最后选择c/c++
,在Define处输入:STM32F10X_MD
,然后点击include Patha添加sys、delay、usart的include路径,如图所示
- 注意!我们必须根据所用 STM32F1 型号的容量,来输入相关宏定义,对于STM32F103 系列芯片,
设置原则
如下:
16KB≤FLASH≤32KB 选择:STM32F10X_LD 64KB≤FLASH≤128KB 选择:STM32F10X_MD
256KB≤FLASH≤512KB 选择:STM32F10X_HD
至此我们的工程就完全建立好啦,可以开始写入代码了。
四.代码的书写
(1)在wor4
文件夹下新建一个HARDWARE
文件夹,用来存储以后与硬件相关的代码。
(2)打开程序,新建两个文件led.c led.h
,保存在HARDWARE中
(3)将文件添加进入工程,步骤与上述操作一致。
(4)点击魔法棒按照之前步骤,将HARDWARE路径加入,以免报错
1.led.c
#include "led.h"
void LED_Init(void)
{RCC->APB2ENR|=1<<2; //APB2-GPIOA外设时钟使能RCC->APB2ENR|=1<<3; //APB2-GPIOB外设时钟使能 RCC->APB2ENR|=1<<4; //APB2-GPIOC外设时钟使能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; //设置初始灯为灭 }
2.led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//--------------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 LED_Init(void); //初始化 #endif
3.test.c
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
void A_light()
{GPIOA_ODR=0x0<<5; //PA5低电平GPIOB_ODR=0x1<<9; //PB9高电平GPIOC_ODR=0x1<<14; //PC14高电平
}
void B_light()
{GPIOA_ODR=0x1<<5; //PA5低电平GPIOB_ODR=0x0<<9; //PB9高电平GPIOC_ODR=0x1<<14; //PC14高电平
}
void C_light()
{GPIOA_ODR=0x1<<5; //PA5低电平GPIOB_ODR=0x1<<9; //PB9高电平GPIOC_ODR=0x0<<14; //PC14高电平
}
int main(void)
{ Stm32_Clock_Init(9);//系统时钟设置delay_init(72); //延时初始化LED_Init(); //初始化与LED连接的硬件接口while(1){A_light();delay_ms(1000);B_light();delay_ms(1000);C_light();delay_ms(1000);}
}
点击编译发现无错误无警告,成功啦!
五.调试问题
当我们点击调试按键时会出现如下警告
我们需要先点击魔法棒
找到Debug
,勾选Use Simulator
(因为我们的电脑没有连接设备);在Utilities
中取消勾选Use Debug Driver
,点击Settings
,选择Reset and Run
就可以正常调试啦。
六.总结
本文带领大家熟悉了一遍寄存器方式编程的基本操作,完成了流水灯实验,笔者在学习期间也遇到过许多困难,但经过查阅资料询问老师同学也解决了问题,受益匪浅,各位在学习途中也不要急于求成要一步一步地来。最后由于笔者暂时还没有面包板故无法进行实物的演示。
参考
1.https://blog.csdn.net/qq_47281915/article/details/120812867
2.https://blog.csdn.net/weixin_47554309/article/details/120810913
3.https://blog.csdn.net/qq_46467126/article/details/120791793?spm=1001.2014.3001.5502
4.https://blog.csdn.net/qq_53112972/article/details/127153401?spm=1001.2014.3001.5502
STM32最小系统核心板(STM32F103C8T6)实现流水灯相关推荐
- C语言使用stm32最小开发板点亮流水灯
目录 一.实验准备 二.寻找地址 三.编写程序 1.打开keil5创建一个工程选择芯片(我这里用的stm32F103c8) 2.设置芯片参数 3.添加函数文件 4.编写代码 5.编译,生成hex文件 ...
- 以TM32最小系统核心板(STM32F103C8T6)为主,实现led流水灯
文章目录 题目要求 一.GPIOx端口的各寄存器地址和详细参数 二.用C语言 寄存器方式编程实现 1.新建文件 2.代码写入 2.1 启动代码 2.1.1 介绍启动代码 2.1.2 添加启动代码 2. ...
- stm32核心板可以点亮灯吗_利用STM32F103C8T6最小系统板点亮流水灯
后台网友建议制作一个流水灯,正好发现自己有之前购买的STM32F103C8T6核心板,今天搭建一个流水灯,正好学习一下STM32 GPIO输出如何实现,将来驱动蜂鸣器.继电器等都会使用的. 流水灯相当 ...
- 【stm32】如何把原子哥的代码移植到最小系统板stm32f103c8t6 以跑马灯实验为例
[stm32]如何把原子哥的代码移植到最小系统板stm32f103c8t6 以跑马灯实验为例 外部硬件: stm32仿真编程器 (仿真编制器自己在网上买,不确定买哪个的可以就买我这个,图片上有牌子,自 ...
- 【2022河南省电赛】SWM181最小系统核心板-开源
SWM181CBT6核心板 写在前面 在2022"数智中原"河南省大学生电子设计大赛的来临之际,河南省电赛组委会也向大家公开部分竞赛信息.主控(MCU)是体现一个系统性能的重要部分 ...
- PCB设计之STM32最小系统板
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 PCB设计之STM32最小系统板 文章目录 文章目录 一.AD版本 二.PCB之原理图绘制步骤 1.STM32F103C8T6最小系统 ...
- 从0到1入门STM32最小系统板(0)——前言
从0到1入门STM32最小系统板--前言 这个系列的文章将从0开始制作一个STM32最小系统板,大概分为如下几个部分: 元件简述: 原理图绘制: PCB布局: 打板焊接: 本篇文章主要讲解一下最小系统 ...
- 从0到1入门STM32最小系统板(2-1)——绘制原理图之器件选型
从0到1入门STM32最小系统板--绘制原理图之器件选型 本次我们选择的芯片是STM32F446RET6,使用立创EDA进行原理图绘制. 文章目录 从0到1入门STM32最小系统板--绘制原理图之器件 ...
- STM32F103C8T6实现流水灯
一.实验原理 1.STM32F103C8T6简介 STM32F103C8T6是一款由意法半导体公司(ST)推出的基于Cortex-M3内核的32位微控制器,硬件采用LQFP48封装,属于ST公司微控制 ...
最新文章
- Dispatch_queue
- 修改mysql数据库编码
- Python 技巧篇 - 英文单词首字母大小写转换功能实例演示,字符串切片实现
- SpringBoot中使用thymeleaf时ajax请求不能回显消息
- mysql动态扩展_动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis
- alinq mysql_ALinq 使用教程(移植 Linq to SQL 的利器)
- 各大公司应聘电子类题目精选
- 极其良心的设计导航网站
- CAP 定理 —— 可用性 (Availability) 和分区容忍 (Partition tolerance)
- 从0开始构建自己的前端知识体系-JS-事件-键盘事件总结
- php跳转qq临时会话,怎样做出在网页中弹出QQ临时对话框
- vue||简易版音乐播放器
- 计算机网络实验——使用网络协议分析仪Wireshark
- cpu性能测试软件 国际象棋,Fritz Chess Benchmark
- 目前三款国内最靠谱最良心的杀毒软件推荐 | 国内杀毒软件哪个好用?威航软件园诚意推荐这三个
- 11 风险管理 人人都是项目经理系列(第11/13篇)
- 计算机二级是wpsoffice高级应用吗,考计算机二级ms office高级应用但是自己电脑上office软件都是wps 这和word ppt excel 软件有区别吗...
- 秦曾昌人工智能课程---6、Decision Tree Learning
- 圣诞节要到了,如何制作自己的一个给头像戴帽子的小程序,请看这
- SpringBoot启动代表出现Process finished with exit code 0