了解cc2431协议栈的基本内容,编写程序完成点对点通信,实现温湿度数据的发送与接收。
硬件连接:
LEDO和LED1分别连接到CC2430的P1_0 P1_1,IO口输出低电平点亮LED。
温湿度传感器sht11为3.3V供电,J5和P1通过硬件连接,因此CC2430的P0_0连接着sht11的clk,CC2430的P0_1连接着SDA,本实验通过GPIO模拟I2C方式实现CC2430对温湿度传感器的控制。
本实验还是用了UART ,P0-2和P0-3为串口通信接口
软件部分:
IO设置:PxSEL设置IO口模式,0为普通IO,1为外设;PxDIR设置IO输入或输出,PxINP设置IO口的输入模式,两态或三态。代码如下:
1. P1DIR = 0X03; //设置LED
2. P0SEL &= ~(0x03<<0); // set general io mode for p0
3. P0DIR = 0X03; //
4. P0INP &= ~0X02;
5. P2INP &= ~(0x01<<5);
UART波特率设置和时钟设置:
1. CLKCON &= ~0x40; //晶振
2. while(!(SLEEP & 0x40)); //等待晶振稳定
3. CLKCON &= ~0x47; //TICHSPD128分频,CLKSPD不分频
4. SLEEP |= 0x04; //关闭不用的RC振荡器
5. /*时钟设置函数*/
6. PERCFG = 0x00; //位置1 P0口
7. P0SEL = 0x3c; //0011 1100 //P0用作串口
8. P2DIR &= ~0XC0; // //P0优先作为串口0
9.
10. U0CSR |= 0x80; //UART方式
11. U0GCR |= 10; //baud_e
12. U0BAUD |= 216; //波特率设为57600
13. UTX0IF = 0; //开UA
宏定义Sensor_DATA_OUT()和Sensor_CLK_OUT() ,设置了CC2431与sht11相连接的IO口P0_0和P0_1为输出,相关寄存器配置在dowhile循环中;之后又宏定义了设置CC2431的与sht11相连接的IO口为高电平或低电平,通过IS_DATA_1() 读取IO口的状态。sht11.h的六个函数,完成的是复位,与sht11建立连接;向sht11写指令;从sht11读数据;计算函数。在实际应用中调用s_measure函数即可,该函数返回值为0时表示操作无误。
1. #define Sensor_DATA_IN() do{P0DIR &= ~(0X02<<0);P0INP &= ~0X02;P2INP &= ~(0x01<<5);}while(0);
2. #define Sensor_CLK_IN() do{P0DIR &= ~(0X01<<0);}while(0);
3.
4. #define Sensor_DATA_OUT() do{P0DIR |= (0X02<<0);P0INP &= ~0X02;P2INP &= ~(0x01<<5);}while(0);
5. #define Sensor_CLK_OUT() do{P0DIR |= (0X01<<0);}while(0);
6.
7. #define set_DATA_1() (P0_1 = 1)
8. #define set_DATA_0() (P0_1 = 0)
9. #define set_CLK_1() (P0_0 = 1)
10. #define set_CLK_0() (P0_0 = 0)
11.
12. #define IS_DATA_1() ( P0_1 )
13. #define IS_CLK_1() ( P0_0 )
14.
15. typedef unsigned int uint;
16.
17. void uDelay(uint n);
18. void _nop_(void);
19.
20. void s_connectionreset(void);
21. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
22. void calc_sth11(float *p_humidity ,float *p_temperature);
23. float calc_dewpoint(float h,float t);
24. char s_read_byte(unsigned char ack);
25. char s_write_byte(unsigned char value);
协议栈目录如下:
整个z-stack协议栈采用分层的软件结构,硬件层HAL包括了各种硬件模块的驱动,包括了Timer,GPIO , UART等应用程序的API。在本次实验中,我们调用hal库中的一些函数,在app_ex_main.c和rf_test.c编写相关代码即可,实现功能即可。
协议栈中重点函数
BOOL sppInit(UINT32 frequency, BYTE address)
功能描述:初始化简单的数据包装协议Simple Packet Protocol (SPP),从 DMA 管理器申请两个 DMA 通道,用于分别从 Rx FIFO 和 Tx FIFO 传输数据。定时器4 管理器同样被设置,这个单元用于在数据包发送后接收器在一定时间内没有返回应答时产生中断。无线部分配置为发送,工作在特定的频率,在发送时自动计算和插入和检查CRC 值。
参数描述:
UINT32 frequency:RF 的频率(kHz.);
BYTE address:节点地址
返回:配置成功返回 TRUE,失败返回FALSE
BYTE sppSend(SPP_TX_STRUCT* pPacketPointer)
功能描述:发送length 字节的数据(最多122),标志,目的地址,源地址在Tx DMA 通道传送有效载荷到Tx FIFO 前插入,如果期望应当,设置相应的标志。
参数:
SPP_TX_STRUCT* pPacketPointer:发送数据包头指针
返回:发送成功返回 TRUE,失败返回FALSE。
void sppReceive(SPP_RX_STRUCT *pReceiveData)
功能描述:
这个函数使能接收 128 字节,包括头和尾。接收数据通过DMA 传输到pReceiveData。DMA 装备同时接收开启。接收数据将触发DMA,当所有的数据包接收并且移走,DMA 产生一个中断同时运行以前定义的函数rxCallBack。
参数
SPP_TX_STRUCT* pPacketPointer:接收数据包头指针
在函数书写时,我们调用的函数主要是如下两个
radioSend(BYTE* transmitData, WORD dataLength, BYTE remoteAddress, BYTE doAck)
使用实例:
res = radioSend((BYTE *)sendBuffer, sizeof(sendBuffer), remoteAddr, DO_NOT_ACK );
例如,定义一个数组,为BYTE类型(char),BYTE sendBuffer[50]
想要发送数组到remoteaddress。
接受:
radioReceive(&receiveBuffer, &length, RECEIVE_TIMEOUT, &sender);
printf((char*)receiveBuffer);
点对点通信代码如下:可以自行添加温湿度代码:
链接:https://pan.baidu.com/s/1ZHFySYuz3H7YPEBJWswrFA
提取码:7hqo