分享:当串口com的端口号太大怎么办?下面教你解除串口端口占用

经验分享admin 发表了文章 • 0 个评论 • 1460 次浏览 • 2014-12-16 22:50 • 来自相关话题

大多数时候电脑的com口没用到但是com口的端口号却不会从小到大来.....
下面教你解除那些占着茅坑不拉屎的端口的方法
虽然现在串口使用的不多了,但是有的时候还是会用上,但是在我门偶尔要使用串口(COM口)的时候却发现,它总是提示被占用(在使用中),而程序又限定了端口号,这个是有我们只有想办法解决串口/COM端口被占用(在使用中)的问题了

第一,检查这个端口是不是有设备在使用,如果有,可以先断开这个设备,让开位置来

第二,也是常见的问题,被某些软件占用了,解决方法如下

点击左下角“开始”菜单——“运行”——输入“regedit”——点击“确定”,打开注册表编辑器。

依照这个路径打开“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\COM Name Arbiter”

删除右侧的“ComDb”值
双击comdb字样,弹出输入框,全选删除,ok
插入串口线,设备管理器里面删除掉此时的端口,或者修改为其他端口,若是删除的,则再次插入后自动变更. 查看全部
大多数时候电脑的com口没用到但是com口的端口号却不会从小到大来.....
下面教你解除那些占着茅坑不拉屎的端口的方法
虽然现在串口使用的不多了,但是有的时候还是会用上,但是在我门偶尔要使用串口(COM口)的时候却发现,它总是提示被占用(在使用中),而程序又限定了端口号,这个是有我们只有想办法解决串口/COM端口被占用(在使用中)的问题了

第一,检查这个端口是不是有设备在使用,如果有,可以先断开这个设备,让开位置来

第二,也是常见的问题,被某些软件占用了,解决方法如下

点击左下角“开始”菜单——“运行”——输入“regedit”——点击“确定”,打开注册表编辑器。

依照这个路径打开“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\COM Name Arbiter”

删除右侧的“ComDb”值
双击comdb字样,弹出输入框,全选删除,ok
插入串口线,设备管理器里面删除掉此时的端口,或者修改为其他端口,若是删除的,则再次插入后自动变更.

stm32的usb虚拟串口驱动win7系统64位和32位不能正常安装的解决办法!stm32 virtual comport win7(终极解决办法)

经验分享admin 发表了文章 • 9 个评论 • 8669 次浏览 • 2014-12-16 13:48 • 来自相关话题

这两天用stm32f4discovery板搞usb虚拟串口,程序用stm32cubemx自动生成
生成的程序中用到了malloc这样的内存分配函数...
导致程序不能正常跑起来,也无法识别,
[相关驱动和文件本站网盘里有]
32位电脑请下载:usb虚拟串口缺失文件和驱动(32位系统x86专用).zip

64位电脑下载:usb虚拟串口缺失文件和驱动(X64位系统用).zip
下载地址:http://pan.baidu.com/s/1gdhcja7

下面都是屁话了.........

经on the way提醒修改了下,PC上面能识别出 [ stm virual comport ]这个设备
但是显示的是叹号,于是拔掉串口连接线,安装ST公司提供的虚拟串口驱动
请去下载 STM32 USB转串口驱动 Virtual COM Port Driver(V1.3.1)版本
这个安装一次完成(切记此时不要连接usb线)
完成后,连接usb虚拟串口的连接线,自动安装驱动
之后由于我的是win7 32位 Ghost系统,而且我安装过电脑管家一类的软件
曾经用清理工具把系统内不用的驱动清理过,所以关键的usbser.sys什么的都没有,
但是下载后添加到系统内还是不行。
**丢失的文件有: mdmcpq.inf 和 usbser.sys
下载这两个文件后,将mdmcpq.inf复制到c:/windows/inf/里面去
将usbser.sys复制到C:/windows/system32/drivers/里面去**
然后重新插入usb线,并在设备管理器界面右键选更新驱动,
仍然提示 已经是最新驱动,安装失败的提示
此时修改c:/windows/inf/里面的mdmcpq.inf文件内容
将里面的
**[FakeModemCopyFileSection]
usbser.sys,,,0x20
修改为
[FakeModemCopyFileSection]
;usbser.sys,,,0x20**
即,在usber.sys之前添加一个分号,然后保存,回到设备管理,更新驱动,OK





大家还有疑问的可以留言,我这次试验了N中办法,就上面的是有效的.
等我回家后试试我电脑win7 64位的如何
实验表明XP和win7 32位可用.............
TNND,win7 64电脑还是不行,百度了下,有人说是64位和32位的usbser.sys不一样,我倒....
我再去找找,坑爹啊,回到家不能用......
再去找找.....发现是usbser.sys问题,已解决 查看全部
这两天用stm32f4discovery板搞usb虚拟串口,程序用stm32cubemx自动生成
生成的程序中用到了malloc这样的内存分配函数...
导致程序不能正常跑起来,也无法识别,
[相关驱动和文件本站网盘里有]
32位电脑请下载:usb虚拟串口缺失文件和驱动(32位系统x86专用).zip

64位电脑下载:usb虚拟串口缺失文件和驱动(X64位系统用).zip
下载地址:http://pan.baidu.com/s/1gdhcja7

下面都是屁话了.........

经on the way提醒修改了下,PC上面能识别出 [ stm virual comport ]这个设备
但是显示的是叹号,于是拔掉串口连接线,安装ST公司提供的虚拟串口驱动
请去下载 STM32 USB转串口驱动 Virtual COM Port Driver(V1.3.1)版本
这个安装一次完成(切记此时不要连接usb线)
完成后,连接usb虚拟串口的连接线,自动安装驱动
之后由于我的是win7 32位 Ghost系统,而且我安装过电脑管家一类的软件
曾经用清理工具把系统内不用的驱动清理过,所以关键的usbser.sys什么的都没有,
但是下载后添加到系统内还是不行。
**丢失的文件有: mdmcpq.inf 和 usbser.sys
下载这两个文件后,将mdmcpq.inf复制到c:/windows/inf/里面去
将usbser.sys复制到C:/windows/system32/drivers/里面去**
然后重新插入usb线,并在设备管理器界面右键选更新驱动,
仍然提示 已经是最新驱动,安装失败的提示
此时修改c:/windows/inf/里面的mdmcpq.inf文件内容
将里面的
**[FakeModemCopyFileSection]
usbser.sys,,,0x20
修改为
[FakeModemCopyFileSection]
;usbser.sys,,,0x20**
即,在usber.sys之前添加一个分号,然后保存,回到设备管理,更新驱动,OK

无标题.png

大家还有疑问的可以留言,我这次试验了N中办法,就上面的是有效的.
等我回家后试试我电脑win7 64位的如何
实验表明XP和win7 32位可用.............
TNND,win7 64电脑还是不行,百度了下,有人说是64位和32位的usbser.sys不一样,我倒....
我再去找找,坑爹啊,回到家不能用......
再去找找.....发现是usbser.sys问题,已解决

stm32 F407, 用Cube做以太网通信不成功,请指教

