LED灯闪烁
将点亮LED灯的工程复制一份后,命名为LED灯闪烁实验
既然要灯闪烁,就要亮一会灭一会,那就要用到延时函数,这个延时函数实现有两种方法,第一种是自己写,第二种是使用stm32的系统滴答定时器
1.自己写
#include "delay.h"
#include "sys.h"
#include "LED.h"
/**
* @name delay
* @brief 延时函数
* @param ms:要延时的时间
* @retval None
*/
void delay(u32 ms)
{
u16 i = 0;
while(ms--)
{
for(i=0;i<5000;i++);
}
}
int main()
{
//LED初始化函数
//LED_Init_1();
//LED_Init_2();
LED_Init_3();
//LED_Init_4();
while(1)
{
GPIOA->ODR &= ~ODR1; //ODR1置0,输出低电平,LED被点亮
delay(1000);
GPIOA->BSRR |= ODR1; //ODR1置1,输出高电平,LED熄灭
delay(1000);
}
}
这里就简单写了个延时函数,虽然能实现LED灯闪烁的效果,但这个延时是让CPU在循环里执行来耗费时间,这个期间CPU不能执行其他操作,而且不像51单片机,有STC-ISP工具来生成一个比较准确的时间,这里循环耗费的时间我也不知道是多少
2.使用系统滴答定时器
使用正点原子给的延时函数和系统初始化函数,引入头文件就能使用,系统时钟设置还在学习

#include "delay.h"
#include "sys.h"
#include "LED.h"
int main()
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
//LED初始化函数
//LED_Init_1();
//LED_Init_2();
LED_Init_3();
//LED_Init_4();
while(1)
{
GPIOA->ODR &= ~ODR1; //ODR1置0,输出低电平,LED被点亮
delay_ms(1000);
GPIOA->BSRR |= ODR1; //ODR1置1,输出高电平,LED熄灭
delay_ms(1000);
}
}
使用位带操作

在Cortex-M3权威指南中,有位带的介绍和使用说明,目的是为了使引脚像51那样对某个地址直接置1或置0,就能使LED灯被熄灭或者点亮,需要根据公式来对位进行映射,目前了解知道有这个即可,平时比较少用

LED.h
LED头文件引入sys.h头文件,sys.h是正点原子提供的,映射的公式和PAout等宏定义都在这个头文件里,直接使用
#ifndef __LED_H__
#define __LED_H__
#include "sys.h"
//位带操作宏定义,PAout的定义在sys.h中
#define LED PAout(1)
//宏定义,LED_Init_3,LED_Init_4
#define IOPAEN 0x01<<2
#define CNF1_AND_MODE1 ((u32)0x0F<<4)
#define OUT_MODE_PP ((u32)0x03<<4)
#define ODR1 ((u16)0x01<<1)
#define BSRR_BR1 ((u32)0x01<<17)
#define BRR_BR1 ((u16)0x01<<1)
void LED_Init_1(void);
void LED_Init_2(void);
void LED_Init_3(void);
void LED_Init_4(void);
#endif
main.c
在主函数中,调用自己定义的LED宏名,对PA1进行赋值操作,实现LED灯闪烁
#include "delay.h"
#include "sys.h"
#include "LED.h"
int main()
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
//LED初始化函数
//LED_Init_1();
//LED_Init_2();
LED_Init_3();
//LED_Init_4();
while(1)
{
LED = 0; //PA1输出低电平,LED灯亮
delay_ms(1000);
LED = 1; //PA1输出高电平,LED灯灭
delay_ms(1000);
}
}
1980

被折叠的 条评论
为什么被折叠?



