昨天在CoIDE环境下使用固件库写的程序,今天想用一下操作寄存器的方法,跟51、msp430单片机一样配置寄存器。
STM32F0308开发板-上LED的电路图:
从图中可以看出两个发光二极管负极接地,那么要点亮LED,只需要将STM32的PC8、PC9的相应引脚上输出高电平。
那怎么设置才能输出高电平呢,先来看一下数据手册:第8章General-purpose I/Os (GPIO))
GPIOx_MODER:端口模式选择寄存器。有4中模式:输入模式、通用输出模式、复用功能模式、模拟输入模式。
由Bits 2y+1:2yMODERy[1:0]:Port x configuration bits (y = 0..15)可知,y的取值范围为0~15,正好16个引脚,每个引脚由两个位控制(2y+1:2y)。
GPIOx_OTYPER:端口输出类型寄存器。有两种类型,Output push-pull(推挽式输出),Output open-drain(开漏输出)。
关于两者的区别这里就不详细解释了,网上也有详细的说明。
GPIOx_OSPEEDR:端口输出速度寄存器。个人理解为引脚响应的速度。有低速、中速、高速三种速度。
GPIOx_ODR:端口输出数据寄存器。顾名思义,输出1即高电平。
GPIOx_BSRR:端口置位/复位寄存器。低16位是置位寄存器,高16位是复位寄存器。
这里需要注意的是,寄存器写1有效。
其他的寄存器暂时用不到,就不介绍了。
下面开始编写用寄存器控制LED的程序了!
在CoIDE下步骤如下:
程序代码:
- #define GPIOC_MODER (*(volatile unsigned int *)0x48000800) //端口配置模式寄存器
- #define GPIOC_OTYPER (*(volatile unsigned int *)0x48000804) //端口配置类型寄存器
- #define GPIOC_OSPEEDR (*(volatile unsigned int *)0x48000808) //端口配置速度寄存器
- #define GPIOC_ODR (*(volatile unsigned int *)0x48000814) //端口配置输出数据寄存器
- #define RCC_AHBENR (*(volatile unsigned int *)0x40021014) // 端口时钟寄存器
- /* 简单延时函数*/
- void delay(void)
- {
- unsigned int i;
- for(i=0;i<500000;i++);
- }
- /* 主函数*/
- int main()
- {
- int i;
- /*打开 GPIOC 的时钟*/
- RCC_AHBENR |= 1<<19;
- /* 配置PC8,PC9为输出模式*/
- GPIOC_MODER = (GPIOC_MODER & 0xfff0ffff) | 0xfff5ffff;
- /* 配置PC8,PC9速度为 高速*/
- GPIOC_OSPEEDR = 0xffffffff;
- /* 配置 PC8,PC9 为通用推挽模式*/
- GPIOC_OTYPER = (GPIOC_OTYPER & 0xf0ff ) | 0xfcff;
- while(1)
- {
- for(i=8;i<=9;i++)
- {
- /* 在 PC8,PC9引脚轮流输出高电平 */
- GPIOC_ODR = (GPIOC_ODR & 0xf0ff) | (1<
- delay();
- }
- }
- }
复制代码
程序中的宏定义怎么弄呢?其实很简单,查看数据手册:
首先要明确GPIOC的时钟总线在哪儿:
GPIOC的起始地址:0x48000800
再看数据手册的第8章相关寄存器的详细部分:拿寄存器GPIOx_OSPEEDR举例
途中偏移地址为0x08,那么我们可以定宏:
#define GPIOC_OSPEEDR (*(volatile unsigned int *)0x48000800 + 0x08)
至于为什么要这样定义,看C语言吧。