keil构建STM32工程并使用proteus仿真led点灯实验

news2024/11/25 6:32:20

    STM32单片机与51单片机有很大区别,不仅结构上有很大差异,STM32更复杂一些,在操作上来说,STM32也要复杂很多,51单片机上手写代码,可以很直接操作引脚,但是STM32单片机在操作引脚之前需要作很多初始化工作,比如开启时钟使能,GPIO管脚初始化。

    下面就入门STM32单片机开发做一个简单的介绍,本文是仿真,不需要真实的STM32单片机,只需要电脑安装开发相关的软件即可,主要是keil-mdk,proteus。

    keil这里安装的是支持STM32单片机的版本,这个需要安装mdk那个版本。这里提供一个支持mdk的keil下载链接,提取码:1234。它的安装和破解和keil-51类似,破解也是使用keygen.exe来生成注册码,安装之后,还需要安装支持STM32单片机的包:Keil.STM32F1xx_DFP.1.0.5.pack,将上面链接下载的包离线安装即可,如下所示:

    选择keil工具栏上的Pack Install按钮,在弹出框中选择File->Import,弹出选择文件对话框,选中下载的pack包,即可离线安装。

    我们要构造STM32工程,还需要一个标准库,同样的,在刚才的下载链接里面自带了:STM32F10x_StdPeriph_Lib_V3.5.0.rar,解压之后,结构如下所示:

 

    我们这里使用标准库来构建STM32工程,这里面有我们工程需要的头文件和源文件,以及启动文件。我们新建STM工程之前,先准备一个这样的工程文件结构:

    这里Core,也可以起名CMSIS,根据个人习惯,字面意思就是核心文件,这里我们要将标准库中core_cm3.h , core_cm3.c文件拷贝进来。路径是STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport

   Fwlib是固件库firmware library的意思,这里我们把标准库中STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src的inc和src文件夹都拷贝过来。

    Project 是用来存放keil工程的,后面在keil中新建工程,我们把保存位置指定到这里。

    User,这里是用户文件,拷贝STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x下的stm32f10x.h,system_stm32f10x.c,system_stm32f10x.h文件 和

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template 下的stm32f10x_conf.h,stm32f10x_it.c,stm32f10x_it.h,system_stm32f10x.h(重复)。

 

    Startup启动文件存放的文件夹,这里我们把STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm下的s结尾的文件都拷贝过来(实际只用到一个)。

   这样,我们除了Project文件夹中没有文件之外,其他四个目录都有了文件。

   keil新建工程

   打开keil-mdk,新建工程,位置选择刚才准备的Project文件夹。

     

    在接下来的向导,为构建目标选择设备,我们选择STM32F103C8,其他也可以,根据仿真需要选择。

 

这个新工程是没有任何内容的,我们要重新设置。点击工具栏的"管理工程项目"按钮(三色块):

Project Targets 修改为工程名称,

Groups这里添加四个Group,分别是Core,Fwlib,Startup,User,他们里面的文件,我们通过选择之前放到文件夹Core,Fwlib,Startup,User里面的文件,结构如下所示:

我们还需要手动在User目录中添加main.c文件,然后通过在User这个Group上右键选择:添加已有文件到组中。

最终的工程文件结构:

    我们可以在main.c中增加部分代码,让他可以作为一个空工程编译。

#include "stm32f10x.h"

int main()
{

}

这个时候直接编译项目会报错,我们需要作设置,设置头文件查找范围,具体操作是点击工具栏魔法棒(Options for Targets),弹出框中选择c/c++,Define处输入USE_STDPERIPH_DRIVER,下方的Include Paths选择我们的文件夹Core,Fwlib/inc,User三个目录,手动选择:

    最后可以编译成功:

 

  因为仿真最后需要的是hex文件,所以还需要一个设置,点击Options for Targets,切换到output,然后勾选Create HEX File:

    STM32单片机点灯的代码有一些复杂,主要需要开启时钟,并设置管脚电平。

#include "stm32f10x.h"

void Delay()
{
	unsigned int i, j;
    for(i = 0; i < 2000; i++)
	  for(j = 0; j < 110; j++);
}

void LED_Config()
{
      GPIO_InitTypeDef GPIO_InitStructure;                  // GPIO初始化结构体
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //APB2时钟使能,这里单片机开启的是B口,所以对应RCC_APB2Periph_GPIOB,如果开启A口,这里对应RCC_APB2Periph_GPIOA
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      // 推挽模式
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;             // 管脚B5作为输出
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //时钟频率
      GPIO_Init(GPIOB, &GPIO_InitStructure);                // GPIO初始化,开启GPIOB,如果要开启A或者C,改变这里的GPIOA或者GPIOC
}

