切换到宽版
  • 417阅读
  • 5回复

[ARM]STM32 ARDUINO HALMX 应用集锦(三):_ConstPin 类 [复制链接]

上一主题 下一主题
离线huaweiwx
 

发帖
1177
M币
1746
专家
49
粉丝
208
在我这一版ARDUINO HALMX中,作了大量的功能扩充,一方面是为了方便实用,更是为了节约资源,以前一个小程序就是十几k,现在只有几k,这归公于这个基础类:_ConstPin ,以下结合应用作个介绍。

一 官方arduino PIN:
首先我们先看一下arduino程序的基本框架,这是arduino的blink.ino
  1. void setup() {
  2.   // initialize digital pin LED_BUILTIN as an output.
  3.   pinMode(LED_BUILTIN, OUTPUT);
  4. }
  5. // the loop function runs over and over again forever
  6. void loop() {
  7.   digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  8.   delay(1000);                       // wait for a second
  9.   digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  10.   delay(1000);                       // wait for a second
  11. }

  第三行中的 LED_BUILTIN 是arduino的官方led指示灯的位置定义,通常是采用了如下三种定义方式之一来定义的如:
1   emu类型定义+宏定义:
       emu{
              ...,
              PA5,
             ....
              };
     #define LED_BUILTIN   PA5
2  定义变量+宏定义:
   const uint8_t  PA5 = 13;
    #define LED_BUILTIN   PA5
3   直接宏定义:  #define   LED_BUILTIN    13
因此无论述那种方式来定义这个LED,最后在程序中均作为一个常数来对待;

二  在ARDUINO HALMX中的扩充:
我们来看个示例:(示例位置 HALMX\libraries\BoardExamples\examples\Extension\ConstPin\ConstPinOut\ConstPinOut.ino)
  1. void setup() {
  2.   pinMode(LED_BUILTIN,OUTPUT);
  3.   pinMode(BOTTON,INPUT);
  4. }
  5. void loop() {
  6.   LED_BUILTIN << BOTTON;
  7. }

该程序只在arduino应用程序框架中加上了三条语句(2 3 7),
2 3 初始化LED(LED_BUILTIN)为输出,按键脚(BOTTON)为输人;因为 arv和stm32 每个gpio pin均有多种输出输入模式,我们必须设定它的工作模式(缺省是输入模式),另外对于stm32 每个端口均有独立的时钟,也需要打开,在这里要说一下,有些版本的arduino或者有些坛友喜欢stm32在初始化的时候就一次性打开全部时钟,但我这个版本,始终是用到什么资源时才打开时钟,这样既节省响应的初始化代码长度,也降低功耗,可以更好的和以后的低功耗设计打好基础,方便开发为电池供电的应用程序;这就是第三行语句的必要性。
7  读取按键的状态并通过LED脚输出;

三  _ConstPin  类:
上述  第7行语句是我们这个程序中最复杂一句,有别于常规的c语言,先看一下标准C的含义:
在 C中,<< >> 这是个移位操作符,  1<<7代表将 1 左移7位,显然   该值为 0x80;
但在 C++ 中,对数值而言,仍然是向下兼容于C ,代表移位操作,如果按此理解将LED_BUILTIN的状态左移(BOTTON 的状态 0或1),显然是错误的,也并不是我们需要的操作!
如果坛友们玩过pc的c++编程,经常会看到这样的语句:
COUT <<  "HELLO!";   我们显然不能把它理解成移位操作;这就是C++对操作符的重载,有了对操作符(operator)的重载功能,我们就可以对各种对象进行想要的操作了。在这里COUT代表输出设备,即将字符串HELLO!在COUT上输出;
再回到二,第7行  LED_BUILTIN 和 BOTTON 如果在C语言中,它们都是简单数值类型,如果在C++中也是如此,那么是不允许重载 << 操作符的,我们必须进行处理成可重载的对象,这就是在C++中它们都不是简单的数值类型,而是我们这一版本中定义的最重要的一个基础类型,原型定义在HALMX\cores\arduino\stm32\stm32_pin_list.h:
  1. #ifndef STM32_PIN_LIST_H
  2. #define STM32_PIN_LIST_H
  3. #include "variant.h"
  4. #include "stm32_HAL/stm32XXxx_ll_gpio.h"
  5. #ifdef VARIANT_PIN_LIST
  6.   #define PIN_LIST VARIANT_PIN_LIST
  7. #else
  8.   #define PIN_LIST CHIP_PIN_LIST
  9. #endif
  10. #ifdef __cplusplus
  11.     class __ConstPin {
  12.     public:
  13.       constexpr __ConstPin(const int val): val(val) {};
  14.       constexpr operator int() const { return val; }
  15.       const int val;
  16.     };
  17.     #define PIN(a, b) __P##a##b
  18.         enum {
  19.             PIN_LIST
  20.             NUM_DIGITAL_PINS,
  21.         };
  22.     #undef PIN
  23.     #define PIN(a, b) P##a##b(__P##a##b)
  24.       constexpr __ConstPin PIN_LIST __IGNORE(-1);
  25.     #undef PIN
  26. #else
  27.     #define PIN(a, b) P ## a ## b
  28.     enum {
  29.         PIN_LIST
  30.         NUM_DIGITAL_PINS,
  31.     };
  32.     #undef PIN
  33. #endif

