一、知识梳理

1. Zigbee、蓝牙、IEEE802.11b(WiFi)标准都是工作在2.4G频段的无线通信标准;Zigbee主要用在短距离无线控制系统,传输少量的控制信息;

2. 短距离无线网络主要分为:无线局域网(WLANs)和无线个域网(WPANs)

3. 无线个域网所对应的通信协议:
HR-WPANS:802.15.3
MR-WPANS:蓝牙
LR-WPANS(低速率无线个域网):802.15.4

4. Zigbee最大传输速率: 250kbps。 ZigBee可工作在2.4GHz(全球流行)、868MHz(欧洲流行) 和915 MHz(美国流行)3个频段上,分别具有最高250kbit/s、20kbit/s和40kbit/s的传输速率,它的传输距离在10-75m的范围内, 但可以继续增加 。

5. Zigbee无线网络分层: 物理层(PHY) 介质访问控制(MAC)网络层(NWK)应用程序支持子层(APS) 应用层(APL)
其中802.15.4 定义了物理层和介质访问控制层;Zigbee协议定义了网络层、应用程序支持子层和应用层

6. Zigbee特点:(自组网)
高可靠性: 采取了碰撞避免策略;MAC层采用了完全确认的数据传输模式;
低成本、低功耗 : ZigBee模块的复杂度不高,ZigBee协议免专利费,再加之使用的频段无需付费,所以它的成本较低;ZigBee的传输速率低,发射功率仅为1mW,而且采用了休眠模式,功耗低
高安全 : 采用高级加密标准(AES 128) 的对称密码;
低数据速率

7. Zigbee设备类型:
协调器(ZC Coordinator):主要负责无线网络的建立与维护;(每个ZigBee网络必须有一个)
路由器(ZR Router):主要负责无线网络的路由;( (1)允许其他网络设备加入 (2)多跳路由 (3)协助电池供电的子节点通信(4)自己作为终端节点应用)
终端节点(ZED End-device):主要负责无线网络数据的采集。(1)向路由节点传递数(2)没有路由功能(3)低功耗(Zigbee的低功耗主要体现在这里)(4)可选择睡眠与唤醒。(路由因不断转发数据需电源供电,终端节点电池供电))

8. Zigbee工作在ISM(工业、科学和医疗)频带,共规定了27个信道:
2.4GHz频段 共16个信道,通信速率为250kbps
915MHz频段 共10个信道,通信速率为40kbps
896MHz频段 共1个信道,通信速率为20kbps

9. Zigbee网络拓扑结构: 星型;网络型;簇状;

10. Zigbee应用为: 周期性 ;反复; 间断数据采集应用;

11. Zigbee模块开发一般包括两个文件:.h头文件和.c文件
.h文件可理解为一份接口描述文件;
.c文件主要功能是对.h文件中声明的外部函数进行具体实现。

12. 网络中传输的三类数据:
周期性数据:如家庭中水、电、气三表数据的传输;
间断性数据:如电灯、家用电器的控制等数据的传输;
反复性的低反应时间的数据:如鼠标、操作杆传输的数据。

13. ZigBee设备分类
全功能设备(FFD): 可以担任网络协调者,形成网络,让其它的FFD或是精简功能装置(RFD)连结,FFD具备控制器的功能,可提供信息双向传输。
~附带由标准指定的全部 802.15.4 功能和所有特征
~更多的存储器、计算能力可使其在空闲时起网络路由器作用。
~也能用作终端设备
精简功能设备(RFD): RFD只能传送信息给FFD或从FFD接收信息。
~附带有限的功能来控制成本和复杂性
~在网络中通常用作终端设备。
~ZigBee相对简单的实现自然节省了费用。RFD由于省掉了内存和其他电路,降低了ZigBee部件的成本,而简单的8位处理器和小协议栈也有助于降低成本。
Zigbee设备类型与角色对应关系
在这里插入图片描述

14. ZigBee协议架构
① 物理层功能: PHY层由射频收发器以及底层的控制模块构成;
(1)激活和休眠射频收发器;
(2)信道能量检测(energy detect);
(3) 检测接收数据包的链路质量指示(link quality indication , LQI);
(4)空闲信道评估(clear channel assessment, CCA);
(5)收发数据。

② 数据链路层功能: MAC子层为高层访问物理信道提供点到点通信的服务接口
(1)协调器产生并发送信标帧,普通设备根据协调器的信标帧与协议器同步;
(2)支持PAN网络的关联(association)和取消关联(disassociation)操作;
(3)支持无线信道通信安全;
(4)使用CSMA-CA(载波侦听多路访问/冲突避免)机制访问信道;
(5)支持时槽保障(guaranteed time slot, GTS)机制;
(6)支持不同设备的MAC层间可靠传输。

③ 网络层功能:
(1)ZigBee网络层的主要功能就是提供一些必要的函数,确保ZIgBee的MAC层(IEEE 802.15.4-2003)正常工作,并且为应用层提供合适的服务接口。为了向应用层提供其接口,网络层提供了两个必须的功能服务实体,它们分别为数据服务实体和管理服务实体。
(2)网络层数据实体(NLDE)通过网络层数据服务实体服务接入点(NLDE-SAP)提供数据传输服务;
(3)网络层管理实体(NLME)通过网络层管理实体服务接入点(NLME-SAP)提供网络管理服务。网络层管理实体利用网络层数据实体完成一些网络的管理工作,并且,网络层管理实体完成对网络信息库(NIB)的维护和管理。

④应用会聚层功能: 该层主要负责把不同的应用映射到ZigBee网络上,具体而言包括:
(1)安全与鉴权
(2)多个业务数据流的会聚
(3)设备发现
(4)服务发现

15. TCP/IP结构对应OSI结构
在这里插入图片描述
16. Z-Stack协议栈文件组织结构介绍
在这里插入图片描述
17. 设备地址:
64位IEEE地址:长地址又称 MAC地址或 扩展地址(全球唯一)
16位网络地址:短地址 又称逻辑地址(协调器地址为0x0000,其他设备入网时由协调器分配)(1)在网络中标识不同设备;(2)在网络数据传输时指定目的地址和源地址;

18. 网络地址: 唯一标示网络中的一个节点(用网络地址来区分不同的节点);(P135)

19. 网络地址最多可以分配65536个节点,地址分配取决于整个网络的架构,整个网络的架构由一下3个值决定:
1、网络最大深度
2、每个父节点拥有的孩子节点最大数目
3、每个父节点拥有的孩子节点路由器的最大数目
同一父节点相连的终端节点的网络地址是连续的
同一父节点相连的路由器节点的网络地址通常是不连续的

20. 端口: 每个节点上最多支持240(1-240)个端口,每个节点上的所有端口共用一个发射/接收天线(用端口来区分同一节点的端口);

21. PANID: Zigbee网络号 可手动设置(或自动随机生成),如果指定的PANID被占用则自动加1。
~PANID范围是0X0001----0XFFFF;
~可以通过给不同的网络指定不同的网络ID号来区分网络,避免干扰;
~如果设置为0XFFFF,那么协调器则随机产生一个值作为自己的PANID;

非易失性闪存条目ID号(NV操作用到的ID则定义在0x0201~0x0FFF 范围内!)
在这里插入图片描述

二、编程实战

  1. 利用定时器中断实现LED1大约每隔4秒闪烁一次(自由运行模式,模模式,正计数/倒计数模式分别实现)。
  2. 定时器1和定时器3分别控制LED1(模模式)和LED2(正计数/倒计数模式)以不同频率闪烁,LED1大约5秒闪烁一次,LED2大约2秒闪烁一次。
#include <ioCC2530.h>
#define uint unsigned int 
#define uchar unsigned char 
#define uint32 unsigned long

#define led1 P0_0
#define led2 P2_0
uint counter=0;
uint counter1=0;
void LED_Init()
{
  P0SEL &=~0X01;   //0000 0001
  P0DIR |=0X01;
  P2SEL &=~0X01;   //0000 0001
  P2DIR |=0X01;
}

void TIM1_Init()
{
  CLKCONCMD&=~0X7f;         //晶振设置为32MHz
  while(CLKCONSTA & 0x40);  //等待晶振稳定

  EA=1;                     //开总中断
  T1IE=1;                   //开T1溢出中断
  //T1CTL=0x09;               //0000 1001启动设32分频,设自由模式
  
  
  //T1CTL=0x0A;               //0000 1010启动设32分频,设模模式
  //T1CC0H=0X30;              //30D4=12500
  //T1CC0L=0XD4;
  //T1CCTL0|=0x04;           //开启通道0的输出比较模式
  
  T1CTL=0x0B;               //0000 1011启动设32分频,设正/倒计数模式
  T1CC0H=0X30;              //30D4=12500  
  T1CC0L=0XD4;
  
  led1=1;
  led2=0;   
}     

