用STM32F103C8T6制作流水灯

目录

一、关于STM32与51的区别

二、题目要求

三、工程的建立

四、程序的编写

1、对于工程内部的熟悉

2、对于工程文件的添加与撰写

2.1 电路示意图

2.2 代码撰写 

2.3 仿真

六、程序的烧录

1、关于USB-TTL与板子之间的连线方法

2、开发板BOOT配置

3、驱动及烧录程序

 七、连接电路

八、运行结果

九、总结



一、关于STM32与51的区别

51单片机是对所有兼容Intel8031指令系统的单片机的统称,这一系列的单片机的始祖是Intel的8031单片机,后来随着flash ROM技术的发展,8031单片机取得了长足的进展成为了应用最广泛的8bit单片机之一,他的代表型号就是ATMEL公司的AT89系列。

STM32单片机则是ST(意法半导体)公司使用arm公司的cortex-M3为核心生产的32bit系列的单片机,他的内部资源(寄存器和外设功能)较8051、AVR和PIC都要多的多,基本上接近于计算机的CPU了,适用于手机、路由器等等。

相较于我们刚开始学习单片机时接触的51单片机,32单片机的功能更为强大,能让我们实现更多的功能。想必大家一定想开始自己写程序实现功能了吧,现在我们就一起来制作一个最简单的流水灯。

二、题目要求

以 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED 搭建电路,使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长1秒。

三、工程的建立

工程的建立对于我们编写程序来说非常重要,对于初学32单片机的同学来说,模板的建立也许相对困难。我们可以选择网上现成的工程模板文件,这些文件都由其他大佬编写,他们将不同的文件以功能作为区分,放在了不同的文件夹下面,非常得清晰,一目了然。我们使用时只需要编写我们需要的文件(为了工程的美观性,我们也按功能将我们编写的文件放入对应的文件夹中)并调用就可以了。

这里我使用的工程模板是“洋桃电子”版本,大家也可以去如下网址下载:www.doyoung.net/YT/xx3.htmlhttp://www.doyoung.net/YT/xx3.html

四、程序的编写

1、对于工程内部的熟悉

 注意:我们下载好的工程模板一定要记得解压到我们对应的文件夹,如果直接在压缩状态打开的话系统只是创立了一个临时文件夹来打开该工程,但是对于我们要调用的文件,此文件夹中是没有的,所以直接编译会出错。

并且我们将改模板解压后一定要将路径中的中文改成英文,不然的话后续编译过程会出错很麻烦。

 打开工程,我们可以看到主文件中的主函数,我们以后都在这里面调用跟我们要用到的功能。

用STM32F103C8T6制作流水灯_第1张图片

用STM32F103C8T6制作流水灯_第2张图片

 可以看到我们左边的工程栏中,有一些人家事先按功能分好的文件夹。我们之后要写的文件就按功能放到对应文件夹中就OK。

这次我们要实现的功能是用面包板加上STM32F103C8T6的最小系统制作一个最简单的流水灯。值得一提的是对于初学者来说,32单片机中的C语言并不像C51那样通俗易懂,主要是因为我们在写32程序的时候需要我们根据自己的需求初始化对应的功能才能正常使用,可能刚开始接触32单片机会感觉到不适,但是慢慢下来,熟悉以后就会对初始化三步有更深刻的了解

2、对于工程文件的添加与撰写

我们本次制作流水灯所用到的硬件是三个LED灯,这三个LED灯该怎样与开发板的管脚进行连接呢,我们又该怎样使小灯亮起来呢。切听我细细道来。

2.1 电路示意图

首先我们要先搞懂我们的电路图,搞清楚我们的电路该怎样接才能使小灯亮起来。在这里,考虑到我的板子上接入管脚的方便,所以我选择用PA.0 PB.0 PC.15这三个管脚,示意图如下:

用STM32F103C8T6制作流水灯_第3张图片

 将三个LED的负极接到GND(地),所以说LED正极必须必须收到一个高电平的时候才会亮。流水灯就是要使三个LED轮流点亮和熄灭,所以流水灯的制作就可以理解为三个管脚来回输出高低电平。

2.2 代码撰写 

但是先不要把问题想的那么简单,还记得我上面提到的初始化三步吗,所以我们首先需要将管脚初始化成我们需要的样子,首先我们创建一个led.c文件用于存放我们的初始化代码。

led.c:

#include "led.h"

