收藏官网首页
查看: 14090|回复: 2

[资料分享] Atmega2560移植MCU代码 修改串口中断 加速

3

主题

8

帖子

275

积分

中级会员

Rank: 3Rank: 3

积分
275
发表于 2018-2-16 12:19:06 | 显示全部楼层 |阅读模式
免费使用STM32、APP自动代码生成工具
本帖最后由 weeksy 于 2018-2-16 19:13 编辑

使用arduino atmega2560这款主板与GAgent通信,代码和UNO的一样,也是可以的。
如果通信不正常,可以首先用串口工具,检查下MCU的回复信息。 WIFI模块上电后,会首先发送查询MCU状态的命令。
此时MCU如果正常回复了,那么Gagent才可以从中获得PK码和产品密钥。这样才能联网。大多数不能联网的问题,都出在这里。无法得到密钥,就没法连接到服务器。

您可以通过检查Gagent模块上的GPIO2号口,来获取WIFI模块的LOG信息。

程序要移植的话,先看看官方例子,下面代码中,红色的部分很重要。 官方库,使用的是在loop中轮询的方式,实现的“上报” 和“下传”命令逻辑。这是因为Arduino中,官方串口库,没有提供对外的中断服务接口。而是内部调用串口接收中断后,将得到的byte写到了一个默认64byte的Buffer中。通过Serial.available,Serial.read()来读取。这个就不是实时的。也就是说,当我们查询到缓存中有40个byte数据的时候,可能这条命令已经发送过来一段时间了。因此就产生了,命令处理的滞后。 如果我们在loop中加了延时,而Gagent模块不断发送查询命令的话,这个Buffer中的数据就冲掉了,覆盖了。所以就导致无法正确解析。

我开始因为在程序中加入了delay(5000);导致MCU接到的串口数据不能及时解析,就被冲掉了,所以一直连不上网,就是这个原因。


void loop() {  

  // delay(5000);   //错误的延迟!

  KEY_Handle();            //key handle , network configure
  wifiStatusHandle();    //WIFI Status Handle
  myGizwits.process();

}

所以,如果您采用上面的官方例子,直接 使用的话。就需要不断的调用  myGizwits.process(); 每次调用时间的间隔,决定了程序处理下发数据的效率。这样轮询的方式,很麻烦。效率不高。 因此我决定使用AVR操作寄存器的方式,直接绕过Arduino的串口库,再中断服务函数中,直接执行myGizwits.process();这样移植后,效率大涨。

需要修改 Gizwits.cpp 这个文件的几个地方  ,这里我使用了Serial3,与Gagent通信。

/**
************
* @file         Gizwits + ArduinoUnoR3 Library
* @brief        Gizwits Process , Protcol Transformation
* @author       Gizwits
* @date         2017-08-01
* @version      V03030000
* @copyright    Gizwits
*
* @note         机智云.只为智能硬件而生
*               Gizwits Smart Cloud  for Smart Products
*               链接|增值ֵ|开放|中立|安全|自有|自由|生态
*               www.gizwits.com
*
************/
#include "Gizwits.h"
#include <Arduino.h>

dataPoint_t currentDataPoint;
wifiStatueFlags_t wifiStatueFlags;

#define SETBIT(ADDRESS,BIT) (ADDRESS|=(1<< BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS&=~(1<< BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS&(1<< BIT))


Gizwits::Gizwits()
{
        memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));
}


Gizwits::~Gizwits()
{
        return;
}


void Gizwits::begin(void)
{

        unsigned int UBRR;
        UBRR   = ((F_CPU>>4)/9600 - 1);

        UBRR3L = (unsigned char)(UBRR & 0xFF);
        UBRR3H = (unsigned char)(UBRR>>8 & 0xFF);

        UCSR3B = (1 << RXEN3) | (1 << TXEN3) | (1 << RXCIE0) ;  /* Enable receiver and transmitter */
        UCSR3C = (1 << UCSZ31) | (1 << UCSZ30);  /* Set frame format: Asynchronous 8 data, 1 stop bit */

        gizwitsInit();
  
}


/**
* @brief Serial write , Send to wifi module
*
* @param buf      : Input data
* @param len       : data length
*
* @return : Success,payload length
*                        -1,Error
*/
int32_t uartWrite(uint8_t *buf, uint32_t len)
{
    uint32_t i = 0;
   
    if(NULL == buf)
    {
        return -1;
    }
   
    for(i=0; i<len; i++)
    {
                  while (!CHECKBIT(UCSR3A, UDRE3));  /* Wait for empty transmit buffer */
                  UDR3 = buf;  /* Put data into buffer, transmits the data */


        if(i >=2 && buf == 0xFF)
        {
                 while (!CHECKBIT(UCSR3A, UDRE3));  /* Wait for empty transmit buffer */
                        UDR3 = 0x55;  /* Put data into buffer, transmits the data */
        }


    }
    return len;
}


/*void serialEvent(void)
{
        uint8_t value = 0;
        value = (unsigned char)Serial3.read();
        gizPutData(&value, 1);
}*/




/**
* @brief Get package , Handle Protocol Data
*
*
* @return : Null
*/
void Gizwits::process(void)
{
        gizwitsHandle((dataPoint_t *)&tDataPoint);
}


bool Gizwits::wifiHasBeenSet(EVENT_TYPE_T eventType)
{
        bool flag;
        switch(eventType)
        {
                        case WIFI_SOFTAP:
                                flag =         wifiStatueFlags.flagWifi_softap;
                                wifiStatueFlags.flagWifi_softap = 0;
                        break;
                        case WIFI_AIRLINK:
                                flag =         wifiStatueFlags.flagWifi_airlink;
                                wifiStatueFlags.flagWifi_airlink = 0;
                        break;
                        case WIFI_STATION:
                                flag =         wifiStatueFlags.flagWifi_station;
                                wifiStatueFlags.flagWifi_station = 0;
                        break;
                        case WIFI_CON_ROUTER:
                                flag =         wifiStatueFlags.flagWifi_con_router;
                                wifiStatueFlags.flagWifi_con_router = 0;
                        break;
                        case WIFI_DISCON_ROUTER:
                                flag =         wifiStatueFlags.flagWifi_discon_router;
                                wifiStatueFlags.flagWifi_discon_router = 0;
                        break;
                        case WIFI_CON_M2M:
                                flag =         wifiStatueFlags.flagWifi_con_m2m;
                                wifiStatueFlags.flagWifi_con_m2m = 0;
                        break;
                        case WIFI_DISCON_M2M:
                                flag =         wifiStatueFlags.flagWifi_discon_m2m;
                                wifiStatueFlags.flagWifi_discon_m2m = 0;
                        break;
                        default:
                        break;
        }
        
        return flag;
}


void Gizwits::setBindMode(uint8_t mode)
{
        gizwitsSetMode(mode);
}




/** The Structure of the current device status **/
attrFlags_t attrFlags;


/**
* @brief Get Datapoint Value


* Description:


* Get Value From currentDataPoint
* @param [in] eventType: event queue
* @param [in] value: Dest , Type In bool/uint32_t/int32_t/float/uint8_t(for binary)
* @return NULL
* @ref Gizwits.h
*/
void Gizwits::read(EVENT_TYPE_T eventType, bool* value)
{
        switch(eventType)
        {
              case EVENT_language:
                *value = currentDataPoint.valuelanguage;
                break;
              case EVENT_backLight:
                *value = currentDataPoint.valuebackLight;
                break;
              case EVENT_indicator:
                *value = currentDataPoint.valueindicator;
                break;
              case EVENT_reset:
                *value = currentDataPoint.valuereset;
                break;
                default:
                        break;
        }
        
        return;
}


void Gizwits::read(EVENT_TYPE_T eventType, uint32_t* value)
{
        switch(eventType)
        {
              case EVENT_brightness:
                *value = currentDataPoint.valuebrightness;
                break;
              case EVENT_rhOffset:
                *value = currentDataPoint.valuerhOffset;
                break;
              case EVENT_hchoOffset:
                *value = currentDataPoint.valuehchoOffset;
                break;
              case EVENT_tvocOffset:
                *value = currentDataPoint.valuetvocOffset;
                break;
              case EVENT_tempOffset:
                *value = currentDataPoint.valuetempOffset;
                break;
                default:
                        break;
        }
        
        return;
}
void Gizwits::read(EVENT_TYPE_T eventType, int32_t* value)
{
        switch(eventType)
        {
              case EVENT_brightness:
                *value = currentDataPoint.valuebrightness;
                break;
              case EVENT_rhOffset:
                *value = currentDataPoint.valuerhOffset;
                break;
              case EVENT_hchoOffset:
                *value = currentDataPoint.valuehchoOffset;
                break;
              case EVENT_tvocOffset:
                *value = currentDataPoint.valuetvocOffset;
                break;
              case EVENT_tempOffset:
                *value = currentDataPoint.valuetempOffset;
                break;
                default:
                        break;
        }
        
        return;
}
void Gizwits::read(EVENT_TYPE_T eventType, float* value)
{
        switch(eventType)
        {
              case EVENT_brightness:
                *value = currentDataPoint.valuebrightness;
                break;
              case EVENT_rhOffset:
                *value = currentDataPoint.valuerhOffset;
                break;
              case EVENT_hchoOffset:
                *value = currentDataPoint.valuehchoOffset;
                break;
              case EVENT_tvocOffset:
                *value = currentDataPoint.valuetvocOffset;
                break;
              case EVENT_tempOffset:
                *value = currentDataPoint.valuetempOffset;
                break;
                default:
                        break;
        }
        
        return;
}


void Gizwits::readBinary(EVENT_TYPE_T eventType, uint8_t* data)
{
        switch(eventType)
        {
                default:
                        break;
        }
        
        return;
}


/**
* @brief Check datapoint event is or not happen


* Description:


* @param [in] eventType: event queue
* @return 1,This datapoint event happen
*                  0,This datapoint event is not happen
* @ref Gizwits.h
*/
bool Gizwits::hasBeenSet(EVENT_TYPE_T eventType)
{
        bool flag;
        switch(eventType)
        {
                        case EVENT_language:
                                flag =         attrFlags.flaglanguage;
                                attrFlags.flaglanguage = 0;
                                break;
                        case EVENT_backLight:
                                flag =         attrFlags.flagbackLight;
                                attrFlags.flagbackLight = 0;
                                break;
                        case EVENT_indicator:
                                flag =         attrFlags.flagindicator;
                                attrFlags.flagindicator = 0;
                                break;
                        case EVENT_reset:
                                flag =         attrFlags.flagreset;
                                attrFlags.flagreset = 0;
                                break;
                        case EVENT_brightness:
                                flag =         attrFlags.flagbrightness;
                                attrFlags.flagbrightness = 0;
                                break;
                        case EVENT_rhOffset:
                                flag =         attrFlags.flagrhOffset;
                                attrFlags.flagrhOffset = 0;
                                break;
                        case EVENT_hchoOffset:
                                flag =         attrFlags.flaghchoOffset;
                                attrFlags.flaghchoOffset = 0;
                                break;
                        case EVENT_tvocOffset:
                                flag =         attrFlags.flagtvocOffset;
                                attrFlags.flagtvocOffset = 0;
                                break;
                        case EVENT_tempOffset:
                                flag =         attrFlags.flagtempOffset;
                                attrFlags.flagtempOffset = 0;
                                break;
                default:
                        break;
        }
        
        return flag;
}


/**
* @brief Write Datapoint Value


* Description:


* Write value to currentDataPoint
* @param [in] eventType: event queue
* @param [in] value: Source value , Type In bool/uint32_t/int32_t/float/uint8_t(for binary)
* @return NULL
* @ref Gizwits.h
*/
void Gizwits::write(VALUE_TYPE_T valueType, bool value)
{
        switch(valueType)
        {
                case VALUE_PM2D5_NA:
                        currentDataPoint.valuePM2D5_NA = value;
                break;
                case VALUE_PM10_NA:
                        currentDataPoint.valuePM10_NA = value;
                default:
                        break;
        }
        return;
}


void Gizwits::write(VALUE_TYPE_T valueType, uint32_t value)
{
        switch(valueType)
        {
                case VALUE_PM2D5:
                        currentDataPoint.valuePM2D5 = value;
                break;
                case VALUE_PM10:
                        currentDataPoint.valuePM10 = value;
                break;
        
                default:
                        break;
        }


        return;
}


void Gizwits::write(VALUE_TYPE_T valueType, int32_t value)
{
        switch(valueType)
        {
                case VALUE_PM2D5:
                        currentDataPoint.valuePM2D5 = value;
                break;
                case VALUE_PM10:
                        currentDataPoint.valuePM10 = value;

                default:
                        break;
        }


        return;
}


void Gizwits::write(VALUE_TYPE_T valueType, float value)
{
        switch(valueType)
        {
                case VALUE_PM2D5:
                        currentDataPoint.valuePM2D5 = value;
                break;
                case VALUE_PM10:
                        currentDataPoint.valuePM10 = value;
                default:
                        break;
        }


        return;
}
void Gizwits::writeBinary(VALUE_TYPE_T valueType, uint8_t* data,uint32_t dataLen)
{
        switch(valueType)
        {
                default:
                break;
        }
        
        return;
}




/**
* @brief Read ms timer


* @param none
* @return System Millisecond
*/
uint32_t gizGetTimerCount(void)
{
  return millis();
}



ISR(USART3_RX_vect)
{
        unsigned char data ;
        while (!CHECKBIT(UCSR3A, RXC3));  /* Wait for data to be received */
        data =UDR3;
        gizPutData(&data, 1);
        gizwitsHandle((dataPoint_t *)&tDataPoint);

}



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表