weeksy 发表于 2018-2-16 12:19:06

Atmega2560移植MCU代码 修改串口中断 加速

本帖最后由 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 Cloudfor 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 eventType: event queue
* @param 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 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 eventType: event queue
* @param 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);

}



mylorder 发表于 2019-2-23 09:41:15

mylorder 发表于 2019-2-23 09:41:42

页: [1]
查看完整版本: Atmega2560移植MCU代码 修改串口中断 加速