void LED_Init(void){ //LED灯的接口初始化

 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //开启时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 //初始化管脚
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //设置输出模式,推挽输出模式
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//设置输出速率
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOA,GPIO_Pin_0);					//将该管脚初始值定义为低电平
	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
 GPIO_Init(GPIOB, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOB,GPIO_Pin_0);
	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;				 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
 GPIO_Init(GPIOC, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOC,GPIO_Pin_15);
}
 

注:其实这段代码可以放在main文件中的,但是为了美观以及方便调用,我们通常是将每个功能都分开写在不同的文件中,这样既美观又方便我们修改与纠错。 

这里的设置输出模式为推挽输出模式,其实还有几种其他的输出方式,但是我们流水灯用到的大电流输出需要用到的就是推挽输出,另外的输出如下:

GPIO_Mode_AIN:模拟输入模式
GPIO_Mode_IN_FLOATING:浮空输入模式
GPIO_Mode_IPD:下拉输入模式
GPIO_Mode_IPU:上拉输入模式
GPIO_Mode_Out_OD:通用开漏输出模式
GPIO_Mode_Out_PP:通用推挽输出模式
GPIO_Mode_AF_OD:复用开漏输出模式
GPIO_Mode_AF_PP:复用推挽输出模式

详细可以看: (20条消息) 单片机STM32的引脚模式设置_qingfeng_博客-CSDN博客

至于为什么一定要将管脚初始值设置为低电平,可以将管脚输出想象成一个变量,如果没有一个定值的话,它的输出我们是不知道的,所以我们必须将它设置为一个我们知道的定值。(如果电路示意图跟我上面接法正好相反的话,就需要把初始值设置为高电平。

上面我们编写好了led.c文件,并在其中创建了一个LED_Init(void)初始化函数,我们在main文件中需要调用这个函数的时候就需要事先声明,所以我们创建一个头文件led.h用于声明我们这个函数名,再在main文件的头文件上加上#include "led.h"用于调用该头文件下的函数。

led.h:

#include "stm32f10x.h"
void LED_Init(void);//初始化

编写好这两个文件以后,我们就需要将他们保存并导入到我们的工程中,我们需要怎么做呢,步骤如下:

双击左边工程栏里的Hardware文件夹,然后找到我们刚保存的led.c文件,点击add即可

用STM32F103C8T6制作流水灯_第4张图片

现在我们打开我们的Hardware文件夹就可以看到led.c及其调用的其他文件了 。

到此,我们的硬件(LED)算是编写完成,但是我们的main函数还是空空如也。所以接下来我们就要对我们的main函数进行编写了。

首先我们要在main函数中调用我们刚刚写好的led.c文件中的LED初始化函数,所以我们需要在main文件中加上我们的头文件#include"led.h",然后再在main函数中写上我们的初始化函数,但是这只是完成了我们的LED初始化,并没有开始真正的流水灯程序。

要实现流水灯,我们就要让我们定义的输出管脚的输出在高低电平之间反复横跳,所以我们要对其进行赋值,具体操作代码如下:

main.c:

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"


int main (void){//主程序
	RCC_Configuration(); //时钟设置
	LED_Init();
	while(1){		
	  GPIO_SetBits(GPIOA,GPIO_Pin_0);	//这个就是将IO口设置为高电平就是3.3V
	  delay_ms(500);
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);   						 
    GPIO_SetBits(GPIOB,GPIO_Pin_0);	//这个就是将IO口设置为高电平就是3.3V
    delay_ms(500); 
		GPIO_ResetBits(GPIOB,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);   
    GPIO_SetBits(GPIOC,GPIO_Pin_15);	//这个就是将IO口设置为高电平就是3.3V
    delay_ms(500); 
		GPIO_ResetBits(GPIOC,GPIO_Pin_15);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);  
	}
}


我们注意到代码中有#include"delay.h"delay_ms(500),这两句代码的意思是调用delay.h中的delay_ms()函数,这是延时函数,是32中最为经典的函数之一,但是这只是软件延时,延时的时间并不准确,后面我们再来讨论具体延时时间是多少。为什么要用到延时函数呢,这是因为我们的流水灯是闪烁的,也就是说我们的LED灯并不是一直亮或者一直灭的。

注:delay.h并不是keil编译器给我们准备好的,而是我下载的模板的作者为我们准备的,根据定义该头文件中的延时函数的方法不同,延时的准确性也有一定的差距。

GPIO_SetBits(GPIOX,GPIO_Pin_x),这个函数的意思是将该管脚置为高电平,也就是我之前提到过的赋值为1,Reset则表示赋值为0。怎么样,是不是感觉思路瞬间清晰了。

