ZigBee2-2 练习 串口


理论部分学习: 无线传感网络 --ZigBee2-3 串口

2-3 串口通讯–收发字符串

要求:
(2)在《2-3 串口通讯–收发字符串》中完成了串口数据收发的功能,要求修改代码,使得串口调试助手向开发板发送字符串“D1#”时,Led1交替改变亮和灭的状态。

原代码

/****************************************************************************
* 文 件 名: main.c
* 作    者: Andy
* 修    订: 2013-01-08
* 版    本: 1.0
* 描    述: 设置串口调试助手波特率:115200bps 8N1
*           串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串
****************************************************************************/
#include <ioCC2530.h>
#include <string.h>

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];        //存储发送字符串

/****************************************************************************
* 名    称: 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;
    }
}

/****************************************************************************
* 名    称: UART0_ISR(void) 串口中断处理函数 
* 描    述: 当串口0产生接收中断,将收到的数据保存在RxBuf中
****************************************************************************/
#pragma vector = URX0_VECTOR 
__interrupt void UART0_ISR(void) 
{ 
    URX0IF = 0;       // 清中断标志 
    RxBuf = U0DBUF;                           
}


/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{	
    CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
   
    InitUart();                                //调用串口初始化函数   
    UartState = UART0_RX;                      //串口0默认处于接收模式
    memset(RxData, 0, SIZE);
    
    while(1)
    {
        if(UartState == UART0_RX)              //接收状态 
        { 
            if(RxBuf != 0) 
            {                 
                if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 50)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else
                        UartState = UART0_TX;  //进入发送状态 
                }
                RxBuf  = 0;
            }
        }
        
        if(UartState == UART0_TX)              //发送状态 
        {                         
            U0CSR &= ~0x40;                    //禁止接收 
            UartSendString(RxData, count);     //发送已记录的字符串。
            U0CSR |= 0x40;                     //允许接收 
            UartState = UART0_RX;              //恢复到接收状态 
            count = 0;                         //计数清0
            memset(RxData, 0, SIZE);           //清空接收缓冲区
        }    
    }
}

分析:

要使得串口调试助手向开发板发送字符串“D1#”时,Led1交替改变亮和灭的状态,在结束的情况中加入另一种结束的情况D1#的情况

                if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 50)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else
                        UartState = UART0_TX;  //进入发送状态 
                }
                if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 50)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else{
                      if((RxData[0]=='D') && (RxData[1]=='1') && count==2){
                        //if((RxData[0]=='D') && (RxData[1]=='1')) 选择这种方式的话输入D11#小灯也会闪烁
                        LED1 = ~LED1;//
                      }
                }

修改后代码

/****************************************************************************
* 文 件 名: main.c
* 作    者: Andy
* 修    订: 2013-01-08
* 版    本: 1.0
* 描    述: 设置串口调试助手波特率:115200bps 8N1
*           串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串
****************************************************************************/
#include <ioCC2530.h>
#include <string.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define UART0_RX    1
#define UART0_TX    2
#define SIZE       51
#define LED1 P1_0                //定义P1.0口为LED1控制端
#define LED3 P1_4                //定义P1.0口为LED1控制端

char RxBuf;
char UartState;
uchar count;
char RxData[SIZE];        //存储发送字符串

/****************************************************************************
* 名    称: 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;            //开总中断允许接收中断  
    
    P1DIR |= 0x11;               //P1.0定义为输出口
}

/****************************************************************************
* 名    称: UartSendString()
* 功    能: 串口发送函数
* 入口参数: Data:发送缓冲区   len:发送长度
* 出口参数: 无
****************************************************************************/
void UartSendString(char *Data, int len)
{
    uint i;
    
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
}

/****************************************************************************
* 名    称: UART0_ISR(void) 串口中断处理函数 
* 描    述: 当串口0产生接收中断,将收到的数据保存在RxBuf中
****************************************************************************/
#pragma vector = URX0_VECTOR 
__interrupt void UART0_ISR(void) 
{ 
    URX0IF = 0;       // 清中断标志 
    RxBuf = U0DBUF;                           
}