问题困惑admin 回复了问题 • 5 人关注 • 1 个回复 • 3136 次浏览 • 2014-12-12 16:42 • 来自相关话题

分享stm32cubemx软件和各芯片驱动包下载和手动安装驱动包的方法

软件教程admin 发表了文章 • 64 个评论 • 73350 次浏览 • 2014-11-17 12:59 • 来自相关话题

由于先前分享中同时转载有其他网盘文件,
遭到版权方投诉侵权!
导致分享文件均被强制撤回!

先前如有冒犯版权作者请见谅!

**本站专用百度网盘:
http://pan.baidu.com/s/1gdhcja7**

网盘里包含本站所有实验程序和相关软件,随时更新!
同时欢迎大家提供相关程序和好用的软件!
提交到邮箱: AD@Stm32cube.com


文件列表如下;
文件名 大小 修改日期
24c02_IGT已调试成功可连续写入.zip
5.3M 2014-12-10 22:10
AN2784 使用大容量STM32F10xxx的FSMC驱动外部的存储器.pdf
715KB 2015-01-06 22:25
ATxmega单片机自动分页写24c02代码.zip
2KB 2015-02-08 20:46
AVR_XMEGA_应用教程.pdf
1.5M 2015-03-23 15:50
Atxmega64A3单片机读写24C64.zip
2KB 2015-02-11 09:36
CAN_Loopback实验.zip
5M 2014-12-31 15:19
CANopen协议分析指南.zip
898KB 2015-01-03 13:07
CAN总线原理和应用系统设计.pdf
6.5M 2015-01-18 14:15
CH372-DRIVER示例.zip
38KB 2015-04-14 16:13
CoIDE-V2Beta-20141205(ARM编程软件需GCC编译器).exe
111.9M 2014-12-21 14:32
Cube关于usb驱动库介绍.pdf
1.2M 2015-02-13 15:42
C浮点数与字符转换工具.exe
28KB 2015-03-03 21:00
F103芯片fsmc操作nand官方中文.pdf
715KB 2014-12-31 10:17
F303-i2c-neu(来自中文论坛-【福清】Paderboy分享).rar
2.8M 2015-07-27 10:44
FSMC_NAND(无坏块管理).rar
831KB 2015-01-05 19:15
HAL驱动详解.pdf
4.5M 2014-11-22 19:55
ICCAVR+V6.31带注册机.rar
4.5M 2014-11-22 19:55
IIC模拟程序(驱动部分).zip
3KB 2015-02-06 15:57
KEIL MDK4.60crack破解文件.zip
16KB 2014-11-22 19:55
LCD时序图怎么读.doc
561KB 2015-03-10 21:11
LED(Systick(非中断方式)精确定时闪烁).zip
906KB 2015-03-23 16:59
MEMS_stm32f4_discovery参考程序.zip
45KB 2015-01-06 22:58
ModBusPol(本站freemodbus移植所用软件之一).rar
3.6M 2015-01-05 19:57
STM32Cube USB device library (2).pdf
1.4M 2014-12-14 13:21
STM32F303RET-TIM2-ADC2-ADC4-DMA-UART(来自中文论坛-[福清]Paderboy分享).rar
4.5M 2015-07-27 16:56
STM32F4xx中文参考手册.zip
12.3M 2015-05-20 11:37
STM32_PID.rar
484KB 2015-01-08 16:34
STM32串口环形队列.rar
1.2M 2015-01-18 20:07
STM32自学笔记.pdf
35.8M 2014-11-22 19:55
ST专用虚拟com口驱动工具stm32 virtual com.zip
2.2M 2014-12-05 15:07
UART.rar
3.1M 2015-01-06 13:59
UCOSIII_freemodbus.7z
428KB 2014-12-12 19:45
USB_MIDI协议.pdf
184KB 2014-12-14 13:21
USB芯片Ch372和Ch375调试助手.zip
8KB 2015-03-03 22:35
UsbHidDemonstrator.zip
4.8M 2015-01-12 17:21
VS2012_ULT_chs.iso
1.53G 2015-01-21 09:57
VS_VisualAssistX_2012破解版.zip
13.3M 2015-03-24 13:30
VisualGDB-4.2r4.rar
6.1M 2015-02-13 15:19
WPF编程宝典:使用C#2012和NET 4.5 第4版_13353713.pdf
89.7M 2015-03-07 22:03
YXD-1602G LCM.pdf
188KB 2015-03-08 18:42
ad_dma_duo多路DMA采集示例.zip
10.9M 2015-01-05 19:56
altium designer14.3.14.iso
2.97G 2015-03-23 16:03
bushound5.0使用.pdf
360KB 2015-01-12 11:47
bushound50.rar
594KB 2015-02-02 20:32
chromeinstall-7u60.exe
897KB 2014-11-22 19:55
cube输入捕获红外解码-芯片F103(坛友:整个夏天 提供).docx
333KB 2015-02-28 21:29
freemodbus-v1.5.0(原版官方文件).zip
4.2M 2015-01-05 19:58
freemodbus_stm32F407_stm32cubemx移植成功.zip
9.1M 2015-01-05 19:44
gcc-arm-win32编译器(辅助CoIDE编译器用).exe
81.9M 2014-12-21 14:31
lcd1602资料.pdf
621KB 2015-03-08 20:16
malloc.zip
2KB 2014-12-16 19:02
mdk474.exe
576.8M 2014-11-22 19:55
modbus协议解析.pdf
1.5M 2015-01-05 19:57
pcl6045b_四轴运动控制芯片_中文说明.pdf
14.1M 2015-01-08 15:20
st-link_v2_usbdriver.zip
9.9M 2014-11-22 19:55
stm32F405_407XX.pdf
5.7M 2015-05-15 15:10
stm32F407-四线方式操作lcd1602(型号YXD-1602G02).zip
8.9M 2015-04-15 16:48
stm32L0.pdf
10.1M 2014-11-22 19:55
stm32cube-crc校验例程.zip
9.1M 2015-04-21 10:20
stm32cube.com_RTOS文档.pdf
710KB 2014-12-31 16:09
stm32cube_tcp_ip操作.pdf
1000KB 2014-12-31 09:59
stm32cubemx软件和驱动库下载
[]2015-04-21 16:37[/]stm32cube使用教程1-流水灯怎样用软件设置和编写的.pdf
2.6M 2014-11-22 19:55
stm32f3-usb-vcom-echo.zip
525KB 2015-03-17 11:42
stm32f407_eval学习板原理图SCH和PCB图.zip
2.7M 2014-12-12 21:16
stm32f407_pwm_uart.zip
10.3M 2015-04-20 15:40
stm32f407使用DS18b20测试温度.zip
5M 2014-12-10 22:13
stm32f4discovery_sch.zip
300KB 2014-11-22 19:55
usb_cdc简单实验.rar
5.5M 2015-01-05 18:51
usb_hid测试代码F407discovery板(配合官方Demonstrator发送和接收).zip
7.4M 2015-01-18 17:56
usb虚拟串口缺失文件和驱动(32位系统x86专用).zip
5.7M 2014-12-16 21:07
usb虚拟串口缺失文件和驱动(X64位系统用).zip
5.7M 2014-12-16 21:04
《STM32自学笔记》随书资料.rar
22M 2014-11-22 19:55
【STM32神舟III号实验例程】——NAND FLASH访问实验(实验十四) - .pdf
12.2M 2015-01-04 11:25
一些cube实验程序.zip
65.6M 2014-11-28 09:09
你好,放大器.pdf
9M 2015-04-16 15:25
使用 STM32F40507xx 和 STM32F415417xx微控制器的浮点运算单元.pdf
282KB 2015-02-02 22:42
使用 U 盘更新 STM32F4DISCOVERY 板固件.pdf
463KB 2015-04-28 17:26
使用stm32F2XX和4XX微控器时,如何提供ADC精度.PDF
602KB 2015-03-26 19:45
关于stm32cube对SRAM的操作和设置.zip
5.3M 2015-01-22 11:39
周立功◆ARM嵌入式系统实验教程(一).pdf
2.9M 2015-07-02 13:59
周立功◆ARM嵌入式系统实验教程(三).pdf
2.9M 2015-07-02 14:02
国外写的usb虚拟串口程序STM32DiscoveryVCP-master.zip
209KB 2014-12-05 15:07
圈圈教你玩USB.pdf
25M 2015-06-04 14:07
基于STM32的 PMSM FOC软件库培训.zip
2.5M 2015-05-06 14:22
基于STM32的USB程序开发笔记(stm32cubemx.com中文网提供).pdf
2.4M 2014-12-05 15:34
基于stm32cubef4(HAL驱动,非固件库)的httpserver-socket(freertos lwip)在407上调试成功(RMII模式).7z
24.2M 2015-01-06 13:59
如何编写应用程序与USB_HID_设备通讯(读写USB_HID设备).pdf
1.1M 2015-03-26 11:56
安富莱STM32-V5开发板STemWin教程1-60期.pdf
15M 2015-05-27 09:35
实例讲解USB的枚举(配置)过程.pdf
1.1M 2015-03-26 11:53
教你使用1602液晶_详细的中文指导_兼容51、AVR、PIC单片机.pdf
973KB 2015-04-17 13:52
最新stm32f407zgt-sram-cubemx.zip
9.5M 2015-04-21 11:59
本站演示所用串口调试助手(推荐).zip
133KB 2015-01-05 19:55
模拟工程师速查参考.pdf
7.1M 2015-04-17 09:44
深入解析STM32_USB-FS-Device_Lib库.pdf
697KB 2014-12-05 15:30
用STM32CubeMX初始化SD卡终于好使了 STM32F407 .png
308KB 2015-01-06 22:22
电机控制中的MOSFET和IGBT基础知识.pdf
401KB 2015-04-17 09:27
虚拟串口工具.zip
4.7M 2015-01-27 12:50
西门子PLC上所使用的软件PID程序.zip
1.1M 2015-01-03 21:07
设计原理图.pdf
38KB 2015-04-14 15:12
12864_uc1701.zip
5.6M 2015-05-19 12:00
(中文)使用STM32F2xx 和STM32F4xx 微控制器时如何提高ADC 测量精度.PDF
602KB 2015-01-29 12:59
(感谢QQ群成员-一毛-提供)F4多通道ADC+DMA+UART采集数据.zip
8.5M 2015-07-27 16:39
(电机驱动库官方版4.0)STM32_FOC_SDK_4.0.0.zip
70.8M 2015-05-06 14:45