现在我们就完成了基本的程序编写工作了,就可以开始编译了。在将程序烧录进板子之前,我们可以在keil上仿真看看波形,以便于我们及时纠错。

2.3 仿真

在开始仿真之前我们需要对keil进行一系列的配置,点击“仙女棒”,然后在Debug选项中选择软件仿真(use simulator),并且将下面的设置改成你对应的芯片即可。 

用STM32F103C8T6制作流水灯_第5张图片

现在我们再运行仿真,并调出逻辑窗口,在逻辑窗口中添加上我们需要查看的管脚号。

 

点击setup添加对应管脚号。

点击添加管教号,然后输入我们想查看的管脚号即可,比如:porta.0

 用STM32F103C8T6制作流水灯_第6张图片

 开始仿真,得到结果,观察仿真波形图。

用STM32F103C8T6制作流水灯_第7张图片

六、程序的烧录

我们写好程序之后需要将程序烧录进板子中,这时我们就需要用到专门的烧录硬件和软件了,硬件是USB转TTL,用于我们的PC和板子连接,软件是Fly MCUCH340驱动直接在CSDN上搜索就可以下载到,安装好就可以了。也可以下载我分享的链接:https://pan.baidu.com/s/1YsxFylplA659Kpe_TCQH9g 
提取码:1111

1、关于USB-TTL与板子之间的连线方法

现在我们仔细观察我们的USB-TTL和板子,可以看到我们USB-TTL身上有五个管脚,分别是5V电源管脚、3.3V电源管脚、TXD(数据传送)管脚、RXD(数据接收)管脚、GND管脚。我们要实现PC与板子相连接就要让对应管脚连接起来,即板子的TXD接USB-TTL的RX,RXD接TX。

经过我们查询STM32F103C8T6的资料可以发现,PA9对应TX,PA10对应RX。
在这里插入图片描述

 所以我们的对应关系为:

PA9---RXD

PA10---TXD

我们也可以直接插到面包板上进行烧录操作,只需将线连好。

用STM32F103C8T6制作流水灯_第8张图片

2、开发板BOOT配置

我们此时注意到板子上有两个跳线帽,分别在BOOT0BOOT1上,我们要烧录程序之前必须改变模式BOOT0BOOT1模式为系统存储器模式。

用STM32F103C8T6制作流水灯_第9张图片

 即需要将BOOT0用跳线帽与3.3V短接,BOOT1用跳线帽与GND短接,如图:

用STM32F103C8T6制作流水灯_第10张图片

3、驱动及烧录程序

在安装好CH340驱动以后,我们可以在我们的设备管理器中找到对应连接的设备

用STM32F103C8T6制作流水灯_第11张图片

现在只需要我们打开FlyMCU进行一定的配置后,就可以进行烧录了。配置如下图:

用STM32F103C8T6制作流水灯_第12张图片

 注意这里我的端口是COM4,每个人每台机器都可能不一样,记得搜索一下端口在选择对应的端口号即可。

点击开始编程即可进行烧录。

注:每次烧录开始前记得按一下板子上的RESET(复位)按钮,否则可能出现烧录不进去的情况。 

 七、连接电路

烧录完我们的程序之后就可以进行电路的连线了,根据我们上面的电路示意图可以看出我们的LED小灯是共地的,所以需要从我们的板子上引出GND接到面包板的负极。如图红线:用STM32F103C8T6制作流水灯_第13张图片

由于我们设置的输出管脚并未占用烧录所需要的管脚,所以我们可以直接用USB-TTL供电,而不需要改变原有的杜邦线。

八、运行结果

九、总结

通过两种方式实现LED流水灯,可以很清楚地了解到这两种方式各自的优缺点。对于初学者来说,尝试一些寄存器开发的方式,还是很有帮助理解整个过程。虽然,固件库的方式会更快,但是,去对于初学者来说,还是有些地方不是很容易搞清楚。实验过程,开始编译烧录后,灯一直不亮,我一直以为是程序的问题(寄存器地址),结果最后才发现是自己忘了接电源。如果,你也有类似的问题,先检查自己器件的连接是否有问题,不用急着去看代码。

参考资料:

(20条消息) stm32和51的区别_sweetfather的博客-CSDN博客_51和32的区别

资料下载地址:

www.doyoung.net/YT/xx3.html

https://pan.baidu.com/s/1YsxFylplA659Kpe_TCQH9g 
提取码:1111

你可能感兴趣的:(stm32,单片机,嵌入式硬件)