使用寄存器点亮LED
目标
使用寄存器点亮LED_G
原理图
由原理图可知, LED_G阳极接3V3, 阴极接PB0, 故只需将PB0输出低电平即可点亮LED_G
打开时钟
使用RCC_APB2ENR寄存器
RCC的起始地址为0x4002 1000, RCC_APB2ENR的偏移地址为0x18, 故RCC_APB2ENR的绝对地址为0x4002 1000 + 0x18 = 0x4002 1018
由于我们需使用PB0所以需要打开IO端口B时钟, 由于GPIOB在APB2上所以需要使用RCC_APB2ENR
由图可知, 需将RCC_APB2ENR的位3置1
代码如下:
*(unsigned int *)0x40021018 |= (1 << 3); // 打开时钟, 控制RCC_APB2ENR寄存器, 实现IO端口B时钟开启
/*
* Notes:
* |= (1 << 3); // 1左移3位后相或, 即可把Bit3置位
*/
配置GPIO的模式
使用GPIOx_CRL寄存器, 如下图
由于使用PB0, 所以应配置GPIOB, GPIOB的起始地址为0x4001 0C00, 如下图
CRL的偏移地址为0x00, 故GPIOB_CRL的绝对地址为0x4001 0C00 + 0x00 = 0x4001 0C00
由于使用PB0, 所以需要配置端口0, 故使用CRL寄存器而非CRH寄存器, 并配置CNF0和MODE0
将PB0口配置成输出模式, 最大速度10MHz, 通用推挽输出模式, (关于GPIO原理的讲解在下节)
故MODE0 = 01, CNF0 = 00
代码如下:
*(unsigned int *)0x40010C00 |= ((1) << (4*0)); // 配置IO口为输出, 控制CRL寄存器, 实现GPIOB端口0为10MHz的推挽输出模式
/*
* Notes:
* 分成n个一组, 对清零后的第i组设置成某二进制数, 该数对应的十进制为b
* a |= (b << n * i);
* 此时 |= ((1) << (4 * 0)); // 分成4个一组, 将第0组(即bit3~0)设置为1对应的二进制(即0001B)
*/
PB0输出低电平
使用ODR寄存器, 如下图
由于需要使PB0输出故基地址应为GPIOB的起始地址**(即0x4001 0C00)**, 如图
故GPIOB_ODR的绝对地址为0x4001 0C00 + 0x0C = 0x4001 0C0C
因要使端口0输出低电平, 故应向ODR0 写入 0
代码如下:
*(unsigned int *)0x40010C0C &= ~(1 << 0); // 控制ODR寄存器, 实现GPIOB端口0输出低电平
/*
* Notes:
* 将变量a的Bit n位清零, a &= ~(1 << n)
*/
源码
main.c文件
#include "stm32f10x.h"
int main(void)
{
*(unsigned int *)0x40021018 |= (1 << 3); // 打开时钟, 控制RCC_APB2ENR寄存器, 实现IO端口B时钟开启
/*
* RCC_APB2ENR寄存器(Address : 0x40021000(RCC) + 0x18)
* Bit3 : IOPBN : IO端口B时钟使能(I/O port B clock enable)
* 由软件置1或请0
* 0 : IO端口B时钟关闭
* 1 : IO端口B时钟开启
*/
*(unsigned int *)0x40010C00 |= ((1) << (4*0)); // 配置IO口为输出, 控制CRL寄存器, 实现GPIOB端口0为10MHz的推挽输出模式
/*
* GPIOx_CRL 端口配置低寄存器(Address : 0x40010C00(GPIO端口B) + 0x00)
* Bit32 CNF0 : 00 通用推挽输出模式
* Bit10 MODE0 : 01 输出模式, 最大速度10MHz
*
* Notes:
* 分成n个一组, 对清零后的第i组设置成某二进制数, 该数对应的十进制为b
* a |= (b << n * i);
* 此时 |= ((1) << (4 * 0)); // 分成4个一组, 将第0组(即bit3~0)设置为1对应的二进制(即0001B)
*/
*(unsigned int *)0x40010C0C &= ~(1 << 0); // 控制ODR寄存器, 实现GPIOB端口0输出低电平
/*
* GPIOx_ODR 端口输出数据寄存器(Address : 0x40010C00(GPIO端口B)+ 0x0C)
* Bit0 ODR0 : 端口输出数据
*
* Notes:
* 将变量a的Bit n清零, a &= ~(1 << n);
*
* 注 :
* 根据原理图LED_G的阳极为3V3, 阴极接PB0
*/
return 0;
}
/*
* Notes:
*
* 置位 : |=
* |= (1 << 3); // 1左移3位后相或, 把Bit3置位
*
* 复位 : &= ~
* &= ~(1 << 0); 1左移0位取反后相与, 把Bit0复位
*/
void SystemInit(void)
{
return; // 编译需要
}
stm32f10x.h文件
// 用来存放STM32寄存器映射的代码
// 暂时不写
启动文件startup_stm32f10x_hd.s
;* SRAM mounted on STM3210E-EVAL board to be used as data
;* memory (optional, to be enabled by user)
;* - Branches to __main in the C library (which eventually
;* calls main()).
;* After Reset the CortexM3 processor is in Thread mode