mx更新内容如下:
Added support of code generation, clock and power consumption calculation for the new part numbers of STM32F7 series.
Management of the dependency and configuration of external I/O, when required by a peripheral
STM32CubeMX can now be installed from a console.
STM32CubeMX supports now a command line mode.
F4更新如下:
Add support of System Workbench for STM32 (SW4STM32) toolchain
Maintenance release to fix known defects, in HAL and Projects

b更新STM32Cubemx软件到4.8.0版本[/b]
------------->文件名:stm32cubemx-4.8.0.zip
(2015.3.24)更新STM32cubeF4驱动库到1.6.0版本
--------------->文件名:stm32cubef4-1.6.0.zip


喜讯: Cube支持F1系列了!
请大家务必更新!

重新上传了!以前那个没法添加后续更新文件,晕死
最近有童鞋新入手stm32cubemx软件,但是不知道怎么安装和更新,尤其是软件自动更新慢如蜗牛,
惨不忍睹,导致很多人放弃了.
在此,分享下官方最新安装包和驱动包,
本帖也会长期更新驱动的更新和官方提供的中文PDF文档下载
希望对童鞋们节省翻墙的时间................
不废话了,上地址,百度网盘

另外,官方提供的示例代码在各芯片的驱动库里面,详情请看下面的帖子
http://www.stm32cube.com/question/17
我已经将下面所有介绍到的文件都共享到上面的地址里面了
大家下载的时候按照下面的介绍文件名选择下载

首先是stm32cubemx的安装程序,最新版本是4.4.0(于2014,11,17更新)
文件名: stm32cubemx-4.4.0.zip

安装mx之后必须按照你要用到的芯片型号选择驱动包下载,
文件名类似: stm32cubef4-1.3.0.zip





下面介绍下安装驱动包的步骤:
在C盘新建一个文件夹,必须英文,也可以不是c盘,随你便




将你需要安装的驱动包下载后,解压到这个文件夹里面,无需修改任何东西
返回到stm32cubemx软件,找到heip点击 updater setting,在里面选择刚才新建的文件夹















好了,已经安装好了
你可以点击help里面的install new library查看下






软件和驱动包都安装好了.
下面说下生成程序最好设置的一个地方





这样,生成程序的时候对应的外设会分别生成.c文件,便于管理,层次更清晰
推荐使用keil4.74版本,前面的下载里面有最新的mdk474下载,里面有个绿化工具
推荐大家购买正版.
keil4.70以上版本可以支持自动补全功能,非常方便,虽然没viral stdio好用,但是也很好了.呵呵
以后慢慢更新官方发布的中文使用文档 查看全部
由于先前分享中同时转载有其他网盘文件,
遭到版权方投诉侵权!
导致分享文件均被强制撤回!

先前如有冒犯版权作者请见谅!

**本站专用百度网盘:
http://pan.baidu.com/s/1gdhcja7**

网盘里包含本站所有实验程序和相关软件,随时更新!
同时欢迎大家提供相关程序和好用的软件!
提交到邮箱: AD@Stm32cube.com


