这个下次再写
小系统板LED部分原理图如下:
上方的LED是电源指示灯,上电后会保持点亮,我们能够操作的是下面的LED。LED正极已经接3.3V,因此只需要我们控制PC13输出0V(低电平),就可以点亮LED
控制思路:
1.打开端口的时钟
2.配置端口
3.控制端口
开启时钟
在STM32中,时钟不是默认打开的,而是根据需要,打开对应的时钟。时钟由RCC寄存器控制。LED灯使用PC13,也就是GPIOC的第13个引脚,由系统结构图可知,需要打开APB2-GPIOC的时钟。
使用 APB2 外设时钟使能寄存器(RCC_APB2ENR) 「这里请顾名思义啦」
别的东西咱暂时不管,先找GPIO,在这里就是IOPCEN
所以开启操作就是:1左移4位
*(unsigned int *)0x40021018 |=(1<<4);
关于0x40021018:
RCC寄存器地址从0x40021000开始,RCC_APB2ENR的地址偏移是0x18(见上文),两数相加就可以啦
关于 *(unsigned int *):
0x40021018是一个数字,要操作这个地址,就要强制类型转换:(unsigned int *)0x40021018,现在得到了一个地址,要操作里面的内容,就需要地址操作符*:*(unsigned int *)0x40021018
关于|=:
首先想C语言的+=:a+=1 -> a=a+1;然后想位操作:1<<4 -> 10000(二进制)
所以上面的代码可以翻译为:*(unsigned int *)0x40021018 =*(unsigned int *)0x40021018 | 10000
P.S. | 表示 按位或
任何数与1取或一定是1,因此第五位,也就是IOPCEN对应的位,被置1;任何数与0取或一定是它本身,因此其他位没有被改变
配置端口:
PC13,使用第13个端口,因此使用端口配置高寄存器
「P0~P7使用端口配置低寄存器,P8~P15使用高」
每4位控制一个端口
前两位控制输入/输出模式,后两位控制输入/输出的最大速度「一般来说速度可以随机选择」
这里需要注意的是,输入还是输出,是由后两位控制的。如果后两位是00,则前两位表示输入的模式配置;当后两位不是00时,前两位表示输出的模式配置。
在这里就使用通用推挽输出模式,最大速度10MHz的配置
那么控制的这4位应该是0001
*(unsigned int *)0x40011004 &=~(1111<<(4*5));
*(unsigned int *)0x40011004 |=(1<<(4*5));
关于0x40011004:
参看上面的关于0x40021018
关于&=~:
&=是一个运算,跟之前的|=一样理解;~针对的它后面的内容
1111左移20位: 1111 0000 0000 0000 0000 0000
~表示取反:0000 1111 1111 1111 1111 1111
& 表示 按位与
任何数跟0取与都是0,因此CNF13和MODE13对应的位被置零;任何数跟1取与都是它本身,因此其他位没有被改变
控制端口
有多个方法可以控制端口,这里使用端口输出数据寄存器
要控制第13个管脚输出低电平,也就是让这个位置为0
「地址偏移里的h表示这是十六进制HEX,相当于0x0C」
*(unsigned int *)0x4001100C &=~(1<<13);
关于0x4001100C:
寄存器写着GPIOx_ODR,表示起始地址是GPIO端口的基地址,所以使用GPIOC的0x40011000+0x0C得到
#include "stm32f10x.h"
//用引号表示在当前工程目录下找,找不到再去软件根目录
//stm32f10x.h这个文件可以自己新建,里面什么都不用写
int main(void)
{
*(unsigned int *)0x40021018 |=(1<<4);
//打开gpio c端口的时钟
*(unsigned int *)0x40011004 &=~(1111<<(4*5));
*(unsigned int *)0x40011004 |=(1<<(4*5));
//配置io口为输出,10MHz
*(unsigned int *)0x4001100C &=~(1<<13);
//控制odr寄存器输出低电平
while(1)
{
//暂时不用理解这个干啥用的,不写也行
}
}
void SystemInit(void)
{
//函数体为空,骗过编译器不报错
}
附:STM32F10x参考手册:
http://「stm32F10X参考手册.pdf」,点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 链接:https://www.aliyundrive.com/s/9XdPz9Ds1gK