相信不少初学stm32的小白和我一样,不知道如何去编写stm32流水灯,去网上找资料却无奈看不懂,接下来我会用一系列通俗易懂的语言来给大家讲解如何去编写流水灯。
首先让我们先打开比赛给的资源包中的液晶驱动程序历程,并用keil4或keil5打开Project中的程序,为了使代码更加简洁,我们可以把源程序中的lcd程序删掉,至于为什么要直接用是因为这样我们不用自己配置程序环境,省了很多事,在这过程中我们首先创建一个led.h和led.c,并分别把这两个放在Inc(里面全为程序中.h)Sre(里面全为程序中.c),好都搞好了我们接下来写程序。
一.led.h文件
1.首先是
#include
它是整个程序运行的库,我们编写的代码基本上是在他的基础上实现的;
然后为了方便以后的调用,我们对led进行宏定义,我们先看一下led在原理图中的位置吧
它的引脚在stm32f10x_giao.h的127行左右可以找到,好了,不啰嗦了,上代码
#define led1 GPIO_Pin_8
#define led2 GPIO_Pin_9
#define led3 GPIO_Pin_10
#define led4 GPIO_Pin_11
#define led5 GPIO_Pin_12
#define led6 GPIO_Pin_13
#define led7 GPIO_Pin_14
#define led8 GPIO_Pin_15
#define ledall GPIO_Pin_All
2.声明led.c所用函数
void led_init(void);
void led_display(unsigned int led,unsigned char state);
二.led.c文件
我们先引用led.h
然后在对led初始化
1.对GPIO进行初始化
GPIO_InitTypeDef GPIO_InitStruct;
2.使能GPIOB和GPIOC的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
如何使用请参考stm32f10x_giao.c中第108行STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c的1090行左右
3配置PC8-PC15结构体
这里有四个步骤配置引脚-速度-输出模式-初始化GPIO,具体原理可以参开其他博主的博客,因为我也没搞太懂。不过我感觉stm32就是不断调用函数的过程,大家只需要记住在哪找就可以了,
在stm32f10x_giao.h的第58-86可以看到速度和模式,127-143为引脚,然后大家接下来就可以配置了
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_All;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOC,&GPIO_InitStruct);
选择全部引脚省去一个一个的麻烦,而使用最高的速度可以使程序运行更流畅,接下来是推挽输出,最后初始化GPIOC,PD2结构体的配置也是一样的,不同的地方就是引脚
GPIO_InitStruct.GPIO_Pin=GPIO_2;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOC,&GPIO_InitStruct);
4.使灯全部关闭
我们注意观察原理图,发现led末端全部接在高电平上的,所以只能输入端为低电平led灯才会亮,
根据stm32f10x_giao.c可知GPIO_SetBits()作用为拉高电平,GPIO_ResetBits()作用为拉底电平,知道了这点,我们就可以编写我们的程序
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_SetBits(GPIOC,ledall);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
接下来我们就可以编写使led灯亮灭的程序啦,是不是很期待呢,不说了,上代码
void led_display(unsigned int led,unsigned char state)
{
if(state==0)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOC,led);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else if(state==1)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_SetBits(GPIOC,led);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
(说明一下led表示led灯,stae表示状态0:亮;1:灭)
呼~终于led.c程序编写完了,开心
三.main.c文件
唔~哈哈哈,此时已经是好几天后了,接下来就是重头戏啦,打起精神来~
在写程序之前我们应先把 stm32f10x_it.c中137行左右的滴答定时器函数给删去,写在主程序里,因为这样比较容易调用,滴答定时器是本流水灯的关键。
同样,我们首先引用led头文件
#include
然后在定义滴答定时器数据类型
unsigned long TimingDelay=0;
由于习惯,我都是先写主函数int mian(),对于什么时候写int main()或者void main我又不是很清楚,大家可以参考
int main() 主函数返回的值是0,即 return 0;这个返回值不是显示在屏幕上的,而是函数的一部分。
void main是写入,int main是定义读取你要求的东西。
void的意思是没有返回值,int的意思是返回一个int类型的数
具体代码如下
int main(void)
{
SysTick_Config(72000); //设置系统时钟为72MHZ
LED_Init();//LED初始化
while(1)
{
LED_show(led6,0);
}
}
对于while()里面的可写可不写,如果你想让其中一个LED灯一直亮着,就写上
接下里就是滴答定时器的函数,对于如何用滴答定时器实现流水灯记得当时我想了半天,因为当时C语言功底还不是很扎实(当然现在也不是很扎实),最后抱着试一试的态度套用了if()else if()的逻辑,成功!以下是我写的代码
void SysTick_Handler(void)
{
TimingDelay++; //开始计时
if(TimingDelay<200)//0~200ms
{
LED_show(led2,0);//LED2亮
}
else if(TimingDelay<400)//200~400ms
{
LED_show(led2,1);//LED2灭
LED_show(led4,0);//LED3亮
}
else if(TimingDelay<600)
{
LED_show(led4,1);
LED_show(led6,0);
}
else if(TimingDelay<800)
{
LED_show(led6,1);
LED_show(led8,0);
}
else if(TimingDelay<1000)
{
LED_show(led8,1);
LED_show(led3,0);
}
else if(TimingDelay<1200)
{
LED_show(led3,1);
LED_show(led5,0);
}
else if(TimingDelay<1400)
{
LED_show(led5,1);
LED_show(led7,0);
}
else if(TimingDelay<1600)
{
LED_show(ledall,1);//千万最后不要忘记让全部灯灭,不然好像会有bug
}
else if(TimingDelay==1800)
{
TimingDelay=0;//返回最开始
}
}
以上就是我对如何写stm32流水灯的一些见解,因为是第一次写博客,难免会有些披露,希望大家多多谅解,我也是为了更好地学习而且看市面上流水灯看不懂才写这篇文章,希望大家互相交流~
就酱