文件列表如下;
文件名 大小 修改日期
24c02_IGT已调试成功可连续写入.zip
5.3M 2014-12-10 22:10
AN2784 使用大容量STM32F10xxx的FSMC驱动外部的存储器.pdf
715KB 2015-01-06 22:25
ATxmega单片机自动分页写24c02代码.zip
2KB 2015-02-08 20:46
AVR_XMEGA_应用教程.pdf
1.5M 2015-03-23 15:50
Atxmega64A3单片机读写24C64.zip
2KB 2015-02-11 09:36
CAN_Loopback实验.zip
5M 2014-12-31 15:19
CANopen协议分析指南.zip
898KB 2015-01-03 13:07
CAN总线原理和应用系统设计.pdf
6.5M 2015-01-18 14:15
CH372-DRIVER示例.zip
38KB 2015-04-14 16:13
CoIDE-V2Beta-20141205(ARM编程软件需GCC编译器).exe
111.9M 2014-12-21 14:32
Cube关于usb驱动库介绍.pdf
1.2M 2015-02-13 15:42
C浮点数与字符转换工具.exe
28KB 2015-03-03 21:00
F103芯片fsmc操作nand官方中文.pdf
715KB 2014-12-31 10:17
F303-i2c-neu(来自中文论坛-【福清】Paderboy分享).rar
2.8M 2015-07-27 10:44
FSMC_NAND(无坏块管理).rar
831KB 2015-01-05 19:15
HAL驱动详解.pdf
4.5M 2014-11-22 19:55
ICCAVR+V6.31带注册机.rar
4.5M 2014-11-22 19:55
IIC模拟程序(驱动部分).zip
3KB 2015-02-06 15:57
KEIL MDK4.60crack破解文件.zip
16KB 2014-11-22 19:55
LCD时序图怎么读.doc
561KB 2015-03-10 21:11
LED(Systick(非中断方式)精确定时闪烁).zip
906KB 2015-03-23 16:59
MEMS_stm32f4_discovery参考程序.zip
45KB 2015-01-06 22:58
ModBusPol(本站freemodbus移植所用软件之一).rar
3.6M 2015-01-05 19:57
STM32Cube USB device library (2).pdf
1.4M 2014-12-14 13:21
STM32F303RET-TIM2-ADC2-ADC4-DMA-UART(来自中文论坛-[福清]Paderboy分享).rar
4.5M 2015-07-27 16:56
STM32F4xx中文参考手册.zip
12.3M 2015-05-20 11:37
STM32_PID.rar
484KB 2015-01-08 16:34
STM32串口环形队列.rar
1.2M 2015-01-18 20:07
STM32自学笔记.pdf
35.8M 2014-11-22 19:55
ST专用虚拟com口驱动工具stm32 virtual com.zip
2.2M 2014-12-05 15:07
UART.rar
3.1M 2015-01-06 13:59
UCOSIII_freemodbus.7z
428KB 2014-12-12 19:45
USB_MIDI协议.pdf
184KB 2014-12-14 13:21
USB芯片Ch372和Ch375调试助手.zip
8KB 2015-03-03 22:35
UsbHidDemonstrator.zip
4.8M 2015-01-12 17:21
VS2012_ULT_chs.iso
1.53G 2015-01-21 09:57
VS_VisualAssistX_2012破解版.zip
13.3M 2015-03-24 13:30
VisualGDB-4.2r4.rar
6.1M 2015-02-13 15:19
WPF编程宝典:使用C#2012和NET 4.5 第4版_13353713.pdf
89.7M 2015-03-07 22:03
YXD-1602G LCM.pdf
188KB 2015-03-08 18:42
ad_dma_duo多路DMA采集示例.zip
10.9M 2015-01-05 19:56
altium designer14.3.14.iso
2.97G 2015-03-23 16:03
bushound5.0使用.pdf
360KB 2015-01-12 11:47
bushound50.rar
594KB 2015-02-02 20:32
chromeinstall-7u60.exe
897KB 2014-11-22 19:55
cube输入捕获红外解码-芯片F103(坛友:整个夏天 提供).docx
333KB 2015-02-28 21:29
freemodbus-v1.5.0(原版官方文件).zip
4.2M 2015-01-05 19:58
freemodbus_stm32F407_stm32cubemx移植成功.zip
9.1M 2015-01-05 19:44
gcc-arm-win32编译器(辅助CoIDE编译器用).exe
81.9M 2014-12-21 14:31
lcd1602资料.pdf
621KB 2015-03-08 20:16
malloc.zip
2KB 2014-12-16 19:02
mdk474.exe
576.8M 2014-11-22 19:55
modbus协议解析.pdf
1.5M 2015-01-05 19:57
pcl6045b_四轴运动控制芯片_中文说明.pdf
14.1M 2015-01-08 15:20
st-link_v2_usbdriver.zip
9.9M 2014-11-22 19:55
stm32F405_407XX.pdf
5.7M 2015-05-15 15:10
stm32F407-四线方式操作lcd1602(型号YXD-1602G02).zip
8.9M 2015-04-15 16:48
stm32L0.pdf
10.1M 2014-11-22 19:55
stm32cube-crc校验例程.zip
9.1M 2015-04-21 10:20
stm32cube.com_RTOS文档.pdf
710KB 2014-12-31 16:09
stm32cube_tcp_ip操作.pdf
1000KB 2014-12-31 09:59
stm32cubemx软件和驱动库下载
    []2015-04-21 16:37[/]
stm32cube使用教程1-流水灯怎样用软件设置和编写的.pdf
2.6M 2014-11-22 19:55
stm32f3-usb-vcom-echo.zip
525KB 2015-03-17 11:42
stm32f407_eval学习板原理图SCH和PCB图.zip
2.7M 2014-12-12 21:16
stm32f407_pwm_uart.zip
10.3M 2015-04-20 15:40
stm32f407使用DS18b20测试温度.zip
5M 2014-12-10 22:13
stm32f4discovery_sch.zip
300KB 2014-11-22 19:55
usb_cdc简单实验.rar
5.5M 2015-01-05 18:51
usb_hid测试代码F407discovery板(配合官方Demonstrator发送和接收).zip
7.4M 2015-01-18 17:56
usb虚拟串口缺失文件和驱动(32位系统x86专用).zip
5.7M 2014-12-16 21:07
usb虚拟串口缺失文件和驱动(X64位系统用).zip
5.7M 2014-12-16 21:04
《STM32自学笔记》随书资料.rar
22M 2014-11-22 19:55
【STM32神舟III号实验例程】——NAND FLASH访问实验(实验十四) - .pdf
12.2M 2015-01-04 11:25
一些cube实验程序.zip
65.6M 2014-11-28 09:09
你好,放大器.pdf
9M 2015-04-16 15:25
使用 STM32F40507xx 和 STM32F415417xx微控制器的浮点运算单元.pdf
282KB 2015-02-02 22:42
使用 U 盘更新 STM32F4DISCOVERY 板固件.pdf
463KB 2015-04-28 17:26
使用stm32F2XX和4XX微控器时,如何提供ADC精度.PDF
602KB 2015-03-26 19:45
关于stm32cube对SRAM的操作和设置.zip
5.3M 2015-01-22 11:39
周立功◆ARM嵌入式系统实验教程(一).pdf
2.9M 2015-07-02 13:59
周立功◆ARM嵌入式系统实验教程(三).pdf
2.9M 2015-07-02 14:02
国外写的usb虚拟串口程序STM32DiscoveryVCP-master.zip
209KB 2014-12-05 15:07
圈圈教你玩USB.pdf
25M 2015-06-04 14:07
基于STM32的 PMSM FOC软件库培训.zip
2.5M 2015-05-06 14:22
基于STM32的USB程序开发笔记(stm32cubemx.com中文网提供).pdf
2.4M 2014-12-05 15:34
基于stm32cubef4(HAL驱动,非固件库)的httpserver-socket(freertos lwip)在407上调试成功(RMII模式).7z
24.2M 2015-01-06 13:59
如何编写应用程序与USB_HID_设备通讯(读写USB_HID设备).pdf
1.1M 2015-03-26 11:56
安富莱STM32-V5开发板STemWin教程1-60期.pdf
15M 2015-05-27 09:35
实例讲解USB的枚举(配置)过程.pdf
1.1M 2015-03-26 11:53
教你使用1602液晶_详细的中文指导_兼容51、AVR、PIC单片机.pdf
973KB 2015-04-17 13:52
最新stm32f407zgt-sram-cubemx.zip
9.5M 2015-04-21 11:59
本站演示所用串口调试助手(推荐).zip
133KB 2015-01-05 19:55
模拟工程师速查参考.pdf
7.1M 2015-04-17 09:44
深入解析STM32_USB-FS-Device_Lib库.pdf
697KB 2014-12-05 15:30
用STM32CubeMX初始化SD卡终于好使了 STM32F407 .png
308KB 2015-01-06 22:22
电机控制中的MOSFET和IGBT基础知识.pdf
401KB 2015-04-17 09:27
虚拟串口工具.zip
4.7M 2015-01-27 12:50
西门子PLC上所使用的软件PID程序.zip
1.1M 2015-01-03 21:07
设计原理图.pdf
38KB 2015-04-14 15:12
12864_uc1701.zip
5.6M 2015-05-19 12:00
(中文)使用STM32F2xx 和STM32F4xx 微控制器时如何提高ADC 测量精度.PDF
602KB 2015-01-29 12:59
(感谢QQ群成员-一毛-提供)F4多通道ADC+DMA+UART采集数据.zip
8.5M 2015-07-27 16:39
(电机驱动库官方版4.0)STM32_FOC_SDK_4.0.0.zip
70.8M 2015-05-06 14:45