/*
void TIM3_Init()
{
  T3IE=1;
  T3CTL=0XBC;                //T3启动,设32分频,设自由模式
}
*/
void TIM3_Init()
{
  T3IE=1;
  T3CTL=0XBF;                //T3启动,设32分频,设正/倒计数模式
  T3CC0=255;
}

void main()
{  
  LED_Init();
  
  TIM1_Init();
  TIM3_Init();
  while(1)
  {
    
    
  }
}

#pragma vector = T1_VECTOR
__interrupt void LED1(void)
{
    IRCON=0x00;
    //if(counter <76)  // 自由模式5s 
    //if(counter <61)  // 自由模式4s 
    //if(counter <320)  // 模模式4s 
    if(counter <160) //倒计数模式4s  
    {
      counter++;
    }else{
      counter=0;
      led1=!led1;
      
    }
}

#pragma vector = T3_VECTOR
__interrupt void LED2(void)
{
    IRCON=0x00;
    //if(counter1 <7812) //   自由模式 2s
    if(counter1 <3906) //   正/倒计数模式 2s
    {
      counter1++;
    }else{
      counter1=0;
      led2=!led2;
    }
}

1.当串口接收到来自串口调试助手发送来的0x01时改变LED2 状态,并发送"welcome"
2.通过定时器和串口协调配合,每隔6秒向PC发送 “everything is ok”
3.实验平台通过串口向PC串口发送字符串“What is your name?”,计算机向平台发送名字,名字的以#号结束,实验平台向串口发送字符串“HELLO”+名字。
*4. 编程实现,串口如果收到”LED11#”,打开LED1,如果收到”LED12#”,关闭LED1; 串口如果收到”LED21#”,打开LED2,如果收到”LED22#”,关闭LED2。

#include <iocc2530.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1 P1_0
#define LED2 P2_0

void LED_Init();
void initUART0(void);
void InitialAD(void);
void UartTX_Send_String(uchar *Data,int len);
void delay(void);

uchar Recdata1[10]="Hello\n";
uchar Recdata[10]="Welcome\n";
uchar RXTXflag = 1;
uchar temp=0;
uint  datanumber = 0;
uint  stringlen;

