mdk5怎样mdk5.14创建stm32工程m3硬件头文件

21ic官方微信-->
后使用快捷导航没有帐号?
查看: 2048|回复: 8
MDK5.17没有芯片型号如何解决
&&未结帖(20)
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
MDK5.17没有芯片型号如何解决。里面只有M0\M3\M4\M7
主题帖子积分
主题帖子积分
专家等级:结帖率:10%打赏:0.00受赏:33.00
主题帖子积分
找芯片代理商或原厂
ARM入门经典好书:《ARM Linux入门与实践》
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
找芯片代理商或原厂
软件是破解注册的!
主题帖子积分
主题帖子积分
专家等级:结帖率:10%打赏:0.00受赏:33.00
主题帖子积分
破解没关系的,或者你就说用评估版本的
ARM入门经典好书:《ARM Linux入门与实践》
主题帖子积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
到keil 官网下载pack包
想我的时候别憋着,来找我吧!
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 12, 距离下一级还需 38 积分
实习生, 积分 12, 距离下一级还需 38 积分
到keil 官网下载pack包
谢谢,解决了
主题帖子积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
助理工程师, 积分 1629, 距离下一级还需 371 积分
想我的时候别憋着,来找我吧!
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
peak包下载不了啊。有没有人能分享下
主题帖子积分
主题帖子积分
专家等级:结帖率:10%打赏:0.00受赏:33.00
主题帖子积分
peak包下载不了啊。有没有人能分享下
直接下安装包吧
ARM入门经典好书:《ARM Linux入门与实践》
核心会员奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术导师奖章
人才类勋章
技术新星奖章
人才类勋章
热门推荐 /3 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
MDK环境下利用STM32库V35创建工程并调试的方法
下载积分:600
内容提示:MDK环境下利用STM32库V35创建工程并调试的方法MDK,35
文档格式:PDF|
浏览次数:70|
上传日期: 20:40:50|
文档星级:
该用户还上传了这些文档
MDK环境下利用STM32库V35创建工程并调试的方法
官方公共微信MDK工程的建立方法_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
MDK工程的建立方法
上传于||文档简介
&&M​D​K​工​程​的​建​立​方​法
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢[ M3 LN ] STM32F10XXX(Cortex-M3) MDK-RAM 时钟初始化配置 - 博客频道 - CSDN.NET
《西决》 —— 克里斯·保罗 [笑]
分类:-[小西南]-
(1) 时钟源与时钟信号
时钟信号是指有固定周期并与运行无关的信号量,它用于决定逻辑单元中的状态何时更新。如时钟边沿触发信号意味着所有的状态变化都发生在时钟边沿到来时刻。在边沿触发机制中,只有上升沿或下降沿才是有效信号,才能控制逻辑单元状态量的改变。至于到底是上升沿还是下降沿作为有效触发信号,则取决于逻辑设计的技术。
时钟源是产生时钟信号的硬件(系统),如晶体/陶瓷谐振器。
(2) 时钟信号的作用
在“”中有抽象的提到关于时钟信号的作用。用一个较实际的例子来说明时钟信号的作用应该会让人觉得更为亲切:计数器只有在有效驱动时钟信号(如上升沿)CK_CNT到来时才发生计数操作。CK_CNT的频率(如1MHZ)决定了计数器计数一次所花的时间t1(1us)。若计数1000次发生了溢出/下溢从而间接的决定时基的大小1ms,由多个时基从而就可以得到现实生活中的10ms,1s之类的时间段了。时钟驱动计数器见《》
Page255 图99 ~ 106。
(3) 外部时钟与内部时钟
外部时钟在芯片外部通过芯片引脚和内部电路发生关系。外部时钟信号可由外部晶体或外部时钟源提供,外部晶体为震荡模式,是使用片内震荡电路和外部接的晶体来产生时钟信号,外部时钟源是一个可以产生时钟信号的器件,比如时钟发生器。
内部时钟在芯片内部。一般都是由RC震荡器产生。
2 读时钟树图
跟时钟相关的模块都被集中到了“时钟树图”之上,所以学会读“时钟树图”还稍带必要性。就像“每次”到食堂吃早饭一样,吃鸡蛋之前都要先喝几口粥,但也不能将粥都先喝完了,不然后面吃鸡蛋的时候会被哽噎到。“时钟树图”就是那碗粥。
系统时钟 (SYSCLK)是核心。因为片内太多模块的时钟信号都是从这里“散发”出去的,它散发到需要时钟信号的每一个模块形成新的时钟信号以驱动这些模块工作。但SYSCLK并非就是由某个时钟源头发出时钟信号,它的来由可以来自“几大”时钟信号,再追踪这“几大”时钟信号就能够追踪到时钟源了。追踪到时钟源就差不多了,因为那已经是硬件成分了。可以在PCB原理图的时候仔细研究一下子,将其原理搞清楚。
以下面的时钟图(摘自STM32F10XXX参考手册)并以SYSCLK为线索了解一下时钟,一个方面是向前追踪到各模块的时钟信号,另一个方向是往回追踪直到时钟源。
Figure1:时钟树
(1) SYSCLK去处
Figure 1时钟树的SYSCLK时钟信号在深红色方框处。它的去处分为如图所示的1,2两个方向。假设SYSCLK已经存在(已经有了时钟信号)。
[1] 去往I2Sx[x=2,3]
暂且不管I2Sx模块具体是什么。因为这里我只关心SYSCLK时钟去处为I2SxCLK,从图中可以看出SYSCLK直接作为了I2SxCLK。当然作为外设,在配置好SYSCLK的情况下,还需要使能I2SxCLK时钟后才能使用I2SxCLK时钟信号。
[2] 去往AHB预分频器
SYSCLK的第二个去向就是AHB预分频器,AHB预分频器可对SYSCLK时钟进行1,2…,512分频。经AHB预分频器分频后的时钟信号会去往以下模块:
至SDIO (FSMC)成为SDIOCLK(FSMCCLK),只要使能SDIO (FSMCCLK)模块时钟,SDIOCLK (FSMCCLK)就被激活即可驱动SDIO (FSMC)模块工作。跟SYSCLK拥有一样的频率。至AHB总线、核心存储器和DMA模块成为HCLK,在使能HCLK后HCLK就被打开去驱动此模块工作。经8分频后至(成为)Cortex系统时钟。即假设SYSCLK为72MHz,则Cortex系统时钟为9MHz。至APB1预分频器。APB1预分频器可对经AHB预分频器后SYSCLK信号进行1, 2,…,16分频,然后再分往两个去处。去往APB1外设的PCLK1时钟最大只能为36MHz即AHB与APB1预分频器的分频系数不能同时为1,在让PCLK1驱动APB1外设工作时需要提前使能外设各自对应的时钟。去往TIMx[x=2,3,…7]作为TIMXCLK,若APB1预分频系数为1则TIMXCLK的频率率与所在APB总线频率一致,否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。在使用TIMx时需要使能对应的时钟TIMxCLK。进入APB2预分频器的时钟信号除新增ADC模块后同上 (APB1)。经2分频后进入SDIO的AHB接口,时钟频率大小为HCLK/2。使用此模块时钟需要提前对其使能。
从时钟图中可以看出来,除了至Cortex系统时钟之外的信号在使用前都需要做使能操作。其中APB1外设和APB2外设在图中并没有体现。但对于编写程序来说还不是很重要,因为我们暂时只需要知道使能各个模块时钟的寄存器为RCC_APBxENR。
(2) SYSCLK来源
SYSCLK最大允许的频率为72MHz。
SYSCLK的来源在时钟树中用粉红色方框标记。从图中可以看出,SYSCLK来源于时钟源(除PLL):
HIS(内部高速时钟):它是由被称为“HSI RC时钟源”的东西产生的频率为8MHz的时钟信号可直接作为SYSCLK的来源。HSE(外部高速时钟): HSE信号的时钟源可以分为“外部时钟源”和外部晶体/陶瓷谐振器。后者是使用“片内震荡电路”和“外部接的晶体”组成的时钟源来产生的名为HSE的时钟信号;前者是通过如时钟产生器的东西产生HSE,4 ~ 16MHz的HSE可被直接作为SYSCLK的来源。PLL时钟来源于HSE或HSI/2,然后将其倍频送给SYSCLK。当HSI被用于作为PLL时钟的输入时,系统时钟能得到的最大频率是64MHz。当HSE作为PLL时钟时,选择倍频时要考虑到SYSCLK最大频率不得超过72MHz。
系统复位后,HSI振荡器被选为系统时钟。当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止。 只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时钟源的切换才会发生。在被选择时钟源没有就绪时,系统时钟的切换不会发生。直至目标时钟源就绪,才发生切换。 在时钟控制寄存器(RCC_CR)里的状态位指示哪个时钟已经准备好了,哪个时钟目前被用作系统时钟。
(3) 其它时钟源
LSE(外部低速时钟):跟HSE时钟一样时钟源分为两种,提供的频率为32.768KHz。主要是为实时时钟(RTC)或其它定时模块提供一个低功耗且精确的时钟源。RTC还可以有由HSE/128提供。LSI(内部低速时钟):时钟源为“LSI RC”振荡器,LSI频率大约为40KHz(30KHz ~ 60KHz),为独立看门狗和自动唤醒单元提供时钟。如果需要在应用中使用USB接口,PLL必须被设置为输出48或72MHZ时钟,用于提供48MHz的USBCLK时钟。
(4) 时钟总结
时钟信号的作用。低速时钟一般没有那么精确,都设有校准位。配置时钟的操作都在对应RCC寄存器内。时钟的稳定由硬件设置,开启和关闭某一时钟作为SYSCLK可在RCC_CR、RCC_CFGR寄存器内设置。
3 时钟初始化配置
时钟初始化配置主要配置“SYSCLK的来源(HIS OrHSE Or PLL(HIS/2& Or& HSE))”以及“各模块时钟源频率(HCLK[AHB分频], PCLKx)”。
假设现在要将SYSCLK配置为72MHz,PCLKx频率也为最大时就只能选择HSE作为PLL时钟的输入,再选用经倍频后的PLL时钟作为SYSCLK时钟来源,并设置AHB预分频器分频系数为1,限制PCLK1的时钟频率最大为36MHz。在这个过程中需要配置的寄存器为:
RCC_CR:&&&&&&& 含HSE、HLI、PLL时钟的开启位及三大时钟的稳定状态指示位,及HLI的校准位。RCC_CFGR:&&&&& 含“系统时钟源状态位”、“系统时钟选择位”、“PLL时钟来源位”、“PLL时钟输出倍频位”及“其它时钟(HCLK、HSE、PCLKx)分频系数位”。
在进行这些配置的时候需要将相关的配置寄存器都设成复位时的状态,以方便后续“开启HSE”、“设置PCLKx、HCLK分频”、“选择SYSCLK时钟源”配置。
(1) 时钟复位
设置RCC时钟在系统复位时的默认配置。
void RCC_Reset(void)
& & //复位时选择HIS作为系统时钟
& &&RCC-&CR |= (unsigned &int)0x;
& &&//复位SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO位
& &&//即HSI作为系统时钟,SYSCLK不分频,HCLK不分频(PCLK1分频系数),HCLK不分频(PCLK2分频系数),…
& &&RCC-&CFGR &= (unsigned &int)0xF8FF0000;
& &&//复位HSEON, CSSON and PLLON 位即关闭HSE、CSS、PLL时钟
& &&RCC-&CR &= (unsigned &int)0xFEF6FFFF;
& &&//复位HSEBYP位即外部4-16MHz振荡器没有旁路
& &&RCC-&CR &= (unsigned &int)0xFFFBFFFF;
& &&//复位PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE位
& &&//即设置PLL来源,分频,倍频、USB等分频
& &&RCC-&CFGR &= (unsigned &int)0xFF80FFFF;
& &&//清除所有时钟就绪的中断,写1清除
& &&RCC-&CIR = 0x009F0000;
(2) 开启HSE
开启HSE时钟就是将RCC_CR中的HSEON位开启,并判断RCC_CR中的HSERDY是否为1,为1就说明HSE已经稳定就绪可被输出使用了,如果超过某个时间后HSERDY依旧为0则作超时处理。
void &HSE_Enable(void)
& &&//外部4-16MHz振荡器没有旁路
& &&RCC & &|= (unsigned &int)0x
#define HSEStartUp_TimeOut & &((unsigned &short)0x0500) /* Time out for HSE start up */
//返回0表面HSE时钟正常启动
char &RCC_WaitHseStartUp(void)
& & &unsigned &short counter = 0;
& && & &&;
& &&}while( (RCC-&CR & (unsigned &int)0x) && ++counter != HSEStartUp_TimeOut );
& &&if(counter != HSEStartUp_TimeOut){
& && & &&return 1;
& &&}else {
& && & &&return 0;
如果HSE启动超时失败,此时有HIS作为系统时钟。而且我们还可以重新给开发板上电再次尝试启动HSE时钟。
(3) HCLK、PCLKx分频
在RCC_WaitHseStartUp()函数返回为0的情况下继续配置时钟。
void HP_CLKx_Set(void)
& & //使能预取缓冲
& &&FLASH-&ACR |= 0x10;
& &&//Flash 2 等待状态
& &&FLASH-&ACR &= (unsigned &int)(( unsigned &int)~ 0x03);
& &&FLASH-&ACR |= (unsigned &int) 0x02;
& &&//HCLK = SYSCLK,HPRE[3:0] =0xx,AHB不分频
& & RCC-&CFGR |= (unsigned &int)0x;
& & //PCLK2 = HCLK,PPRE2[2:0]=0xx,PCLK2预分频系数为1
& & RCC-&CFGR |= (unsigned &int) 0x;
& & //PCLK1 = HCLK/2,PPRE1[2:0]=100,PCLK1预分频系数为2
& & RCC-&CFGR |= (unsigned &int) 0x;
前两个语句是关于闪存的配置,可见《PM0075 Flash memory,闪存编程》手册[待我阅读此手册一两天]。可见“”的预取指模块配置。
(4) 选择PLL时钟为SYSCLK时钟源
凡是打开一个时钟后都得等待这个时钟的启动与稳定。SYSCLK的时钟源切换也需要等待。
void PLL_To_SYSCLK(void)
& &&//设置HSE为PLL的时钟信号输入源,并且设置9倍倍频输出PLL
& &&//PLLCLK = HSE * 9
& &&RCC-&CFGR &= (unsigned &int)(( unsigned &int)~( 0x | 0x | & & & &&0x003C0000));//消除其它时钟作为PLL输入时的设置
& &&RCC-&CFGR |= (unsigned &int)( 0x | 0x001C0000);
& &&//使能PLL时钟
& &&RCC-&CR |= (unsigned &int)0x;
& &&//等待PLL时钟启动至稳定
& &&while((RCC-&CR & 0x) == 0)
& &&//选择PLL时钟作为SYSCLK信号源
& &&RCC-&CFGR &= (unsigned &int)( ~ (0x)); &//消除某时钟源作为SYSCLK的标记
& &&RCC-&CFGR |= (unsigned &int) 0x;
& &&//直到PLL时钟被切换为SYSCLK的时钟信号
& &&while ((RCC-&CFGR & (unsigned &int) 0x0000000C) != (uint32_t)0x08)
此时,HSE产生的频率为8MHz,当开板后,其频率固定。。再回头看看从SYSCLK散发出去的时钟信号,它们(HCLK,PCLK1,PCLK2)的频率已经在前面的HP_CLKx_Set()函数中设定了,只要PLL顺利的成为了SYSCLK时钟信号源,就可以得到预想频率的HCLK,PCLKx时钟信号,就可以驱动相应模块工作了。
Learning &Note Over.
排名:第590名
(2)(416)
--------老师--------
--------室友--------案例说明stm32官方库函数使用方法 (库版本v3.5, Keil MDK 5)
案例说明stm32官方库函数使用方法 (库版本v3.5, Keil MDK 5)
相关文件下载:于文章最后
stm32的官方库非常方便,但是里面的使用手册是英文的,而且也没有很详细的使用说明,对新手来说入门比较困难,而且网上现存的教程要么是针对v2.x的库的,要么是针对keil 4.x的,这两个东西更新后差别都蛮大。有新的可用为何不用最新的呢?
一: 用keil 5构建模板工程。在keil顶部选Project-&New uVision Project, 输入工程名称,进入device选择界面。注意,因为keil 5变成了在线安装Package的模式(即刚安装好软件并不附带各种芯片的包,用哪个下哪个),如果你已经安装了ST的Package,不要用那个Package!!Keil 5暂时不兼容官方库,如果用了的话编译会报错。解决方案:1.使用附带的ARM - ARM Cortex M3& & 2.如果还不行就下载我这个吧,下载好之后模板就全部构建完成了。
在你想要创建工程的文件夹下创建三个文件夹:Library、Project和Output,把刚才创建的工程所有文件剪切进Project文件夹。好了之后,我们需要添加库函数文件。解压库函数包,把解压目录下Library文件夹中的CM3文件夹和STM32F10x_StdPeriph_Driver文件夹复制到工程目录下Library文件夹下,把标准库目录下的:STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_Std Periph_Template文件夹下的main.c、stm32f10x_conf.h、stm32f10x_it.h、
stm32f10x_it.c 拷贝到你的工程\Project目录下。
用keil打开你刚才创建的工程,右键点击Source Group-&Manage Project Item
把Groups改成下图这样:
然后选择STARTUP,点击右下方的Add Files,添加startup_stm32f10x_md.s ( . Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm
),注意后缀,.s为汇编文件。(具体添加哪一个需要根据你的板载芯片来定,我的芯片Flash是128k的,属于MD,因此添加startup_stm32f10x_md.s,若为256k,则应添加startup_stm32f10x_hd.s,其他请参见官方文件进行选择)然后选择Library,在library组里面添加 “Libraries\STM32F10x_StdPeriph_Driver\src”里面的全部文件 。
再选择CMSIS,添加Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x”路径下的 system_stm32f10x.c文件,以及Libraries\CMSIS\CM3\CoreSupport下的core_cm3.c 文件。注意,除了了一个.s文件外,只添加.c即可,不需要添加.h。
添加完之后是这个样子(刚添加完没每个文件前有那个加号,编译一次之后就有了):
&添加完之后还不能编译,因为此时Keil还是从默认的路径去寻找要包括的头文件,肯定是找不到的,因此我们要更改一下路径设置,点击魔棒按钮:
点上面C/C++那一栏,点开之后下面有一个Include
Paths,点开,修改成下图这样
就是从库函数存放的位置寻找头文件。根据库函数的声明,我们需要根据自己不同的芯片uncomment掉相应的注释。库函数stm32f10x.h原话如下:&
但大家可以试一下,修改这个文件是修改不了的,因为它是只读的。一种做法是找到这个文件之后右键勾掉只读选项再修改,但这种做法太麻烦。Keil提供了一个宏定义的功能,我们只需要在刚才C/C++选项框那里Define栏写上相应代号就行了,相同的还有USE_STDPERIPH_DRIVER, 定义这个才能使用外设库。在Define栏输入USE_STDPERIPH_DRIVER,STM32F10X_MD。
这就相当于在程序中写:#define USE_STDPERIPH_DRIVER
#define STM32F10X_MD
省事很多。
还有在Output选项卡中勾选Create HEX File, 点Select Folder for Objects,选择你建立的Output文件夹(这样所有的生成文件都在Output下,方便管理)。至此,构建就完成了。
大家写程序只需要在main.c中写就行,那么如何引用库函数呢?只需要在main开头写一句include “stm32f10x.h”就可以了,这样就已经包含进了所需的所有库函数。
现在可以编译一下试一下。如果失败,那么可能有两种原因,一是你操作的过 程失误,重新来一下;二是keil5提供的devices还是不兼容,刚才建立工程的时候大家选择的是ARM - ARM Cortex M3 ,其实应该什么都不选的,但什么都不选工程无法建立,那大家可以通过直接下载我的这个工程来规避这个问题。
下面解释一下在Project文件夹下刚才复制进的几个文件:
1.stm32f10x_conf.h文件:该文件不需要手动添加进工程,会自动添加。打开之后会发现,该文件就是include了各种外设的头文件。我们需要用那个,就保留哪个include即可,其他可以删掉或注释掉。默认是全部包含,当然我们不去改动也完全可以。
2.stm32f10x_it.c文件:这个文件包含了所要使用的中断,如果有的话加入即可。
大家可以注意到解压开库函数zip之后有一个chm文件,那个就是官方固件库文档,使用很方便,用哪个查哪个即可,不过当然是全英文。
这里举几个例子说明如何使用这个文档吧,以按键控制LED为例。
首先一定要仔细读这个文档首页的几个链接的内容。看完之后,我们首先明白使用GPIO,就要先用PPP_InitTypeDef函数定义相应结构体,
GPIO_InitTypeDef GPIO_InitS
然后使能对应的时钟,即RCC。用哪个函数呢?打开文档,选择Modules-STM32F10x_Periph_Driver-RCC-RCC_Exported_Functions,这个就是RCC相关的函数了,通过硬件原理图我们可以发现GPIO使用的是APB2时钟,因此就是这个函数了:
&该函数参数:
因此我们写成:
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA , ENABLE ) ;
就是这样,其他的函数使用方法和这个大同小异。
同时,大家也要下载官方硬件的Reference Manual,代号RM0008,可以到我个人网页中下载。推荐仔细阅读前几个章节,后面的需要用那个读哪个。
案例程序main.c:
/*************************************************************
作者:Alan Zhao
CSDN博客:http://blog.csdn.net/alanzjl
*************************************************************
针脚说明:Key1-PA0,Key2-PA1,LED1-PA2,LED2-PB2,LED3-PA3
*************************************************************
#include &stm32f10x.h&
enum{LED1,LED2,LED3}LED;
enum{Key1,Key2}K
void delay(int nms){
for(;nms&=0;nms--){
for(n=1200;n&=0;n--);
void LED_Init(GPIO_TypeDef* Pin_Mode, uint16_t pin){ //LED初始化
GPIO_InitTypeDef GPIOInitS
if(Pin_Mode == GPIOA)
//由于LED1和LED3为PA,LED2为PB,因此此处需判断
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
else if(Pin_Mode == GPIOB)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOInitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIOInitStructure.GPIO_Pin =
GPIO_Init(Pin_Mode,&GPIOInitStructure);
void Key_Init(uint16_t pin){
//按键初始化
GPIO_InitTypeDef GPIO_InitS
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin =
//GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init (GPIOA,&GPIO_InitStruct);
int Keyscan(uint16_t pin){
//键盘扫描 pin为按键管脚
status=GPIO_ReadInputDataBit(GPIOA,pin); //读取按键状态,0为按下
if(status==0){
void LED_ON(LED){
//开灯函数
if(LED==LED1){
GPIOA-&BRR=GPIO_Pin_2;
else if(LED==LED2){
GPIOB-&BRR=GPIO_Pin_2;
else if(LED==LED3){
GPIOA-&BRR=GPIO_Pin_3;
void LED_OFF(LED){
//关灯函数
if(LED==LED1){
GPIOA-&BSRR=GPIO_Pin_2;
else if(LED==LED2){
GPIOB-&BSRR=GPIO_Pin_2;
else if(LED==LED3){
GPIOA-&BSRR=GPIO_Pin_3;
/****************************************************************/
int main(void){
LED_Init(GPIOA,GPIO_Pin_3);
LED_Init(GPIOA,GPIO_Pin_2);
LED_Init(GPIOB,GPIO_Pin_2);
Key_Init(GPIO_Pin_0);
Key_Init(GPIO_Pin_1);
LED_OFF(LED1);
//初始化时全部关灯
LED_OFF(LED2);
LED_OFF(LED3);
LED_ON(LED2);
delay(1000);
LED_OFF(LED2);
delay(1000);
//LED2不停闪烁
if(Keyscan(GPIO_Pin_0)){
delay(200); //去抖动
if(Keyscan(GPIO_Pin_0)){
while(Keyscan(GPIO_Pin_0));
GPIOA-&ODR ^= GPIO_Pin_2;
//灯状态取反
if(Keyscan(GPIO_Pin_1)){
delay(200);
if(Keyscan(GPIO_Pin_1)){
while(Keyscan(GPIO_Pin_1));
GPIOA-&ODR ^= GPIO_Pin_3;
//灯状态取反
相关文件下载:STM32官方固件库v3.5 & &&http://download.csdn.net/detail/alanzjl/8638291
STM32官方固件库v3.5模板工程 & &http://download.csdn.net/detail/alanzjl/8638303
我的热门文章
即使是一小步也想与你分享

我要回帖

更多关于 mdk硬件仿真 的文章

 

随机推荐