mx更新内容如下:
Added support of code generation, clock and power consumption calculation for the new part numbers of STM32F7 series.
Management of the dependency and configuration of external I/O, when required by a peripheral
STM32CubeMX can now be installed from a console.
STM32CubeMX supports now a command line mode.
F4更新如下:
Add support of System Workbench for STM32 (SW4STM32) toolchain
Maintenance release to fix known defects, in HAL and Projects

b更新STM32Cubemx软件到4.8.0版本[/b]
------------->文件名:stm32cubemx-4.8.0.zip
(2015.3.24)更新STM32cubeF4驱动库到1.6.0版本
--------------->文件名:stm32cubef4-1.6.0.zip


喜讯: Cube支持F1系列了!
请大家务必更新!

重新上传了!以前那个没法添加后续更新文件,晕死
最近有童鞋新入手stm32cubemx软件,但是不知道怎么安装和更新,尤其是软件自动更新慢如蜗牛,
惨不忍睹,导致很多人放弃了.
在此,分享下官方最新安装包和驱动包,
本帖也会长期更新驱动的更新和官方提供的中文PDF文档下载
希望对童鞋们节省翻墙的时间................
不废话了,上地址,百度网盘

另外,官方提供的示例代码在各芯片的驱动库里面,详情请看下面的帖子
http://www.stm32cube.com/question/17
我已经将下面所有介绍到的文件都共享到上面的地址里面了
大家下载的时候按照下面的介绍文件名选择下载

首先是stm32cubemx的安装程序,最新版本是4.4.0(于2014,11,17更新)
文件名: stm32cubemx-4.4.0.zip

安装mx之后必须按照你要用到的芯片型号选择驱动包下载,
文件名类似: stm32cubef4-1.3.0.zip

无标题.png

下面介绍下安装驱动包的步骤:
在C盘新建一个文件夹,必须英文,也可以不是c盘,随你便
无标题3.png

将你需要安装的驱动包下载后,解压到这个文件夹里面,无需修改任何东西
返回到stm32cubemx软件,找到heip点击 updater setting,在里面选择刚才新建的文件夹

无标题1.png


无标题2.png


无标题22.png

好了,已经安装好了
你可以点击help里面的install new library查看下

无标题4.png


软件和驱动包都安装好了.
下面说下生成程序最好设置的一个地方

无标题45.png

这样,生成程序的时候对应的外设会分别生成.c文件,便于管理,层次更清晰
推荐使用keil4.74版本,前面的下载里面有最新的mdk474下载,里面有个绿化工具
推荐大家购买正版.
keil4.70以上版本可以支持自动补全功能,非常方便,虽然没viral stdio好用,但是也很好了.呵呵
以后慢慢更新官方发布的中文使用文档

记录stm32cubemx中I2C的DMA板卡之间的传输设置

软件教程admin 发表了文章 • 3 个评论 • 4290 次浏览 • 2014-11-07 09:23 • 来自相关话题

I2c板卡之间连接示意图





先上图,后面解释..




















2楼注释 查看全部
I2c板卡之间连接示意图

5.png

先上图,后面解释..

1.png


2.png


3.png


4.png

2楼注释

stm32cubemx教程之ADC采集通过DMA传输,听说能省很多CPU时间做其他事

软件教程admin 发表了文章 • 21 个评论 • 12922 次浏览 • 2014-11-06 11:44 • 来自相关话题

再次写写stm32cubemx中AD采集的问题,这次不用while里面的查询,也不用中断采样了,直接用DMA
先说下用DMA的好处:无论是中断采样还是查询采样,都需要在主程序中占用好多时间出来,嗯,你可以这样理解
那种采样都需要调用HAL_ADC_GetValue()这个函数,,,就是要取得转换后的值,中断还好点,要是查询的话,有可能会丢失数据啊. 用dma就可以避免了
DMA用的事总线时间,无线cpu干预,额,这种说法貌似有点问题.管它呢
在AD转换结束的时候自动连接你准备存取的变量的地址,数据一步到位.额,省了多少事..
使用stm32cubemx对AD的配置





然后对她的DMA配置,并开启DMA的中断




然后生成代码吧
打开main.c文件,在这个地方添加代码

/[i] USER CODE BEGIN 0 [/i]/
__IO uint16_t uhADCxConvertedValue = 0;
/[i] USER CODE END 0 [/i]/

在main()函数里添加

/[i] USER CODE BEGIN 2 [/i]/
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue, 1);

/[i] USER CODE END 2 [/i]/

意思是开启dma传输,传送一个字的数据到uhADCxConvertedValue这个变量里面
然后再文件的末尾处添加

/[i] USER CODE BEGIN 4 [/i]/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/[i] Turn LED1 on: Transfer process is correct [/i]/
// BSP_LED_On(LED1);
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
}
/[i] USER CODE END 4 [/i]/

