请问马老师:有关“ UART (USART)口的多机通信 ─ 利用 ZigBee 无线模块相互通信“的
整个系统由“1台PC和5组感测模块(M16L + 6轴传感器)“组成,其中:
主机部分:1块ZigBee无线通信模块由RS-232 to USB到1台PC,标志为0号。
从机部分:5块ZigBee无线通信模块各自和5组感测模块的UART接口串接,分别标志为1~5号。
总共有6个节点,而全部的ZigBee无线通信模块皆设置为“广播模式”。
程序流程为:
一、1~5号模块分别上电后,进入INITIAL状态,等待接收Capture命令。
二、由0号(PC)透过自身的ZigBee模块”广播”发送一个Capture命令(0xFF0xEC),让1~5号的ZigBee模块一起接收此命令。
三、1~5号模块判断接收到Capture命令(认定为几乎同时收到!?)以后,禁止接收功能(RXEN = 0)。
四、开始对传感器信号进行ADC,各轴轮流采样转换,各5次并且取平均值后,进入INITIAL状态,始能接收功能(RXEN = 1),等待接收ID命令。
五、其中,当1号模块完成ADC后,会自动进入发送数据状态(无需等待接收ID命令),发送全部的数据后,进入INITIAL状态,始能接收功能(RXEN = 1),
之后又再次地等待0号发送Capture命令。
数据包格式为: “ID地址、数据1、数据2、数据3、数据4、数据5、数据6“,共7个字节。
六、当0号(PC)接收完1号发送的完整数据包后,开始发送2号的ID命令(0xFFID地址),让2号模块传回它自身模块的数据包。
七、2号模块判断接收到ID命令后,进入发送状态,并且禁止接收功能;数据包发送完成后,进入INITIAL状态,始能接收功能,
之后又再次地等待0号发送Capture命令。
八、3、4、5号的状态分别类似于六、和七、。
九、最后,0号接收完5号模块的完整数据包后,判断并处理1~5号的数据,又再次地”广播”发送Capture命令,让1~5号的ZigBee模块一起准备接收此命令,
回到流程二、。
问题描述如下:
发现了4种数据通信的问题情况,导致整体流程通信到一半,就卡住停止了:
1. 0号(PC)开始发送Capture命令,整体流程通信了一段时间,突然1~5号模块没有收到Capture命令?
2. 整体流程通信了一段时间,突然1~5号模块的某一号模块没有收到0号发送的ID命令,以致数据只显示到上一号模块。
3. 同上,但情况变为:0号(PC)没有收到1~5号某一号模块的数据包,以致无法发送下一组的ID命令。
4. 同上,情况为:0号(PC)没有收到5号模块的数据包,以致无法发送Capture命令。
检查过PC收到的每一号模块的数据包内容,皆正确无误。
而这些问题发生的时间都是随机不固定的,有时发生在启动后2秒内,有时发生在启动后10秒内,甚至有时发生在2分钟内,但是有时候通信却很稳定。
已经思考了很久,但仍不知道哪里有问题,在此麻烦请教马老师和各位,谢谢。
(下方为2号模块的M16L程序内容) /*****************************************************************************************************************************
CPU : ATmega16L
CLK : 7.3728 MHz
Buad Rate : 57600
*****************************************************************************************************************************/
#define F_CPU 7372800
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "ZIG100.h"
#define ID 0x32 //编号2
#defineSTART 0xEC //模块启动命令
#defineCALLFLAG 0xFF //接收起始旗标
#defineSENSOR 6 //感测轴数
#define TIMES 5 //采样次数
/* 状态参数 */
#defineINITIAL 0 //初始
#defineACTION 1 //AD转换
#defineTX 2 //传送
#defineWAIT 4 //等待ADC完成
/* 指令接收参数 */
#defineQUANTITY 2 //指令数据2笔
#defineFIRST 0 //索引值 0
#defineSECOND 1 //索引值 1
/* USART参数 */
#define FOSC 7372800 // Clock频率 //
#define BUAD 57600 // Buad Rate //
#define UBRR (FOSC/(16*BUAD))-1
/* ADC参数 */
#defineADC_INITI 0x60 // ADC参考电压:AVcc,数据向左对齐 //
/* 各个输入通道 */
#define ADC1 0x01
#define ADC2 0x02
#define ADC3 0x03
#define ADC4 0x04
#define ADC5 0x05
#define ADC6 0x06
volatile int State = 0;
int RxNum = 0;
int Axis = 0, Count = 0; //惯性轴和采样次数
unsigned int ADC_Data; //组合ADC数据
unsigned int ADC_Average; //ADC平均
unsigned char RX_Command;
//ADC取5次平均//
void AverageFilter(void)
{
int axis, count;
for(axis = 0; axis < SENSOR; axis++)
{
ADC_Average = INITIAL; //清空上一堆数据
for(count = 0; count < TIMES; count++)
{
ADC_Average += ADC_Data; //不断累加
}
ADC_Average /= TIMES; //平均=累加和/5
}
}
//无线传送ADC值//
void ADC_Tx(void)
{
int axis;
ZIG100_Tx(ID); //传送ID
for(axis = 0; axis < SENSOR; axis++)
{
ZIG100_Tx((unsigned char)ADC_Average); //数据1~6
}
}
//USART接收中断程序//
ISR(USART_RXC_vect)
{
RX_Command = UDR; //读取UDR值,更新RXC
switch(RxNum)
{
case FIRST:
if(RX_Command == CALLFLAG)
{
RxNum = SECOND;
}
break;
case SECOND:
switch(RX_Command)
{
case START: //Capture 命令
UCSRB &= ~_BV(RXEN);
State = ACTION;
break;
case ID: //ID 命令
UCSRB &= ~_BV(RXEN);
State = TX;
break;
}
RxNum = FIRST;
break;
}
}
//ADC中断程序//
ISR(ADC_vect)
{
//在取样次数内即可转换,超过即取平均//
if(Count < TIMES)
{
ADC_Data = ADCH;
ADMUX++; //切换channel
Axis++; //切换axis
//重新切换并采样次数+1//
if(Axis == SENSOR)
{
ADMUX = ADC_INITI | ADC1; //再从ADC1开始
Axis = INITIAL;
Count++;
}
State = ACTION;
}
else
{
AverageFilter(); //Count超过后,开始取平均
Count = INITIAL; //重新计数采样次数
State = INITIAL;
}
}
int main(void)
{
DDRA = 0x00; //PA为传感器输入
PORTA = 0x00;
//USART抗干扰//
DDRD = 0x02; //RXD输入,TXD输出
PORTD = 0x03; //RXD上拉电阻有效,TXD输出
ADMUX = ADC_INITI | ADC1; //从 ADC1 开始 //
USART_Initi(UBRR); //设定USART和buad rate
//ADC enable, ADC interrupt enable, ADC_clk=7.3728 M/64=115.2 KHz//
ADCSRA = _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1);
sei(); //全局中断
while(1)
{
switch(State)
{
case INITIAL:
State = WAIT;
UCSRB |= _BV(RXEN); //启动RX,准备接收讯号进入中断
break;
case ACTION:
ADCSRA |= _BV(ADSC); //ADC start (单次转换, 每次到完成都需要25个ADC_clk周期)
State = WAIT;
break;
case TX:
ADC_Tx();
State = INITIAL;
break;
case WAIT:
// 等待 //
break;
}
}
}
------------------------------------ZIG100.h------------------------------------------------
void USART_Initi(unsigned int ubrr)
{
UBRRH = (unsigned char)(ubrr >> 8);
UBRRL = (unsigned char)ubrr;
UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);
UCSRC = (1 << URSEL) | (3 << UCSZ0);
}
void ZIG100_Tx(unsigned char data)
{
while( !(UCSRA & (1 << UDRE)) );
UDR = data;
} 后来有尝试将数据包的内容修改,加了数据包头 (0xFF0xAA0x55),并且再增加一个测试节点,接收主/从机的所有数据。
全部使用的ZigBee模块是ZIG-100,模块上的芯片是CC2420。
PC(0号)端的程序是使用DataReceived触发的,接收到上一个节点的数据,处理后便会发送呼叫下一个节点回传数据。
但是通信一段时间,在某个时间点,PC端却没有进入触发程序 (下一个节点没有回传数据);透过测试端接收测试的话,确实有收到下一个节点发送的回传数据,这是不懂的问题所在。
烦请指导,谢谢。 上述现象和你的程序没有关联,问题出在通讯协议上。看来是你自已定义的“自定义协议”。
问题如下:
五、其中,当1号模块完成ADC后,会自动进入发送数据状态(无需等待接收ID命令),发送全部的数据后,进入INITIAL状态,始能接收功能(RXEN = 1),之后又再次地等待0号发送Capture命令。
可能出现如下现象:
模块1 ---> 模块5 同时给PC机发送数据,导致通讯线路混乱。
解决方法:
仔细阅读 MODBUS 协议吧!一个主站最多可以挂接127个从站。
(1)、主站不请求,从站不应答。
(2)、主站发送广播时,从站只是接收,不能回送应答报文。(否则导致通讯线路混乱)
(3)、主站给1号从站发送报文时,其它从站(2--->5)也能收到,但是经过地址比较,发现不是呼叫自己,因此2--->5号从站不予理睬,只有1号从站给主站回送应答报文。
注:其它广泛应用于工业的现场总线都采用上述通讯方式,例如:modbus , profibus dp 回复【3樓】ba_wang_mao
-----------------------------------------------------------------------
我将「自定义协议」修改了一下:
1. 主站0号 (PC机) 发送广播,从站模块1~5号等待接收。
2. 等待一段时间,主站0号开始发送寻址命令。
3. 主站0号先发送从站1号的寻址命令,从站1号接收比较后,发现是呼叫自己,回送应答报文;
而从站2~5号接收比较后,发现不是呼叫自己,不予理睬。
4. 0号主站接收完1号从站的回送应答报文后,接着发送从站2号的寻址命令,下面的作动反应如同步骤3,从站3~5号也依此类推。
5. 等0号主站接收完5号从站的回送应答报文后,代表完整收齐全部的资料,准备再一次新的广播发送。
让将流程符合您提供的解决方法,但是经过测试之后,仍然会有同样的问题,让整个无线系统停住:
1. 主站0号已发送了某个从站模块的寻址命令,但是对应的从站模块却没收到?或是没回送应答报文?
2. 从站模块已回送了应答报文,主站PC机却没有收到,导致无法接着发送下一个从站模块的寻址命令。
仍在思考和不解原因为何?
烦请指导,谢谢您! 1. 主站0号 (PC机) 发送广播,从站模块1~5号等待接收。
主站不发送广播。
a.那么主站主何如何知道总线上有多少块从站呢?解决方法如下:
主站依次发送1 ---30 ,
(1)、呼叫从站1,从站1号接收比较后,发现是呼叫自己,回送应答报文(其它从站比对地址,发现不是呼叫自己,不予理睬),主站收到从站1的应答报文后,主站就知道总线上有从站1了。
(2)、呼叫从站2,从站2号接收比较后,发现是呼叫自己,回送应答报文(其它从站比对地址,发现不是呼叫自己,不予理睬),主站收到从站2的应答报文后,主站就知道总线上有从站1了。
b.如何解决模块的热插拔
运行过程中,如果用户从总线上去掉了一块模块,主站如何知道总线上还有哪些模块呢?
解决方法:依照TCP/IP协议中,ARP协议采用的办法,建立一个高速缓存表,记录下当前总线上在线的模块,在这段时间内,主站只访问高速缓存表中记录下来的模块。
然后主站每隔1分钟重新在依次呼叫总线上的所有模块(1-30),然后将在线的从站号填写到高速缓存表中。平时主站只访问高速缓存表中记录下来的从站,高速缓存表中没有记录的从站不予访问。 但是经过测试之后,仍然会有同样的问题,让整个无线系统停住:
1. 主站0号已发送了某个从站模块的寻址命令,但是对应的从站模块却没收到?或是没回送应答报文?
2. 从站模块已回送了应答报文,主站PC机却没有收到,导致无法接着发送下一个从站模块的寻址命令。
上述两个现象,应该是你的中断服务程序出现了问题。
1、假定定时中断服务程序周期是50ms,定时中断服务程序中代码的执行时间是20ms,在执行定时中断服务程序这段时间内,PC机给从站发送数据,由于在20ms内,都无法进入串口中断,由于串口硬件缓存有限,导致后面来的字节挤掉了前面的字节,因此会出现上述现象。
记住一条原则:
(1)、所有的中断服务程序必须尽可能的短。
(2)、定时中断中只有跟时间非常严格要求的代码才放在定时中断程序中,否则应该在定时中断中置一个标志,然后通过该标志在主程序中执行。
(3)、串口应该采用 中断+缓存的方式接收
串口中断应该尽量短,只需要将接收到的数据放到缓存中,既应该立即退出中断。
(4)、串口分析包的过程应该放在主程序中完成 回复【6樓】ba_wang_mao
-----------------------------------------------------------------------
请问这样的中断服务程序还会很久吗?
因为是由PC机发送命令,而所有从机只需要判断是否为相应的命令即可,再根据相应的命令进入要作动的状态。
中断服务程序如下:
ISR(USART_RXC_vect)
{
char data;
data = UDR;
RX_Command = data; //将资料存入缓存区
switch(rxIndex) //判断存入缓存的次数和命令
{
case 0: //判断第一个缓存区的资料是否为同步字节:是的话,将下一个资料存入缓存
if(RX_Command != SYNCHRON)
{
rxIndex = 0;
}
else
{
rxIndex = 1;
}
break;
case 1: //判断第二个缓存区的数据是为启动命令还是请求ID命令:是的话,可进入相应的状态
switch(RX_Command)
{
case START:
State = ACTION; //进入ADC状态
UCSRB &= ~_BV(RXEN); //进入相应的状态后,就禁止接收
break;
case ID:
State = TX; //进入准备传送封包状态
UCSRB &= ~_BV(RXEN);
break;
}
rxIndex = 0; //判断完后,回归队列
break;
}
}
上面原本的写法:
是直接让 data = UDR; ,接着将判断RX_Command改为判断data就好。
后来我依您的建议硬是加入了一个缓存,但是,我只需按照PC机发送相应的命令,进入相应的状态就好,这样还会影响串口处理时间吗?
如有更好的写法,烦请指导,谢谢。 mark 1、确保主站(PC机)每隔100毫秒发送一次请求帧(从机能够及时响应)
2、你程序中,其它中断服务程序必须尽可能的执行时间非常短(这是编写中断服务程序的基本原则)
3、串口架构可以采用TCP/IP和MODBUS国际标准协议采用的方法
(1)、modbus 规定,当接收的两个字节之间的间隔时间大于3.5字符的时间,就认为接收到一帧完整的数据包。
(2)、因此开启一个定时器0,定时器0的周期=3.5字符静止时间。比如:设置定时器定时器0的溢出时间为5ms(3.5字符时间)。
(3)、当进入串口接收中断后,立即开启定时器0.这样当定时器0溢出后,就认为已经接收到一帧完整的数据。
中断服务程序只用于接收数据,具体的分析和判断放在主程序中处理。
4、排查通讯错误时,请把所有和通讯无关的代码屏蔽,专心检查是否是由于通讯造成的上述现象。
#define OS_ENTER_CRITICAL() CLI()
#define OS_EXIT_CRITICAL() SEI()
#define MSCOMM_BUFFER_LENGTH (255)
//开启定时器0
#define TIMER0_START() (TCCR0 = (0 << WGM00) | (0 << WGM01) | (1 << CS02) | (1 << CS01) | (0 << CS00)) // 256 分频
//停止定时器0
#define TIMER0_STOP() (TCCR0 = 0x00)
INT8U volatile USART0_receCount = 0;//接收指针
INT8U USART0_mscomm_buffer;//接收缓冲区
BOOL USART0_OK_mark = FALSE;//定时器0溢出,假定已经接收到一帧完整的数据包(只是假定,数据包是否正确还需要在主程序中判断)
//====================================================================================================
//TIMER0 initialize - prescale:256
// WGM: Normal
// desired value: 1.25mSec
// actual value:1.250mSec (0.0%)
// CTC 模式
// OCR0=11059200*1.25/256/1000-1=54-1=53=0x35
// 溢出模式
// TCNT0=256-11059200*1.25/256/1000=256-54==202=0xCA
//====================================================================================================
void TIMER0_Init(void)
{
TCCR0 = 0x00;
ASSR= 0x00;
TCNT0 = 0xCA;
OCR0 = 0x35;
TIMSK |= (1 << TOIE0);
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
USART0_OK_mark = TRUE;//定时器0溢出,假定已经接收到一帧完整的数据包(只是假定,数据包是否正确还需要在主程序中判断)
TIMER0_STOP();//
}
#pragma interrupt_handler USART0_RI_ISR:iv_USART0_RX
void USART0_RI_ISR(void)
{
INT8U ch;
ch = UDR0; //必须将数据从硬件缓冲区中先取出来
if (USART0_receCount < MSCOMM_BUFFER_LENGTH)
USART0_mscomm_buffer = ch;
TIMER0_STOP();//停止定时器0
TCNT0 = 0xCA; //装载定时器0的初值(5ms)
TIMER0_START();//开启定时器0
}
void main(void)
{
OS_ENTER_CRITICAL();
PORT_Init();
TIMER0_Init();
USART0_Init();
OS_EXIT_CRITICAL();
while (1)
{
if (USART0_OK_mark)//;//定时器0溢出,假定已经接收到一帧完整的数据包(只是假定,数据包是否正确还需要在主程序中判断)
{
USART0_OK_mark = FALSE;
USART0_Modbus_Analyze();// 解析函数
//--------------------------------------------
// 说明: 执行完解析函数后,必须将接收指针“USART0_receCount ”清零。
// (1).当前收到的包是正确的,“USART0_receCount ”必须清零
// (2).当前收到的包是错误的,(例如:通讯线路干扰,PC机发送了8个字节,串口只收到7个字节),因此
// 必须放弃这一帧不完整的数据包(即:最后必须清除清除接收指针=0)。
//--------------------------------------------
USART0_receCount = 0; // 清除接收指针=0
}
}
}
void USART0_Modbus_Analyze(void)
{
if (USART0_receCount >= 8) // 接收数据合法吗?(虽然USART0_OK_mark=TRUE,认为接收到一帧完整的数据,但是还必须再仔细分析该帧数据是否正确)
{
switch (USART0_mscomm_buffer)
{
case 1:
break;
}
}
} 关于多机通信,我的书中有非常详细的介绍和例子,可以参考。 回复【9樓】ba_wang_mao
-----------------------------------------------------------------------
在问题解决测试期间,已先将通讯功能以外的其他功能全都关闭排除了。
经过许多方法测试之后(包括您建议提供的),仍然会有同样的问题,让整个无线系统停住:
1. 主站0号已发送了某个从站模块的寻址命令,但是对应的从站模块却没收到?或是没回送应答报文?
2. 从站模块已回送了应答报文,主站PC机却没有收到,导致无法接着发送下一个从站模块的寻址命令。
而对我使用的系统来说,只要通讯期间有停摆的情况,就要重新启动系统,但这样很耗时,故想找出解决方法和原因。
是否是因为使用无线通信(ZIG-100),所以一定会有收发失误率的产生?
烦请指导,谢谢你。 回复【10楼】machao
-----------------------------------------------------------------------
马老师您好,
原先测试的方式,就是参照您书上的多机通信的范例使用。
在中断服务程序内,先判断收到为同步字节,下一次判断收到为地址字节后,
就禁止接收始能,并在中断结束后,要求进入的作动状态。
在测试期间,已先将通讯功能以外的其他功能全都关闭排除了。
经过许多方法测试之后,仍然会有同样的问题,让整个无线系统停住:
1. 主站0号已发送了某个从站模块的寻址命令,但是对应的从站模块却没收到?或是没回送应答报文?
2. 从站模块已回送了应答报文,主站PC机却没有收到,导致无法接着发送下一个从站模块的寻址命令。
是否是因为使用无线通信(ZIG-100),所以一定会有收发失误率的产生?
烦请指导,谢谢您。 点击此处下载 ourdev_612616Z6NMKL.pdf
(文件大小:716K) (原文件名:UTC-1212无线模块使用文档2.0.pdf)
点击此处下载 ourdev_612617SAH7NP.pdf
(文件大小:1.18M) (原文件名:UTC-2303使用手册2.0.pdf)
点击此处下载 ourdev_612030EKE7Y1.rar(文件大小:11K)
(原文件名:UTC1212-C51参考程序.rar)
点击此处下载 ourdev_612031XYUJW9.rar(文件大小:4.63M)
(原文件名:UTC2303驱动.rar)
点击此处下载 ourdev_612032HBJX03.rar(文件大小:311K)
(原文件名:UTC-121配置软件.rar) 回复【13樓】rfinchina2011
-----------------------------------------------------------------------
谢谢你,但目前未考虑要更换无线模块。 ZIGBEE距离比较近,而且隔墙传输效果不好,楼主要慎重 【9楼】给你提供的代码,经过了严格测试,通讯次数达到2000000(2百万),接收全部正确,没有一次错误。
会不会是你初始化串口时,使用了9位传输模式造成的?
一般的MODBUS-rtu国际标准协议,都是采用8位传输模式,而且“从站地址”就包含在数据包中。不要使用AVR单片机中第9位来区分地址帧还是数据帧。
建议你看一下modbus-rtu协议。将你的自定义协议,改造成国际标准协议。
#include <iom128v.h>
void USART1_Init(void)
{
UCSR1B = 0x00;
UCSR1A = 0x00;
UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
switch (STOP_NO)
{
case 0:
UCSR1C |= (0 << USBS1);
break;
case 1:
UCSR1C |= (1 << USBS1);
break;
}
switch (UPM_NO)
{
case 0:
UCSR1C |= ((0 << UPM11) | ( 0 << UPM10));
break;
case 1: // 偶校验
UCSR1C |= ((1 << UPM11) | ( 0 << UPM10));
break;
case 2: // 奇校验
UCSR1C |= ((1 << UPM11) | ( 1 << UPM10));
break;
}
switch (Baud_NO)
{
case 0: // 1200
UBRR1L = 0x3F;
UBRR1H = 0x02;
break;
case 1: // 2400
UBRR1L = 0x1F;
UBRR1H = 0x01;
break;
case 2: // 4800
UBRR1L = 0x8F;
UBRR1H = 0x00;
break;
case 3: // 9600
UBRR1L = 0x47;
UBRR1H = 0x00;
break;
case 4: // 14400=(11059200/16/14400-1)%256
UBRR1L = 0x2F;
UBRR1H = 0x00;
break;
case 5: // 19200
UBRR1L = 0x23;
UBRR1H = 0x00;
break;
case 6: // 38400
UBRR1L = 0x11;
UBRR1H = 0x00;
break;
case 7: // 57600
UBRR1L = 0x0B;
UBRR1H = 0x00;
break;
default: // 115200
UBRR1L = 0x05;
UBRR1H = 0x00;
break;
}
UCSR1B = (1 << RXEN1) | (1 << RXCIE1) | (1 << TXEN1) | (1 << TXCIE1);
} 回复【16樓】ba_wang_mao
-----------------------------------------------------------------------
我自定义的协议的应该就是MODBUS-rtu国际标准协议了,
采用8位传输模式,1位停止位,「从站地址」包含在数据包中,
也没有使用AVR单片机中第9位来区分地址帧还是数据帧,
波特率也测试过从9600到115200,但仍然有问题。
烦请指导,谢谢你。 无线通信产生误码的情况可能行非常大。在考虑协议中,应该考虑出现误码的情况。
例如:
1。规定上位机发送命令给1号从机,从机必须在500ms给出回答。
2。上位机在规定的500m时间内接受不到正确的回答(或根本没有回答),则再次重发。
3。3次重发后还是没有正确的回答,那么就需要转入错误处理,比如提示通信故障。
这样就是模块坏了,程序也不会“死掉”
进入“死循环”的过程:上位机下发命令了,但传到1号从机为误码,1号从机不做回答,此时上位机在“死”等1号从机的回答。
======================================
在我编写的书中,P402、P409都讲到这个问题。书中有例子。由于篇幅,书中只有下位机代码,上位机是PC,用VB写的,代码在光盘中,你全面看过了?
在我的例子中,如果把通信线拔掉,上位机马上就给出通信故障的提示,程序不会“死”在那里。 建议:
1、首先去掉复杂的通讯协议,上位机使用一个“串口调试精灵”软件(记录有发送次数)
固定给某一个从站发送数据
2、“串口调试精灵”软件每隔500ms发送一帧固定的数据(8个字节)
例如:“1,2,3,4,5,6,7,8”
3、然后在从站中,接收上述数据,看是否每次都接收正确。
将正确接收次数显示到数码管上。
上述正确后,再查找你程序的其它问题。 弱弱的问一句,你这个跑的是zigbee协议栈吗?TI的?
从机的设备类型是什么?ZED or ZR?
好像没有提到自组网什么的。 mark ZigBee 无线信号强度比较弱,一般它的发射功率都小于20mW,肯定很容易被干扰。我想楼主的问题应该是信号受到干扰,造成数据接收错误。
我对这块也很感兴趣,以后常来这里看看。 mark 技术贴,给了很多思路,多谢
页:
[1]