基于标准外设库的LED流水灯及Keil仿真的逻辑分析仪查看波形
一、创建项目
固件库:
链接:https://pan.baidu.com/s/1X2Udc8gnvYgcXM0-fcsdKg?pwd=5pe8
提取码:5pe8
压缩包解压密码:32
下载固件库并解压,之后在存放项目的地方新建一个项目文件夹,取名为STM32Project,方便管理我们的项目。
在Keil中新建工程到刚刚新建的文件夹中,再新建一个文件夹用于存储接下来的项目,取名为“流水灯”并选择该文件夹。
在文件夹中为项目取名为Project,注意项目名称不容易更改且不得包含中文。
选择芯片型号STM32F103C8
对于新建工程小助手暂时不需要,直接关闭即可,这样工程就新建好了,但是还不能使用,需要添加一些工程的必要文件。
找到刚刚解压好的固件库,点击Libraries->CMSIS->CM3->DeviceSupport->ST->STM32F10x->setup->arm,这些为STM32的启动文件,全选启动文件并复制
然后回到流水灯项目存储的地方,可以看到新建工程自动生成的文件,再新建一个文件夹名为“Start”,把启动文件粘贴到Start中
然后回到固件库Libraries->CMSIS->CM3->DeviceSupport->ST->STM32F10x中,找到一个.h文件和两个system开头的文件,它们分别为STM32的外设寄存器描述文件和配置时钟文件,将它们三个也复制到Start下
Start文件:
在固件库Libraries->CMSIS->CM3->CoreSupport选择.c和.h文件,这两个文件为内核的寄存器描述
在工程项目文件夹中新建文件夹“Library”
在固件库Libraries->STM32F10x_StdPeriph_Driver->src,将文件全选复制粘贴到工程项目“Library”文件夹
再到固件库Libraries->STM32F10x_StdPeriph_Driver->inc,将文件全选复制粘贴到工程项目“Library”文件夹
再到固件库Project->STM32F10x_StdPeriph_Template,选择main.c文件、两个it文件和conf文件复制粘贴到工程项目"User"文件夹
二、添加文件到组
添加文件到组有两种方法
1.方法一
回到Keil工程中,将刚才复制的文件添加到工程中,点击Source Group1,将其重命名为Start
右键Start,选择Add Existing Files to Group…添加已经存在的文件到组里
找到项目文件夹里的Start,将文件类型改为All Files,找到后缀为md.s的启动文件、两个core_cm3文件、两个system文件和一个stm32f10x文件,将它们添加后关闭,这些文件我们是没有权限修改的
2.方法二
点击Keil上方三个工具箱按钮,新建三个组分别为:User、Libraries、Start,之后添加文件,Start的文件方法一已添加,现在点击Library添加Library的文件
打开工程项目下的Library文件夹,将文件类型改为ALL Files,文件全选,点击Add
点击User组,文件类型改为全选,之后文件全选点击Add
由于方法二已将main.c文件移动到工程中,不再需要新建.c文件,下面讲新建.c文件的方法
3、新建.c文件
在Keil找到User,右键新建文件
选择C File,取名main,注意,路径一定要在User文件夹下,不然默认是在文件夹外的
之后点击魔术棒按钮,在C/C++中将路径添加进来
最后在Define下写“USE_STDPERIPH_DROVER”字符串
二、程序编写
在main.c文件中右键添加头文件
第一步:开启时钟
选择的GPIOA端口,并将它置为使能端
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟
第二步:初始化GPIO参数
首先定义GPIO结构体为GPIO_InitStruct,设置参数:Mode、Pin、Speed,其中Mode设置为推挽输出(GPIO_Mode_Out_PP),由于有三个LED灯,选择GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4,最后速度选择GPIO_Speed_50MHz。
注意:对于某些Keil的旧版本,需要将定义结构体放在最前面(放在开启时钟之前),否则会出现报错。
GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;```
```c
```bash
在这里插入代码片
第三步:使能GPIO端口
GPIO_Init(GPIOA,&GPIO_InitStruct);
第四步:GPIO端口输出低电平,点亮LED灯
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
第五步:延时
Delay.c
#include "stm32f10x.h"
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
Delay.h
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
调用延时函数:
Delay_ms(1000);
新建一个组名为“System”并将Delay函数放进去,后面就可以直接使用了。
第六步:GPIO端口输出高电平,熄灭LED灯
GPIO_SetBits(GPIOA,GPIO_Pin_0);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
第八步:延时
Delay_ms(1000);
代码:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
while(1)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0);
Delay_ms(1000);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
Delay_ms(1000);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
Delay_ms(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
Delay_ms(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
Delay_ms(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
Delay_ms(1000);
}
}
STM32实现:
三、Keil仿真
点击魔术棒勾选Use Simulator,并修改参数如下图:
点击仿真按钮开始仿真,打开逻辑分析仪窗口
点击Setup,添加端口,我使用的是GPIOA.0、GPIOA.2和GPIOA.4,所以点击新建New (Insert)分别输入“PORTA.0”“PORTA.2”“PORTA.4”,将Display Type设置为“Bit”,Add Mask改为“0x0000010”,将Shift Right改为4即可,否则会有没有方波出现的问题
波形:
经过分析波形时序状态正确,LED灯闪烁周期大约为4005.22ms(有误差)。