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);
}
页:
[1]