int main()
{
    LED_Config();
	  while(1)
	  {
			GPIO_SetBits(GPIOB, GPIO_Pin_5);
			Delay();
			GPIO_ResetBits(GPIOB, GPIO_Pin_5);
			Delay();
	 }
}

    编译不报错,就可以开始进行仿真了,在proteus中,我们搭建如下所示的led设计图:

 

   选择芯片STM32F103C8,然后找到发光二极管LED-GREEN,再加上电阻,接地。简单的连线,STM32单片机好像和51单片机有些不一样,这里还需要对连线作处理,在菜单栏Design选择Power Rail Configuration,把GND和VCC/VDD左侧列出的部分都通过中间的Add(右移)箭头添加到右边:

    还有一个地方很重要,需要设置,就是单片机的晶振频率,如果不设置,将会报错:

Access to register of unclocked peripheral at 0x40010C00 cause BUS_FAULT [U1_CM3CORE]
 

    这个问题只有在仿真的时候可能会报错,有的地方说需要在代码里面设置开启时钟使能,但是我们的代码里面明显设置了,就是 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   这句代码。这个问题很折腾人,我开始以为是代码没有执行到main.c文件中的内容,其实不是的,而是晶振频率问题,但是同样不设置频率,我使用STM32CubeMX生成的代码执行就没有问题,这也很奇怪。

    

    这里的50MHz就是代码中设置的时钟频率GPIO_Speed_50MHz。 

    最后仿真不报错的情况: 

     这里是使用标准库建立STM32工程,所以加入了一些标准库的头文件和源文件,这里根据项目特点新建了Core,Fwlib,Project,Startup,User文件夹,并加入了相关文件,最后在keil工程的目标中建立的组Core,Fwlib,Startup,User并不是一个意思,只是名字相同而已,最后还需要手动添加文件到这些组中。

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/873218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学无止境·运维高阶⑤(LVS-DR 群集 配置Nginx负载均衡)

LVS-DR 群集 && 配置Nginx负载均衡 一、LVS-DR 群集1、相关配置环境2、在RS上配置并启动脚本2.1相关脚本2.2 启动脚本&#xff0c;另一台RS同样步骤 3、LVS-DR模式配置脚本4、测试 二、Nginx负载均衡1、安装Nginx并关闭相应设置2、向主机 node2&#xff0c;node3 写入内…

【第二阶段】kotlin函数引用

针对上篇传入函数参数我们也可以重新定义一个函数&#xff0c;然后在main中调用时传入函数对象 lambda属于函数类型的对象&#xff0c;需要把普通函数变成函数类型的对象&#xff08;函数引用&#xff09;&#xff0c;使用“&#xff1a;&#xff1a;” /*** You can edit, ru…

[足式机器人]Part3机构运动微分几何学分析与综合Ch03-1 空间约束曲线与约束曲面微分几何学——【读书笔记】

本文仅供学习使用 本文参考&#xff1a; 《机构运动微分几何学分析与综合》-王德伦、汪伟 《微分几何》吴大任 Ch01-4 平面运动微分几何学 3.1 空间曲线微分几何学概述3.1.1 矢量表示3.1.2 Frenet标架 连杆机构中的连杆与连架杆构成运动副&#xff0c;该运动副元素的特征点或特…

二十二、策略模式

目录 1、项目需求2、传统方案解决鸭子问题的分析和代码实现3、传统方式实现存在的问题分析和解决方案4、策略模式基本介绍5、使用策略模式解决鸭子问题6、策略模式的注意事项和细节7、策略模式的使用场景 以具体项目来演示为什么需要策略模式&#xff0c;策略模式的优点&#x…

GitHub 如何部署写好的H5静态页面

感谢粉皮zu的私信&#xff0c;又有素材写笔记了。(●’◡’●) 刚好记录一下我示例代码的GitHub部署配置&#xff0c;以便于后期追加仓库。 效果 环境 gitwin 步骤 第一步 新建仓库 第二步 拉取代码 将仓库clone到本地 git clone 地址第三步 部署文件 新建.github\workflo…

线性规划模型-应用篇

文章目录 模型特点使用技巧工具包和求解器模型线性化 应用实例经验总结 模型特点 上一篇中&#xff0c;详细阐述了线性规划问题和单纯形法的算法原理&#xff0c;本文将着重介绍线性模型在工业场景中的应用。 首先需要说清楚的是&#xff0c;为什么线性模型深受研发人员青睐。…

五、约束编程求解优化问题

文章目录 1、瑶草问题-离散优化问题2、重试优化3、分支限界法-改进重试优化法4、重启式搜索4.1 重启方针/策略4.2 自动化搜索策略 THE END 1、瑶草问题-离散优化问题 \qquad 要求在一个建木上构建一个完整的分枝树&#xff0c;每一个完整的分枝有100段&#xff0c;完整分枝上的…

2023年《开学第一课》播出时间是什么时候?开学第一课怎么在手机上观看高清直播?