意思是AD转换完成调用这个函数,哈数里使能led
也许,你会问,为毛是HAL_ADC_ConvCpltCallback()这个函数啊,这个函数不是当开启AD的中断的时候才调用的吗?
嗯,对,这个函数是这样的,但是你仔细去分析下开启AD的DMA中断函数里面,就会发现这个函数也在啊
如下图.进入HAL_ADC_Start_DMA函数里面,看到





在进入到图中的ADC_DMAConvCplt函数里面看到





OK,疑问解决,
以后用到AD就可以直接调用这个CALL了,不要纠结了. 查看全部
再次写写stm32cubemx中AD采集的问题,这次不用while里面的查询,也不用中断采样了,直接用DMA
先说下用DMA的好处:无论是中断采样还是查询采样,都需要在主程序中占用好多时间出来,嗯,你可以这样理解
那种采样都需要调用HAL_ADC_GetValue()这个函数,,,就是要取得转换后的值,中断还好点,要是查询的话,有可能会丢失数据啊. 用dma就可以避免了
DMA用的事总线时间,无线cpu干预,额,这种说法貌似有点问题.管它呢
在AD转换结束的时候自动连接你准备存取的变量的地址,数据一步到位.额,省了多少事..
使用stm32cubemx对AD的配置

5.png

然后对她的DMA配置,并开启DMA的中断
无标题.png

然后生成代码吧
打开main.c文件,在这个地方添加代码

/[i] USER CODE BEGIN 0 [/i]/
__IO uint16_t uhADCxConvertedValue = 0;
/[i] USER CODE END 0 [/i]/


在main()函数里添加

  /[i] USER CODE BEGIN 2 [/i]/
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue, 1);

/[i] USER CODE END 2 [/i]/


意思是开启dma传输,传送一个字的数据到uhADCxConvertedValue这个变量里面
然后再文件的末尾处添加

/[i] USER CODE BEGIN 4 [/i]/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/[i] Turn LED1 on: Transfer process is correct [/i]/
// BSP_LED_On(LED1);
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
}
/[i] USER CODE END 4 [/i]/


意思是AD转换完成调用这个函数,哈数里使能led
也许,你会问,为毛是HAL_ADC_ConvCpltCallback()这个函数啊,这个函数不是当开启AD的中断的时候才调用的吗?
嗯,对,这个函数是这样的,但是你仔细去分析下开启AD的DMA中断函数里面,就会发现这个函数也在啊
如下图.进入HAL_ADC_Start_DMA函数里面,看到

2.png

在进入到图中的ADC_DMAConvCplt函数里面看到

3.png

OK,疑问解决,
以后用到AD就可以直接调用这个CALL了,不要纠结了.

stm32cubemx教程之简单测试片内FLASH的烧写

软件教程admin 发表了文章 • 8 个评论 • 12861 次浏览 • 2014-11-04 17:25 • 来自相关话题

基于官方的flash例子来做的
针对flash的擦除和写入软件stm32cubemx不需要设置任何外设,因为没用到,
额,我用了一个led作为擦除后写入在读取比较的指示
所以,软件商设置好RCC和GPIO口的led灯配置,生成代码
因为,stm32cube用的最新的库函数,里面已经包含了以前stm32f1系列针对flash的操作
根本不需要自己编写任何函数.嗯,方便了不少
falsh是按照SECTOR来擦除的,这方面有很多的资料
所以打开main.c后
在用户代码输入0处写入以下代码


/[i] USER CODE BEGIN 0 [/i]/
#define DATA_32 ((uint32_t)0x12345678)

uint32_t startAddress = 0, endAddress = 0;
uint32_t data32 = 0 , MemoryProgramStatus = 0;

static FLASH_EraseInitTypeDef EraseInitStruct;
/[i] USER CODE END 0 [/i]/


以上,定义了几个变量,分别是起始地址和终止地址,这两个是我准备写入的范围
接着是data32就是32位的数据变量,等会要用来存储读出的32位数据

static FLASH_EraseInitTypeDef EraseInitStruct;

// 这个意思是flash要擦除的块的一个结构体变量,额,这个库里面定义的,我们只需要修改值就行
在main函数中用户代码输入2处写入以下代码


/[i] USER CODE BEGIN 2 [/i]/
HAL_FLASH_Unlock(); //解锁,删除和写入必须先解锁,规定的
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct .VoltageRange =VOLTAGE_RANGE_3 ;
EraseInitStruct.Sector = FLASH_SECTOR_2 ;
EraseInitStruct.NbSectors = 2;
//以上,定义删除类型是SECTORS就是块,提供的电压是3.3v的所以选VOLTAGE_RANGE_3
//从FLASH_SECTOR_2业就是第二块开始删除,删除的数量是2个
HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
//清除函数,如果出错则错误码存储到SectorError这个里面
startAddress = 0x08008000;
endAddress = 0x0800C000;
//设置了准备写入数据的起始地址和结束地址
while (startAddress < endAddress)
{
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, startAddress, DATA_32) == HAL_OK)
{
startAddress = startAddress + 4;
}

}
//以上,如果起始地址开始累加写入,一直写入到endAddress这个地址结束,写入的是0x12345678这个数
HAL_FLASH_Lock();
//锁定,读取的话,无需解锁
startAddress = 0x08008000;
MemoryProgramStatus = 0x0;

while (startAddress < endAddress)
{
data32 = [url=__IO uint32_t[/i]]i[/url]startAddress;

if (data32 != DATA_32)
{
MemoryProgramStatus++;
}

startAddress = startAddress + 4;
}
//以上,逐个读取32位数据和前面写入的数据0x12345678对比,若不同则MemoryProgramStatus这个变量自加1
/[i]Check if there is an issue to program data[/i]/
if (MemoryProgramStatus == 0)
{
/[i] No error detected. Switch on LED4[/i]/
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
}
else
{
/[i] Error detected. Switch on LED5[/i]/
// Error_Handler();
}

//以上,若MemoryProgramStatus这个变量一直是0没加过,说明没有任何错误,数据写入正确,led点亮
/[i] USER CODE END 2 [/i]/

当然你也可以输入刚才写入的地址看看里面的数据是否是你要的.
以keil为例,在线调试状态下,在右下角的memery地址里面输入0x08008000,看看里面的数据,嗯,是对的 查看全部
基于官方的flash例子来做的
针对flash的擦除和写入软件stm32cubemx不需要设置任何外设,因为没用到,
额,我用了一个led作为擦除后写入在读取比较的指示
所以,软件商设置好RCC和GPIO口的led灯配置,生成代码
因为,stm32cube用的最新的库函数,里面已经包含了以前stm32f1系列针对flash的操作
根本不需要自己编写任何函数.嗯,方便了不少
falsh是按照SECTOR来擦除的,这方面有很多的资料
所以打开main.c后
在用户代码输入0处写入以下代码


/[i] USER CODE BEGIN 0 [/i]/
#define DATA_32 ((uint32_t)0x12345678)

uint32_t startAddress = 0, endAddress = 0;
uint32_t data32 = 0 , MemoryProgramStatus = 0;

static FLASH_EraseInitTypeDef EraseInitStruct;
/[i] USER CODE END 0 [/i]/


