单片机开发第一站,LED点灯。
目标:点亮引脚PF9上的LED灯
我们在应用单片机进行各种控制时,都是利用计算机语言设置单片机的内部寄存器来完成操作的。在涉及寄存器的大部分操作中,C语言的位运算符是不可或缺的一环。
& 位逻辑与
| 位逻辑或
^ 位逻辑异或
~ 位逻辑非
以及 >> 右移和 << 左移
熟练掌握C语言中的位运算符以及进制之间的转换,对我们使用寄存器非常重要。
相关操作将以下列代码为例;
#define GPIOF_ODR(*(volatile unsigned int*)0x40021414)
基地址:STM32的每个模块都包含多个寄存器,它们的地址通常是连续的,而第一个寄存器的地址(即地址值最低的地址),就是基地址。
偏移地址:寄存器在本模块中的地址偏移量。
绝对地址:即寄存器的实际地址,相当于基地址+偏移地址。
表1-1中的GPIOF_MODER等不过是开发人员为了便于操作人为定义的符号,使这些符号能够真正的代表其对应的寄存器单元,还需要进一步处理。
(*) 0x40021414
(*) 0x40021414
指向的存储单元的数据类型:由于寄存器中存放的都是无符号整型数据,故有(unsigned int*) 0x40021414
(volatile unsigned int*) 0x40021414
*(volatile unsigned int*) 0x40021414
#define GPIOF_ODR ( *(volatile unsigned int*) 0x40021414)
GPIO端口可配置成输入、输出、复用、模数/数模转换时模拟信号输入输出等四种工作模式,其中,作输出和复用模式时又可以配置成推挽模式和开漏模式,作输入时又可以配置为浮空输入、上拉输入和下拉输入。
IO引脚的工作模式的设置通过模式选择寄存器GPIOx_MODER来完成。
每组位段的值与IO引脚的功能设置的关系如下:
设置为00时,该引脚为输入功能;
设置为01时,该引脚为输出功能;
设置为10时,该引脚为复用功能,引脚复用意思是指该引脚可以使用为其他的功能,比如做某个串口的通信引脚;
设置为11时,对于模拟/数字信号转换,该引脚为模拟信号的输入引脚,对于数字/模拟信号转换,该引脚为模拟信号的输出引脚。
要设置PF9为输出,则需要将GPIOF的MODER9[1:0]设置为01:
GPIOF_MODER &= ~(3<<18); //清除bit[19:18]
GPIOF_MODER |= (1<<18); //设置bit[19:18]的值
使用单片机为STM32F407ZGT6
1.使能端口时钟
要想使用STM32的某个引脚功能,首先要使能该引脚所在的端口的时钟。实际上,对于STM32的各个模块,在使用前都要先使能对应模块的时钟。对于GPIOF组端口,其时钟使能控制位位于寄存器 RCC_AHB1ENR中。
GPIOF组端口时钟使能由RCC_AHB1ENR第5位进行控制,可以用如下语句使能 GPIOF的时钟: RCC_AHB1ENR |= 1<<5
2.配置端口位的工作模式(通过GPIOx_MODER来完成)
3.配置电路驱动类型寄存器GPIOx_OTYPER
PF9只需要输出高低电平驱动LED,所以设置PF9的输出电路类型为推挽类型GPIOF_OTYPER &= ~( 1<<9)
由于OTYPE寄存器的默认值为0,所以如果是配置为推挽工作方式,则可以不用配置该寄存器,此时采用默认即可
4.配置引脚响应速度寄存器GPIOx_OSPEEDER
与GPIOx_MODER类似,GPIOx_OSPEEDR也是两个位控制一只引脚的响应速度。位段和配置的速度的关系为:
GPIOx_OSPEEDR为响应速度设置寄存器,和GPIOx_OTYPER都是将某引脚设置为输出时才需要配置的寄存器。
5.配置上下拉电阻设置寄存器GPIOx_PUPDR
GPIOx_PUPDR用于IO引脚内部的上拉和下拉电阻。
当某个引脚的电路的驱动方式设置为推挽方式时,由于推挽方式既可输出0又可以输出1,所以不需要配置上下拉电阻,当某个引脚的电路驱动方式设置为开漏方式时,由于该方式只能直接输出0,要想输出1必须使能上拉电阻或者在该引脚外部增加一个上拉电阻。
6.配置输出数据寄存器GPIOx_ODR
前面四个寄存器都用于设置PF9的工作属性,作输出时输出的数据位在寄存器GPIOx_ODR中设置。
由于STM32F4的每一组引脚只有16个引脚,而ODR寄存器的一位控制一只引脚,所以ODR寄存器中只有16位有效。当ODR寄存器的某位置1时对应引脚输出高电平,置0时输出低电平,所以要想点亮LED0,则只需将PF组端口的输出数据寄存器ODR的第9位置0,让PF9输出低电平即可:
GPIOF_ODR &= ~(1<<9); //PF9引脚输出低电平
GPIOF_ODR |= (1<<9); //PF9引脚输出高电平
上述所用到的寄存器,具体可查看STM32F4xx中文参考手册。
点灯具体代码如下所示:
/* GPIOF 口相关寄存器的定义 */
#define GPIOF_MODER (*(volatile unsigned *)0x40021400) //端口 x 输入输出模式配置寄存器
#define GPIOF_ODR (*(volatile unsigned *)0x40021414) //端口输出数据寄存器
/* 时钟系统相关寄存器的定义 */
#define RCC_AHB1ENR (*(volatile unsigned *)0x40023830) //外设时钟使能寄存器
/* 主函数定义 */
int main(void)
{
RCC_AHB1ENR |= (1<<5); //使能 PORTF 时钟
GPIOF_MODER &= ~(3<<(9*2)); //将配置 PF9 引脚相关位 bit18,bit19 清 0
GPIOF_MODER |= (1<<(9*2)); //将模式寄存器的 bit19、bit18 设置为 01
GPIOF_ODR |= (1<<9); //LED0 灭
while(1)
{
GPIOF_ODR &= ~(1<<9); //LED0 亮
}
}