首页 > 代码库 > TinyOS系列——网关接收服务器指令模块,实现的难题及解决方案
TinyOS系列——网关接收服务器指令模块,实现的难题及解决方案
今天刚刚把棘手已久的问题解决,感觉特别开心,想记录一下解决的思路。
------------------------------------------------分割线----------------------------------------------------
1)首先,假设节点内已经烧好了写好的程序,那么通过PC端的串口调试助手,完全可以完成这个任务
2)其次,节点通过串口接收数据用的是ATmega128,那ATmega128串口这块如何配置?
推荐一个网址,http://blog.chinaunix.net/uid-21658993-id-1819999.html
Atmega128有两个串口:USART0与USART1
假设使用USART0,无非就是有下面几部分:
假设使用USART0,无非就是有下面几部分:
1 void uart0_init() //串口0初始化 2 { 3 UCSR0B = 0x00; 4 // 关闭USART0,设置波特率前,要关闭USART0的所有使用,包括使能和中断 5 UCSR0A = 0x00; //不使用倍速发送 U2X=0 6 /* 7 UCSR0A能写的有Bit0,Bit1,Bit6,其他5位为状态位.我们一般使用的有Bit1-U2X0, 8 当这一位为1时,波特率的分频因子从16降到8,能够有效的将异步通信模式的传输速率加倍, 9 但是这一位仅对异步操作有影响,使用同步操作时应将此位清零.10 */11 UCSR0C =(1<<UCSZ01)|(1<<UCSZ00); //8bit+1bit stop 八位数据位,一位停止位12 // UBRR0L=(fosc/16/(baud+1))%256;13 // UBRR0H=(fosc/16/(baud+1))/256;14 /* 15 Bit6-UMSEL0:USART0的模式选择,0为异步模式,1为同步模式16 Bit5:4-UPM01:0:奇偶校验模式,00禁止,01,保留,10偶校验,11,奇校验17 Bit3-USBS0:停止位的选择,0停止位为1bit,1停止位为2-bits18 Bit2:1-UCSZ01:0:字符长度,当UCSZ02为0时,00表示5位,01表示6位,10表示7位,19 1表示8位.当UCSZ02为1时,11表示9位.(UCSZ02为UCSR0B里的一位寄存器)20 eg:21 UCSR0C=0B00000110 //异步模式,禁止奇偶校验,停止位为1位,数据位为8位22 */23 UBRR0L=7; //波特率:57600 Bps24 UBRR0H=0x00; //误差率:0.156%25 UCSR0B =(1<<RXEN0)|(1<<TXEN0); //RXCEN TXCEN26 call Leds.led0On();27 }
再次,那我节点如何接收服务器发送来的数据?
1 //串口0接收字符2 unsigned char getchar0()3 {4 while(!(UCSR0A& (1<<RXC0)));5 //call Leds.led1Toggle();6 return UDR0;7 }
接收起始与截止位分别为"$nodeId Cmd$"
1 while(1) 2 { 3 judge = getchar0(); 4 if(judge == ‘$‘) 5 { 6 judge = getchar0(); 7 inputNum = 0; 8 addr = 0; 9 cmd = 0;10 while(judge !=‘$‘)11 {12 if(judge - ‘0‘ >= 0 && judge-‘0‘ <= 9)13 {14 inputNum = (inputNum * 10) + (judge - ‘0‘);15 addr = inputNum;16 }17 else18 {19 //取最后一个字符作为命令的参数20 cmd = judge - ‘0‘;21 }22 judge = getchar0();23 }24 breakflag=1;25 if(breakflag==1)26 {27 breakflag=0;28 break;29 }30 31 }32 }
紧接着,最大的问题就来了,这也是我出错的地方,搞了半天才搞好,网关接收服务器指令后,如何将消息发送出去?并且通过基站进行回显?我这里用了一个取巧的办法,广播,基站收到消息后回显
这里因为牵扯的问题比较广,我会重点阐述一下,如果要进行广播或者是单播,首先必须要开启射频无线模块AMControl.start(),但是接收数据并且发送指令这块的工作是绝对不能放到Boot函数中来执行的,否则无法正常发送,只能放在AMControl.startDone()中来执行;在循环函数体内绝对不能进行AMSend.send(),否则只能send一次,无法正常进入AMSend.sendDone()
我的解决方案:
1)必要的位置加delay()延迟
2)接收消息、发送消息在AMControl.startDone()中编写
3)在AMSend.sendDone()中将AMControl.stop()关闭 (核心出错点!!!)
4)在AMControl.stopDone()中对AMControl.stop()进行重新调用
2)接收消息、发送消息在AMControl.startDone()中编写
3)在AMSend.sendDone()中将AMControl.stop()关闭 (核心出错点!!!)
4)在AMControl.stopDone()中对AMControl.stop()进行重新调用
1 event void AMControl.startDone(error_t err) { 2 PCUartCmd* cmdpkt = (PCUartCmd*)(call Packet.getPayload(&pkt, sizeof(PCUartCmd))); 3 4 5 while(1) 6 { 7 judge = getchar0(); 8 if(judge == ‘$‘) 9 {10 judge = getchar0();11 inputNum = 0;12 addr = 0;13 cmd = 0;14 while(judge !=‘$‘)15 {16 if(judge - ‘0‘ >= 0 && judge-‘0‘ <= 9)17 {18 inputNum = (inputNum * 10) + (judge - ‘0‘);19 addr = inputNum;20 }21 else22 {23 //取最后一个字符作为命令的参数24 cmd = judge - ‘0‘;25 }26 judge = getchar0();27 }28 breakflag=1;29 if(breakflag==1)30 {31 breakflag=0;32 break;33 }34 35 }36 }37 38 cmdpkt->nodeid = addr;39 cmdpkt->data =http://www.mamicode.com/ cmd;40 41 cmdpkt->relay1 = 11;42 cmdpkt->relay2 = 12;43 cmdpkt->relay3 = 13;44 cmdpkt->relay4 = 14;45 cmdpkt->relay5 = 15;46 cmdpkt->yuliu = 0;47 48 49 if(busy==0)50 {51 busy=1;52 call Leds.led0Toggle();53 call AMSend.send(addr, &pkt, sizeof(PCUartCmd));54 call Leds.led1Toggle(); 55 }56 else57 {58 }59 60 inputNum = 0;61 addr = 0;62 cmd = 0; 63 }64 65 66 67 68 event void AMSend.sendDone(message_t* msg, error_t err) {69 call Leds.led1Toggle();70 if (err == SUCCESS) 71 { 72 call Leds.led2Toggle();73 } 74 busy=0;75 76 call AMControl.stop();77 }78 79 80 event void Timer0.fired()81 {82 //call Leds.led1Toggle();83 }84 85 86 87 event void AMControl.stopDone(error_t err) 88 {89 if (err == SUCCESS) 90 { 91 call Leds.led0Off(); 92 call AMControl.start();93 94 }95 else96 {97 call AMControl.stop();98 }99 }
下面是有几个比较然的点:阐述一下
1、修改串口寄存器会不会AMSend产生影响?
不会!ATmega128修改串口寄存器,使得节点能够与PC通过串口进行通信,与CC2420射频无线模块没有任何关系。ATmega128的作用是通过串口接收数据后,发送给射频无线模块。射频无线模块的作用是调制发送数据。
2、波特率设置会不会影响两个节点间的正常通信?
不会!波特率只是规定通信双方的数据速率,一般是PC与节点,或者是其他。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。