以上,定义了几个变量,分别是起始地址和终止地址,这两个是我准备写入的范围
接着是data32就是32位的数据变量,等会要用来存储读出的32位数据

static FLASH_EraseInitTypeDef EraseInitStruct; 


// 这个意思是flash要擦除的块的一个结构体变量,额,这个库里面定义的,我们只需要修改值就行
在main函数中用户代码输入2处写入以下代码


 /[i] USER CODE BEGIN 2 [/i]/
HAL_FLASH_Unlock(); //解锁,删除和写入必须先解锁,规定的
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct .VoltageRange =VOLTAGE_RANGE_3 ;
EraseInitStruct.Sector = FLASH_SECTOR_2 ;
EraseInitStruct.NbSectors = 2;
//以上,定义删除类型是SECTORS就是块,提供的电压是3.3v的所以选VOLTAGE_RANGE_3
//从FLASH_SECTOR_2业就是第二块开始删除,删除的数量是2个
HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
//清除函数,如果出错则错误码存储到SectorError这个里面
startAddress = 0x08008000;
endAddress = 0x0800C000;
//设置了准备写入数据的起始地址和结束地址
while (startAddress < endAddress)
{
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, startAddress, DATA_32) == HAL_OK)
{
startAddress = startAddress + 4;
}

}
//以上,如果起始地址开始累加写入,一直写入到endAddress这个地址结束,写入的是0x12345678这个数
HAL_FLASH_Lock();
//锁定,读取的话,无需解锁
startAddress = 0x08008000;
MemoryProgramStatus = 0x0;

while (startAddress < endAddress)
{
data32 = [url=__IO uint32_t[/i]]i[/url]startAddress;

if (data32 != DATA_32)
{
MemoryProgramStatus++;
}

startAddress = startAddress + 4;
}
//以上,逐个读取32位数据和前面写入的数据0x12345678对比,若不同则MemoryProgramStatus这个变量自加1
/[i]Check if there is an issue to program data[/i]/
if (MemoryProgramStatus == 0)
{
/[i] No error detected. Switch on LED4[/i]/
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
}
else
{
/[i] Error detected. Switch on LED5[/i]/
// Error_Handler();
}

//以上,若MemoryProgramStatus这个变量一直是0没加过,说明没有任何错误,数据写入正确,led点亮
/[i] USER CODE END 2 [/i]/


当然你也可以输入刚才写入的地址看看里面的数据是否是你要的.
以keil为例,在线调试状态下,在右下角的memery地址里面输入0x08008000,看看里面的数据,嗯,是对的

无标题.png


关于stm32cubemx生成的RTC程序的学习记录,用到RTC/usart/printf/sprintf,基于官方库例子

软件教程admin 发表了文章 • 27 个评论 • 10943 次浏览 • 2014-11-04 10:22 • 来自相关话题

先大略的看了下官方的RTC的例子,
于是准备利用usart的printf输出,启用了stm32cube中的RTC
首先初始化了uart的printf初始化了rtc,
然后随便uart输出一个东西,
发现此时上电后,usart输出好慢,不是立马输出
于是,注释掉MX_RTC_Init();
重新烧录,输出速度正常了......
说明stm32cubemx生成的RTC初始化代码初始RTC时间长啊....不是一般的长,我还没有开始初始定义的说.
好了,2楼继续

好吧,懒得仔细搞了,就大致按照官方的例子弄下算了
过程如下:
设置此时的时间为2:20:00,2014年1月18号
定时时间为:2:20:30秒零56,2014年1月18号,
定时时间到产生中断,使LED灯亮.
ok,就按照这个来做,
下面的图示是stm32cubemx软件的相关RTC设置




















还有GPIO的设置,推挽,上拉,ok
设置完毕后自动生成代码
打开RTc.c文件,更改下面的代码为:
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;

/**Initialize RTC and set the Time and Date
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_RTC_Init(&hrtc);

sTime.Hours = 0x02;
sTime.Minutes = 0x20;
sTime.Seconds = 0;
sTime.SubSeconds = 0;
sTime.TimeFormat = RTC_HOURFORMAT12_AM;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD);

sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x18;
sDate.Year = 0x14;
HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD);

/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0x02;
sAlarm.AlarmTime.Minutes = 0x20;
sAlarm.AlarmTime.Seconds = 0x30;
sAlarm.AlarmTime.SubSeconds = 0x56;
sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_None;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);

}
这个就是刚才第一步时候提到的时间,对号入座....不解释了
返回到main.c文件
在用户代码4的地方写入:
/ USER CODE BEGIN 4 /
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_RTC_AlarmAEventCallback could be implemented in the user file
*/
HAL_GPIO_WritePin (GPIOG,GPIO_PIN_6,GPIO_PIN_RESET );
}
这个是定时中断的返回调用,当中断的时候,使LED亮(我的板子是负驱动)...
ok,测试和官方实例效果一样......
30秒后led亮.....
当然这个事例子......你可以设定时间长一点,比如,好几天之后的某天..
修修补补就可以用了. 查看全部
先大略的看了下官方的RTC的例子,
于是准备利用usart的printf输出,启用了stm32cube中的RTC
首先初始化了uart的printf初始化了rtc,
然后随便uart输出一个东西,
发现此时上电后,usart输出好慢,不是立马输出
于是,注释掉MX_RTC_Init();
重新烧录,输出速度正常了......
说明stm32cubemx生成的RTC初始化代码初始RTC时间长啊....不是一般的长,我还没有开始初始定义的说.
好了,2楼继续

好吧,懒得仔细搞了,就大致按照官方的例子弄下算了
过程如下:
设置此时的时间为2:20:00,2014年1月18号
定时时间为:2:20:30秒零56,2014年1月18号,
定时时间到产生中断,使LED灯亮.
ok,就按照这个来做,
下面的图示是stm32cubemx软件的相关RTC设置

2.png


3.png


4.png


5.png

还有GPIO的设置,推挽,上拉,ok
设置完毕后自动生成代码
打开RTc.c文件,更改下面的代码为:
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;

/**Initialize RTC and set the Time and Date
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_RTC_Init(&hrtc);

sTime.Hours = 0x02;
sTime.Minutes = 0x20;
sTime.Seconds = 0;
sTime.SubSeconds = 0;
sTime.TimeFormat = RTC_HOURFORMAT12_AM;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD);

sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x18;
sDate.Year = 0x14;
HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD);

/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0x02;
sAlarm.AlarmTime.Minutes = 0x20;
sAlarm.AlarmTime.Seconds = 0x30;
sAlarm.AlarmTime.SubSeconds = 0x56;
sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_None;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);

}
这个就是刚才第一步时候提到的时间,对号入座....不解释了
返回到main.c文件
在用户代码4的地方写入:
/ USER CODE BEGIN 4 /
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_RTC_AlarmAEventCallback could be implemented in the user file
*/
HAL_GPIO_WritePin (GPIOG,GPIO_PIN_6,GPIO_PIN_RESET );
}
这个是定时中断的返回调用,当中断的时候,使LED亮(我的板子是负驱动)...
ok,测试和官方实例效果一样......
30秒后led亮.....
当然这个事例子......你可以设定时间长一点,比如,好几天之后的某天..
修修补补就可以用了.

