基于STM32F103C8T8寄存器方式点亮led灯
前言
??本文详细介绍了如何使用STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED 搭建电路,使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长1秒。
一、寄存器配置介绍
??在使用寄存器之前,首先需要对寄存器进行一定的了解,以下对寄存器配置进行粗略介绍,主要是了参考了stm32f103x-参考中文手册 ??通过查询手册可知,GPIO寄存器分为了以下七种: ??本次实验采用端口配置低寄存器(GPIOx_CRL) (x=A…E);查询手册可知,这个寄存器是32位的。CRL控制着S每个IO端口(A~G)的低8位(0-7)的模式。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。CRL寄存器的偏移地址:0x00 ,那么偏移地址又是何物?在后面再做介绍;复位值为0X4444 4444 ,并不是0x0000 0000。所谓的复位值,就是指如果没有操作这个寄存器时,寄存器存放的默认值。复位值按位拆分0x4 = 0b0100,0x表示16进制,0b表示二进制,也就是默认CNF 01,MODE 00,是浮空输入;从手册中,我们还可以查询知道CRL寄存器有四种输入模式,存在着四种不同的输出模式,寄存器的MOOE与输入以及输出模式都有关系,影响着输出速度最大值; ??我们知道,寄存器顾名思义是用于存放东西,那么我们要怎么使用寄存器来存放东西呢?先从生活中举个简单的例子来认识,就比如说我们在超市存放东西我们需要知道自己存放那个柜子的编号是好多才可以进行存放,我们要在寄存器里面存放或者是要使用某个寄存器,我们需要先知道寄存器的地址在哪才可以进行操作。那么现在的问题就是如何找到寄存器的地址! ??回到偏移地址这里,偏移地址是相对于某个地址偏移之后的,那么他是怎么偏移的,这得有一个基准。查阅参考手册可知(p28页),GPIO七个不同端口的地址范围大小是好多,如GPIO端口B 的地址范围是0x4001 0C00-0x4001 0FFF ,初始地址为0x4001 0800,偏移0x00 之后的地址为以得出GPIOB->CRL 的地址(GPIOB端口的起始地址+偏移地址)为0x4001 0C08 。 ??这里我只是介绍了GPIO-CRL寄存器的相关内容,大家有兴趣的话,可以通过参考手册学习另外六种的相关内知识。
二、使用寄存器方式点亮led
1、MDK建立工程模板
??由于stm32已经提供了一个用c语言封装好的固件库,我们要实现什么功能,直接调用相应的库函数即可。要使用ST固件库,可以建立一个工程模板,方便我们调用函数。 1.1新建文件夹 ??新建总文件夹,用来存放本次工程的所有程序,然后再建CORE、HARDWARE、OBJ、FWLIB、SYSTEM、USER这六个文件夹。其中,HARDWARE文件夹是用来存放外设硬件代码,OBJ用来存放生成调试代码如hex文件,FWLIB是各种.c和.h文件,具体如下: 具体每个文件夹存放的文件如下: CORE文件夹: HARDWARE文件夹: OBJ文件夹: STM2F10x_FWLIB文件夹: SYSTEM文件夹: USER文件夹: 1.2 MDK新建工程 打开MDK软件,点击菜单栏的Project ,然后在跳出来的页面选择New uVision Project 新建一个工程,将其保存到USER文件夹;
我用的是32的最小系统开发板,此处芯片选择STM32F103C8,根据自己用的芯片进行选择; 在弹出Manage Run-time Environment窗口,点击取消 1.3 在MDK添加项目所需要的分组以及文件: 右击Target 1 ,选择Manage Project Item ; 创建Groups,修改名称,点击右边的Add File 按钮添加相应的文件; 1.4 配置options for target: 其中,select folder for objects 是选择生成的hex存放的目录 ,这里选择存放在OBJ文件夹中,create HEX file是生成hex文件,用于下载到开发板的: 添加目录: 到此,一个完整的工程就建立完成了!
2、GPIO端口配置
??GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,STM32 芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能; GPIO端口的初始化设置主要有以下三个步骤: (1)时钟配置 (2)输入输出模式设置 (3)最大速率设置 2.1 配置时钟 ??为什么配置时钟?在学习51的时候,由于我们用的都是同一时钟,在调用的时候不需要设置时钟。STM32在设计的时候为了让用户更好地掌握功耗,对每个外设的时钟都设置了开关,让用户可以精确地控制,关闭不需要的设备,达到节省供电的目的为了省电,默认的时钟都是关闭的。所以在配置STM32的任何资源前,都必须进行先时钟配置。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
2.2 初始化结构体 ??STM32的库函数中提供了一个结构体来配置GPIO端口的输入输出模式设置 、 最大速率设置等,如下
typedef struct
{
uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;
2.3 配置输入输出模式、最大输出速率 设置为通用推挽输出、最大输出速率为2M
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1 ;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
至此一个GPIOB_Pin_1配置完毕。另外两个端口的配置方法同上!
3、主要函数
led.c
#ifndef _LED_H
#define _LED_H
#include "stm32f10x.h"
void LED_R_TOGGLE(void);
void LED_G_TOGGLE(void);
void LED_Y_TOGGLE(void);
void LED_Init(void);
#endif
led.h
#include "led.h"
#include "delay.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12 ;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1 ;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_14 ;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOC,&GPIO_InitStruct);
}
void LED_R_TOGGLE(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_12) ;
delay_ms(500);
GPIO_ResetBits(GPIOA,GPIO_Pin_12);
}
void LED_G_TOGGLE(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_1);
delay_ms(500);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
}
void LED_Y_TOGGLE(void)
{
GPIO_SetBits(GPIOC, GPIO_Pin_14);
delay_ms(500);
GPIO_ResetBits(GPIOC,GPIO_Pin_14);
}
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
int main(void)
{
LED_Init();
delay_init();
while(1)
{
LED_R_TOGGLE();
delay_ms(500);
LED_G_TOGGLE();
delay_ms(500);
LED_Y_TOGGLE();
delay_ms(500);
}
}
4、仿真生成hex文件
编译调试通过生成了hex文件,其大小也显示了出来, hex文件存于OJB文件夹之下;
5、电路搭建
本次电路的搭建是在面包板上进行的,在此之前需要先学习面包板的使用,关于面包板的使用可参考:面包板使用简介 搭建好的电路如下: 这里需要注意二极管的管脚不能接反了,以及接端口的时候要仔细一点,接错了端口LED灯也亮不了。
7、串口下载程序
打开 mcuisp 软件,配置如下: ①搜索串口,设置波特率 75800(尽量不要设置的太高) ②选择要下载的HEX 文件 ③DTR 低电平复位,RTS 高电平进入 bootloader ④读器件信息 ⑤开始编程,如果出现一直连接的情况,按一下开发板的复位键即可 下载成功效果图:
注: 下载程序的时候如果出现芯片超时,一个可能是频率调高了,需要手动调低;一个可能是芯片没有查稳,用手按压一下就好了。
8、实验效果
可以看到红黄蓝三个LED灯轮流闪烁,间隔1秒。
三、总结
??经过本次寄存器方式点亮LED灯的实验,我收获颇多。整个实验下来,要注意地方有很多,尤其是需要注意GPIO端口的设置,在搭建电路的时候一定要一一对应。插芯片或者是元器件的时候一定要插稳,不然电路断路,LED灯没法亮起来了。学习嵌入式是一个漫长又艰难的过程,本次实验让我打开嵌入式新的大门。
四、参考资料
STM32F103x_中文参考手册百度网盘链接:https://pan.baidu.com/s/1g6IHWCrAfdLhutiX_KrmGQ 提取码:ji3v STM32寄存器的简介、地址查找,与直接操作寄存器 stm32f103c8t6工程模板的建立 GPIO->CRL 端口低配置寄存器
|