如何使stm32程序更好移植, 结构体相当于define
原创:转载请标注引用地址
如何定义 led1对应于PA8 呢
:对于我一开始学习的方法::
#include "main.h"
#define led1 GPIO_Pin_8 //管脚宏定义 PA8
//=================================================================================================
//函数名称: GPIO_Configuration
//输入参数: void
//输出参数: void
//函数功能: 所用到的GPIO的初始化
//日 期: 2017-11-13
//作 者: GXTon
//=================================================================================================
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTA时钟
//下面是用于测试的小灯的设置
GPIO_InitStructure.GPIO_Pin = led1; //PA8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
在主函数中:
void main(void)
{
//一系列的初始化
.........
.........
GPIO_Configuration();
while(1)
{
GPIO_SetBits(GPIOA,led1); //点亮灯
Delay_ms(1000);
GPIO_ResetBits(GPIOA,led1); //灭掉灯
Delay_ms(1000);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
上面的程序是经常用的,但是总感觉不太顺利,尤其是每次要换板子
,也就是对应的小灯在新的板子上换了引脚:
如把 led1==PA8 改成 led1==PB10
对应的引脚总要改三个地方:: 点亮一个小灯也就需要下面三个函数,
也就是说你要移植一个程序,就要改动用到函数的每一个部分,
这根本就不是很好的程序
1: #define led1 GPIO_Pin_8 //管脚宏定义 PA8 ---->改为GPIO_Pin_10
2:void GPIO_Configuration(void) ---->需要改时钟,改赋值处
3:GPIO_SetBits(GPIOA,led1); //点亮灯 ---->需要改为GPIO_SetBits(GPIOB,led1);
下面对这三部分进行改造,
第一部分不用define,而用结构体,,,用结构体的好处是,,可以用一个变量 struct led1,来代表很多变量,,,,因为一个结构体里面有好多元素,,,可以认为结构体是define的升级版
第二部分GPIO_Configuration(void),,要改进它,,它不在是传入void,,而是传入结构体 这样就可以和第一部分关联起来了
也许不用传入变量,直接在里面引入结构体的元素就行
第三部分GPIO_SetBits(GPIOA,led1),,也是把传入的参数:GPIOA,led1 这里是两个参数,我们就改成传入一个结构体的两个元素.
经过这样的改编,第二部分和第三部分都和第一部分的结构体扯上了关系,那么我们以后一直程序的时候,就只需要改编第一部分的
结构体就行了,,这样第二部分和第三部分就会有相应的变动传入,,大大简化了,,移植的步骤
///////////////////////////////////////////////////////////////////////////////////////////////////
也许我们可以定义一个新的函数,让它来包含所有的函数,,然后把硬件小灯这里的led1设置成为一种
结构体,,
结构体里面包含了小灯的引脚组(A或者B...)
结构体里也包含了小灯的引脚号(8引脚或者10引脚...)
结构体里可以包含引脚连接的标号(led1或者TX,,RX..CLK,,DIO)
结构体里可以包含小灯的各种动作,使用一个函数指针,指向对应函数实现的,不过没有试过(一直亮,一直灭,闪烁)
结构体里可以包含小灯在这个状态的时间(闪烁时,,,处于关闭的时间变量 处于发光的时间是变量)
////////////////////////////////////////////////////////////////////////////////////////////////
下面我试着实现以下
下面是结构体,
struct LED //为什么它只能在这里定义,在main.c中却是不能呢
{
GPIO_TypeDef* GPIOx; //引脚分组, 如A管脚或B管脚
uint16_t GPIO_Pin; //引脚号, PA8里的 8 或者 PB10里的 10
uint32_t RCC_APB2Periph //引脚挂接在哪个时钟下面
int ON_T;
int OFF_T;
int TIME;
u8 ZT; //状态,off/on
u8 led_enable; //这个是防止重新进入的,因为led的处理没有必要每次都进入,只需要运行一次进入即可
int cnt; //这个是用来计数的,计算闪亮了多少次
int cntt; //这个是计数停止的界限
u8 sjxd; //需不需要限定时间
}; 这个是个模具,,用它来扣蛋糕,,蛋糕的名字叫led1,led2或者led3...
对GPIO_Configuration 函数的改造
//=================================================================================================
//函数名称: GPIO_Configuration
//输入参数: struct LED *led //这个是一个结构体,里面包含了小灯的所有信息,,,我也在犹豫,,,要不要传进所有的信息,,,还是只传入结构体内的部分变量就好
//输出参数: void
//函数功能: 所用到的GPIO的初始化
//日 期: 2017-11-13
//作 者: GXTon
//=================================================================================================
void GPIO_Configuration(struct LED *led)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(led->RCC_APB2Periph ,ENABLE); //使能PORTA时钟
//下面是用于测试的小灯的设置
GPIO_InitStructure.GPIO_Pin = led->GPIO_Pin; //PA8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(led->GPIOx,&GPIO_InitStructure);
}
对于点亮小灯的函数改造
GPIO_SetBits(led->GPIOx, led->GPIO_Pin); //亮
当然这只是一部分,小灯不只会亮,还会灭,也能闪,,所以要改造涉及的所有函数
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
不一定要统一所有外设,,灯能亮,,但是马达还能亮吗?显然不能,,,,,外设也是分类的
我们的程序不一定要把灯和马达都搞到一个结构体里,,,可以设置两个结构体嘛
这样灯有灯的结构体,,马达有马达的结构体,,
也许会分的更细,,红灯有红灯的结构体,绿灯有绿灯的结构体,,黄灯有黄灯的结构体
编写程序前需要分类,,分好类之后按照类型创建结构体,过度的统一并不是好的事情
void LED_CL(struct LED *led,u8 ztbh,u8 sjxd, int cnt); //处理led用于改变led状态时才去调用
void LED_ZT( struct LED *led); //接收led结构体的状态,去执行
如何使stm32程序更好移植, 结构体相当于define的更多相关文章
- 结构体中使用#define定义宏
struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* ...
- 失落的C语言结构体封装艺术
Eric S. Raymond <esr@thyrsus.com> 目录 1. 谁该阅读这篇文章 2. 我为什么写这篇文章 3.对齐要求 4.填充 5.结构体对齐及填充 6.结构体重排序 ...
- (转)失落的C语言结构体封装艺术
目录1. 谁该阅读这篇文章 2. 我为什么写这篇文章 3.对齐要求 4.填充 5.结构体对齐及填充 6.结构体重排序 7.难以处理的标量的情况 8.可读性和缓存局部性 9.其他封装的技术 10.工具 ...
- 5、数组&字符串&结构体&共用体&枚举
程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...
- C/C++编程笔记:C语言对齐问题【结构体、栈内存以及位域对齐】
引言 考虑下面的结构体定义: 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4. 现在,我们编写一个简单的程序: 运行后输出: 为什么会这 ...
- .NET C#基础(5):结构体 - 高性能代码的基石
0. 文章目的 本文面向有一定.NET C#基础知识的学习者,介绍C#中结构体定义.使用以及特点. 1. 阅读基础 了解C#基本语法 了解.NET中的栈与托管堆 2. 值类型 2.1 .N ...
- C语言入门(14)——结构体
整数.字符.布尔值.浮点数这些数据类型都具有单一的值,这些可称为基本数据类型.但字符串是一个例外,它由很多字符组成,像这种由基本类型组成的数据类型称为复合数据类型,正如表达式和语句有组合规则一样,由基 ...
- 使用Delphi声明C++带函数的结构体实战 good
在小组开发中,应用程序部分采用Delphi7,一些组件使用C++做.在今天将一个动态库的C++接口声明头文件转换为D7的Unit单元时,一切都很顺利,直到遇到下面这样一个另类的东西: typedef ...
- C语言结构体定义的几种方法
什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类.结构体可以被声明为变量.指针或数组等,用以实现较复杂的数据 ...
随机推荐
- Linux-PS1变量详解
1.PS1 要修改linux终端命令行颜色,我们需要用到PS1,PS1是Linux终端用户的一个环境变量,用来说明命令行提示符的设置.在终端输入命令:#set,即可在输出中找到关于PS1的定义如下: ...
- 【Codeforces Round #456 (Div. 2) A】Tricky Alchemy
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 统计需要的个数. 不够了,就买. [代码] #include <bits/stdc++.h> #define ll lo ...
- C++异常实现与longjmp, setjmp,栈指针EBP, Active Record
这篇讲的不错: http://blog.csdn.net/smstong/article/details/50728022 首先Active Record 然后EBP,ESP等指针 2 通过setjm ...
- 使用Cygwin在Windows上体验Linux的快感
前言 记得大学的时候就以前使用过Cygwin,可惜当时没有发现她的美,我相信如今大多数朋友可能会更加倾向于使用Git或者干脆直接使用虚拟机以及原生Unix. 只是对于刚进入Linux的世界新人来说,使 ...
- Python和C|C++的混编(二):利用Cython进行混编
还能够使用Cython来实现混编 1 下载Cython.用python setup.py install进行安装 2 一个实例 ① 创建helloworld文件夹 创建helloworld.pyx,内 ...
- Leetcode:signal_number_ii
一. 题目 给一个数组,当中仅仅有一个数出现一次.其它的数都出现3次,请找出这个数.要求时间复杂度是O(n).空间复杂度O(1). 二. 分析 第一次遇见这种题,真心没思路-.前面的s ...
- 74.sscanf数据扫描
"%[0-9A-Za-z] 读取一个集合,遇到不是数组或者大小写字母跳出 %*[^0-9A-Za-z]读取所有的非数字字母的字符,忽略 示例: ]= "123sadsadasd ...
- Day4下午解题报告
预计分数:30+30+0=60 实际分数:30+30+10=70 稳有个毛线用,,又拿不出成绩来,, T1 https://www.luogu.org/problem/show?pid=T15626 ...
- c#的中英文混合字符串截取 public static string SubString(string inputString, int byteLength)
/// <summary> /// c#的中英文混合字符串截取(区分中英文) /// </summary> /// <param ...
- vue中watch函数的用法
vue中watch函数: 不仅可以判断路由变化(上篇博客有介绍),还可以判断数据的变化 (1):首先写watch函数 (2):在data里定义值 (3):在methods里写方法 (4):使用值