为什么fsmc控制nand,将时间都调到最大了,写入数据后读出来还是不一样啊?

回复

问题困惑admin 回复了问题 • 1 人关注 • 1 个回复 • 1985 次浏览 • 2014-10-31 17:27 • 来自相关话题

K9F1G08三星nand芯片数据的理解,数据手册怎么看?

回复

经验分享admin 回复了问题 • 1 人关注 • 1 个回复 • 1548 次浏览 • 2014-10-30 10:34 • 来自相关话题

自问自答:有人用过stm32cubemx生成的fsmc的nand程序?用stm32cube生成的代码怎么用啊?

回复

经验分享admin 回复了问题 • 1 人关注 • 2 个回复 • 4866 次浏览 • 2014-10-29 17:23 • 来自相关话题

usart的真正用法之一堆栈,push和pop处理uart得到的数据,不要再说stm32cube的新库函数不好用了

软件教程admin 发表了文章 • 17 个评论 • 6153 次浏览 • 2014-10-22 14:17 • 来自相关话题

b[/b]

如题:
刚开始用stm32cube的最新uart库函数的时候其实我也发牢骚了半天.
甚至不知道应该怎么去处理数据..........
汗,只怪自己就没怎么认真学过,还敢自称会用uart,汗颜
以前就是直接接收到数据,然后判断处理,这个其实就是小成用法.
下面列出研究了两天的稍微大成点的用法
将uart取得的数据,经过入栈存入到一个数据表中,然后用pop出栈进行数据处理
大体做法是:
要进行传输的数据必须格式化,例如设置数据头和数据尾来判断一帧完整的数据.
数据的头和尾之间是有效数据,可以包含数据的定义和数据本身
单片机接受到数据后,先存入到
HAL_UART_Receive_IT(&huart1, que._data, QUEUE_max_size);
这句话的que._data数据表中,这个数据表可以设置的长一点,不会溢出就行
然后写一个程序处理这个里面的数据,第一步就是查找判断这个数据是不是按照上面的数据格式
的数据,如果不是则舍弃,否则,按照你的数据规则取得这个有效的数据例如queue_find_cmd(cmd_buffer,30),其中cmd_buffer里面就是得到的数据.
然后可以依照规则将每位进行分解处理,例如cmd_buffer[1]=0x00表示这次传输的是数字,=0x01则表示传输的是字符串,然后cmd_buffer[2]+(cmd_buffer[3]<<8)+(cmd_buffer[4]<<16)+(cmd_buffer[5]<<24).
这样表示后面的是连续32位数据,呵呵
2楼继续. 查看全部
b[/b]

如题:
刚开始用stm32cube的最新uart库函数的时候其实我也发牢骚了半天.
甚至不知道应该怎么去处理数据..........
汗,只怪自己就没怎么认真学过,还敢自称会用uart,汗颜
以前就是直接接收到数据,然后判断处理,这个其实就是小成用法.
下面列出研究了两天的稍微大成点的用法
将uart取得的数据,经过入栈存入到一个数据表中,然后用pop出栈进行数据处理
大体做法是:
要进行传输的数据必须格式化,例如设置数据头和数据尾来判断一帧完整的数据.
数据的头和尾之间是有效数据,可以包含数据的定义和数据本身
单片机接受到数据后,先存入到
HAL_UART_Receive_IT(&huart1, que._data, QUEUE_max_size);
这句话的que._data数据表中,这个数据表可以设置的长一点,不会溢出就行
然后写一个程序处理这个里面的数据,第一步就是查找判断这个数据是不是按照上面的数据格式
的数据,如果不是则舍弃,否则,按照你的数据规则取得这个有效的数据例如queue_find_cmd(cmd_buffer,30),其中cmd_buffer里面就是得到的数据.
然后可以依照规则将每位进行分解处理,例如cmd_buffer[1]=0x00表示这次传输的是数字,=0x01则表示传输的是字符串,然后cmd_buffer[2]+(cmd_buffer[3]<<8)+(cmd_buffer[4]<<16)+(cmd_buffer[5]<<24).
这样表示后面的是连续32位数据,呵呵
2楼继续.

祝贺版主,希望持续的关注,能给你继续努力的动力

新手交流admin 回复了问题 • 1 人关注 • 2 个回复 • 562 次浏览 • 2014-10-21 10:54 • 来自相关话题

TIM定时器再次研究,其实一直都是只知道用,不知道道理,导致后面出了好多问题,烦

经验分享admin 发表了文章 • 12 个评论 • 12822 次浏览 • 2014-10-20 09:59 • 来自相关话题

只研究stm32cube生成的代码里面的TIM定时器的用法.
这次务必搞懂,不留后遗症,一直知道怎么用,但是还是不了解为什么,导致问题多多,以此借鉴!






1: 生成了一个定时一秒的代码,如下:
/ TIM3 init function /
void MX_TIM3_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 8399;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 9999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);

}
为什么呢?以前是按照我总结的写的,这次原理要弄懂.tnnd
htim3.Init.Prescaler = 8399; 这个是分频数,就是将时钟分频使频率降低,额,我是这样理解的
上面用的定时器3,连接的是APB1时钟,而我的时钟是:





所以当前的频率是:时钟频率/(分频数+1)=84000000/8400=10000HZ
即每次定时器自加1时间为1/10000=0.0001s
htim3.Init.Period = 9999; 这个意思是:自动重载值,可以理解为当从0开始加到这个值的时候,定时器中断一次
所以从0加到9999共10000次,所需时间=10000*0.0001=1s
定时时间1s.
好了,2楼回复中继续研究定时器其他参数. 查看全部
只研究stm32cube生成的代码里面的TIM定时器的用法.
这次务必搞懂,不留后遗症,一直知道怎么用,但是还是不了解为什么,导致问题多多,以此借鉴!

1345217050_8286.JPG


1: 生成了一个定时一秒的代码,如下:
/ TIM3 init function /
void MX_TIM3_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 8399;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 9999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);

}
为什么呢?以前是按照我总结的写的,这次原理要弄懂.tnnd
htim3.Init.Prescaler = 8399; 这个是分频数,就是将时钟分频使频率降低,额,我是这样理解的
上面用的定时器3,连接的是APB1时钟,而我的时钟是:

QQ图片20141020095418.jpg

所以当前的频率是:时钟频率/(分频数+1)=84000000/8400=10000HZ
即每次定时器自加1时间为1/10000=0.0001s
htim3.Init.Period = 9999; 这个意思是:自动重载值,可以理解为当从0开始加到这个值的时候,定时器中断一次
所以从0加到9999共10000次,所需时间=10000*0.0001=1s
定时时间1s.
好了,2楼回复中继续研究定时器其他参数.

(分享)经典的按键程序,用状态机写的,支持长按双按等

经验分享admin 发表了文章 • 2 个评论 • 2174 次浏览 • 2014-10-16 14:08 • 来自相关话题

转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif 查看全部
转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif