在keil上安装标准外设库
首先我们需要前往ST的官网,对我们对应型号的stm32mcu进行下载
网址如下:链接: [link](https://www.st.com/zh/embedded-software/stm32-standard-peripheral-libraries.html
进入官网后我们点击对应器件号
看到下面那个F1了吗,那就是我们要找的,当然你可能是其他型号。
进入过后我们需要下载最新版本。
随后会让你输入你的邮箱,要好好输入,因为下载连接会发送到你的邮箱里面。
下载完成后我们呢需要在我们本来存放源程序的地方分别创建不同的文件夹,你可以自定义,这是我们保存我们需要用的标准外设库的地方。
好的,现在我们解压并且打开我们刚刚下载的外设库。
那个LIibraries文件明显就是我们的库文件了,进入它。
这边两个文件都有用,我们先进入下面的DRIVER文件再进入src(sources的简写)
可以看到我们的标准外设库
有源文件就有头文件,刚刚src上面的文件就是头文件.h 这些是我们都需要用到的,复制到你自定义的文件夹里面,注意头文件和源文件都要复制进去。
我们回来进入到CMSIS里面的核心文件是都需要的,也复制到另一个你自定义的文件夹里面
下面的硬件支持device sup 里面的stm32的也都需要
建议和核心都复制到一个文件夹里面。
随后我们再创建一个system文件,来存放我们自己编写的函数。
一个user文件存放我们的工程文件。
打开我们的keil 随便创建一个工程,在左边的target那里右键点击manage project 如下
这里创建的不同组是你在keil里面的分类,这里就安装自己喜欢创建,然后把之前复制的文件夹分开添加就行
如下,ok,现在我们可以安安全全的使用标准库了。
编写我们这次写的流水灯程序。
#include "stm32f10x.h" // 头文件,记得添加库不然识别不了
#include "Delay.h"
int main()
{
GPIO_InitTypeDef led_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
led_init.GPIO_Pin = GPIO_Pin_5; //
led_init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
GPIO_Init(GPIOA, &led_init);
//上面是初始化gpioA-5
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
led_init.GPIO_Pin = GPIO_Pin_1; //
led_init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
GPIO_Init(GPIOB, &led_init);
//上面是初始化gpioB-1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
led_init.GPIO_Pin = GPIO_Pin_14; //
led_init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
GPIO_Init(GPIOC, &led_init);
//上面是初始化gpioC-14
led_init.GPIO_Pin = GPIO_Pin_13; //
led_init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
GPIO_Init(GPIOC, &led_init);
//上面是初始化gpioC-13
//以上的GPIO口初始化流程都是差不多的,直接复制更加方便。
while(1) //无限循环
{
//GPIO_SetBits(GPIOC,GPIO_Pin_13); 这个set函数是直接置n 位,一般是直接出高电平
GPIO_ResetBits(GPIOC,GPIO_Pin_13); //P13引脚输出低电平 reset就是直接出低电平
Delay_ms(100);
GPIO_SetBits(GPIOC,GPIO_Pin_13);
Delay_ms(100);
GPIO_SetBits(GPIOA,GPIO_Pin_5);//p5输出高电平 reset则相反
Delay_ms(100);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
Delay_ms(100);
GPIO_SetBits(GPIOB,GPIO_Pin_1); //P1引脚输出高电平 reset就是直接出低电平
Delay_ms(100);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
Delay_ms(100);
GPIO_SetBits(GPIOC,GPIO_Pin_14); //P14引脚输出高电平 reset就是直接出低电平
Delay_ms(100);
GPIO_ResetBits(GPIOC,GPIO_Pin_14);
Delay_ms(100);
}
}
在keil上使用逻辑测试对我们的程序进行纠错。
首先我们先进入debug模式
即使那个望远镜中间有个d。
进入过后,我们点击这个按钮
这个有着红色波形的仪器按钮。
然后点击左上角的setup按钮设置我们需要的不同接口
则进入如下画面
注意所有的接口下面的Dosplay Type 改成BIT 点击右上角的虚线图标,然后输入PORTA5 等输入你想要监测的IO口就行,下面的颜色也可以自行设定。然后关闭。
开始运行程序。
鼠标滚轮可以调整每一格的时间间隔,可以更加全部的观察图像,可以看到,我们的对应IO口高低电平变化,和对应的延时功能实现都很正常。
于是可以使用flymcu烧录进入我们的硬件来观察情况。
延时时间函数的时间到底是多少?
我的思路是使用记录时间的函数,在一个延时函数执行前和执行后分别记录时间,然后相减,再调整单位就可以得到我们能看到的秒时,唯一的问题是,记录时间的函数精度如何,如果延时函数执行时间过短,可能系统无法准确记录,或者还和硬件的时钟晶振有关,8MHZ 和 12MHZ 的延时函数影响是什么。
现在vs上随意写一个循环时间延时函数。
#include<iostream>
#include <time.h>
using namespace std;
int main()
{
clock_t start = clock();
int i, j;
for (i = 100;i>0; i--)
for (j = 0; j < 100000; j++);
clock_t end = clock(); // 记录程序结束执行的时钟时间
double execution_time = (double)(end - start) / CLOCKS_PER_SEC; // 计算程序执行时间(以秒为单位)
cout << execution_time << endl;
cout << end << endl << start;
return 0;
}
执行
可以看到时间变化。
参考文献:
- https://blog.youkuaiyun.com/qq_43279579/article/details/110320013
- https://www.st.com/zh/embedded-software/stm32-standard-peripheral-libraries.html