打印
[STM32F1]

根据最简单的脚本实现STM32管脚自动配置

[复制链接]
3256|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mohanwei|  楼主 | 2016-7-4 11:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mohanwei 于 2016-7-4 11:28 编辑

问题:
一个很变态的需求:一个#define能否产生多行#define?
https://bbs.21ic.com/icview-1608666-1-1.html

答案是实现不了。只能退而求其次,自己写个工具来解释GPIO初始化脚本,格式化出C代码,粘贴到工程里。
想到就做,很快就搞好了,其实不麻烦,每次读取1行,简单切割成N个字符串,然后把这些字符串用sprintf拼凑出可用的源代码,最后输出到c文件和h文件里……

经过一天的试用,重构了最近做的几个工程,发现很好用很省事……发上来希望对网友有所帮助。
欢迎测试并反馈。

使用方法:
1-下载压缩包,解压: amo的编程小工具集合V1.2.17-新增STM32F0和STM32F1系列IO配置脚本解析功能-2016-7-3.r.rar (149.56 KB)
2-目前只支持STM32F0和STM32F1这两个系列。根据你选用的系列,选一个脚本配置文件。推荐选择excel格式的,只需要填写红色内容,蓝色的点击单元格下拉箭头选择相应的选项即可:
   
  
STM32F1:FSU
  
  
信号名称
  
  
PortPin
  
  
Speed
  
  
Mode
  
  
  
  
STM32DefGPIO(
  
  
SDA
  
  
PA1
  
  
GPIO_Speed_10MHz
  
  
GPIO_Mode_Out_OD
  
  
)//I2C SDA
  
  
STM32DefGPIO(
  
  
SCL
  
  
PB12
  
  
GPIO_Speed_10MHz
  
  
GPIO_Mode_Out_OD
  
  
)//I2C SCL
  
  
STM32DefGPIO(
  
  
Blue_LED
  
  
PC15
  
  
GPIO_Speed_2MHz
  
  
GPIO_Mode_Out_PP
  
  
)//蓝色指示灯
  
  
STM32DefGPIO(
  
  
Green_Red_LED
  
  
PD5
  
  
GPIO_Speed_2MHz
  
  
GPIO_Mode_Out_PP
  
  
)//红绿指示灯
  

3-打开后,照猫画虎,把你用到的管脚都填写上去……认真检查
4-打开里面的“amo的编程小工具集合V1.2.17-新增STM32F0和F1的IO配置脚本解析.exe”,把excel里的脚本全选,复制,粘贴到“输入1”编辑框,然后点击“STM32配置IO”按钮即可
5-在程序所在目录里打开生成的c和h文件,复制代码粘贴到你的工程里。如果你的工程风格跟它一致,直接拷贝这两个文件进去即可
沙发
mohanwei|  楼主 | 2016-7-4 11:30 | 只看该作者
主贴里的例子,生成的代码:FSU_GPIO_Config.c

#include "FSU_GPIO_Config.h"

//*  如果在其它c文件已定义,则去掉本行第一个斜杠,以屏蔽这个函数定义
//STM32F1系列设置GPIO
void SetGPIO(GPIO_TypeDef *Port,
                         u16 pin,
                         GPIOSpeed_TypeDef speed,
                         GPIOMode_TypeDef mode)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin = pin;
        GPIO_InitStructure.GPIO_Mode = mode;
        GPIO_InitStructure.GPIO_Speed = speed;

        GPIO_Init(Port, &GPIO_InitStructure);
}
//  */

const GPIO_Define_Struct FSU_Gpio[FSU_GPIO_Count] = {
        {GPIOA,        GPIO_Pin_1 ,GPIO_Speed_10MHz,        GPIO_Mode_Out_OD,        SDA},        //PA1 定义为SDA
        {GPIOB,        GPIO_Pin_12,GPIO_Speed_10MHz,        GPIO_Mode_Out_OD,        SCL},        //PB12定义为SCL
        {GPIOC,        GPIO_Pin_15,GPIO_Speed_2MHz,        GPIO_Mode_Out_PP,        Blue_LED},        //PC15定义为Blue_LED
        {GPIOD,        GPIO_Pin_5 ,GPIO_Speed_2MHz,        GPIO_Mode_Out_PP,        Green_Red_LED},        //PD5 定义为Green_Red_LED
};

void FSU_GPIO_Configuration(void)//初始化所用到的GPIO
{
        u8 i,num=FSU_GPIO_Count;
        for(i=0;i<num;i++)
        {
                if(FSU_Gpio[i].no != i)//检查管脚编号是否正确
                {
                //        DebugPrint("错误的管脚编号!");
                        while(1)
                                ;
                }
                else
                {
                        SetGPIO(FSU_Gpio[i].Port,FSU_Gpio[i].pin,FSU_Gpio[i].speed,FSU_Gpio[i].mode);
                }
        }
        //添加其它初始化(如重映射、拉高或拉低某些IO等等)……
}

使用特权

评论回复
板凳
mohanwei|  楼主 | 2016-7-4 11:31 | 只看该作者
生成的头文件FSU_GPIO_Config.h:

#ifndef __FSU_GPIO_Config_h__
#define __FSU_GPIO_Config_h__

//*  如果在其它h文件已定义,则去掉本行第一个斜杠,以屏蔽这个结构体定义
typedef struct
{
        GPIO_TypeDef *Port;
        u16 pin;
        GPIOSpeed_TypeDef speed;
        GPIOMode_TypeDef mode;
        u8 no;//枚举号
}GPIO_Define_Struct;
//  */

typedef enum
{
        SDA=0,        //PA1 定义为SDA
        SCL,        //PB12定义为SCL
        Blue_LED,        //PC15定义为Blue_LED
        Green_Red_LED,        //PD5 定义为Green_Red_LED

        FSU_GPIO_Count        //使用的IO总数
}FSU_GPIO_Enum;

extern const GPIO_Define_Struct FSU_Gpio[FSU_GPIO_Count];

//PA1 定义为SDA:
#define _SetSDA                GPIO_SetBits(FSU_Gpio[SDA].Port,FSU_Gpio[SDA].pin)
#define _ClrSDA              GPIO_ResetBits(FSU_Gpio[SDA].Port,FSU_Gpio[SDA].pin)
#define _ReadSDA              GPIO_ReadBits(FSU_Gpio[SDA].Port,FSU_Gpio[SDA].pin)
//PB12定义为SCL:
#define _SetSCL                GPIO_SetBits(FSU_Gpio[SCL].Port,FSU_Gpio[SCL].pin)
#define _ClrSCL              GPIO_ResetBits(FSU_Gpio[SCL].Port,FSU_Gpio[SCL].pin)
#define _ReadSCL              GPIO_ReadBits(FSU_Gpio[SCL].Port,FSU_Gpio[SCL].pin)
//PC15定义为Blue_LED:
#define _SetBlue_LED           GPIO_SetBits(FSU_Gpio[Blue_LED].Port,FSU_Gpio[Blue_LED].pin)
#define _ClrBlue_LED         GPIO_ResetBits(FSU_Gpio[Blue_LED].Port,FSU_Gpio[Blue_LED].pin)
#define _ReadBlue_LED         GPIO_ReadBits(FSU_Gpio[Blue_LED].Port,FSU_Gpio[Blue_LED].pin)
//PD5 定义为Green_Red_LED:
#define _SetGreen_Red_LED      GPIO_SetBits(FSU_Gpio[Green_Red_LED].Port,FSU_Gpio[Green_Red_LED].pin)
#define _ClrGreen_Red_LED    GPIO_ResetBits(FSU_Gpio[Green_Red_LED].Port,FSU_Gpio[Green_Red_LED].pin)
#define _ReadGreen_Red_LED    GPIO_ReadBits(FSU_Gpio[Green_Red_LED].Port,FSU_Gpio[Green_Red_LED].pin)