简单介绍:
小知识:
对于许多运算来说,编译器会尽量的优化代码,对于常量来说,通常会在编译时就合并计算,运行时代码就得到了优化,这种编译优化分两种种情形,预处理和编译;前者典型的是宏扩展,对于常量运算,无论多复杂,最后都可以扩展成一个常量结果,但对于类和函数,我们可以明确要求编译器最终根据对象的构造和使用情形在编译时就算出结果,这样代码就大大的优化了,这就是C++新的常表达式(函数)的限定词:constexpr ,在_ConstPin类定义中满足这个要求;
因此 行line16~ 21 为_ConstPin 类定义,其中构造函数line18 带个参数是 const int ;函数类型用了 constexpr 这是C++关键词;
该类有个常量 const int val (line 20)
line19         constexpr operator int() const { return val; }   告诉系统如果要对这个对象进行求整数值的话 int()  那么返回line20的那个常整数const int val ,前面加了个constexpr 要求系统在编译时就处理好;而如果知道是求值 ,则通过 operator 这个C++ 关键词,重载 这个();

接着我们就要来对全部gpio 来构造了:
对于每个脚我们事先已经定了一个宏如 GPIOA的5号脚,我们写成 PIN(A,5) , 全部脚 写成一个序列 PIN_LIST;
而在不同的地方我们来处理PIN(A,5)这样的定义成为我们需要的数值或类型,在不同的地方我们进行不同处理;
22~27  我们将PIN(A,5)转换成__PA5,并且 通过emu 枚举成了一个常数,代表了不同的脚;
29~31  进一步将所有的脚来构造一个对应脚的对象(_ConstPin 类),对于PIN(A,5)就扩展成  _ConstPin  PA5(__PA5) 来构造一个实例PA5;
以上都是用在C++场合,而在C应用场合,恢复到传统的arduino定义:
35~40 即 PIN(A,5)  处理成了 PA5 的枚举类型,兼容于arduino官方的脚属性;

那么在c/c++中用PA5代表了不同内容,会有歧义吗,是否在C++中用__PA5代替PA5?不,因为只要用到PA5,编译程序会帮我们来根据不同场合分别处理,这就是line19
当需要这个数值时就用val代替,而val就是构造PA5时输入的参数__PA5;

再次回到二中的第7行:
LED_BUILTIN << BOTTON 用了<<操作符,但我们在_ConstPin类中没有重载构造这个操作,这放在 HALMX\cores\arduino\stm32\stm32_gpio.h,其中有如下语句:
  1. template<class T>
  2. inline void operator << (__ConstPin co, T value){
  3.   digitalWrite(co, (uint8_t)value);
  4. }
  5. inline void operator << (__ConstPin co, __ConstPin ci){
  6.   digitalWrite(co, (uint8_t)digitalRead(ci));
  7. }
  8. template<class T>
  9. inline void operator >> (__ConstPin ci, T &value) {
  10.   value = digitalRead(ci);
  11. }
  12. inline void operator >> (__ConstPin ci, __ConstPin co){
  13.   digitalWrite(co, (uint8_t)digitalRead(ci));
  14. }


在这里我们针对 重载了 << 和 >>  两个操作符,要求该操作符的左边必须是_ConstPin类型,右边可以是一个值或另外一个_ConstPin,
对于<< 如果右边也是_ConstPin 就将其通过digitalRead读出,并用digitalWrite写;
<< >>用在arudino 脚的电平输入输出,和PC上的标准输入输出设备使用方式极为相似,好用又好记;
以下均是合法的_ConstPin应用方法:
1
   uint8_t status;
   BOTTON >> status;

2
   LED_BUILTIN << 1;

3
   LED_BUILTIN << 0;

4
  LED_BUILTIN << BOTTON;

5
   BOTTON >> LED_BUILTIN ;

以上内容均包含在我的最新版本中,更多的示例 在:HALMX\libraries\BoardExamples\examples\Extension\ConstPin\

[ 此帖被huaweiwx在2018-02-13 14:49重新编辑 ]
本帖最近打赏记录:共3条打赏M币+63
花生仔 M币 +13 謝謝分享 昨天 00:45
jpdd521 M币 +30 新年力作!顶老哥!! 02-13
2545889167 M币 +20 - 02-13
离线huaweiwx

发帖
1177
M币
1746
专家
49
粉丝
208
只看该作者 1楼 发表于: 02-13
这些功能都只能在我的ARDUINO HALMX最新版本中使用;对于avr sam,也在进行优化和扩充,喜欢的坛友可关注;
本帖最近打赏记录:共1条打赏M币+20
2545889167 M币 +20 - 02-13
离线liqi5230

发帖
149
M币
73
专家
0
粉丝
5
只看该作者 2楼 发表于: 02-13
支持下  教程很有水平 努力学习消化
本帖最近打赏记录:共1条打赏M币+8
huaweiwx M币 +8 新年快乐! 02-14
在线jpdd521

发帖
24258
M币
11496
专家
15
粉丝
325
只看该作者 3楼 发表于: 02-13
    新年力作!顶老哥!!
本帖最近打赏记录:共1条打赏M币+20
huaweiwx M币 +20 新年快乐! 02-14
离线bg4rff

发帖
1097
M币
915
专家
3
粉丝
12
只看该作者 4楼 发表于: 02-13
精品教程,学习中
本帖最近打赏记录:共1条打赏M币+20
huaweiwx M币 +20 新年快乐! 02-14
离线liquidator

发帖
3430
M币
10135
专家
1
粉丝
26
只看该作者 5楼 发表于: 02-15
大师做些视频教程就好了。
本帖最近打赏记录:共1条打赏M币+20
huaweiwx M币 +20 新年快乐! 02-15
快速回复
限80 字节
温馨提示:所有技术区严禁灌水,“沙发”“顶”字样;禁止广告贴;以免被删除
 
上一个 下一个