查看: 2318|回复: 0

【体验】生成代码体验第二弹

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-10 08:31
  • 签到天数: 300 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2018-3-4 09:56:11 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 day_day 于 2018-3-4 09:56 编辑

    (一)时间获取方案
    我的目标项目核心之一是定时功能,之前曾经探索过一个解决方案:通过网络接口每秒获取一次网络时间,具体可以看我之前在机制云社区的帖子:
    http://club.gizwits.com/thread-8038-1-1.html
    但现在回过头来想,一直调用这个接口估计对服务器压力挺大的,一台两台设备还好,如果是大量的设备马不停蹄地申请网络时间,估计服务器就不干了。
    实际上我猜想这个网络接口仅仅是用来进行一些时间校准功能,不停地申请时间并不是一个正常的做法。现在就考虑使用单片机自己的资源定时。
    实际上做过定时实验就知道,如果是按照时分秒定时,为了防止时间溢出,判断逻辑总是很麻烦的。所幸系统有个时基单元:
    1. static uint32_t timerMsCount;
    复制代码
    在定时器中断中被调用,每毫秒加一。作为一个无符号32位整型,算一下,可以整整维持接近50天连续开机的计算。

    (二)只读节点操作
    只读节点操作只需要在userHandle()修改结构体:
    1. /** User Area Device State Structure */
    2. typedef struct {
    3.   bool valuestart_pool;
    4.   bool valuepause;
    5.   bool valuewater_in;
    6.   bool valuepooling;
    7.   bool valuewate_out;
    8. } dataPoint_t;
    复制代码
    这个结构体在gizwits_produte.c文件里实例化为currentDataPoint变量。生成的协议就会自动循环上报,不需要操心。具体实现形式可以参考上面提到的帖子,虽然库文件版本修改,但本质上实现没有太大出入。

    (三)硬件初始化
    机智云使用HAL库的原因之一就是自带的CubeMX工程。
    6.png
    可以使用CubeMX便捷地初始化接口。
    7.jpg
    当然我只是初始化三个IO口就没必要这么麻烦。
    在main里面的,MX_GPIO_Init();里面累死地添加IO初始化代码即可。
    由于gokit二代的功能板引出了A0-A5的IO口,我就初始化A0-A2对应PA0、PA1、PA4。
    1. /*Configure GPIO pin : water_in */
    2.         GPIO_InitStruct.Pin = GPIO_PIN_0;
    3.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    4.         GPIO_InitStruct.Pull = GPIO_PULLUP;
    5.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    6.         
    7.         /*Configure GPIO pin : POOLING */
    8.         GPIO_InitStruct.Pin = GPIO_PIN_1;
    9.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    10.         GPIO_InitStruct.Pull = GPIO_PULLUP;
    11.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    12.         
    13.         /*Configure GPIO pin : water_out */
    14.         GPIO_InitStruct.Pin = GPIO_PIN_4;
    15.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    16.         GPIO_InitStruct.Pull = GPIO_PULLUP;
    17.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    复制代码
    (四)具体实现
    IO操作、只读数据节点修改等一系列操作都在userHandle里面解决:
    在gizwits_product.c声明:
    1. unsigned int current_state;                //定义目前状态
    2. uint32_t assist_timeresist;                //协助计时
    复制代码
    实现两个更新函数——数据节点更新、IO状态更新:
    1. void update_io(void)
    2. {
    3.         switch(current_state)
    4.         {
    5.                 case 0:
    6.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
    7.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
    8.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
    9.                         break;
    10.                 case 1:
    11.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
    12.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
    13.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
    14.                         break;
    15.                 case 2:
    16.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
    17.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
    18.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
    19.                         break;
    20.                 case 3:
    21.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
    22.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
    23.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
    24.                         break;
    25.         }
    26. }

    27. void update_state(void)
    28. {
    29.         if(timerMsCount>=assist_timeresist+10000){
    30.                 current_state = (current_state+1)%4;
    31.                 assist_timeresist = timerMsCount;
    32.                
    33.                 switch(current_state)
    34.                 {
    35.                         case 0:
    36.                                 currentDataPoint.valuewater_in = 0;
    37.                                 currentDataPoint.valuepooling = 0;
    38.                                 currentDataPoint.valuewate_out = 0;
    39.                                 break;
    40.                         case 1:
    41.                                 currentDataPoint.valuewater_in = 1;
    42.                                 currentDataPoint.valuepooling = 0;
    43.                                 currentDataPoint.valuewate_out = 0;
    44.                                 break;
    45.                         case 2:
    46.                                 currentDataPoint.valuewater_in = 0;
    47.                                 currentDataPoint.valuepooling = 1;
    48.                                 currentDataPoint.valuewate_out = 0;
    49.                                 break;
    50.                         case 3:
    51.                                 currentDataPoint.valuewater_in = 0;
    52.                                 currentDataPoint.valuepooling = 0;
    53.                                 currentDataPoint.valuewate_out = 1;
    54.                                 break;
    55.                 }
    56.         }
    57. }
    复制代码

    在userHandle()内添加:
    1. if(currentDataPoint.valuestart_pool && !currentDataPoint.valuepause)
    2. {
    3.                         update_state();
    4.                         update_io();
    5. }
    复制代码
    可写数据节点,在gizwitsEventProcess里编写:
    1. case EVENT_start_pool:
    2.         currentDataPoint.valuestart_pool = dataPointPtr->valuestart_pool;
    3.         GIZWITS_LOG("Evt: EVENT_start_pool %d \n", currentDataPoint.valuestart_pool);
    4.         if(0x01 == currentDataPoint.valuestart_pool)
    5.         {
    6.                         assist_timeresist = timerMsCount;        //user handle
    7.                         current_state = 0;
    8.         }
    9.         else
    10.         {
    11.                         currentDataPoint.valuewater_in = 0;
    12.                         currentDataPoint.valuepooling = 0;
    13.                         currentDataPoint.valuewate_out = 0; //user handle   
    14.         }
    15.         break;
    复制代码
    编译。

    (五)展示功能
    1.png
    2.jpg
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-25 15:28 , Processed in 0.121506 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.