void SetGPIO(GPIO_TypeDef *Port,
                         u16 pin,
                         GPIOSpeed_TypeDef speed,
                         GPIOMode_TypeDef mode);
void FSU_GPIO_Configuration(void);//初始化所用到的GPIO

#endif //__FSU_GPIO_Config_h__

使用特权

评论回复
地板
mmuuss586| | 2016-7-4 11:46 | 只看该作者
谢谢分享;

使用特权

评论回复
5
knightman| | 2016-7-11 09:26 | 只看该作者
个人感觉,使用库函数对管脚进行配置,是很方便的事情啊。

不过,还是很佩服楼主这种想到就做到的风格。 谢谢分享!

使用特权

评论回复
6
mohanwei|  楼主 | 2016-7-11 11:18 | 只看该作者
knightman 发表于 2016-7-11 09:26
个人感觉,使用库函数对管脚进行配置,是很方便的事情啊。

不过,还是很佩服楼主这种想到就做到的风格。  ...

库函数例程的槽点太多,代码完整读几遍你还不一定能能搞清楚用了多少个管脚、有没有重复……

如果只做一个功能、并且管脚也不多,怎么搞都可以……
如果有很多功能很多管脚,还要移植到其它产品拆分重组……有个总表才不会浪费时间在核查、debug上

使用特权

评论回复
7
knightman| | 2016-7-12 16:16 | 只看该作者
mohanwei 发表于 2016-7-11 11:18
库函数例程的槽点太多,代码完整读几遍你还不一定能能搞清楚用了多少个管脚、有没有重复……

如果只做一 ...

你说的对! 库函数的管脚配置,确实有些繁琐。

长知识了。楼主是牛人,还望多多指教。感谢分享你的技能…

使用特权

评论回复
8
Thethree| | 2016-7-12 21:22 | 只看该作者
难道有和FPGA里面一样的方法通过脚本设置管脚的?

使用特权

评论回复
9
Bjorn| | 2016-7-12 22:02 | 只看该作者
使用库函数对管脚进行配置还是很方便的

使用特权

评论回复
10
mohanwei|  楼主 | 2016-7-13 09:20 | 只看该作者
Bjorn 发表于 2016-7-12 22:02
使用库函数对管脚进行配置还是很方便的

这个用的就是库函数,只是封装了一下而已

ST提供的库例程和开发板例程,查找管脚定义都很麻烦,而且跟一个管脚相关的代码有很多个地方,你如果要把一个管脚从PA1改到PC3,可能要在N个文件里修改,很容易出错……
在这里只需要在excel里更改2个字母A1->C3。改完后,excel还能给你检查管脚是否有冲突,如果有,相应的单元格会变颜色高亮提示

使用特权

评论回复
11
siemens11| | 2016-7-13 09:35 | 只看该作者
单看标题还以为是几年的帖子。

这个如果放在几年前的话,的确是非常的方便的,,,

现在有了cubeMX之后,你想做的st已经给你做好,而且还比你预期的做得更好

使用特权

评论回复
12
neeringstu| | 2016-7-13 09:51 | 只看该作者
现在的工具真是越来越发达了,这样不容易出错

使用特权

评论回复
13
mohanwei|  楼主 | 2016-7-13 10:29 | 只看该作者
siemens11 发表于 2016-7-13 09:35
单看标题还以为是几年的帖子。

这个如果放在几年前的话,的确是非常的方便的,,,

cube试用过几次就卸载了。感觉如果是新手可以用它快速熟悉一下评估板……

从STM32第一片上市就开始用,现在维护的工程还有IAR4的。ST提供的例程,bug多、性能低,仅验证一下单个外设功能还可以,想用到产品还是要除错、优化过才行。而且它的库追随IDE升级,兼容性差,本质功能却并没有什么提高,所以我都不追新了,一个版本稳定了就一直用下去……
现在这样配置,看一下总表,就能不假思索的敲代码,感觉就是最简便了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:试一下能否设置签名档

177

主题

9320

帖子

24

粉丝