码迷,mamicode.com
首页 > 其他好文 > 详细

TinyOS系列——网关接收服务器指令模块,实现的难题及解决方案

时间:2014-07-19 18:39:49      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   

今天刚刚把棘手已久的问题解决,感觉特别开心,想记录一下解决的思路。
------------------------------------------------分割线----------------------------------------------------
1)首先,假设节点内已经烧好了写好的程序,那么通过PC端的串口调试助手,完全可以完成这个任务
2)其次,节点通过串口接收数据用的是ATmega128,那ATmega128串口这块如何配置?
 Atmega128有两个串口:USART0与USART1
假设使用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-bits
18             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 Bps
24         UBRR0H=0x00;                        //误差率:0.156%
25         UCSR0B =(1<<RXEN0)|(1<<TXEN0);    //RXCEN TXCEN
26         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                     else
18                     {
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()进行重新调用
 
 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                     else
22                     {
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 = 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         else
57         {
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         else
96         {
97         call AMControl.stop();
98         }
99     }
下面是有几个比较然的点:阐述一下
1、修改串口寄存器会不会AMSend产生影响?
不会!ATmega128修改串口寄存器,使得节点能够与PC通过串口进行通信,与CC2420射频无线模块没有任何关系。ATmega128的作用是通过串口接收数据后,发送给射频无线模块。射频无线模块的作用是调制发送数据。
2、波特率设置会不会影响两个节点间的正常通信?
不会!波特率只是规定通信双方的数据速率,一般是PC与节点,或者是其他。

TinyOS系列——网关接收服务器指令模块,实现的难题及解决方案,布布扣,bubuko.com

TinyOS系列——网关接收服务器指令模块,实现的难题及解决方案

标签:style   blog   http   color   使用   os   

原文地址:http://www.cnblogs.com/zlcxbb/p/3854925.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!