一种简单方便又直观的c语言嵌入式设计
c语言嵌入式设计的本质无非就是“打开/关闭某个端口”或是“置高/置低某个引脚”。当我们想置高/置低某个引脚时,常常会使用如下两种方式。/*置高PB6*/GPIO_BOP(GPIOB) = GPIO_PIN_6;/*置低PB6*/GPIO_BC(GPIOB) = GPIO_PIN_6;但这有个很大的问题,也就是并不直观!让我们来慢慢分析。首先,我们为什么要置高置低某个引脚?因为我们在设计时是根据某
一、启发
c语言嵌入式设计的本质无非就是“打开/关闭某个端口”或是“置高/置低某个引脚”。当我们想置高/置低某个引脚时,常常会使用如下两种方式。
/*置高PB6*/
GPIO_BOP(GPIOB) = GPIO_PIN_6;
/*置低PB6*/
GPIO_BC(GPIOB) = GPIO_PIN_6;
但这有个很大的问题,也就是并不直观!让我们来慢慢分析。
首先,我们为什么要置高置低某个引脚?因为我们在设计时是根据某个协议的,而协议一般都有默认的引脚名称。比如IIC的SCL、SDA,比如UART的RX、TX,比如CAN的CANH、CANL(这个会有点不同,但大致都是围绕CAN_HIGH、CAN_LOW展开)。但体现在硬件上,也就是PB6、PB7......。
发现了吗?如果我们在设计时一直使用PB6这种硬件名称的话并不直观,哪怕是本人,在隔了一段时间后再看都得老老实实的去查手册,看看PB6对应的是什么功能的引脚。
既然如此,那有什么方法更加直观又强势吗?有的兄弟,有的!
那就是我下面将要讲的方法。
二、更加直观又强势的方法
请看最终结果:
void scl_50k_test() //SCL以50k的频率振动。SDA以25k的频率振动。T = 10us*2
{
delay_1us (15) ;
DataHigh (SCL) ;
delay_1us (15) ;
DataLow (SCL) ;
DataHigh (SDA) ;
delay_1us (15) ;
DataHigh (SCL) ;
delay_1us (15) ;
DataLow (SCL) ;
DataLow (SDA) ;
}
如何?是不是很直观了呢?置高就写DataHigh( PIN_NAME ),置低就写DataLow( PIN_NAME )
我们来看看如何实现的。我们从结果慢慢倒推回去。
2.1 名称如何跟pin脚绑定(一)
首先是PIN_NAME,也就是SCL、SDA如何跟pin脚绑定的?
//xxx.h文件定义
typedef enum
{
SCL = 0,
SDA = 1
} SCLSDA_enum;
//xxx.c文件定义
void test(SCLSDA_enum cdchoose)
{
a( cdchoose ) //假设存在一种方法a()
}
test在声明时,声明的变量并不是常规的“int”、“char”等,而是我们在“xxx.h”中定义过的枚举类型定义。当我们使用test()时,把【test(SCL)】展开的情况如下:
并不是设计代码,而是按执行顺序展开!
SCLSDA_enum cdchoose = SCL;
test( cdchoose );
a( 0 )
很好,我们已经能看到一点雏形了,当我们输入SCL时,方法内部会自动转成0,SDA会自动转成1。让我们继续优化。
2.2 名称如何跟pin脚绑定(二)
我们现在要解决的就是,如何把 0/1 转换成 pin 脚。如下:
xxx.h文件定义
typedef enum
{
SCL = 0,
SDA = 1
} SCLSDA_enum;
#define SCLpin GPIO_PIN_6
#define SCLclk GPIOB
#define SDApin GPIO_PIN_7
#define SDAclk GPIOB
#define CDCLKCHOOSEn 2U
#define CDPINCHOOSEn 2U
xxx.c文件定义
static uint32_t SCLSDA_CLK_CHOOSE[CDCLKCHOOSEn] = {SCLclk,SDAclk};
static uint32_t SCLSDA_PIN_CHOOSE[CDPINCHOOSEn] = {SCLpin,SDApin};
void DataHigh (SCLSDA_enum cdchoose)
{
GPIO_BOP(SCLSDA_CLK_CHOOSE[cdchoose]) = SCLSDA_PIN_CHOOSE[cdchoose];
}
void DataLow (SCLSDA_enum cdchoose)
{
GPIO_BC(SCLSDA_CLK_CHOOSE[cdchoose]) = SCLSDA_PIN_CHOOSE[cdchoose];
}
SCLSDA_CLK_CHOOSE[CDCLKCHOOSEn]是一个数组。输入0,就返回SCLclk,而SCLclk代表的是GPIOB,输入1同理。
SCLSDA_PIN_CHOOSE[CDPINCHOOSEn]也是一个数组。输入0,就返回SCLpin,而SCLpin代表的是GPIO_PIN_6,输入1同理。
需要注意的是“CDCLKCHOOSEn”与“CDPINCHOOSEn”是数组宽度。
所以,我们就可以达成我们的目标了!当我们使用方法DataHigh()时,展开后如下:
【DataHigh(SCL)】⬇️
DataHigh( 0 );
GPIO_BOP(SCLSDA_CLK_CHOOSE[ 0 ]) = SCLSDA_PIN_CHOOSE[ 0 ];
GPIO_BOP( GPIOB ) = GPIO_PIN_6;
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)