文章目录
以STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿黄LED 搭建电路,使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长1秒。
一、程序设计思路
1.STM32F103C8T6介绍
STM32F103C8T6是意法半导体(STMicroelectronics)推出的一款32位ARM Cortex-M3内核微控制器芯片,是STM32F10x系列的一种。其具有丰富的外设资源和高性能的处理能力,广泛应用于各种嵌入式系统中。
该芯片主要技术参数如下:
- 内核:基于ARM Cortex-M3内核,频率为72MHz。
- 存储器:64KB闪存、20KB SRAM和2KB EEPROM。
- 通信接口:包括多个UART、SPI、I2C接口以及USB2.0全速设备接口。
- 定时器:包括16位或32位定时器、看门狗定时器等。
- ADC:12位ADC,转换速率为1Msps。
- 电源管理:内置低功耗模式,并支持多种功耗模式切换。
- 封装:LQFP48封装。
引脚原理图
核心板原理图
2.GPIOx端口的各寄存器地址和详细参数
-
端口配置低寄存器(GPIOx_CRL)(x=A…E)
-
端口配置高寄存器(GPIOx_CRH)(x=A…E)
-
端口输入数据寄存器(GPIOx_IDR)(x=A…E)
-
端口输出数据寄存器(GPIOx_ODR)(x=A…E)
-
端口位设置/复位寄存器(GPIOx_BSRR)(x=A…E)
-
端口位复位寄存器(GPIOx_BRR)(x=A…E)
-
端口配置锁定寄存器(GPIOx_LCKR)(x=A…E)
3.GPIO端口初始化设置及输入输出模式
流水灯的设计思路为:控制寄存器输出1,点亮LED灯,在一段时间之后,再控制LED灯灭,然后加入循环语句,呈现出的效果,就是流水灯。
GPIO_Mode_AIN = 0x0, // 模拟输入
GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入
GPIO_Mode_IPD = 0x28, // 下拉输入
GPIO_Mode_IPU = 0x48, // 上拉输入
GPIO_Mode_Out_OD = 0x14, // 开漏输出
GPIO_Mode_Out_PP = 0x10, // 推挽输出
GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出
GPIO_Mode_AF_PP = 0x18 // 复用推挽输出
-
时钟配置
-
输入输出模式设置、最大速率设置
采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上三个引脚。其中A4属于端口配置低寄存器偏移地址为0x00,B9、C14属于端口配置高寄存器偏移地址为0x04。 -
GPIOx端口基地址
例单个GPIO端口
GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
第二步:设置GPIOA参数:输出OR输入,工作模式,端口翻转速率
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8; //设定要操作的管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
第三步:调用GPIOA口初始化函数,进行初始化。
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA
第四步:调用GPIO-SetBits函数,进行相应为的置位。
GPIO_SetBits(GPIOA,GPIO_Pin_0); //输出高
二、C语言寄存器方式编程
1.实验过程
1.1创建一个新工程 text1
1.2选择STM32F103C8
1.3创建项目出现弹窗,勾选 CORE 项,点击 OK 完成创建
1.4在界面左侧的Project栏,打开Target1,鼠标右键单击Source Group1, 选择Add New Item to Group,添加.c文件:
1.5添加启动代码
启动代码是一段和硬件相关的汇编代码
主要作用如下:
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
通过查阅资料可知,C8T6的Flash容量为128K,属于中容量,因此这里采用startup_stm32f10x_md.s作为启动文件
将启动文件拷贝到text1工程文件夹下:
回到Keil,展开Target1→双击Source Group1→设置打开文件类型为 Asm Source file→选择 startup_stm32f10x_md.s→点击 Add:
1.6点击魔法棒设置生成HEX文件
2.编写c程序
//--------------APB2使能时钟寄存器------------------------
#define RCC_APB2ENR *((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 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<10000;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(){
RCC_APB2ENR|=1<<2; //APB2-GPIOA外设时钟使能
RCC_APB2ENR|=1<<3; //APB2-GPIOB外设时钟使能
RCC_APB2ENR|=1<<4; //APB2-GPIOC外设时钟使能
//也可以写成 RCC_APB2ENR|=1<<3|1<<4;
GPIOA_CRL&=0xFFF0FFFF; //设置位清零
GPIOA_CRL|=0X00200000; //PA5推挽输出,把第23、22、21、20位变为0010
GPIOB_CRH&=0xFF0FFFFF; //设置位清零
GPIOB_CRH|=0x00000020; //PB9推挽输出,把第7、6、5、4变为0010
GPIOC_CRH&=0xFF0FFFFF; //设置位清零
GPIOC_CRH|=0x02000000; //PC14推挽输出,把第27、26、25、24变为0010
GPIOA_ODR |= (1<<5);
GPIOB_ODR |= (1<<9); //设置灯的初始状态为灭
GPIOC_ODR |= (1<<14);
while(1)
{
A_LED_LIGHT();
Delay_ms(60);
B_LED_LIGHT();
Delay_ms(60);
C_LED_LIGHT();
Delay_ms(60);
}
}
3.成功运行
4.仿真
利用Proteus8.9进行仿真,打开Proteus,在主页点击“新建工程”
在弹出的窗口中进行以下设置:建立原理图设计;不需要PCB;添加固件项目,选择STM32F103C6(也可以先不添加,在固件库中进行搜索),由于版本过低,无C8仿真芯片,故用C6进行代替。
创建完成后,按照程序中所写到的接口进行电路连接。本次实验需要用到PA5,PB9以及PC14。
仿真结果如下:
三、电路硬件连接
STM32最小系统核心板子出厂时已经焊接好了1个led灯(标注了PC13处),一般可通过此灯的点亮让编程者验证自己烧录的代码是否正常运行了
ST-Link与 C8T6 之间通过杜邦线按照下图连接
将程序烧录到 C8T6 上,烧录成功后红灯长亮
使用杜邦线将 A5、B9、C14连接到LED的负极(短脚),将开发板的3.3V输出通过杜邦线连接到LED的正极(长脚)
实验效果
烧录之后,按一下开发板上的 reset 键
四、总结
本次主要使用STM32F103C8T6核心板,通过电路搭建实现LED灯轮流闪烁。本次实验加深对GPIO寄存器的知识的理解和运用。本次实验由于初步学习GPIO的初始化以及配置,总体知识还不太熟悉导致花费了很长的实验时间。在学习和实验期间也遇到过许多困难,但经过查阅资料询问老师同学也解决了问题。之后希望通过不断学习可以提高自己的动手能力和解决问题的能力。