/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{	
    CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
   
    InitUart();                                //调用串口初始化函数   
    UartState = UART0_RX;                      //串口0默认处于接收模式
    memset(RxData, 0, SIZE);
    
    while(1)
    {
        if(UartState == UART0_RX)              //接收状态 
        { 
            if(RxBuf != 0) 
            {                 
                if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 50)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else{
                      if((RxData[0]=='D') && (RxData[1]=='1') && count==2){
                        //if((RxData[0]=='D') && (RxData[1]=='1')) 选择这种方式的话输入D11#小灯也会闪烁
                        LED1 = ~LED1;//
                      }
                      UartState = UART0_TX;  //进入发送状态 
                    }
                }
                
                RxBuf  = 0;
            }
        }
        
        if(UartState == UART0_TX)              //发送状态 
        {                         
            U0CSR &= ~0x40;                    //禁止接收 
            UartSendString(RxData, count);     //发送已记录的字符串。
            U0CSR |= 0x40;                     //允许接收 
            UartState = UART0_RX;              //恢复到接收状态 
            count = 0;                         //计数清0
            memset(RxData, 0, SIZE);           //清空接收缓冲区
        }    
    }
}

2-4 AD采集cc2530温度串口显示

要求:
在《2-4 AD采集cc2530温度串口显示》中完成了片内温度数据采集和通过串口发送温度数据的功能,要求修改代码,使得每个两秒钟发送一次温度数据,并且用嘴对芯片吹气,查看温度变化。

原代码

/****************************************************************************
* 文 件 名: main.c
* 作    者: Andy
* 修    订: 2013-01-09
* 版    本: 1.0
* 描    述: ADC把芯片温度通过串口发给电脑,部分芯片误差较大需校准
*           手摸芯片温度有明显变化
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "UartTimer.h"

/****************************************************************************
* 名    称: 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℃(不同芯片根据具体情况校正)
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void) 
{   
    char i; 
    float AvgTemp;   
    char strTemp[6];
    
    InitUART();                           //初始化串口 
    InitSensor();                         //初始化 ADC 
    
    while(1) 
    { 
        AvgTemp = 0;          
        for (i=0; i<64; i++) 
        {    
            AvgTemp += GetTemperature();  
            AvgTemp = AvgTemp/2;          //每次累加后除 2 
        }
       
        memset(strTemp, 0, 6);
        sprintf(strTemp,"%.02f", AvgTemp);//将浮点数转成字符串
        UartSendString(strTemp, 5);       //通过串口发给电脑显示芯片温度
        DelayMS(1000);                    //延时
    } 
}

分析:

最后的延时修改为2000即可

修改后代码

/****************************************************************************
* 文 件 名: main.c
* 作    者: Andy
* 修    订: 2013-01-09
* 版    本: 1.0
* 描    述: ADC把芯片温度通过串口发给电脑,部分芯片误差较大需校准
*           手摸芯片温度有明显变化
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "UartTimer.h"

/****************************************************************************
* 名    称: 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℃(不同芯片根据具体情况校正)
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void) 
{   
    char i; 
    float AvgTemp;   
    char strTemp[6];
    
    InitUART();                           //初始化串口 
    InitSensor();                         //初始化 ADC 
    
    while(1) 
    { 
        AvgTemp = 0;          
        for (i=0; i<64; i++) 
        {    
            AvgTemp += GetTemperature();  
            AvgTemp = AvgTemp/2;          //每次累加后除 2 
        }
       
        memset(strTemp, 0, 6);
        sprintf(strTemp,"%.02f", AvgTemp);//将浮点数转成字符串
        UartSendString(strTemp, 5);       //通过串口发给电脑显示芯片温度
        DelayMS(2000);                    //延时
    } 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值