先复习:
在keil5上创建好工程模板后,创建下列三个文件(记得添加进项目中)
具体代码怎么写?需要阅读相关原理图、文档和手册。
//LED寄存器开发main.c
#include "stm32f4xx.h"
#include "led.h"
//粗延时
void delayms(int n)
{
int i, j;
for(i=0; i<n; i++)
for(j=0; j<30000; j++);
}
//这是一个主函数
int main(void)
{
Led_Init();
while(1)
{
GPIOF_BSRR |= (1<<25); //25位置1 ODR输出0 LED0灯亮
delayms(1000);
GPIOF_BSRR |= (1<<9); //9位置1 ODR输出1 LED0灯灭
delayms(1000);
}
return 0;
}
//led.h
#ifndef __LED_H
#define __LED_H
#include "stm32f4xx.h"
#define RCC_AHB1ENR *((volatile unsigned int *)(0x40023800 + 0x30)) //数据强制转化为地址,再解引用访问地址空间
#define GPIOF_MODER *((volatile unsigned int *)(0x40021400 + 0x00)) //数据强制转化为地址,再解引用访问地址空间
#define GPIOF_OTYPER *((volatile unsigned int *)(0x40021400 + 0x04)) //数据强制转化为地址,再解引用访问地址空间
#define GPIOF_OSPEEDR *((volatile unsigned int *)(0x40021400 + 0x08)) //数据强制转化为地址,再解引用访问地址空间
#define GPIOF_PUPDR *((volatile unsigned int *)(0x40021400 + 0x0C)) //数据强制转化为地址,再解引用访问地址空间
#define GPIOF_BSRR *((volatile unsigned int *)(0x40021400 + 0x18)) //数据强制转化为地址,再解引用访问地址空间
void Led_Init(void);
#endif
//led.c
#include "led.h"
void Led_Init(void)
{
//打开F组时钟
RCC_AHB1ENR |= (1<<5);
//设置PF9为输出模式 01
GPIOF_MODER &= ~(1<<19); //对位清0
GPIOF_MODER |= (1<<18); //对位置1
//设置PF9为输出推挽
GPIOF_OTYPER &= ~(1<<9); //对位清0
//设置输出速度为50MHZ 10
GPIOF_OSPEEDR |= (1<<19); //对位置1
GPIOF_OSPEEDR &= ~(1<<18); //对位清0
//设置为上拉 01
GPIOF_PUPDR &= ~(1<<19); //对位清0
GPIOF_PUPDR |= (1<<18); //对位置1
}
一、理解LED电路原理
LED0连接在PF9引脚
当PF9输出高电平(1),灯灭
当PF9输出低电平(0),灯亮
小结论:
如果引脚电平由程序员来改,则为输出
如果引脚电平由外部电路来改变,则为输入
二、打开GPIO F组时钟(系统默认不打开外设时钟,为了功耗)
//打开F组时钟
//为什么是F组?因为LED0连接在PF9引脚
RCC_AHB1ENR |= (1<<5);
(这里2应该是AHB1)
三、设置PF9的模式 输出类型 上下拉电阻 及速度
//设置PF9为输出模式 01
GPIOF_MODER &= ~(1<<19); //对位清0
GPIOF_MODER |= (1<<18); //对位置1
//设置PF9为输出推挽
GPIOF_OTYPER &= ~(1<<9); //对位清0
//设置输出速度为50MHZ 10
GPIOF_OSPEEDR |= (1<<19); //对位置1
GPIOF_OSPEEDR &= ~(1<<18); //对位清0
//设置为上拉 01
GPIOF_PUPDR &= ~(1<<19); //对位清0
GPIOF_PUPDR |= (1<<18); //对位置1
四、通过置位/复位寄存器控制数据输出,从而控制LED0亮与灭
GPIOF_BSRR |= (1<<25); //25位置1 ODR输出0 LED0灯亮
delayms(1000);
GPIOF_BSRR |= (1<<9); //9位置1 ODR输出1 LED0灯灭
delayms(1000);