2023年《开学第一课》播出时间是什么时候&#xff1f; 根据往年《开学第一课》播出时间预计2023年《开学第一课》播出时间是2023年9月1日20:00&#xff0c;如有变化请以官方公布为准&#xff1b; 2023年开学第一课怎么在手机上观看高清直播&#xff1f; 1、打开手机微信&…

第三章,矩阵,07-用初等变换求逆矩阵、矩阵的LU分解

第三章&#xff0c;矩阵&#xff0c;07-用初等变换求逆矩阵、矩阵的LU分解 一个基本的方法求 A − 1 B A^{-1}B A−1BLU分解例1&#xff0c;求矩阵A的LU分解&#xff1a;例12&#xff0c;LU分解解线性方程组&#xff1a; 玩转线性代数(19)初等矩阵与初等变换的相关应用的笔记&a…

Rx.NET in Action 第一章学习笔记

Part 1 初入反应式扩展 什么是反应式程序&#xff1f;它们有什么用&#xff1f;使用反应式扩展&#xff08;Rx&#xff09;编程&#xff0c;会如何改变你编写代码的方式&#xff1f;在开始使用 Rx 之前应该做些什么&#xff1f;为什么 Rx 比传统的事件驱动编程更好&#xff1f…

简单认识Zabbix监控系统及配置

文章目录 一、zabbix概述1、定义2、zabbix监控原理3、监控对象4、zabbix的3种架构&#xff08;1&#xff09; C/S架构&#xff08;2&#xff09;分布式架构&#xff1a;zabbix-proxy-client架构&#xff08;3&#xff09; master-node-client架构 5、zabbix监控模式 二、部署za…

Apollo Planning2.0决策规划算法代码详细解析 (1):环境搭建

背景: apollo开源团队近期更新了planning版本,对代码进行了一定程度上的重构。 重构后代码结构更加清晰,对扩展更为友好;此外,也更新了dreamview对pnc的支持,使得调试更加方便。 本教程将继续更新对于Apollo Planning2.0决策规划算法代码的详细解析,便于大家更好理解…

[鹏城杯 2022]简单包含

直接用php&#xff1a;// 有wtf 加脏数据绕过

Spring boot中的线程池-ThreadPoolTaskExecutor

一、jdk的阻塞队列&#xff1a; 二、Spring boot工程的有哪些阻塞队列呢&#xff1f; 1、默认注入的ThreadPoolTaskExecutor 视频解说&#xff1a; 线程池篇-springboot项目中的service层里简单注入ThreadPoolTaskExecutor并且使用_哔哩哔哩_bilibili 程序代码&#xff1a;…

Impala实践:解析glog打印的 C++ 报错堆栈

Impala实践&#xff1a;解析glog打印的 C 报错堆栈 Impala使用glog生成日志。生产环境用的都是release build&#xff0c;glog产生的报错堆栈里没有函数名&#xff0c;很难像Java报错堆栈那样方便定位问题。下面是 Impalad 日志中的一个报错&#xff1a; I0522 09:07:16.0020…

浅复制和深复制(使用python)

在编程语言中&#xff0c;复制通常是通过赋值操作来实现的。具体实现方式可能因编程语言而异。 1. 浅复制&#xff08;Shallow Copy&#xff09; 浅复制是指创建一个新对象&#xff0c;新对象的内容是原始对象的引用。换句话说&#xff0c;新对象和原始对象共享相同的数据&am…

【JVM】JVM 调优的参数都有哪些?

文章目录 1. 设置堆空间大小2. 虚拟机栈的设置3. 年轻代中Eden区和两个Survivor区的大小比例4. 年轻代晋升老年代阈值5. 设置垃圾回收收集器 1. 设置堆空间大小 设置堆的初始大小和最大大小&#xff0c;为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间&…

【Linux系统编程】21.echo、env、fork、getpid、getppid

目录 echo PATH SHELL TERM LANG HOME env fork 返回值 getpid getppid 测试代码1 测试结果 测试代码2 测试结果 父子进程相同 父子进程不同 父子进程共享 echo 查看单个环境变量。 PATH 可执行文件的搜索路径。 SHELL 当前Shell。 TERM 当前终端类型。终端…

一休休的面试题

重点面试题(今天又看了很多的博客大概有个三十来篇吧所以总结了一休休的面试题)&#xff1a; ps:已经入秋了为什么还是这么热&#xff01;&#xff01;&#xff01; 1、受管 bean 的生命周期 对于普通的 Java 对象&#xff0c;new 的时候会去创建对象&#xff0c;而当它没有…

Redis进阶(3)——在Linux上基于Docker容器Redis搭建一主二从三哨兵 SpringBoot整合Redis哨兵

目录 引出redis主从搭建&#xff1a;一主2从6389Master准备文件redis.confredis.log日志文件运行容器查看日志方式tail 6390Slave6391Slave 创建3哨兵创建文件夹sentinel创建运行哨兵容器问题&#xff1a;脑裂问题 SpringBoot整合Redis哨兵启动1主2从&#xff0c;3哨兵pom.xml文…