1.寄存器点亮LED测试
(1)stm32最小系统板与stlink烧录器进行连接
其中,刚买来的板子连接烧录器现象为:一个灯常量(电源灯),另一个灯默认是闪烁状态(测试程序)
然后,在keil中配置调试器,点击魔术棒,选择debug,调试器默认是ULINK,更换为stlink调试器,然后再点击右边的设置按钮,在flash下载这一项,把reset and run 勾上(勾上后,下载程序后会立马复位并执行,否则每次下载后,还需要按一下板子上的复位按键才能执行程序),配置好调试器后,点击确定,ok。
(2)打开GPIOC的时钟(PC13置一---点亮LED灯)
首先RCC的一个寄存器,来使能GPIOc的时钟,GPIO都是APB2的外设,所以在APB2外设时钟使能寄存器RCC_APB2ENR里面配置,在参考手册中可以看到这里有个位4IOPCEN,这一位就是使能GPIOC的时钟的,这一位写1就是打开GPIOC的时钟,(这一位写1,其它无关项先给0,那整个寄存器的2进制数据换成16进制,就是4个分组,也就是0 0 0 0 0 0 1 0)。然后回到keil,在while死循环之前,写上RCC的APB2ENR寄存器等于0x0000 0010,这样就可以打开GPIOC的时钟了。如下图。
(3)配置PC13口的模式-------端口输出数据寄存器(GPIOx_ODR)
在参考手册中找到端口配置高寄存器GPIOx_CRH(因为灯接在PC13口上的,低寄存器是0-7,高寄存器是8-15,所以配置高寄存器),这个x可以是A到E的任意一个字母(看打开哪个端口),然后右边的CNF13和MODE13就是用来配置13号口的,CNF配置为通用推挽输出模式,也就是这两位为00,MODE配置为输出模式,最大速度可以给50MHz,也就是这两位为11,最后我们对照上面的寄存器,那四位为0011,其它都给配置为0,这样整个寄存器的值换算成16进制就是0030 0000,然后在keil中写上GPIOC的CRH=0x0030 0000。
(4)端口输出数据寄存器
接下来我们就可以给pc13口输出数据了,在参考手册中看到端口输出数据寄存器GPIOx_ODR,中间有一位ODR13,这一位写1,13号口就是高电平,写0就是低电平。如果写1的话,ODR的值就是0000 2000,在keil中写上GPIOC的ODR等于0x0000 2000,因为灯是低电平点亮的,所以我们给ODR等于0x0000 0000就是亮,给ODR等于0x0000 2000,就是灭灯。
(5)代码实现
#include "stm32f10x.h" // Device header-头文件
int main (void) // main函数是一个int型返回值,void参数的函数
{
RCC->APB2ENR = 0x00000010; // 打开GPIOC的时钟
GPIOC->CRH = 0x00300000; // 配置pc13的模式
GPIOC->ODR = 0x00002000; // 配置端口输出数据寄存器,pc13高电平灭灯
while(1)
{
}
}
// 最后一行必须是空行,要不然会报错
2.库函数点LED灯
库函数也是间接配置寄存器,和寄存器方式操作步骤类似。使用基于库函数的项目模板进行开发。
(1)使能时钟
使用如下函数来开启时钟,第一个参数是选择外设,第二个是选择新的状态
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);// 打开GPIOC的时钟
右键,跳转到函数定义,有函数的简介和参数说明,brief是简介,param是参数,一共两个参数。第一个参数可以是@arg里的任意一个,第二个参数为enable或者disable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);这个函数内部其实还是配置RCC-APB2ENR这个寄存器,但经过函数的包装,不需要去查手册来确定哪一位是干嘛。而且,已经使用与或来操作了,所以这个库函数是不会影响到寄存器的其它位,这就是库函数和寄存器的区别。
(2)配置端口模式
GPIO_Init有两个参数,第一个为选择哪个GPIO,第二个是参数的结构体,根据提示来配置参数即可。这里使用了结构体来配置参数,代码逻辑有些复杂;
首先去到这个函数的定义,介绍说是根据GPIO-Init结构体的参数来配置GPIO,第一个参数GPIOx,其中x可以是A到G,来选择你要配置哪个GPIO,第二个参数是GPIO-InitTypeDef的结构体
需要先定义一个结构体,在上面先把这个结构体的类型写上,然后给结构体起个名字,根据官方的推荐,最好起一个这样的名字,叫GPIO-InitStructure,然后把结构体的每个参数填上,复制粘贴结构体的名字,然后用点来引出结构体的参数(三个参数:GPIO模式、GPIO端口、GPIO速度)
右键转到Mode的定义介绍,说这个参数可以是GPIOMode-TypeDef里的一个值,可以选中GPIOMode-TypeDef这个字符,跳转到其定义,可以看到,这是个枚举类型的结构体,GPIOMode就是这里的其中一个值,然后我们选择Out-PP这一项,是通用推挽输出
然后继续看下一个参数 GPIO_InitStructure.GPIO_Pin,转到它的定义,这里下面出现了一个框,这个是说他的定义有很多个,在框中选择member这一项,双击,然后跳转的其实还是刚才那个函数说明位置,这个GPIO_Pin的说明是说这个参数在GPIO_pins_define里面定义了,选中,Ctrl+F, find next,可以看到有个宏定义的列表,选择GPIO_PIN_13,复制,然后填到第二个参数位置
结构体第三个参数也是一样,右键,跳到定义,选中,Ctrl+F,Find Next,选中50MHz的速度,复制粘贴
目前,结构体变量就有了,如下代码:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
现在,可以填这个GPIO_Init的第二个参数了,第二个参数的说明是一个指向结构体的指针,所以这里需要传递结构体的地址,复制结构体的名字,粘贴到第二个参数位置,然后前面加一个取地址的符号(&),这样,GPIO模式就配置完成了。
GPIO_Init(GPIOC, &GPIO_InitStructure);
(3)设置端口的高低电平来进行点灯。
函数GPIO_SetBits,可以把指定端口设置为高电平,也可以去看一下参数的说明,第一个是GPIOC,第二个是GPIO_Pin_13,这一句可以将PC13口置为高电平
GPIO_ResetBits(GPIOC,GPIO_Pin_13); // 设置端口的低电平
使用库函数点灯的代码为:
#include "stm32f10x.h" // Device header
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// GPIO_SetBits(GPIOC, GPIO_Pin_13);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
while (1)
{
}
}
参考学习:江协科技