/****************************************************************
串口发送字符串函数				
****************************************************************/
void UartTX_Send_String(uchar *Data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

void LED_Init()
{
  P0SEL &=~0X01;
  P0DIR |=0X01;
  P2SEL &=~0X01;
  P2DIR |=0X01;
  LED1=1;
  LED2=1;
}
void delay(void)
{
  int i = 0,j = 0;
  for(i = 0;i < 1000;i++)
for(j = 0;j < 500;j++);
}

/****************************************************************
初始化串口0函数					
****************************************************************/
void initUART0(void)
{
    CLKCONCMD &= ~0x40;                         //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                    //等待晶振稳定
    CLKCONCMD &= ~0x47;                         //设置系统主时钟频率为32MHZ
   
    PERCFG = 0x00;				//位置1 P0口
    P0SEL = 0x3c;				//P0用作串口
    P2DIR &= ~0XC0;                             //P0优先作为UART0    
    U0CSR |= 0x80;				//串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;				//波特率设为115200
    UTX0IF = 1;                                 //UART0 TX中断标志初始置位1    
    U0CSR |= 0X40;				//允许接收
    IEN0 |= 0x84;				//开总中断,接收中断
}

/****************************************************************
主函数							
****************************************************************/
void main(void)
{	
        LED_Init();
	initUART0(); 
	while(1)
	{
          if(RXTXflag == 1)			     //接收状态
          {
              if(temp!=0)
              {
                  LED2=!LED2;		
                  UartTX_Send_String(Recdata,10);
                  UartTX_Send_String("\n",1);
                  RXTXflag = 3;                      //进入发送状态
               }

              temp  = 0;
          }
          if(RXTXflag == 3)			//发送状态
          {          

            U0CSR &= ~0x40;			//不能收数
            U0CSR |= 0x40;			//允许接收
            RXTXflag = 1;		        //恢复到接收状态

          }
	}
}
/****************************************************************
串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.
****************************************************************/
#pragma vector = URX0_VECTOR
 __interrupt void UART0_ISR(void)
 {
 	URX0IF = 0;				//清中断标志
	temp = U0DBUF;      
 }

#include <iocc2530.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1 P1_0
#define LED2 P2_0

void LED_Init();
void initUART0(void);
void InitialAD(void);
void UartTX_Send_String(uchar *Data,int len);
void delay(void);

uchar Recdata1[10]="Hello\n";
uchar Recdata[10]="Welcome\n";
uchar RXTXflag = 1;
uchar temp=0;
uint  datanumber = 0;
uint  stringlen;
int counter=0;
/****************************************************************
串口发送字符串函数				
****************************************************************/
void UartTX_Send_String(uchar *Data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

void TIM1_Init()
{
  CLKCONCMD&=~0X7f;         //晶振设置为32MHz
  while(CLKCONSTA & 0x40);  //等待晶振稳定

  EA=1;                     //开总中断
  T1IE=1;                   //开T1溢出中断
  T1CTL=0x09;               //0000 1001启动设32分频,设自由模式
}     

void LED_Init()
{
  P0SEL &=~0X01;
  P0DIR |=0X01;
  P2SEL &=~0X01;
  P2DIR |=0X01;
  LED1=1;
  LED2=1;
}
void delay(void)
{
  int i = 0,j = 0;
  for(i = 0;i < 1000;i++)
for(j = 0;j < 500;j++);
}

/****************************************************************
初始化串口0函数					
****************************************************************/
void initUART0(void)
{
    CLKCONCMD &= ~0x40;                         //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                    //等待晶振稳定
    CLKCONCMD &= ~0x47;                         //设置系统主时钟频率为32MHZ
   
    PERCFG = 0x00;				//位置1 P0口
    P0SEL = 0x3c;				//P0用作串口
    P2DIR &= ~0XC0;                             //P0优先作为UART0    
    U0CSR |= 0x80;				//串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;				//波特率设为115200
    UTX0IF = 1;                                 //UART0 TX中断标志初始置位1    
    U0CSR |= 0X40;				//允许接收
    IEN0 |= 0x84;				//开总中断,接收中断
}

/****************************************************************
主函数							
****************************************************************/
void main(void)
{	
        LED_Init();
	initUART0(); 
        TIM1_Init();
	while(1)
	{
	}
}
/****************************************************************
串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.
****************************************************************/
#pragma vector = URX0_VECTOR
 __interrupt void UART0_ISR(void)
 {
 	URX0IF = 0;				//清中断标志
	temp = U0DBUF;      
 }

#pragma vector = T1_VECTOR
__interrupt void Uart(void)
{
    

    IRCON=0x00;
    if(counter <91)  // 自由模式6s 
    {
      counter++;
    }else{
      LED2=0;
      counter=0;
      UartTX_Send_String("everything is ok",17);
    }
}

#include <iocc2530.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1 P1_0
#define LED2 P2_0

void LED_Init();
void initUART0(void);
void InitialAD(void);
void UartTX_Send_String(uchar *Data,int len);
void delay(void);

uchar Recdata[10]="Welcome\n";
uchar RXTXflag = 1;
uchar temp=0;
uint  datanumber = 0;
uint  stringlen;
int counter=0;
/****************************************************************
串口发送字符串函数				
****************************************************************/
void UartTX_Send_String(uchar *Data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}   

void LED_Init()
{
  P0SEL &=~0X01;
  P0DIR |=0X01;
  P2SEL &=~0X01;
  P2DIR |=0X01;
  LED1=1;
  LED2=1;
}


/****************************************************************
初始化串口0函数					
****************************************************************/
void initUART0(void)
{
    CLKCONCMD &= ~0x40;                         //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                    //等待晶振稳定
    CLKCONCMD &= ~0x47;                         //设置系统主时钟频率为32MHZ
   
    PERCFG = 0x00;				//位置1 P0口
    P0SEL = 0x3c;				//P0用作串口
    P2DIR &= ~0XC0;                             //P0优先作为UART0    
    U0CSR |= 0x80;				//串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;				//波特率设为115200
    UTX0IF = 1;                                 //UART0 TX中断标志初始置位1    
    U0CSR |= 0X40;				//允许接收
    IEN0 |= 0x84;				//开总中断,接收中断
}

/****************************************************************
主函数							
****************************************************************/
void main(void)
{	
	initUART0();
        stringlen = strlen((char *)Recdata);
        if(counter==0){
          counter=1;
          UartTX_Send_String("What is your name?",19);
        }
		            
	while(1)
	{
          if(RXTXflag == 1)			     //接收状态
          {
            if( temp != 0)
            {
                if((temp!='#')&&(datanumber<50))     //’#‘被定义为结束字符,最多能接收50个字符
                {          
                 Recdata[datanumber++] = temp;
                }
                else
                {
                  RXTXflag = 3;                      //进入发送状态
                }
                if(datanumber == 50)
                  RXTXflag = 3;
              temp  = 0;
            }
          }
          if(RXTXflag == 3)			//发送状态
          {
            UartTX_Send_String("send:",5);
            
            U0CSR &= ~0x40;			//不能收数
            UartTX_Send_String("Hello ",7);
            UartTX_Send_String(Recdata,datanumber);
            UartTX_Send_String("\n",1);
            U0CSR |= 0x40;			//允许接收
            RXTXflag = 1;		        //恢复到接收状态
            datanumber = 0;			//指针归0
            memset(Recdata, 0, sizeof(Recdata));
          }
	}

}
/****************************************************************
串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.
****************************************************************/
#pragma vector = URX0_VECTOR
 __interrupt void UART0_ISR(void)
 {
 	URX0IF = 0;				//清中断标志
	temp = U0DBUF;      
 }


#include <iocc2530.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1 P0_0
#define LED2 P2_0

void LED_Init();
void initUART0(void);
void InitialAD(void);
void UartTX_Send_String(uchar *Data,int len);

int cnt=0;
int flag=0;
uchar Recdata[6];
uchar RXTXflag = 1;
uchar temp=0;
uint  datanumber = 0;
uint  stringlen;
int counter=0;
/****************************************************************
串口发送字符串函数				
****************************************************************/
void UartTX_Send_String(uchar *Data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}   

void LED_Init()
{
  P0SEL &=~0X01;
  P0DIR |=0X01;
  P2SEL &=~0X01;
  P2DIR |=0X01;
  LED1=1;
  LED2=1;
}


/****************************************************************
初始化串口0函数					
****************************************************************/
void initUART0(void)
{
    CLKCONCMD &= ~0x40;                         //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                    //等待晶振稳定
    CLKCONCMD &= ~0x47;                         //设置系统主时钟频率为32MHZ
   
    PERCFG = 0x00;				//位置1 P0口
    P0SEL = 0x3c;				//P0用作串口
    P2DIR &= ~0XC0;                             //P0优先作为UART0    
    U0CSR |= 0x80;				//串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;				//波特率设为115200
    UTX0IF = 1;                                 //UART0 TX中断标志初始置位1    
    U0CSR |= 0X40;				//允许接收
    IEN0 |= 0x84;				//开总中断,接收中断
}

/****************************************************************
主函数							
****************************************************************/
void main(void)
{	
	initUART0();
        LED_Init();            
	while(1)
	{
          
	}

}
/****************************************************************
串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.
****************************************************************/
#pragma vector = URX0_VECTOR
 __interrupt void UART0_ISR(void)
 {
      
 URX0IF = 0;

 Recdata[datanumber++] = U0DBUF;
 if(datanumber==5)
  {
      if(Recdata[0] == 'L' && Recdata[1] == 'E' && Recdata[2] == 'D'&& Recdata[3] == '1'&& Recdata[4] == '1')
        LED1=0;
      if(Recdata[0] == 'L' && Recdata[1] == 'E' && Recdata[2] == 'D'&& Recdata[3] == '1'&& Recdata[4] == '2')
        LED1=1;
      if(Recdata[0] == 'L' && Recdata[1] == 'E' && Recdata[2] == 'D'&& Recdata[3] == '2'&& Recdata[4] == '1')
        LED2=0;
      if(Recdata[0] == 'L' && Recdata[1] == 'E' && Recdata[2] == 'D'&& Recdata[3] == '2'&& Recdata[4] == '2')
        LED2=1;
      datanumber = 0;
      //memset(Recdata,0,sizeof(Recdata));
  }
  
    
 }


1.每隔10秒采集一次VDD/3的电压值并显示出来,并且当串口接收到来自串口调试助手发送来的0x01时,发送VDD/3的电压值。
*2. 每隔20秒询问一次是否有AD采集任务,若收到回复“temp sensor”则令ADC采集片内温度传感器的值并显示出来,若收到回复“vdd”则令ADC采集VDD/3的值并显示出来。

#include <iocc2530.h>
#include <string.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char


void initUART0(void);
void UartTX_Send_String(char *Data,int len);
float GetTemperature(void);
int counter=0;
char Temp[6];
/****************************************************************
串口发送字符串函数				
****************************************************************/
void UartTX_Send_String(char *Data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

void TIM1_Init()
{
  CLKCONCMD&=~0X7f;         //晶振设置为32MHz
  while(CLKCONSTA & 0x40);  //等待晶振稳定

  EA=1;                     //开总中断
  T1IE=1;                   //开T1溢出中断
  T1CTL=0x09;               //0000 1001启动设32分频,设自由模式
  
}     

float GetTemperature(void)
{ 
   uint  value,sum; 
   int i;
   for(i=0;i<4;i++)
   {
     ADCCON3  = (0x3E);            //选择1.25V为参考电压;14位分辨率;对片内温度传感器采样
     ADCCON1 |= 0x30;              //选择ADC的启动模式为手动
     ADCCON1 |= 0x40;              //启动AD转化  
     while(!(ADCCON1 & 0x80));     //等待 AD 转换完成 
     value =  ADCL >> 2;           //ADCL 寄存器低 2 位无效,由于他只有12位有效,ADCL寄存器低4位无效。网络上很多代码这里都是右移两位,那是不对的
     value |= (((uint)ADCH) << 6);
     sum+=value;   
   }
   value=sum>>2;
   return (value-1367.5)/4.5;  
}

/****************************************************************
初始化串口0函数					
****************************************************************/
void initUART0(void)
{
    CLKCONCMD &= ~0x40;                         //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                    //等待晶振稳定
    CLKCONCMD &= ~0x47;                         //设置系统主时钟频率为32MHZ
   
    PERCFG = 0x00;				//位置1 P0口
    P0SEL = 0x3c;				//P0用作串口
    P2DIR &= ~0XC0;                             //P0优先作为UART0    
    U0CSR |= 0x80;				//串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;				//波特率设为115200
    UTX0IF = 1;                                 //UART0 TX中断标志初始置位1    
    U0CSR |= 0X40;				//允许接收
    IEN0 |= 0x84;				//开总中断,接收中断
}

/****************************************************************
主函数							
****************************************************************/
void main(void)
{	
	initUART0(); 
        TIM1_Init();
	while(1)
	{
	}
}

#pragma vector = T1_VECTOR
__interrupt void Uart(void)
{
    

    IRCON=0x00;
    if(counter <15)  // 自由模式1s 
    {
      counter++;
    }else{
        counter=0;   
        float AvgTemp = GetTemperature();         
       
        memset(Temp, 0, 6);
        sprintf(Temp,"%.2f", AvgTemp);//将浮点数转成字符串
        UartTX_Send_String(Temp,5);
        UartTX_Send_String("          ",10);
    }
}

无线射频收发实验

#include "ioCC2530.h"
#define LED2 P2_0
static unsigned char buf[128];
static int len=0;
unsigned char i;

void Delay(unsigned char m)
{  
    int i=0,j=0;
    for(i=0;i<1000;i++)
    {
        for(j=0;j < m; j++);
    }  
}

/***********************
*串口初始化
*返回参数 无
***********************/
void initUARTtest(void)
{
   
    CLKCONCMD &= ~0x40;  //晶振
    while(!(SLEEPSTA & 0x40));   //等待晶振稳定  
    CLKCONCMD &= ~0x47;     //TICHSPD128分频,CLKSPD不分频        
    SLEEPCMD |= 0x04; 	//关闭不用的RC振荡器	 
    PERCFG = 0x00;		 //位置1 P0口		
    P0SEL = 0x3c;		//P0用作串口		
    U0CSR |= 0x80;//UART方式				
    U0GCR |= 10;	//波特率设为57600			
    U0BAUD |= 216;
    UTX0IF = 0;//中断标志清0
    U0CSR |= 0X40;//允许接收
    IEN0 |= 0x84;	//开总中断,接收中断			
}

/*************************************************/
void UartTX_Send_String(unsigned char *Data,int len)
{
  int j;
  //LED2 = ~LED2;
  for(j=0;j<len;j++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

void rf_init()
{       
    //硬件CRC以及AUTO_ACK使能
	//FRMCTRL0 |= (0x20 | 0x40); /* AUTO_ACK | AUTO_CRC */
    TXFILTCFG = 0x09;//设置TX抗混叠过滤器以获得合适的带宽
    AGCCTRL1 = 0x15;//调整AGC目标值
    FSCAL1 = 0x00;//获得最佳的EVM
	RFIRQM0 |= (1<<6);// RXPKTDONE 中断位使能
	IEN2 |= (1<<0);//  RF 中断使能
    EA = 1;//开中断
    FREQCTRL = 0x0d; //信道选择,选择11信道
    SHORT_ADDR0 = 0x05;//目标地址过滤期间使用的短地址
	SHORT_ADDR1 = 0x00;
    PAN_ID0 = 0x22; //目标地址过滤期间使用的PANID
	PAN_ID1 = 0x00;
    RFST = 0xed; //清除RXFIFO缓冲区并复位解调器 
    RFST = 0xe3; //为RX使能并校准频率合成器
    FRMFILT0 &= ~(1<<0);//禁止帧过滤
    //FRMFILT0  = 0x0C;
}

#pragma vector=RF_VECTOR
__interrupt void rf_isr(void) 
{
	unsigned char  i; 
        
	EA = 0; //关中断
    //接收帧结束
    if (RFIRQF0 & (1<<6)) {       
		len = RFD-2;//接收帧长度
		len &= 0x7f;
		//将接收的数据写入buf中
		for (i = 0; i < len; i++) 
            {
	            buf[i] = RFD;
                //Delay(200);
			}
		RFST =0xED; //清除接收缓冲区
        UartTX_Send_String(buf,len); //Uart0SendString(buf);  
		S1CON = 0;  // 清RF中断
        RFIRQF0 &= ~(1<<6); //清 RXPKTDONE中断
        LED2 = ~LED2; //LED1灯状态改变          
	}
	EA = 1; 
}

void tx()
{
    unsigned char i;
    unsigned char mac[]="hncu "; 
    	           
    RFST = 0xe3; //为RX使能并校准频率合成器
	//wait for SFD not active and TX_Active not active 
    // TX_ACTIVE | SFD 
	while (FSMSTAT1 & ((1<<1) | (1<<5))); 
    RFIRQM0 &= ~(1<<6); //禁止RXPKTDONE中断
    IEN2 &= ~(1<<0); //禁止RF中断
    RFST = 0xee; // ISFLUSHTX 
    RFIRQF1 = ~(1<<1);// 清除 TXDONE 中断
         	 
    RFD = 8;// 传输的帧长度
    //将mac的内容写到RFD中
    for(i=0;i<6;i++)
        {
          RFD = mac[i];
        } 
	RFIRQM0 |= (1<<6);// 打开RX中断
	IEN2 |= (1<<0);//打开RF中断
         
	RFST = 0xe9; //发送数据包ISTXON
    while (!(RFIRQF1 & (1<<1)));//等待传输结束
    RFIRQF1 = ~(1<<1);//清除 TXDONE状态 
    LED2=~LED2;//LED1灯状态改变
    //Delay(200);//延时
}

void main(void)
{ 
    initUARTtest();
    //P0DIR |= 0x01;
    P2DIR |= 0x01;             
        
    LED2=1;//关闭LED2
    EA = 0;//关闭总中断
	SLEEPCMD &= ~0x04;//设置时钟频率为32M
	//等待时钟稳定
    while(!(SLEEPSTA & 0x40));
	CLKCONCMD &= ~0x47;
	SLEEPCMD |= 0x04; 
	rf_init();//初始化RF
	EA = 1;//中断使能 
	//发送或等待接收中断
    while(1) {
        //宏定义RX
        #ifndef RX       //如果没有定义RX,开始发送
            tx();
            Delay(200);//延时
            //Delay(200);
        # else   //如果定义RX,等待接收断中
            //UartTX_Send_String(buf,len);
        #endif
			
		
	}
}

三、高校真题

A卷

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

B卷

一键三连联系下方wx领取更多复习资料哦👇👇👇

更多推荐