以 STM32最小系统核心板STM32F103C8T6+面板板+3只红绿蓝LED 搭建电路,使用GPIOA-5、GPIOB-9、GPIOC-14这3个端口控制LED灯,轮流闪烁,间隔时长1秒。 1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数; 2)分别用汇编语言,C语言编程实现。
1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;
2)分别用汇编语言,C语言编程实现。)
一、工程文件模板的建立
新建工程Light2文件,工程名为light,因为之后实验采用C8T6板,因此这里选择STM32F103C8 之后弹出的添加库文件窗口Manage Run-Time Environment,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不做介绍。选择Cancel即可。
1、选择STM32F103C8开发板 2、创建项目出现弹窗,不勾选setgep,只勾选core项 3、添加驱动文件 到这里,我们还只是建了一个框架,还需要添加启动代码,以及.c 文件等。 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
本次选用芯片stm32c8t6其Flash容量为128k,属于中容量,因此我在这里采用startup_stm32f10x_md.s作为启动文件。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/321ed206ee924bc7bb7140fe27b5b4cd.png拷贝到工程文件夹中
右击文件夹,选择Add Existing Files to Group Source Group 1
二、使用寄存器点亮LED灯——编写代码
1、GPIO端口初始化
1.1 时钟配置
打开之前建立的工程模板 注意项目结构,使用的引脚是PA5,PB9,PC14,即GPIOA,B,C三个端口。该三个端口都属于APB2总线 1、找到时钟使能寄存器映射基地址 找到端口偏移地址以及对应端口所在位置 3、使能对应端口时钟
#define RCC_APB2ENR *((unsigned volatile int*)0x40021018)
RCC_APB2ENR|=1<<2|1<<3|1<<4;
2.2输入输出模式和输出速率设置
本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A5、B9、C14三个引脚。其中A5、B9属于端口配置低寄存器偏移地址为0x00,C14属于端口配置高寄存器偏移地址为0x04。 1、找到GPIOx端口基地址 2、配置对应引脚寄存器,基地址+偏移量
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
3、设置输出模式为推挽输出,输出速度为2Mhz
GPIOA_CRL&=0xFFF0FFFF;
GPIOA_CRL|=0x00020000;
GPIOB_CRL&=0xFF0FFFFF;
GPIOB_CRL|=0x00200000;
GPIOC_CRH&=0xFF0FFFFF;
GPIOC_CRH|=0x00200000;
2、代码实现
2.1流水灯原理
本次实验采用三个灯实现,亮灯状态用1表示,灭灯状态用0表示。 初始状态为0 0 0, 状态一为1 0 0 状态二为0 1 0 状态三为0 0 1 状态三结束后继续进入状态一,一直循环达到流水灯效果。
2.2C语言实现
#include "stm32f10x.h"
#define RCC_APB2ENR *((unsigned volatile int*)0x40021018)
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ODR *((unsigned volatile int*)0x4001080C)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ODR *((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ODR *((unsigned volatile int*)0x4001100C)
void Delay()
{
u32 i=0;
for(;i<5000000;i++);
}
int main(void)
{
RCC_APB2ENR|=1<<2|1<<3|1<<4;
GPIOA_CRL&=0xFFF0FFFF;
GPIOA_CRL|=0x00020000;
GPIOA_ODR&=~(1<<5);
GPIOB_CRL&=0xFF0FFFFF;
GPIOB_CRL|=0x00200000;
GPIOB_ODR&=~(1<<9);
GPIOC_CRH&=0xF0FFFFFF;
GPIOC_CRH|=0x02000000;
GPIOC_ODR&=~(1<<14);
while(1){
GPIOA_ODR|=1<<5;
Delay();
GPIOA_ODR&=~(1<<5);
GPIOB_ODR|=1<<9;
Delay();
GPIOB_ODR&=~(1<<9);
GPIOC_ODR|=1<<14;
Delay();
GPIOC_ODR&=~(1<<14);
}
}
3、观察GPIO端口的输出波形
具体操作看我另一篇博客 http://t.csdn.cn/J7DsH
观察波形
三、总结
1、学习和理解STM32F103系列芯片的地址映射和寄存器映射原理 2、了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)
|