基于CC2430的ZigBee通信过程调试分析

  由于论文的实验部分的需求,最近要使用Zigbee通信协议进行通信。实验用的是淘宝上买的基于CC2430的芯片的ZigBee学习板,淘宝的老板给了很多资料,包括芯片手册,协议说明,驱动和协议分析软件、IAR和基于IAR的例程等。实验的任务是实现芯片之间的带ACK机制的通信,并且能够在电脑上看到收发双方的通信数据和是否丢包和重传的情况。

  开始的时候从学习例程开始,一步一步来。在例程的基础上实现两个ZigBee模块的数据收发通信还是比较简单的。但是涉及到丢包和重传就没有头绪了,果真是欲速则不达啊。没办法,只好想办法看懂程序。一步一步调试分析,慢慢来。

  实验过程中主要修改了点对点通信例程(不带ACK的通信过程),网上也很容易找到这个例程(http://www.61ic.com/Article/MSP430/ZigBee/201104/33278.html)。修改程序使双方进行带ACK的通信,调试时发现三次握手的时候并没有进入定时器Timer4的中断,通过分析两个问题:1)timer4AdmInit.c文件中:定时器4的中断服务程序__interrupt void T4_Adm_IRQ (void)在原来的例程中被注释掉了,去掉注释;2)culTimer4AdmInit()函数初始化不完全,导致无法进入定时器的中断服务程序。需要增加下面两句:

1 TIMER_CHANNEL_INTERRUPT_ENABLE(4,0,1);//***add later***
2 INT_ENABLE(INUM_T4,INT_ON);//T4IE=1;//***add later***IEN1.T4IE=1

hal.h中有两个宏定义函数的定义:第一句打开通道,第二句使能T4定时器中断T4IE。

1 // Macro for enabling/ disabling interrupts from the channels of timer 1, 3 or 4.
2 #define TIMER_CHANNEL_INTERRUPT_ENABLE(timer, channel, value) \
3 do{ \
4 if(value){ \
5 T##timer##CCTL##channel## |= 0x40; \
6 } else { \
7 T##timer##CCTL##channel## &= ~0x40; \
8 } \
9 } while(0)
 1 // Macro used together with the INUM_* constants
2 // to enable or disable certain interrupts.
3 // Example usage:
4 // INT_ENABLE(INUM_RFERR, INT_ON);
5 // INT_ENABLE(INUM_URX0, INT_OFF);
6 // INT_ENABLE(INUM_T1, INT_ON);
7 // INT_ENABLE(INUM_T2, INT_OFF);
8 #define INT_ENABLE(inum, on) \
9 do { \
10 if (inum==INUM_RFERR) { RFERRIE = on; } \
11 else if (inum==INUM_ADC) { ADCIE = on; } \
12 else if (inum==INUM_URX0) { URX0IE = on; } \
13 else if (inum==INUM_URX1) { URX1IE = on; } \
14 else if (inum==INUM_ENC) { ENCIE = on; } \
15 else if (inum==INUM_ST) { STIE = on; } \
16 else if (inum==INUM_P2INT) { (on) ? (IEN2 |= 0x02) : (IEN2 &= ~0x02); } \
17 else if (inum==INUM_UTX0) { (on) ? (IEN2 |= 0x04) : (IEN2 &= ~0x04); } \
18 else if (inum==INUM_DMA) { DMAIE = on; } \
19 else if (inum==INUM_T1) { T1IE = on; } \
20 else if (inum==INUM_T2) { T2IE = on; } \
21 else if (inum==INUM_T3) { T3IE = on; } \
22 else if (inum==INUM_T4) { T4IE = on; } \
23 else if (inum==INUM_P0INT) { P0IE = on; } \
24 else if (inum==INUM_UTX1) { (on) ? (IEN2 |= 0x08) : (IEN2 &= ~0x08); } \
25 else if (inum==INUM_P1INT) { (on) ? (IEN2 |= 0x10) : (IEN2 &= ~0x10); } \
26 else if (inum==INUM_RF) { (on) ? (IEN2 |= 0x01) : (IEN2 &= ~0x01); } \
27 else if (inum==INUM_WDT) { (on) ? (IEN2 |= 0x20) : (IEN2 &= ~0x20); } \
28 } while (0)


调试时发现IAR和keil一样,调试功能很强大。通过Register部分可以看到各个寄存器的状态,具体到寄存器某一位的状态都可以看到,从而知道程序是否执行到了想要的结果。

 

实验调试时为了进行定时器问题的分析,仔细看了一下CC2430中断和定时器部分的datasheet说明,按照给的定时器例程自己也写了一个定时器(T1和T4)的例程,不过例程没有用到中断服务程序,这里用到了。实验实现了两个自带LED的交替闪烁。

修改后的定时器中断例程:

  1 #include <ioCC2430.h>
2
3 #define uint unsigned int
4 #define uchar unsigned char
5
6 #define RLED P1_0
7 #define YLED P1_1
8
9 uint counter=0; //统计溢出次数
10 uint TempFlag; //用来标志是否要闪烁
11
12 void Initial(void);
13 void Delay(uint);
14
15 /****************************
16 //普通延时程序
17 ***************************/
18 void Delay(uint n)
19 {
20 uint i;
21 for(i=0;i<n;i++);
22 for(i=0;i<n;i++);
23 for(i=0;i<n;i++);
24 for(i=0;i<n;i++);
25 for(i=0;i<n;i++);
26 }
27
28 /****************************
29 //初始化Timer1
30 ***************************/
31 void InitialTimer1(void)
32 {
33 //初始化P1
34 P1DIR = 0x03; //P10 P11为输出
35 RLED = 1;
36 YLED = 1; //灭LED
37
38 // IEN1
39 T1IE=1;
40 //TIMIF
41 OVFIM=1;
42 T1IF=0;//清定时器中断标志
43 //用T1来做实验
44 T1CTL = 0x1d; //溢出中断有效,128分频;自动重装模式(0x0000->0xffff);
45 EA=1;
46 }
47
48
49
50 /****************************
51 //初始化Timer4
52 ***************************/
53 void InitialTimer4(void)
54 {
55 //初始化P1
56 P1DIR = 0x03; //P10 P11为输出
57 RLED = 1;
58 YLED = 1; //灭LED
59
60 // IEN1
61 T4IE=1;
62 //TIMIF
63 T4OVFIF=1;
64 //IRCON
65 T4IF=0;//清定时器中断标志
66 //用T1来做实验
67 T4CTL = 0xf8; //128分频;溢出中断有效;自动重装模式(0x0000->0xffff);
68 //T4CTL|=0x10;//启动定时器4
69 EA=1;
70 }
71
72
73
74 /***************************
75 //主函数
76 ***************************/
77 void main()
78 {
79 InitialTimer4(); //调用初始化函数
80 RLED = 0; //点亮红色LED
81 while(1) //查询溢出
82 {
83 /*
84 if(IRCON > 0)
85 {
86 IRCON = 0; //清溢出标志
87
88 TempFlag = !TempFlag;
89 }
90 if(TempFlag)
91 {
92 YLED = RLED;
93 RLED = !RLED;
94 Delay(6000);
95 }
96 */
97 }
98 }
99 //cd wxl
100
101
102
103 /***************************
104 //T1_ISR
105 ***************************/
106 #pragma vector = T1_VECTOR
107 __interrupt void T1_ISR(void)
108 {
109 T1IF=0;//清定时器中断标志
110 T1CTL&=~0x01;//stop timer1
111 YLED = RLED;
112 RLED = !RLED;
113 Delay(6000);
114 T1CTL|=0x01;//start timer1
115 }
116
117
118
119 /***************************
120 //T4_ISR
121 ***************************/
122 #pragma vector = T4_VECTOR
123 __interrupt void T4_ISR(void)
124 {
125 T4IF=0;//清定时器中断标志
126 T4CTL&=~0x10;//stop timer4
127 YLED = RLED;
128 RLED = !RLED;
129 Delay(6000);
130 T4CTL|=0x10;//start timer4
131 }


现在回过头来发现,暑假期间参加过电子设计大赛虽然没有得到任何奖项,连省奖都没拿到,但是确实从大牛那学习到很多东西,包括如何阅读datasheet、软硬件结合的调试技巧和学习的习惯等。所以要时刻提醒自己,对待每一件事情都要十分认真。你需要的只是全心的投入,即使没有明显的成功,收获也会颇丰。




posted @ 2012-01-03 22:15  ijustwanttorun  阅读(1034)  评论(0编辑  收藏  举报