XX | 班级 | 学号 | ||||||
同组同学 | ||||||||
实验课表现 | 出勤、表现得分25% | 25 | 实验报告 得分50% | 实验总分 | ||||
操作结果得分25% | 25 | |||||||
实验目的 | ||||||||
了解ZigBee的工作原理和技术特点,利用CC2530芯片开发一个简单的ZigBee组网通信实验。 | ||||||||
实验内容 | ||||||||
以小组为单位,利用CC2530芯片部署无线传感网络实验,分别设计采集节点、汇聚节点的程序,采集节点采集温度信息,并通过无线信道传输给汇聚节点。汇聚节点再将温度数据通过串口传输给上位机(PC机)。要求自己设计通信协议,实现上位机对监控区域的定时和实时温度数据采集。 | ||||||||
实验过程中遇到的问题以与如何解决的?(可以写多条,是否认真填写将影响实验成绩) | ||||||||
在实验过程中我遇到了 2、接收到自己的信息后仍然有很多的噪声干扰出现了很多的乱码 3、接收自己的信息也被转换成乱码 4、遇到了选择性接收上的技术问题 5、温度的acsii码转换错误 通过.......的方式,我解决了这个问题。 1、修改了接收代码并确认发送代码没毛病 2、尝试修改信道 3、检查到接收子程序有问题并修改了 4、老师建议我们使用选择性接收 5、通过组员合作研究讨论并上网查解决 没有问题的情况下,是否有创新思路(或多做哪些工作)。 好像并没有 实验代码如下: 发送代码: /**************************************************************************** * 文 件 名: main.c * 作 者: Andy * 修 订: 2013-01-08 * 版 本: 1.0 * 描 述: 设置串口调试助手波特率:115200bps 8N1 * 串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串 ****************************************************************************/ #include <ioCC2530.h> #include <string.h> #include <stdio.h> #include <stdlib.h> //#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0x00)//三个 char rf_rx_buf[128]; void rf_send( char *pbuf , int len); void rf_receive_isr(); typedef unsigned char uchar; typedef unsigned int uint; #define UART0_RX 1 #define UART0_TX 2 #define SIZE 51 char RxBuf; char UartState; uchar count; char RxData[SIZE]; //存储发送字符串 void InitClock(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为 32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为 32MHZ } /**************************************************************************** * 名 称: InitSensor() * 功 能: 温度传感器初始化函数 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitSensor(void) { //DISABLE_ALL_INTERRUPTS(); //关闭所有中断 InitClock(); //设置系统主时钟为 32M TR0=0x01; //设置为1来连接温度传感器到SOC_ADC ATEST=0x01; //使能温度传感 } /**************************************************************************** * 名 称: GetTemperature() * 功 能: 获取温度传感器 AD 值 * 入口参数: 无 * 出口参数: 通过计算返回实际的温度值 ****************************************************************************/ float GetTemperature(void) { uint value; ADCCON3 = (0x3E); //选择1.25V为参考电压;14位分辨率;对片内温度传感器采样 ADCCON1 |= 0x30; //选择ADC的启动模式为手动 ADCCON1 |= 0x40; //启动AD转化 while(!(ADCCON1 & 0x80)); //等待 AD 转换完成 value = ADCL >> 4; //ADCL 寄存器低 2 位无效 value |= (((uint)ADCH) << 4); return (value-1367.5)/4.5-5; //根据 AD 值,计算出实际的温度,芯片手册有错,温度系数应该是4.5 /℃ //进行温度校正,这里减去5℃(不同芯片根据具体情况校正) } /**************************************************************************** * 名 称: DelayMS() * 功 能: 以毫秒为单位延时 * 入口参数: msec 延时参数,值越大,延时越久 * 出口参数: 无 ****************************************************************************/ void DelayMS(uint msec) { uint i,j; for (i=0; i<msec; i++) for (j=0; j<1070; j++); } /**************************************************************************** * 名 称: InitUart() * 功 能: 串口初始化函数 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitUart(void) { PERCFG = 0x00; //外设控制寄存器 USART 0的IO位置:0为P0口位置1 P0SEL = 0x0c; //P0_2,P0_3用作串口(外设功能) P2DIR &= ~0xC0; //P0优先作为UART0 U0CSR |= 0x80; //设置为UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为115200 UTX0IF = 0; //UART0 TX中断标志初始置位0 U0CSR |= 0x40; //允许接收 IEN0 |= 0x84; //开总中断允许接收中断 } /**************************************************************************** * 名 称: UartSendString() * 功 能: 串口发送函数 * 入口参数: Data:发送缓冲区 len:发送长度 * 出口参数: 无 ****************************************************************************/ void UartSendString(char *Data, int len) { uint i; for(i=0; i<len; i++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } //以下是RF初始化和发送与接收 void rf_init() { TXPOWER = 0xD5; // 发射功率为1dBm //FRMCTRL0 |= (0x20 | 0x40); /* AUTO_ACK | AUTO_CRC */ CCACTRL0 = 0xF8; // 推荐值 smartRF软件生成 FRMFILT0 = 0x0c; // 静止接收过滤,即接收所有数据包 FSCAL1 = 0x00; // 推荐值 smartRF软件生成 TXFILTCFG = 0x09; AGCCTRL1 = 0x15; //AGCCTRL2 = 0xFE; //TXFILTCFG = 0x09; // 推荐值 smartRF软件生成 FREQCTRL = 0x09; // 选择通道11 RFIRQM0 |= (1<<6); // 使能RF数据包接收中断 IEN2 |= (1<<0); // 使能RF中断 RFST = 0xED; // 清除RF接收缓冲区 ISFLUSHRX RFST = 0xE3; // RF接收使能 ISRXON } void rf_send( char *pbuf , int len) { RFST = 0xE3; // RF接收使能 ISRXON while( FSMSTAT1 & (( 1<<1 ) | ( 1<<5 )));// 等待发送状态不活跃 并且 没有接收到SFD RFIRQM0 &= ~(1<<6); // 禁止接收数据包中断 IEN2 &= ~(1<<0); // 清除RF全局中断 RFST = 0xEE; // 清除发送缓冲区 ISFLUSHTX RFIRQF1 = ~(1<<1); // 清除发送完成标志 // 填充缓冲区 填充过程需要增加2字节,CRC校验自动填充 RFD = len + 2; for (int i = 0; i < len; i++) { RFD = *pbuf++; } RFST = 0xE9; // 发送数据包 ISTXON while (!(RFIRQF1 &(1<<1) )); // 等待发送完成 P0_0 = ~P0_0; RFIRQF1 = ~(1<<1); // 清除发送完成标志位 RFIRQM0 |= (1<<6); // RX接收中断 IEN2 |= (1<<0); } /**************************************************************************** * 程序入口函数 ****************************************************************************/ void main(void) { //char i; // float AvgTemp; //char strTemp[6]; 相位调制器 CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ InitUart(); //调用串口初始化函数 UartState = UART0_RX; //串口0默认处于接收模式 memset(RxData, 0, SIZE); InitSensor(); rf_init(); float x = GetTemperature(); char a[10]; sprintf(a, "%g", x); char b[15]="A C1:"; strcat(b,a); while(1) { rf_send(b,20); 电镀废水处理 DelayMS(20); } /* if(UartState == UART0_TX) //发送状态 { U0CSR &= ~0x40; //禁止接收 AvgTemp = 0; for (i=0; i<64; i++) { AvgTemp += GetTemperature(); AvgTemp = AvgTemp/2; //每次累加后除 2 } memset(strTemp, 0, 6); sprintf(strTemp,"%.02f\n", AvgTemp);//将浮点数转成字符串 UartSendString(strTemp, 6); rf_send(strTemp , 5); DelayMS(1000); //延时 // UartSendString(RxData, count); //发送已记录的字符串。 U0CSR |= 0x40; //允许接收 UartState = UART0_RX; //恢复到接收状态 count = 0; //计数清0 memset(RxData, 0, SIZE); //清空接收缓冲区 } } */ } 接收代码: /******************************************************************************* * 文件名称:UART(Receive INT)_Ex.c * 功 能:CC253x系列片上系统基础实验--- UART(接收数据 中断方式) * 描 述:本实验使用CC253x系列片上系统的片内USART控制器,工作在UART模式下,通 * 过UART0接收数据,采用中断方式。 * 实验硬件: * 用USB电缆连接SK-SmartRF05EB上的USB接口与用户PC的USB接口。 * * 作 者:POWER * 日 期:2010-04-18 ******************************************************************************/ /* 包含头文件 */ /********************************************************************/ #include "ioCC2530.h" // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义 #include "LCD.h" // lcd驱动头文件 #include "stdio.h" // C语言标准输入/输出库头文件 /********************************************************************/ /* 定义枚举类型 */ /********************************************************************/ enum SYSCLK_SRC{XOSC_32MHz,RC_16MHz}; // 定义系统时钟源(主时钟源)枚举类型 /********************************************************************/ /********************************************************************* * 函数名称:SystemClockSourceSelect * 功 能:选择系统时钟源(主时钟源) * 入口参数:source * XOSC_32MHz 32MHz晶体振荡器 * RC_16MHz 16MHz RC振荡器 * 出口参数:无 * 返 回 值:无 ********************************************************************/ void SystemClockSourceSelect(enum SYSCLK_SRC source) { unsigned char osc32k_bm = CLKCONCMD & 0x80; unsigned char __clkconcmd,__clkconsta; /* 系统时钟源(主时钟源)选择16MHz RC振荡器,定时器tick设置为16MHz,时钟速度设置为16MHz CLKCONCMD.OSC32K[b7]不改变 32KHz时钟源选择保持先前设置 CLKCONCMD.OSC[b6] = 1 系统时钟源(主时钟源)选择16MHz RC振荡器 CLKCONCMD.TICKSPD[b5..b3] = 001 定时器tick设置为16MHz CLKCONCMD.CLKSPD[b2..b0] = 001 时钟速度设置为16MHz */ if(source == RC_16MHz) { /* CLKCONCMD.OSC32K[b7] */ CLKCONCMD = ((osc32k_bm) | \ /* CLKCONCMD.OSC[b6] = 1 */ (0x01 << 6) | \ /* CLKCONCMD.TICKSPD[b5..b3] = 001 */ (0x01 << 3) | \ /* CLKCONCMD.CLKSPD[b2..b0] = 001 */ (0x01 << 0)); } /* 系统时钟源(主时钟源)选择32MHz晶体振荡器,定时器tick设置为32MHz,时钟速度设置为32MHz CLKCONCMD.OSC32K[b7]不改变 32KHz时钟源选择保持先前设置 CLKCONCMD.OSC[b6] = 0 系统时钟源(主时钟源)选择32MHz晶体振荡器 CLKCONCMD.TICKSPD[b5..b3] = 000 定时器tick设置为32MHz CLKCONCMD.CLKSPD[b2..b0] = 000 时钟速度设置为32MHz */ else if(source == XOSC_32MHz) { CLKCONCMD = (osc32k_bm /*| (0x00<<6) | (0x00<<3) | (0x00 << 0)*/); } 邀请注册 /* 等待所选择的系统时钟源(主时钟源)稳定 */ __clkconcmd = CLKCONCMD; // 读取时钟控制寄存器CLKCONCMD do { __clkconsta = CLKCONSTA; // 读取时钟状态寄存器CLKCONSTA }while(__clkconsta != __clkconcmd); // 直到CLKCONSTA寄存器的值与CLKCONCMD寄存 // 器的值一致,说明所选择的系统时钟源(主 // 时钟源)已经稳定 } /********************************************************************* * 函数名称:InitUART0 * 功 能:UART0初始化 * P0.2 RX * P0.3 TX * 波特率:57600 * 数据位:8 * 停止位:1 * 奇偶校验:无 * 入口参数:无 * 出口参数:无 * 返 回 值:无 ********************************************************************/ void InitUART0(void) { /* 片内外设引脚位置采用上电复位默认值,即PERCFG寄存器采用默认值 */ /* P0.2 RX P0.3 TX P0.4 CT P0.5 RT */ /* UART0相关引脚初始化 */ P0SEL |= ((0x01 << 2) | (0x01 << 3)); // P0.2和P0.3作为片内外设I/O /* P0口外设优先级采用上电复位默认值,即P2DIR寄存器采用默认值 */ /* 第一优先级:USART0 第二优先级:USART1 第三优先级:Timer1 */ /* UART0波特率设置 */ /* 波特率:57600 当使用32MHz 晶体振荡器作为系统时钟时,要获得57600波特率需要如下设置: UxBAUD.BAUD_M = 216 UxGCR.BAUD_E = 10 该设置误差为0.03% */ U0BAUD = 216; U0GCR = 10; /* USART模式选择 */ U0CSR |= 0x80; // UART模式 /* UART0配置 */ U0UCR |= 0x80; // 进行USART清除 /* 以下配置参数采用上电复位默认值: 硬件流控:无 奇偶校验位(第9位):奇校验 第9位数据使能:否 奇偶校验使能:否 停止位:1个 停止位电平:高电平 起始位电平:低电平 */ /* 用於发送的位顺序采用上电复位默认值,即U0GCR寄存器采用上电复位默认值 */ /* LSB先发送 */ URX0IF = 0; // 清零UART0 RX中断标志 U0CSR |= (0x01 << 6); // 使能接收器 URX0IE = 1; // 使能UART0 RX中断 } char rf_rx_buf[16]; char pbuf[16]; /********************************************************************* * 函数名称:UART0SendByte * 功 能:UART0发送一个字节 * 入口参数:c * 出口参数:无 * 返 回 值:无 ********************************************************************/ void UART0SendByte(unsigned char c) { U0DBUF = c; // 将要发送的1字节数据写入U0DBUF while (!UTX0IF); // 等待TX中断标志,即U0DBUF就绪 UTX0IF = 0; // 清零TX中断标志 } /********************************************************************* * 函数名称:UART0SendString * 功 能:UART0发送一个字符串 * 入口参数:无 * 出口参数:无 * 返 回 值:无 ********************************************************************/ void UART0SendString( char *str) { while(1) { if(*str == '\0') break; // 遇到结束符,退出 UART0SendByte(*str++); // 发送一字节 } } void rf_init() { TXPOWER = 0xD5; // 发射功率为1dBm //FRMCTRL0 |= (0x20 | 0x40); /* AUTO_ACK | AUTO_CRC */ CCACTRL0 = 0xF8; // 推荐值 smartRF软件生成 FRMFILT0 = 0x0c; // 静止接收过滤,即接收所有数据包 FSCAL1 = 0x00; // 推荐值 smartRF软件生成 TXFILTCFG = 0x09; AGCCTRL1 = 0x15; //AGCCTRL2 = 0xFE; //TXFILTCFG = 0x09; // 推荐值 smartRF软件生成 FREQCTRL = 0x09; // 选择通道11 RFIRQM0 |= (1<<6); // 使能RF数据包接收中断 IEN2 |= (1<<0); // 使能RF中断 RFST = 0xED; // 清除RF接收缓冲区 ISFLUSHRX RFST = 0xE3; // RF接收使能 ISRXON } void rf_receive_isr() { int rf_rx_len = 0; char r[1] = {0}; char crc_ok = 0; char *rf_rx_buf; rf_rx_len = RFD - 2; // 长度去除两字节附加结果 rf_rx_len &= 0x7F; for (int i = 0; i < rf_rx_len; i++) { rf_rx_buf[i] = RFD; // 连续读取接收缓冲区内容 } r[0] = RFD - 73; // 读取RSSI结果文具盒生产过程 crc_ok = RFD; // 读取CRC校验结果 BIT7 RFST = 0xED; // 清除接收缓冲区 if( crc_ok & 0x80 ) { for(int i=0;i<=strlen(rf_rx_buf);i++) { if(rf_rx_buf[i]==':'){ strcat(rf_rx_buf,"\n"); UART0SendString(rf_rx_buf); } // }// 串口发送 // UartSendString(r,1); } // else // { // UartSendString("CRC Error",9); // } } } //unsigned long rcv_count = 0; // 累计接收到的字节计数 //unsigned long rcv_charA_count = 0; // 累计接收到的字符'A'计数 /********************************************************************* * 函数名称:URX0_ISR * 功 能:UART0 RX中断服务函数 * 入口参数:无 * 出口参数:无 * 返 回 值:无 ********************************************************************/ #pragma vector=RF_VECTOR __interrupt void rf_isr(void) { unsigned char e; P2_0 = ~P2_0; // LED1翻转 提示作用 e = EA; 金属化膜 EA = 0; // 接收到一个完整的数据包 调制解调器固件 if (RFIRQF0 & ( 1<<6 )) { rf_receive_isr(); // 调用接收中断处理函数 S1CON &=~0x03; // 清除RF中断标志 RFIRQF0 &= ~(1<<6); // 清除RF接收完成数据包中断 } EA = e; } /********************************************************************* * 函数名称:main * 功 能:main函数入口 * 入口参数:无 * 出口参数:无 * 返 回 值:无 ********************************************************************/ void main(void) { char s[16]; char rcv_count[16]; char rcv_charA_count[16]; SystemClockSourceSelect(XOSC_32MHz); // 选择32MHz晶体振荡器作为系统时钟源(主时钟源) HalLcdInit(); // LCD初始化 HalLcd_HW_Clear(); // 清屏 /* 在LCD上显示相关信息 */ HalLcdWriteString("CC253x UART0 Recv", HAL_LCD_LINE_1); HalLcdWriteString("57600-8-1-N-N", HAL_LCD_LINE_3); HalLcd_HW_WaitUs(50000); InitUART0(); // UART0初始化 rf_init(); rf_receive_isr(); EA = 1; // 使能全局中断 /* 在LCD上显示从UART0累计接收到的字节数量以与字符'A'的数量 */ while(1) { sprintf(s,"0x%08X",rcv_count); HalLcdWriteString((char *)s, HAL_LCD_LINE_4); // 累计接收(字节) sprintf(s,"0x%08X",rcv_charA_count); HalLcdWriteString((char *)s, HAL_LCD_LINE_5); // 累计接收字符? } } | ||||||||
本次实验的体会(可以写多条,是否认真填写将影响实验成绩) | ||||||||
通过本实验,我理解/了解/熟悉了....... CC2530 是用于2.4-GHz 、ZigBee 和RF4CE 应用的一个真正的片上系统(SoC)解决方案。它能够以非常低的总的材料成本建立强大的网络节点。 2. 组建一个完整的zigbee网状网络包括两个步骤:网络初始化、节点加入网络。其中节点加入网络又包括两个步骤:通过与协调器连接入网和通过已有父节点入网。 3. | ||||||||
思考题 | ||||||||
1.如何实现可靠传输? 答:利用稳定的信道和端口发送和接收信息,并且要排除噪声的干扰以确保接收到的消息的完整性和准确性。ZigBee是一种高可靠的无线数传网络,类似于CDMA和GSM网络。ZigBee数传模块类似于移动网络。通讯距离从标准的75m到几百米、几公里,并且支持无限扩展。 ZigBee是一个由可多到65000个无线数传模块组成的一个无线数传网络平台,在整个网络范围内,每一个ZigBee网络数传模块之间可以相互通信,每个网络节点间的距离可以从标准的75m无限扩展。 2.如何实现数据加密? 在ZigBee技术中,采用对称密钥的安全机制,密钥由网络层和应用层根据实际应用需要生成,并对其进行管理、存储、传送和更新等。 安全机制由安全服务提供层提供。然而值得注意的是,系统的整体安全性是在模板级定义的,这意味着模板应该定义某一特定网络中应该实现何种类型的安全。 每一层(MAC、网络或应用层)都能被保护,为了降低存储要求,它们可以分享安全钥匙。SSP是通过ZD0进行初始化和配置的,要XX现高级加密标准(AES)。ZigBee规范定义了信任中心的用途。信任中心是在网络中分配安全钥匙的一种令人信任的设备。 答:1、先用特定的方式把信息数据转化为特定的符号或其他字段,然后发送到接收端后接收端再用特殊的手段对接收到的信息反编译。 2、给需要发送的信息加上外壳进行保护 3、给需要加密的信息里插入无意义的字符和字段 | ||||||||
教师评价 | ||||||||
实验态度 A. 很认真 B. 认真 C. 比较认真 D. 不认真 独立完成情况 A. 很好 B. 好 C. 比较好 D. 不好 收获和体会 A. 多 B. 比较多 C. 少 D. 很少 思考题回答情况 A. 很好 B. 好 C. 比较好 D. 不好 评阅教师:杨博雄 日 期:2017.4. | ||||||||
本文发布于:2023-05-29 03:24:53,感谢您对本站的认可!
本文链接:https://patent.en369.cn/patent/3/118063.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |