zigbee CC2530 系列教程 2 基础实验

目录

4.1点亮1个LED实验

4.2流水灯实验

4.3按键控制LED实验

4.4外部中断实验

4.5定时器实验

4.6串口数据收发实验

4.7 AD采集内部温度实验

4.8睡眠唤醒实验

4.9看门狗实验

4.10 LCD Nokia 5110液晶实验

4.11温度传感器DS18B20实验

4.12温湿度传感器DHT11实验

4.13烟雾传感器实验

4.14蓝牙控制实验


4.1点亮1个LED实验

4.1.1 实验目的

了解芯片IO的基本配置方法,点亮1个LED。

4.1.2 实验讲解

首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-1所示。

图4-1 开发板LED原理图

可以看到开发板上的3个LED分别连接在芯片的P10、P11及P14引脚,P10、P11低电平点亮,P14高电平点亮,要使芯片P10引脚输出低电平需要配置三个IO口配置寄存器 P1SEL、P1DIR、P1INP,如表4-1所示。

表4-1 IO口寄存器说明

P1SEL

端口1功能选择寄存器

0:通用IO;1:外设功能

P1DIR

端口1方向选择寄存器

0:输入;1:输出

P1INP

端口1输入模式寄存器

0:上拉/下拉;1:三态

P1

端口1 IO寄存器

 

按照表4-1寄存器说明,我们对P10端口进行配置,当P10输出低电平时 LED中的D3被点亮,配置如下:

#define LED1 P1_0  //定义P10口为D3(LED1)控制端
    P1SEL &= ~0x01;   // P10口作为普通 IO 口
    P1DIR |= 0x01;     //P10口定义为输出

LED1 = 0;         //输出低电平

由于P1SEL寄存器上电默认为0x00,所以仅需要配置:

P1DIR |= 0x01;     //P10 定义为输出

LED1 = 0x00;      //输出低电平

具体程序如下:

#include <ioCC2530.h>

#define LED1 P1_0    //定义P10口为D3(LED1)控制端

void main(void)

{

    P1DIR |= 0x01;   //P10定义为输出

    LED1 = 0;       //输出低电平

    while(1);

}

4.1.3 实验效果

    观察开发板D3(LED1)灯,D3灯常亮。

4.2流水灯实验

4.2.1 实验目的

了解使用空循环延时的方法,循环点亮2个LED。

4.2.2 实验讲解

首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-2所示。

图4-2开发板LED原理图

可以看到开发板上的3个LED分别连接在芯片的P10、P11及P14引脚,P10、P11低电平点亮,P14高电平点亮,按照上一节点亮单个LED的说明,我们分别对D3、D4进行配置,循环点亮D 3,D4。

具体程序如下:

#include <ioCC2530.h>

#define LED1 P1_0    //定义P10口为D3(LED1)控制端

#define LED2 P1_1    //定义P11口为D4(LED2)控制端

/****************************

//延时

*****************************/

void Delay(int n)

{

    int i;

    for(i=0;i<n;i++);

    for(i=0;i<n;i++);

    for(i=0;i<n;i++);

    for(i=0;i<n;i++);

    for(i=0;i<n;i++);

}

/***************************

//主函数

***************************/

void main(void)

{

    P1DIR |= 0x03; //P1_0,P1_1定义为输出

    LED1 = 1;

    LED2 = 1;

    while(1)

    {

        LED1 = ! LED1;

        LED2 = ! LED2;

        Delay(10000);

    }

}

4.2.3 实验效果

    观察开发板,依次点亮D3(LED1)和D4(LED2),2个LED不停的闪烁。

4.3按键控制LED实验

4.3.1 实验目的

了解使用按键方法,使用按键切换LED的状态。

4.3.2 实验讲解

首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-3所示。

图4-3开发板LED和按键原理图

可以看到开发板上的D3连接在芯片的P10引脚,按键S3连接在芯片的P04引脚,按照4.1节点亮单个LED的说明,我们分别对P10配置为输出,对按键引脚P04配置为输入,由于外部连接有上拉电阻所以不需要配置引脚的内部上拉。

具体程序如下:

#include <ioCC2530.h>

#define uint unsigned int

#define uchar unsigned char

//定义控制LED灯的端口

#define LED1 P1_0      // D3(LED1)为P10口控制

#define KEY1 P0_4     //S3(KEY1)为P04口控制

//函数声明

void Delayms(uint);     //延时函数

void InitLed(void);      //初始化D3(LED1)

void KeyInit();         //按键初始化

uchar KeyScan();       //按键扫描程序

/****************************

延时函数

*****************************/

void Delayms(uint xms)  //i=xms 即延时i毫秒

{

    uint i,j;

    for(i=xms;i>0;i--)

      for(j=587;j>0;j--);

}

/****************************

      LED初始化函数

*****************************/

void InitLed(void)

{

    P1DIR |= 0x01;  //P10定义为输出

    LED1 = 1;      // D3(LED1)灯熄灭     

}

/****************************

     按键初始化函数

*****************************/

void InitKey()

{

  P0SEL &= ~0X10;   //设置P04为普通IO口  

  P0DIR &= ~0X10;   //按键在P04口,设置为输入模式

  P0INP &= ~0x10;    //打开P04上拉电阻,不影响

}

/****************************

     按键检测函数

*****************************/

uchar KeyScan(void)

{

  if(KEY1==0)

  {   

      Delayms(10);

      if(KEY1==0)

      {

        while(!KEY1);  //松手检测

        return 1;       //有按键按下

      }

  }

  return 0;             //无按键按下

}



/***************************

      主函数

***************************/

void main(void)

{

    InitLed(); //调用初始化函数

    InitKey();

    while(1)

    {

        if(KeyScan())   //按键改变LED状态

        {

            LED1=~LED1;  

        }

    }

}

4.1.3 实验效果

按下开发板按键S3(KEY1)控制D3(LED1)的亮和灭。

4.4外部中断实验

4.4.1 实验目的

了解使用外部中断的方法,在中断处理函数中切换LED的状态。

4.4.2 实验讲解

首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-4所示。

图4-4开发板LED和按键原理图

与上一节相同,D3连接在芯片的P10引脚,按键S3连接在芯片的P04引脚,按照4.1节点亮单个LED的说明,我们对P10配置为输出。

CC2530 的外部中断我们需要配置三个寄存器P0IEN、PICTL、P0IFG、IEN1,配置寄

存器将按键引脚P04的中断使能与总中断打开,使用到的寄存器如表4-2所示

 

表4-2外部中断寄存器说明

P0IEN(0xAB)

P0[7:0]中断掩码寄存器。0:关中断 1:开中断

PICTL(0x8C)

P0口的中断触发控制寄存器
Bit0为P0[7:0]的中断触发配置:
0:上升沿触发 1:下降沿触发

P0IFG(0x89)

P0[7:0]中断标志位,在中断发生时,相应位置1

IEN1(0xB8)

Bit5为P0[7:0]中断使能位:0:关中断 1:开中断

具体程序如下:

#include <ioCC2530.h>

#define LED1 P1_0

/****************************

//初始化按键为中断输入方式

*****************************/

void InitKeyINT(void)

{

    P0IEN |= 0X10;  //P04设置为中断方式

    PICTL |= 0X01;  //下降沿触发

    EA = 1;         //总中断使能

    IEN1 |= 0X20;   //P0中断使能;

    P0IFG |= 0x00;  //初始化中断标志位

}

/***************************

//主函数

***************************/

void main(void)

{

    P1DIR |= 0x01; //P10定义为输出

    LED1 = 1;

    InitKeyINT();

    while (1) ;

}



/****************************

//中断处理函数

*****************************/

#pragma vector = P0INT_VECTOR

__interrupt void P0_ISR(void)

{

    if (P0IFG > 0)    //按键中断

    {

        LED1 = !LED1;

        P0IFG = 0;    //清中断标志

    }

}

4.4.3 实验效果

按下开发板按键S3(KEY1)控制D3(LED1)的亮和灭。

4.5定时器实验

4.5.1 实验目的

了解使用定时器的方法,定时切换LED的状态.

4.5.2 实验讲解

首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-5所示。

图4-5开发板LED原理图

与4.1节相同, D3连接在芯片的P10引脚,按照4.1节点亮单个LED的说明,我们对P10配置为输出,配置寄存器将定时器1的中断使能与总中断打开,使用到的寄存器如表4-3所示:

表4-3定时器1寄存器说明

T1CTL

3:2 配置定时器值分频器划分值

TIMIF

位6 位定时器1中断屏蔽位

IEN1(0XB8)

1为定时器1中断使能

T1STAT

定时器1状态位

具体程序如下:

#include <ioCC2530.h>

#define LED1 P1_0

/****************************

//T1初始化程序

***************************/

void InitialT1test(void)

{

    //初始化计数器1

    T1CTL = 0x0D;

    TIMIF = 0x40;

    IEN1 = 0x02;

    EA = 1; //总中断使能

    T1STAT = 0;  //清中断标志

}

/***************************

//主函数

***************************/

void main(void)

{

P1DIR = 0x01; //P1_0 定义为输出

LED1 = 1;

InitialT1test();

while (1) ;

}

//中断处理函数

#pragma vector = T1_VECTOR

__interrupt void T1_ISR(void)

{

if (T1STAT > 0)            //按键中断

{

LED1 = ! LED1;

T1STAT = 0;          //清中断标志

}

}

4.5.3 实验效果

观察开发板,D3(LED1)周期性闪烁。

4.6串口数据收发实验

4.6.1 实验目的

1.了解串口通信的相关知识;

2.学习CC2530单片机串口相关寄存器配置,实现串口通信功能;

4.6.2 实验讲解

CC2530芯片有两个串行接口UART0和UART1:

UART0对应RXD(P02)、TXD(P03);

UART1对应RXD(P04)、TXD(P05);

在开发板中只接出了串口0(UART0),从串口原理图就可以看出,CC2530的串口信号与P02、P03复用,由于USB接口的众多优势,越来越普遍的被应用到计算机以及工业现场,而RS232接口的市场地位也逐渐淡漠,如图4-6所示,我们的开发板将RS232 信号通过PL2303转换为USB信号与电脑或者工业设备进行串口通信。

图4-6 开发板串口TTL与USB转换电路原理图

要实现CC2530的串口通信除了掌握硬件电路原理,还有一个关键的环节就是有关串口通信寄存器软件配置U0CSR、U0GCR、U0BAUD、U0DBUF、UTX0IF,串口相关寄存器功能描述如表4-4所示:

表4-4相关寄存器功能描述

U0CSR(UART0 控

制和状态寄存器)

 

Bit7:MODE

0:SPI 模式

1:UART 模式

Bit6:RE

0:接收器禁止

1:接收器使能

Bit5:SLAVE

0:SPI 主模式

1:SPI 从模式

Bit4:FE

0:没有检测出帧错误

1:收到字节停止位电平出错

Bit3:ERR

0:没有检测出奇偶检验出错

1:收到字节奇偶检验出错

Bit2:RX_BYTE

0:没有收到字节

1:收到字节就绪

Bit1:TX_BYTE

0:没有发送字节

1:写到数据缓冲区寄存器的最后字节已

经发送

Bit0:ACTIVE

0:USART空闲

1:USART忙

U0GCR(UART0 通

用控制寄存器)

Bit7:CPOL

0:SPI 负时钟极性

1:SPI 正时钟极性

Bit6:CPHA

0:当来自 CPOL 的 SCK 反相之后又返回CPOL 时,数据输出到 MOSI;当来自 CPOL的 SCK 返回 CPOL 反相时,输入数据采样到MISO

1:当来自 CPOL 的 SCK 返回 CPOL 反相时,数据输出到 M OSI ;当来自 CPOL 的 SCK 反相之后又返回 CPOL 时,输入数据采样到 MISO

Bit5:ORDER

0:LSB 先传送

1:MSB 先传送

Bit[4:0]:BAUD_E

波特率指数值 BAUD_E 连同 BAUD_M

一起决定了 UART 的波特率

U0BAUD(UART0 波特率控制寄存器)

Bit[7:0]:BAUD_M

波特率尾数值 BAUD_M 连同 BAUD_E

一起决定了 UART 的波特率

U0DBUF ( UART0

收发数据缓冲区)

 

串口发送/接收数据缓冲区

UTX0IF(发送中断

标志)

中断标志5 IRCON2 的Bit1

0:中断未挂起

1:中断挂起

在本实验中我们采用USART0接口,具体的软件操作以及串口寄存器配置步骤如下:

1、硬件接口配置,配置P02和P03用作串口 UART0。

2、配置相应串口的控制和状态寄存器。

3、配置串口工作的波特率。CC2530单片机的串口数据传输的波特率决定于通用控制寄存器U0GCR的Bit[4:0]——BAUD_E和波特率控制寄存器U0BAUD——BAUD_M,具体的计算公式如式4-1

波特率

在32MHz的系统时钟下常用的波特率所对应的BAUD_M和BAUD_E的值如下表4-5。

表4-5在32MHz的系统时钟下常用的波特率所对应的BAUD_M和BAUD_E的值

常用的波特率

BAUD_M

BAUD_E

误差

2400

59

6

0.14

4800

59

7

0.14

9600

59

8

0.14

14400

216

9

0.03

19200

59

10

0.14

28800

216

11

0.03

38400

59

12

0.14

57600

216

13

0.03

76800

59

14

0.14

115200

216

15

0.03

230400

216

16

0.03

串口寄存器配置程序如下

CLKCONCMD &= ~0x40;      //设置系统时钟源为 32MHZ 晶振

while(CLKCONSTA & 0x40);   //等待晶振稳定

CLKCONCMD &= ~0x47;     //设置系统主时钟频率为 32MHZ

PERCFG = 0x00;             //位置 1 P0 口

P0SEL = 0x3c;               //P0_2,P0_3,P0_4,P0_5 用作串口,第二功能

P2DIR &= ~0XC0;            //P0 优先作为 UART0 ,优先级

U0CSR |= 0x80;              //UART 方式

U0GCR |= 11;                //U0GCR 与 U0BAUD 配合

U0BAUD |= 216;             // 波特率设为 9600

UTX0IF = 0;                 //UART0 TX 中断标志初始置位 1 (收发时候)

U0CSR |= 0X40;              //允许接收

IEN0 |= 0x84;                // 开总中断,接收中断

具体程序如下:

#include <ioCC2530.h>

#include <string.h>

#define uint unsigned int

#define uchar unsigned char

//定义控制LED灯的端口

#define LED1 P1_0    //定义LED1为P10口控制

#define LED2 P1_1    //定义LED1为P11口控制

//函数声明

void Delayms(uint xms);    //延时函数

void InitLed(void);        //初始化P1口

void InitUart();           //初始化串口

void Uart_Send_String(char *Data,int len);

char Rxdata[50];

uchar RXTXflag = 1;

char temp;

uchar  datanumber = 0;

/****************************

          延时函数

*****************************/

void Delayms(uint xms)   

{

  uint i,j;

  for(i=xms;i>0;i--)

    for(j=587;j>0;j--);

}  

/****************************

//初始化程序

*****************************/

void InitLed(void)

{

  P1DIR |= 0x03; //P10、P11定义为输出

  LED1 = 0;     

  LED2 = 0;    

}

/****************************************************************

   串口初始化函数     

***********************************************************/

void InitUart()

{

    CLKCONCMD &= ~0x40;      // 设置系统时钟源为 32MHZ晶振

    while(CLKCONSTA & 0x40);    // 等待晶振稳定

    CLKCONCMD &= ~0x47;      // 设置系统主时钟频率为 32MHZ

    

    PERCFG = 0x00;           //位置1 P0口

    P0SEL  = 0x3c;           //P0_2,P0_3,P0_4,P0_5用作串口,第二功能

    P2DIR &= ~0XC0;         //P0优先作为UART0 ,优先级

    

    U0CSR |= 0x80;           //UART 方式

    U0GCR |= 8;              //U0GCR与U0BAUD配合     

    U0BAUD |= 59;           //波特率设为9600

    UTX0IF = 0;              //UART0 TX 中断标志初始置位1  (收发时候)

    U0CSR |= 0X40;           //允许接收

    IEN0 |= 0x84;             //开总中断,接收中断    

}

/****************************************************************

串口发送字符串函数    

****************************************************************/

void Uart_Send_String(char *Data,int len)

{

    int j;

    for(j=0;j<len;j++)

    {

        U0DBUF = *Data++;

        while(UTX0IF == 0);      //发送完成标志位

        UTX0IF = 0;

    }

}

/***************************

//主函数

***************************/

void main(void)

{

    InitLed(); //调用初始化函数

    InitUart();

    while(1)

    {

        if(RXTXflag == 1) //接收状态

        {

            LED1=1;    //接收状态指示

            if( temp != 0)

            {

                //'#'被定义为结束字符,最多能接收50个字符

                if((temp!='#')&&(datanumber<50))

                {

                    Rxdata[datanumber++] = temp;

                }

                else

                {

                    RXTXflag = 3; //进入发送状态

                    LED1=0;     //关指示灯

                }

                temp  = 0;

            }

        }

        if(RXTXflag == 3)     //发送状态

        {

            LED2= 1;                           

            U0CSR &= ~0x40;   //禁止接收

            Uart_Send_String(Rxdata,datanumber); //发送已记录的字符串。

            U0CSR |= 0x40;    //允许接收

            RXTXflag = 1;     //恢复到接收状态

            datanumber = 0;    //指针归0

            LED2 = 0;         //关发送指示

        }    

    }

}

/****************************************************************

串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,

将接收到的数据赋值给全局变量temp.

****************************************************************/

#pragma vector = URX0_VECTOR

__interrupt void UART0_ISR(void)

{

    URX0IF = 0;    //清中断标志

    temp = U0DBUF;                           

}

4.6.3 实验效果

     实验时,下载程序到开发板后,插上USB线,然后将S1开关拨到ON,即可进行串口实验,实验效果如图4-7所示

图4-7 实验效果图

扩展知识——串口通信基础

在串行通信中,数据在1位宽的单条线路上进行传输,一个字节的数据要分为8次,由低位到高位按顺序一位一位的进行传送。

  串行通信的数据是逐位传输的,发送方发送的每一位都具有固定的时间间隔,这就要求接收方也要按照发送方同样的时间间隔来接收每一位。不仅如此,接收方还必须能够确定一个信息组的开始和结束。

  常用的两种基本串行通信方式包括同步通信和异步通信。

异步通信规定传输的数据格式由起始位(start bit)、数据位(data bit)、奇偶校验位(parity bit)和停止位(stop bit)组成,如图4-8所示(该图中未画出奇偶校验位,因为奇偶检验位不是必须有的,如果有奇偶检验位,则奇偶检验位应该在数据位之后,停止位之前)。

图4-8 异步通信数据格式

  (1)起始位:起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。

  (2)数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是5位、7位或8位,标准的ASCII码是0~127(7位),扩展的ASCII码是0~255(8位)。传输数据时先传送字符的低位,后传送字符的高位。

  (3)奇偶校验位:奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。

  举例来说,假设传输的数据位为01001100,如果是奇校验,则奇校验位为0(要确保总共有奇数个1),如果是偶校验,则偶校验位为1(要确保总共有偶数个1)。

  由此可见,奇偶校验位仅是对数据进行简单的置逻辑高位或逻辑低位,不会对数据进行实质的判断,这样做的好处是接收设备能够知道一个位的状态,有可能判断是否有噪声干扰了通信以及传输的数据是否同步。

  (4)停止位:停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。

(5)空闲位:空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。

4.7 AD采集内部温度实验

4.7.1 实验目的

1.学习CC2530内部温度传感器控制;

2.学习AD数据采集;

3.实现CC2530温度采集并通过串口发送到上位机。

4.7.2 实验讲解

温度检测在工业现场以及物联网领域都有着较为广泛的应用,对于智能控制需要以采集到的环境温度作为控制依据,CC2530单片机在芯片的内部就集成了温度传感器,不需要再外接温度传感器电路,提高了系统的集成度,降低了电路设计的复杂度,但是传感器与MCU的集成由于芯片本身的发热会导致检测温度的偏差,通常需要软件的矫正。

要实现CC2530的温度检测并通过串口发送给上位机,在串口通信部分已经将通信解决,在需要的就是AD与温度检测寄存器的相关配置,所涉及到的寄存器有:

CC2530 的内部温度检测需要配置的寄存器比较多,包括温度和 AD 的

CLKCONCMD、PERCFG、U0CSR、U0GSR、U0BAUD、CLKCONSTA、IEN0、U0DUB、ADCCON1、ADCCON3、ADCH、ADCL。各寄存器功能如下表4-6所示:

表4-6 AD温度检测相关寄存器功能描述

ADC控制寄存器1ADCCON1(0XB4)

ADC 转换完成标志位Bit7:EOC

0:AD 转换进行中

1:AD 转换完成

手动启动 AD 转换

Bit6:RE

0:关

1:启动 AD 转换(需要 Bit5:Bit4=11)

AD 转换启动方式选择

Bit[5:4]

00:外部触发

01:全速转换,不需要触发

10:T1 通道 0 比较触发

11:手动触发

16 位随机数发生器控制位

Bit[3:2]FE

00:普通模式 (13x 打开)

01:开启 LFSR 时钟一次 (13x 打开)

10:保留位

11:关

序列 AD 转换控制寄存器 2ADCCON2(0XB5)

选择 AD 转换参考电压SREF

Bit[7:6]

00:内部参考电压(1.25V)

01:外部参考电压 AIN7 输入

10:模拟电源电压

11:外部参考电压 AIN6-AIN7 差分输入

设置 AD 转换分辨率Bit[5:4]

00: 64dec,7位有效

01: 128dec,9位有效

10: 256dec,10位有效

11: 512dec,12位有效

设置序列 AD 转换最末通道,如果置位

时 ADC 正在运行,则在完成序列 AD 转换后立刻开始,

否则置位后立即开始 AD 转换,转换完成后自动清 0.

Bit[3:0]ORDER

0000: AIN0

0001: AIN1

0010: AIN2

0011: AIN3

0100: AIN4

0101: AIN5

0110: AIN6

0111: AIN7

1000: AIN0-AIN1 差分

1001: AIN2-AIN3 差分

1010: AIN4-AIN5 差分

1011: AIN6-AIN7 差分

1100:GND

1101:保留

1110:温度传感器

1111:1/3模拟电源电压

Bit[4:0]:BAUD_E

波特率指数值 BAUD_E 连同 BAUD_M

一起决定了 UART 的波特率

单通道 AD 转换控制寄存器 2

ADCCON3(0XB5)

选择单通道AD 转换参考电压SREF

Bit[7:6]:

00:内部参考电压(1.25V)

01:外部参考电压 AIN7 输入

10:模拟电源电压

11 :外部参考电压 AIN6-AIN7 差分输入

设置单通道 AD 转换分辨率

Bit[5:4]

00: 64dec,7 位有效

01: 128dec,9 位有效

10: 256dec,10 位有效

11: 512dec,12 位有效

单通道 AD 转换选择,如果置位时 ADC

正在运行,则在完成 AD 转换后立刻开始,否则置位后

立即开始 AD 转换,转换完成后自动清 0.

Bit[3:0]

0000:AIN0

0001: AIN1

0010:AIN2

0011: AIN3

0100:AIN4

0101: AIN5

0110:AIN6

0111: AIN7

1000:AIN0-AIN1 差分

1001: AIN2-AIN3 差分

1010:AIN4-AIN5 差分

1011: AIN6-AIN7 差分

1100:GND

1101:保留

1110:温度传感器

1111:1/3 模拟电源电压

TR0 (0x624B)

Bit0

置 1 表示将温度传感器与 ADC 连接起来

ATEST(0x61BD)

Bit0

置 1 表示将温度传感器启用

根据表中相关寄存器的功能说明,具体进行如下配置:

TR0 = 0X01; //置”1”连接温度传感器与AD采集

ATEST= 0X01; // 使能温度传感器功能

AD 数据采集配置:

ADCCON3 = (0x3E); //选择 1.25V 为参考电压;14 位分辨率;片内采样

ADCCON1 |= 0x30; //选择 ADC 的启动模式为手动

ADCCON1 |= 0x40; //启动 AD 转换

具体程序如下:

#include <ioCC2530.h>

#define uint unsigned int

#define uchar unsigned char

#define uint16 unsigned short

#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0x00)

/**************************

系统时钟 不分频

计数时钟 32分频

**************************/

void InitClock(void)

{   

    CLKCONCMD &= ~0x40;      //设置系统时钟源为 32MHZ晶振

    while(CLKCONSTA & 0x40); //等待晶振稳定

    CLKCONCMD &= ~0x47;      //设置系统主时钟频率为 32MHZ

}

/********************************************************

温度传感器初始化函数       

********************************************************/

void initTempSensor(void)

{

    DISABLE_ALL_INTERRUPTS(); //关闭所有中断

    InitClock();              //设置系统主时钟为 32M

    TR0=0X01;     //set '1' to connectthe temperature sensorto the SOC_ADC.

    ATEST=0X01;   // Enablesthe temperature sensor

}   

/****************************************************************

读取温度传感器 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 |= (((uint16)ADCH) << 4);

    return (value-1367.5)/4.5-5;    //根据 AD 值,计算出实际的温度,芯片手册有错,温度系数应该是4.5 /℃

    //进行温度校正,这里减去5℃(不同芯片根据具体情况校正)

}

/*****************************************

 串口初始化函数:初始化串口 UART0

*****************************************/

void InitUART0(void)

{

    PERCFG = 0x00;    //位置1 P0口

    P0SEL = 0x3c;    //P0用作串口

    P2DIR &= ~0XC0;        //P0优先作为UART0    

    U0CSR |= 0x80;       //串口设置为UART方式

    U0GCR |= 8;

    U0BAUD |= 59;         //波特率设为9600

    UTX0IF = 1;            //UART0 TX中断标志初始置位1  

    U0CSR |= 0X40;         //允许接收

    IEN0 |= 0x84;    //开总中断,接收中断

}

/****************************************************************

   串口发送字符串函数

****************************************************************/

void UartTX_Send_String(char *Data,int len)

{

    int j;

    for(j=0;j<len;j++)

    {

        U0DBUF = *Data++;

        while(UTX0IF == 0);

        UTX0IF = 0;

    }

    U0DBUF = 0x0A;        //换行

    while(UTX0IF == 0);

    UTX0IF = 0;

}

/****************************

//延时函数

*****************************/

void Delayms(uint xms)  

{

    uint i,j;

    for(i=xms;i>0;i--)

      for(j=587;j>0;j--);

}

/****************************************************************

主函数   

****************************************************************/

void main(void)

{   

    char i;

    char TempValue[7];  

    float AvgTemp;         

    InitUART0();                               //初始化串口

    initTempSensor();                           //初始化 ADC

    while(1)

    {

        AvgTemp = 0;          

        for(i = 0 ; i < 64 ; i++)

        {    

            AvgTemp += getTemperature();  

            AvgTemp=AvgTemp/2;                  //每次累加后除 2

        }

        /****温度转换成ascii码发送****/

        TempValue[0] = (unsigned char)(AvgTemp)/10 + 48;       //十位

        TempValue[1] = (unsigned char)(AvgTemp)%10 + 48;      //个位

        TempValue[2] = '.';                                  //小数点

        TempValue[3] = (unsigned char)(AvgTemp*10)%10+48;    //十分位

        TempValue[4] = (unsigned char)(AvgTemp*100)%10+48;   //百分位

        TempValue[5] = '\r';                                  //字符串结束符

        TempValue[6] = '\n';

        UartTX_Send_String( TempValue,7);

        Delayms(2000); //使用32M晶振,故这里2000约等于1S

    }

}

4.6.3 实验效果

图4-9 实验效果图

扩展知识——AD模数转换

以8位的寄存器为例, A/D转换器片内有D/A转换和电压比较器,首先向片内D/A转换器输入1000 0000,若电压比较器:VIN > VN (VN为片内D/A转换的输出,VIN为A/D转换器的输入电压),N位寄存器的首位置1 (若VIN < VN,则寄存器首位写0);再向D/A转换输入1100 0000(首位写0时,输入0111 1111),若VIN > VN则寄存器第二位置1(若VIN < VN,则写0);再向D/A转换输入1110 0000(或0011 1111),若VIN > VN则寄存器第三位置1(若小于,则写0);依次下去直到寄存器第8位赋值结束,控制逻辑监测到比较放大器进行8次后,EOC输入信号,让A/D转换器将结果通过锁存缓存器输出至D0~D9。

4.8睡眠唤醒实验

4.8.1 实验目的

1.学习CC2530的低功耗控制方式;

2.CC2530的中断和定时器唤醒。

4.8.2 实验讲解

对于远距离的无限传输设备,功耗是一个较为关键的技术指标,而基于单片机CC2530单片机的ZigBee系统在低功耗方面有着较为明显的优势,节点模块闲时可以进入睡眠模式,在需要传输数据时候进行唤醒,能进一步节省电量。本节将讲述CC2530 在睡眠模式下的 2 种唤醒方法:外部中断唤醒和定时器唤醒。

ZigBee节点的唤醒有两种方式分别为:定时器唤醒和中断唤醒睡眠,定时器用于设置系统进入和退出低功耗睡眠模式之间的周期,还用于当系统进入低功耗模式后,维持 MAC 定时器(T2)的定时。其特性如下:24位定时计数器运行在 32.768KHZ 的工作频率。24 位的比较器具有中断和 DMA 触发功能在 PM2 低功耗模式下运行。

1.中断唤醒

CC2530 需要配置的主要寄存器如下:PCON ,SLEEPCMD。功能如表4-7所示:

表4-7 CC2530中断方式唤醒休眠相关控制寄存器

系统电源模式控制寄存器PCON(0x87)

Bit0

1

将强制系统进入 SLEEPCMD 所指定的电源模式,所有中断信号都可以

清除此置位。

0

 

系统电源模式设定SLEEPCMD(0xBE)

 

Bit1:Bit0

00

全功能模式

01

PM1

10

PM2

11

PM3

2.定时器唤醒

定时器唤醒除了要对寄存器PCON、SLEEPCMD进行设置,还需要对定时器计数寄存器ST0、ST1、ST2进行设置,其具体功能描述如表4-8:

表4-8 CC2530定时器方式唤醒休眠相关控制寄存器

ST0(0x95)

睡眠计数器数据 Bit7 :Bit0

ST1(0x96)

睡眠计数器数据 Bit15:Bit8

ST2(0x97)

睡眠计数器数据 Bit23:Bit16

根据表中相关寄存器的功能说明,具体进行如下配置:

SLEEPCMD |= i; // 设置系统睡眠模式,i=0,1,2,3

PCON = 0x01; // 进入睡眠模式 ,通过中断打断

PCON = 0x00; // 系统唤醒 ,通过中断打断

UINT32 sleepTimer = 0;

sleepTimer |= ST0;

sleepTimer |= (UINT32)ST1 << 8;

sleepTimer |= (UINT32)ST2 << 16;

sleepTimer += ((UINT32)sec * (UINT32)32768) //低速晶振;

ST2 = (UINT8)(sleepTimer >> 16);

ST1 = (UINT8)(sleepTimer >> 8);

ST0 = (UINT8) sleepTimer;

具体程序如下所示:

中断唤醒程序

#include <ioCC2530.h>

#define uint unsigned int

#define uchar unsigned char

//定义控制LED灯和按键的端口

#define LED2 P1_1 //定义LED2为P11口控制

#define KEY1 P0_4

//函数声明

void Delayms(uint); //延时函数

void InitLed(void);

void SysPowerMode(uchar sel);   //系统工作模式

/****************************

         延时函数

*****************************/

void Delayms(uint xms)   //i=xms 即延时i毫秒

{

 uint i,j;

 for(i=xms;i>0;i--)

   for(j=587;j>0;j--);

}

/****************************

//初始化程序

*****************************/

void InitLed(void)

{

P1DIR |= 0x02;  //P1_1定义为输出

LED2 = 1;    //LED2灯熄灭      

        P0INP  &= ~0X10;   //设置P0口输入电路模式为上拉/ 下拉

        P0IEN |= 0X10;     //P01设置为中断方式

        PICTL |= 0X10;     // 下降沿触发      

}

/****************************************************************

系统工作模式选择函数            

* para1  0  1 2 3          

* mode  PM0 PM1 PM2 PM3              

****************************************************************/

void SysPowerMode(uchar mode)

{

 uchar i,j;

 i = mode;

 if(mode<4)

 {  

     SLEEPCMD |= i;     // 设置系统睡眠模式

     for(j=0;j<4;j++);

     PCON = 0x01;         // 进入睡眠模式 ,通过中断打断

 }

 else

 {

     PCON = 0x00;             // 系统唤醒 ,通过中断打断

 }

}

/***************************

        主函数

***************************/

void main(void)

{   

    uchar count = 0;

InitLed(); //调用初始化函数     

    IEN1 |= 0X20;      // 开P0口总中断

    P0IFG |= 0x00;     //清中断标志

EA = 1;

        while(1)

        {

            LED2=~LED2;

            if(++count>=10)

            {

               count=0;

               SysPowerMode(3); //5次闪烁后进入睡眠状态PM3,等待按键S3中断唤醒

            }

            Delayms(500);

        }

}

/*****************************************

     中断处理函数-系统唤醒

*****************************************/

#pragma vector = P0INT_VECTOR

  __interrupt void P0_ISR(void)

 {

    if(P0IFG>0)

    {

       P0IFG = 0; //清标志位

    }

    P0IF = 0;

     SysPowerMode(4); //正常工作模式

 }

定时器唤醒程序

#include <ioCC2530.h>

#define uint unsigned int

#define uchar unsigned char

#define UINT8 unsigned char

#define UINT32 long unsigned int

//定义控制 LED 灯和按键的端口

#define LED2 P1_1 //定义 LED2 为 P11口控制

#define KEY1 P0_4

//函数声明

void Delayms(uint xms); //延时函数

void InitLed(void); //初始化 P1 口

void SysPowerMode(uchar sel); //系统工作模式

/****************************

延时函数

*****************************/

void Delayms(uint xms) //i=xms 即延时 i 毫秒

{

    uint i,j;

    for(i=xms;i>0;i--)

    for(j=587;j>0;j--);

}/****************************

//初始化程序

*****************************/

void InitLed(void)

{

    P1DIR |= 0x02; //P1_1 定义为输出

    LED2 = 1; //LED2 灯熄灭

    P0INP &= ~0X10; //设置 P0 口输入电路模式为上拉/ 下拉

    P0IEN |= 0X10; //P01 设置为中断方式

    PICTL |= 0X10; // 下降沿触发

}

/***************************************************************

系统工作模式选择函数

* para1 0 1 2 3

* mode PM0 PM1 PM2 PM3

***************************************************************/

void SysPowerMode(uchar mode)

{

    uchar I,j;

    I = mode;

    if(mode<4)

    {

      SLEEPCMD |= I; // 设置系统睡眠模式

      for(j=0;j<4;j++);

      PCON = 0x01; // 进入睡眠模式 ,通过中断打断

    }

    else

    {

      PCON = 0x00; // 系统唤醒 ,通过中断打断

    }

}

/*****************************************

//初始化 Sleep Timer (设定后经过指定时间自行唤醒)

*****************************************/

void Init_SLEEP_TIMER(void)

{

    ST2 = 0X00;

    ST1 = 0X0F;

    ST0 = 0X0F;

    EA = 1; //开中断

    STIE = 1; //SleepTimerinterrupt enable

    STIF = 0; //SleepTimerinterrupt flag 还没处理的

}

/***************************************************************

设置睡眠时间

***************************************************************/

void Set_ST_Period(uint sec)

{

    UINT32 sleepTimer = 0;

    sleepTimer |= ST0;

    sleepTimer |= (UINT32)ST1 << 8;

    sleepTimer |= (UINT32)ST2 << 16;

    sleepTimer += ((UINT32)sec * (UINT32)32768);//低频晶振 PM2 模式

    ST2 = (UINT8)(sleepTimer >> 16);

    ST1 = (UINT8)(sleepTimer >> 8);

    ST0 = (UINT8) sleepTimer;

}/***************************

//主函数

***************************/

void main(void)

{

    uchar i;

    InitLed(); //调用初始化函数

    Init_SLEEP_TIMER(); //初始化 SLEEPTIMER

    while(1)

    {

        for(i=0;i<6;i++) //闪烁 3 下

        {

            LED2=~LED2;

            Delayms(200);

        }

        Set_ST_Period(3); //重新进入睡眠模式

        SysPowerMode(2); //进入 PM2 低频晶振模式

    }

}

//睡眠中断唤醒

#pragma vector = ST_VECTOR

__interrupt void ST_ISR(void)

{

    STIF = 0; //清标志位

    SysPowerMode(4); //进入正常工作模式

}

4.8.3 实验效果

在中断唤醒模式下,通过按下按键 S3(KEY1)产生外部中断进行唤醒,D4(LED2)闪烁5次后进入睡眠状态,重新进入工作模式。

在定时器唤醒模式下,通过设置定时器在特定时间内进行唤醒,重新进入工作模式,每次唤醒D4(LED2)闪烁3下。

扩展知识——CC2530的电源管理

系统电源管理(工作方式如下):

1. 全功能模式,高频晶振(16M 或者 32M )和低频晶振(32.768K RCOSC/XOSC )

全部工作,数字处理模块正常工作。

2. PM1:高频晶振(16M 或者 32M )关闭,低频晶振(32.768K RCOSC/XOSC )

工作,数字核心模块正常工作。

3.PM2:低频晶振(32.768K RCOSC/XOSC )工作,数字核心模块关闭,系统通过 RESET,外部中断或者睡眠计数器溢出唤醒。

4. PM3:晶振全部关闭,数字处理核心模块关闭,系统只能通过 RESET 或外部中断唤醒。此模式下功耗最低。

4.9看门狗实验

4.9.1 实验目的

1.学习CC2530看门狗的工作方式;

2.学习看门狗功能在系统中的运行机制;

4.9.2 实验讲解

有过项目开发经验的读者对于看门狗应该并不陌生,而且看门狗对于一个系统的可靠的运行有着至关重要的作用,它会在软件程序跑飞的情况下,对系统进行复位,以保证程序重新开始正常运行,但是前提是定时喂狗。

CC2530 的看门狗控制较为简单,只涉及到一个寄存器WDCTL,其功能描述如下表4-9所示:

表4-9看门狗控制相关寄存器

系统电源模式控制寄存器PCON(0x87)

清除计数器值Bit[7:4]

 

在看门狗模式下,如果此四位在一个看门狗周期内先后写入0xA,0x5, 则清除 WDT 的值。简称喂狗。

WDT 工作模式选择寄存器Bit[3:2]

00

IDLE

01

IDLE(未使用)

10

看门狗模式

11

定时器模式

看门狗周期选择寄存器Bit[1:0]

00

1 秒

01

0.25 秒

10

15.625 毫秒

11

1.9 毫秒

根据表中相关寄存器的功能说明,具体进行如下配置:

Init_Watchdog:

WDCTL = 0x00; //这是必须的,打开 IDLE 才能设置看门狗

WDCTL |= 0x08; //时间间隔一秒,看门狗模式

FeedDog:

WDCTL = 0xa0; //按寄存器描述来喂狗

WDCTL = 0x50;

具体程序如下所示:

#include <ioCC2530.h>



#define uint unsigned int

#define uchar unsigned char



//定义控制LED灯的端口

#define LED1 P1_0

#define LED2 P1_1

//函数声明

void Delayms(uint xms);//延时函数

void InitLed(void);    //初始化P1口

/****************************

//延时函数

*****************************/

void Delayms(uint xms)   //i=xms 即延时i毫秒

{

    uint i,j;

    for(i=xms;i>0;i--)

     for(j=587;j>0;j--);

}

/****************************

//初始化程序

*****************************/

void InitLed(void)

{

    P1DIR |= 0x03; //P1_0、P1_1定义为输出

    LED1 = 1;     //LED1灯熄灭

    LED2 = 1;  //LED2灯熄灭

}

void Init_Watchdog(void)

{

    WDCTL = 0x00; //这是必须的,打开IDLE才能设置看门狗

    WDCTL |= 0x08;

    //时间间隔一秒,看门狗模式  

}

void FeetDog(void)

{

    WDCTL = 0xa0;

    WDCTL = 0x50;

}

/***************************

//主函数

***************************/

void main(void)

{

    InitLed(); //调用初始化函数

    Init_Watchdog();

    LED1=1;

    while(1)

    {         

        LED2=~LED2;           //仅指示作用。

        Delayms(300);

        LED1=0;

        //通过注释测试,观察LED1,系统在不停复位。

        FeetDog();//防止程序跑飞

    }

}

4.8.3 实验效果

在定时喂狗的情况下,软件程序正常运行,D3(LED1)上电后长亮,D4(LED2)按照延时闪烁。

将喂狗程序注释掉,软件程序会按照预先设定的喂狗频率进行复位,从而导致D3(LED1)也按照喂狗频率闪烁,证明系统在不停的复位。

4.10 LCD Nokia 5110液晶实验

4.10.1 实验目的

学习使用LCD Nokia 5110液晶,并显示自定义的内容。

4.10.2 实验讲解

首先根据开发板硬件原理图确定LCD Nokia 5110与CC2530芯片的连接引脚,如图4-10所示。

图4-10 LCD Nokia 5110接口图

Nokia5110液晶是诺基亚手机的二手拆机屏,底板四角有定位孔,同时提供一排接线端口,排列如下:

1.RST ——复位

2.CE  —— 片选

3.DC  —— 数据/指令选择

4.DIN —— 串行数据线

5.CLK —— 串行时钟线

6.VCC —— 电源输入(3.3V和5V均可,经过实验验证,没有问题)

7.BL  ——  背光控制端

8.GND —— 地线

 

程序中引脚定义

#define SCLK P2_4     //CLK--串行时钟线

#define SDIN P2_3     // DIN--串行数据线

#define LCD_DC P1_3   // DC--数据/指令选择

#define LCD_CE P1_2   // CE--片选

#define LCD_RST P2_0  // RST--复位

主函数部分程序如下:

#include <ioCC2530.h>

#include "nokia_5110.h"

#include "bmp_pixel.h"

void main(void)

{    

    LCD_init();  //初始化液晶    

    LCD_clear(); //LCD清屏

    LCD_write_chinese_string(0,0,12,7,0,0);//液晶显示“风云物联网科技”

    LCD_write_english_string(20,2,"FYWLWKJ");//液晶显示“FYWLWKJ”

    LCD_write_english_string(3,3,"ZigBee CC2530"); //液晶显示“ZigBee CC2530”  

    LCD_write_chinese_string(18,4,12,4,7,0);//液晶显示“风网天下”

    while(1)  

    {      

    }   

}

4.10.3 实验效果

图4-11实验效果图

4.11温度传感器DS18B20实验

4.11.1 实验目的

学习使用温度传感器DS18B20,并在串口显示温度数据。

4.11.2 实验讲解

开发板硬件设计有温湿度传感器DHT11,原理图如图4-12-1所示,可以用此接口代替DS18B20,DS18B20实物图如图4-12-2所示,电源对应连接至DHT11接口,DQ连接至P06接口。

图4-12-1 DHT11接口图                    图4-12-2 DS18B20引脚

主函数部分程序如下:

#include"iocc2530.h"

#include"uart.h"

#include"ds18b20.h"

#include"delay.h"

void Initial() //系统初始化

{

  CLKCONCMD = 0x80;     //选择32M振荡器

  while(CLKCONSTA&0x40); //等待晶振稳定

  UartInitial();              //串口初始化

  P0SEL &= 0xbf;           //DS18B20的io口初始化

}



void main()

{

  char data[5]="Temp="; //串口提示符

  Initial();

  while(1)

  {

    Temp_test();   //温度检测

    /*******温度信息打印 ***********/

    UartTX_Send_String(data,5);

    UartSend(temp/10+48);

    UartSend(temp%10+48);

    UartSend('\n');

    Delay_ms(1000); //延时函数使用定时器方式

  }

}

4.11.3 实验效果

图4-13 实验效果图

4.12温湿度传感器DHT11实验

4.12.1 实验目的

学习使用温湿度传感器DHT11,并在串口显示温湿度数据。

4.12.2 实验讲解

首先根据开发板硬件原理图确定温湿度传感器DHT11与CC2530芯片的连接引脚,如图4-14所示。

图4-14 DHT11接口图

DHT11模块参数如下:

1.可以检测周围环境的湿度和温度

2.传感器采用 DHT11

3.湿度测量范围:20%-95%(0 度-50 度范围)湿度测量误差:+-5%

4.温度测量范围:0 度-50 度 温度测量误差:+-2 度

4.工作电压 3.3V-5V

5.输出形式 数字输出

6.设有固定螺栓孔,方便安装

7.小板 PCB 尺寸:3.2cm * 1.4cm

8.电源指示灯(红色)

 

DHT11 模块接口说明

1 VCC 外接 3.3V-5V

2 DATA 小板开关数字量输出接口接单片机IO口

3 GND 外接 GND

 

主函数部分程序如下:

#include <ioCC2530.h>

#include <string.h>

#include "UART.H"

#include "DHT11.H"

/***************************

          主函数

***************************/

void main(void)

{

    Delay_ms(1000);//让设备稳定

    InitUart();    //串口初始化

while(1)

{          

         DHT11();       //获取温湿度

         P0DIR |= 0x40;  //IO口需要重新配置

         /******温湿度的ASC码转换*******/

         temp[0]=wendu_shi+0x30;

         temp[1]=wendu_ge+0x30;

         humidity[0]=shidu_shi+0x30;

         humidity[1]=shidu_ge+0x30;

         /*******信息通过串口打印********/

         Uart_Send_String(temp1,5);

         Uart_Send_String(temp,2);

         Uart_Send_String("\n",1);

         Uart_Send_String(humidity1,9);

         Uart_Send_String(humidity,2);

         Uart_Send_String("\n",1);

         Delay_ms(2000);  //延时,使周期性2S读取1次

      }

      }

4.12.3 实验效果

图4-15 实验效果图

4.13烟雾传感器实验

4.13.1 实验目的

学习使用烟雾传感器。

4.13.2 实验讲解

首先根据开发板硬件原理图确定烟雾传感器MQ-2与CC2530芯片的连接引脚,如图4-16所示。

图4-16 烟雾传感器接口图

简要说明:

一、 尺寸:mm Xmm Xmm   长X宽X高

二、 主要芯片:气体传感器

三、 工作电压:直流5伏

四、 特点:

1、具有信号输出指示。

2、双路信号输出(模拟量输出及TTL电平输出)

3、TTL输出有效信号为低电平。(当输出低电平时信号灯亮,可直接接单片机)                 

4、模拟量输出0~5V电压,浓度越高电压越高。

5、对液化气,天然气,城市煤气有较好的灵敏度。

6、具有长期的使用寿命和可靠的稳定性

7、快速的响应恢复特性

五、应用:

适用于家庭或工厂的气体泄漏监测装置,适宜于液化气、丁烷、丙烷、甲烷、酒精、氢气、烟雾等监测装置。

全部程序如下:

#include <ioCC2530.h>

//烟雾传感器IO定义

#define AIR P0_7

//LED灯IO定义

#define LED1 P1_0

#define LED2 P1_1

void main(void)

{    

    /******烟雾传感器电路初始化******/

    P0SEL &= ~0X80;    //设置P07为普通IO口

    P0DIR &= ~0X80;    // 在P07口,设置为输入模式

    P0INP &= ~0x80;    //打开P07上拉电阻

    /******LED P1_0,P1_1方向初始化******/

    P1DIR |= 0x03;     //P1_0,P1_1设置为输出模式    

    LED1 = 1;         //熄灭LED1

    LED2 = 1;         //熄灭LED2

    while(1)  

    {    

        if(AIR==1)

        {

            LED1 = 1;         //无烟雾,熄灭LED1

            LED2 = 1;         //无烟雾,熄灭LED2

        }  

        else

        {

            LED1 = 0;         //有烟雾,点亮LED1

            LED2 = 0;         //有烟雾,点亮LED2

        }

    }   

}

4.13.3 实验效果

    无烟雾的情况下,D3(LED1)和D4(LED2)会处于熄灭状态;有烟雾的情况下,D3和D4会处于点亮状态。

4.14蓝牙控制实验

4.14.1 实验目的

学习使用蓝牙模块,并通过风云串口助手控制。

4.14.2 实验讲解

首先根据开发板硬件原理图确定蓝牙模块与CC2530芯片的连接引脚,如图4-17所示。

图4-17 蓝牙模块接口图

此节可参考4.6节串口数据收发实验以及查阅风云蓝牙模块说明书进行学习。

蓝牙模块采用风云蓝牙模块,引脚定义:

蓝牙模块 TXD:蓝牙模块的发送端,正常通信必须接另一个设备的 RXD。

蓝牙模块 RXD:蓝牙模块的接收端,正常通信必须接另一个设备的 TXD。

蓝牙模块 STATE:蓝牙模块的状态引脚,与蓝牙 led 表示的状态一致(此引脚不常用) 。

蓝牙模块 EN:蓝牙模块的使能端(此引脚不常用) 。

蓝牙模块 5V:蓝牙模块的电源引脚。

蓝牙模块 GND:蓝牙模块的接地引脚

注意:通常仅使用 TXD、RXD 、5V 、 GND 即可通信

主函数部分程序如下:

#include <iocc2530.h>

//LED灯IO定义

#define LED1   P1_0

#define LED2   P1_1

unsigned char temp;

void initUART0(void);

/****************************************************************

串口(UART0)初始化函数:

****************************************************************/

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 |= 8;

    U0BAUD |= 59;              //波特率设为9600

    UTX0IF = 1;              //UART0 TX中断标志初始置位1    

    U0CSR |= 0X40;      //允许接收

    IEN0 |= 0x84;            //开总中断,接收中断

}

/****************************************************************

主函数

****************************************************************/

void main(void)

{

    /******LED P1_0,P1_1方向初始化******/

    P1DIR |= 0x03;     //P1_0,P1_1设置为输出模式    

    LED1 = 1;         //熄灭LED1

    LED2 = 1;         //熄灭LED2

    initUART0();

    while(1)

    {

        if(temp == 0x01)

        {

            LED1 = 0;         //点亮LED1

        }

        if(temp == 0x02)

        {

            LED2 = 0;         //点亮LED2

        }

        if(temp == 0x11)

        {

            LED1 = 1;         //熄灭LED1

        }

        if(temp == 0x22)

        {

            LED2 = 1;         //熄灭LED2

        }

    }

}

/****************************************************************

一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.

****************************************************************/

#pragma vector = URX0_VECTOR

 __interrupt void UART0_ISR(void)

{

    URX0IF = 0; //清中断标志

    temp = U0DBUF;

}

4.14.3 实验效果

将风云蓝牙模块接插到开发板相应位置,注意接插方向,请按照正确说明接插进去,然后下载程序,安装给手机安装风云蓝牙串口助手,如图4-18,手机连接蓝牙模块,发送指令如下:

发送0x01指令,开发板D3(LED1)点亮,发送0x11指令,开发板D3(LED1)熄灭;

发送0x02指令,开发板D4(LED2)点亮,发送0x22指令,开发板D4(LED2)熄灭。

图4-18 风云蓝牙串口助手

 

发布了119 篇原创文章 · 获赞 51 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/aa120515692/article/details/104006578