目录
Step1:分析电路图,要使得PB0亮,PB0应该处于什么状态
Step2:让PB0处于低电平状态---------找到rb8.2.4 端口输出数据寄存器(GPIOx_ODR) (x=A..E) (先让端口处于能用的状态)
2:address = base address+ offset address
3. Keil5中如何置位(1)与清零(0)并且不影响其他位
Purpose: 让PB0亮起来
Reference book(rb):STM32官方手册
Step1:分析电路图,要使得PB0亮,PB0应该处于什么状态
Step2:让PB0处于低电平状态---------找到rb8.2.4 端口输出数据寄存器(GPIOx_ODR) (x=A..E) (先让端口处于能用的状态)
因为端口状态是由输出寄存器ODR控制的,所以需要去找端口ODR输出数据寄存器
接下来就去rb上在找地址
rb2.2 存储器组织
首先,我们要控制PB0,PB0是由GPIOB端口控制的,而GPIOB又是在APB2总线上
GPIOB由APB2线控制,先找到APB2线-------------->rb2.3 存储器映像
发现GPIO端口B的起始地址是0X4001 0C00
So according to the implement knowledge 2
ODR寄存器的偏移地址是0Ch
0X4001 0C00 + 0Ch = 0X4001 0C0C
Step3:控制GPIOB口处于输出状态-----------找到rb8.2.1端口配置低寄存器(GPIOx_CRL) (x=A..E) rb8.2.2 端口配置高寄存器(GPIOx_CRH) (x=A..E) (能用了之后再开始传输数据)
因为GPIO端口既可以输入也可以输出,所以调整完PB0的端口状态后需要调整端口的输入输出状态
因为4个位是一个IO口,所以是4*0,在keil5中语法应该是这样
为什么用端口配置低寄存器而不是端口配置高寄存器呢?
因为它是4bit控制一个IO口
Step4:打开GPIOB的时钟
因为每一个GPIO的端口时钟都是被关闭的,所以我们需要打开它,那我们就要去总线构架中去找时钟是由哪个总线控制的
由图可以看出,RCC是控制APB1和APB2的外设,如果要打开GPIOB就要打开APB2的时钟--------------> 查看手册rb 6.3.7 APB2 外设时钟使能寄存器(RCC_APB2ENR)
查看之后发现第三位的需要计为1才能enable
因为RCC在AHB总线上,所以
点亮LED灯完整代码
#include "stm32f10x.h"
int main(void)
{
//打开GPIOB端口时钟
*(unsigned int*)0x40021018|=(1<<3);
//控制IO口为输出
*(unsigned int*)0x40010C00 &=~((0x0F)<<(4*0)); //先把后4位清零
*(unsigned int*)0x40010C00|=((1)<<(4*0)); //再把需要的值代入进去
//控制ODR寄存器(找到PB0口并设置为低电平)
*(unsigned int*)0x40010C0C &=~(1<<0); //基地址+偏移地址 与上=取反1左移0位(注意中英文分号)
}
//置位 |= , 清零 &=~
void SystemInit(void)
{
//函数体为空,目的是为了骗过编译器不报错
}
补充知识点:
1.GPIO
GPIO:General purpose input output--------通用输入输出端口(STM32可控制的引脚)
基本功能:控制引脚输出高电平或者低电平
每一个GPIO端口都有16个IO口
eg:GPIOA(PA0,PA1,...,PA15)
GPIOB(PB0,PB1,...,PB15)
2:address = base address+ offset address
3. Keil5中如何置位(1)与清零(0)并且不影响其他位
3.1 固定语法/与或运算review
我们在编写初始化STM32代码时经常会进行把某位设置为1或者0的情况,那么如果面临有很多个位只想置其中某一位并且不影响其他位怎么办呢?
有一些固定的操作语法
置位(1) :|=
清零(0): &=~
位与运算&:要都是1结果才能是1
位或运算|:只要有一个1结果都是1
3.2 1<<0
1左移0位
3.3 Examples
注意某一位清0与连续几个位清0方法