欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

程序员文章站 2024-02-25 10:40:41
...

1 理论分析

1.1 Usart 发送

当 USART 收/发数据缓冲器、寄存器 UxBUF 写入数据时,该字节发送到输出引脚TXDx。 UxBUF 寄存器是双缓冲的。当字节传送开始时, UxCSR.ACTIVE 位变为高电平,而当字节传送结束时为低。当传送结束时,UxCSR.TX_BYTE 位设置为 1。
当 USART 收/发数据缓冲寄存器就绪,准备接收新的发送数据时,就产生了一个中断请求。该中断在传送开始之后立刻发生,因此,当字节正在发送时,新的字节能够装入数据缓冲器。

1.2 Usart 接收

当 1 写入 UxCSR.RE 位时,在 UART 上数据接收就开始了。然后 UART 会在输入引脚 RXDx 中寻找有效起始位,并且设置 UxCSR.ACTIVE 位为 1。当检测出有效起始位时,收到的字节就传入到接收寄存器,UxCSR.RX_BYTE 位设置为 1。该操作完成时,产生接收中断。同时 UxCSR.ACTIVE 变为低电平。
通过寄存器 UxBUF 提供收到的数据字节。当 UxBUF 读出时,UxCSR.RX_BYTE位由硬件清 0。
注意:当应用程序读 UxDBUF,很重要的一点是不清除 UxCSR.RX_BYTE。清除UxCSR.RX_BYTE 暗示 UART,使得它以为 UART RX 移位寄存器为空,即使它可能保存有未决数据 (一般是由于背对背传输) 。 所以 UART 声明 (TTL 为低电平) RT/RTS线,这会允许数据流进入 UART,导致潜在的溢出。因此 UxCSR.RX_BYTE 标志紧密结合了自动 RT/RTS 功能,因此只能被 SoC UART 本身控制。否则应用程序一般可以经历以下事件:RT/RTS 线保持声明(TTL 为低电平)的状态,即使一个背对背传输清楚地表明应该间歇性地停止数据流。

2实验详解

2.1实验目的

1)、通过实验掌握CC2530 芯片串口配置与使用
2)、接收串口发送过来的数据,通过数据内容分析控制LED
注:嵌入式开发中,当程序能跑起来后,串口是第一个要跑起来的设备,所有的工作状态,交互信息都会从串口输出。我们用的是世界上最好的串口芯片FT232,贵的USB串口线都用该芯片。

2.2实验设备

硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:2000/XP/win7 系统,IAR 8.20 集成开发环境、串口助手

2.3相关电路图

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

图1 FT232

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

图2 USB

2.4实验分析

相关寄存器CLKCONCMD、CLKCONSTA、PERCFG 、P0SEL、P2DIR、 UxCSR、UxUCR、UxGCR、UxBUF、UxBAUD、IRCON2如下表所示.

表1 时钟控制命令

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表2 时钟控制状态

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表3 外设控制

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表4端口0功能选择

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表5端口2方向和端口0外设优先级模式

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表6 USART 0控制和状态

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表7 USART 0 UART控制

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表8 USART 0通用控制

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表9 USART 0接收/传送数据缓存

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表10 USART 0 波特率控制

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表11中断标志

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表12 中断使能

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

表13 串口寄存器

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

由寄存器UxBAUD.BAUD_M[7:0]和UxGCR.BAUD_E[4:0]定义波特率。该波特率用于UART 传送,也用于SPI 传送的串行时钟速率。波特率由下式给出:
=(256+BAUD_M)2BAUD_E228F

其中:F 是系统时钟频率,等于16 MHz RCOSC 或者32 MHz XOSC。
32 MHz 系统时钟常用的波特率设置。
表14 波特率设置

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

CC2530 配置串口的一般步骤:
1、配置IO,使用外部设备功能。此处配置P0_2 和P0_3 用作串口UART0
2、配置相应串口的控制和状态寄存器。此处配置 UART0 的工作寄存器。
3、配置串口工作的波特率, 此处配置为波特率为 115200。由于此实验增加了串口接收功能,寄存器有所改变(红色部分),具体配置如下:

PERCFG = 0x00; //位置1 P0 口 
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; //开总中断允许接收中断 

2.5源码分析

/**Includes*********************************************************************/
#include <ioCC2530.h>
#include <string.h>

/**宏定义***********************************************************************/
//定义数据类型
#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1   P1_0
#define LED2   P1_1
#define LED3   P0_4

/**函数声明*********************************************************************/
void initUART0(void);
void Init_LED_IO(void);        //LED初始化

/**全局变量*********************************************************************/
uchar Recdata[3]="000";
uchar RXTXflag = 1;
uchar temp;
uint  datanumber = 0;
uint  stringlen;

/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main(void)
{
  uchar i;
  Init_LED_IO();
  initUART0();
  while(1)
  {
    if(RXTXflag == 1)            //接收状态
    {
      if( temp != 0)
      {
        if((temp!='#')&&(datanumber<3))
        {
          //’#‘被定义为结束字符                   
          //最多能接收3个字符        
          Recdata[datanumber++] = temp;        
        }       
        else       
        {        
          RXTXflag = 3;                   //进入改变小灯的程序   
        }    
        if(datanumber == 3)RXTXflag = 3;    
        temp  = 0;    
      }
    }     
    if(RXTXflag == 3)   
    {  
      if(Recdata[0]=='R') 
      {
        if(Recdata[1]=='0')
          LED1 = 1;                       // R0# 关D1    
        else
          LED1 = 0;                       // R1# 开D1
      }
      if(Recdata[0]=='Y')
      {
        if(Recdata[1]=='0')
          LED3 = 1;                       // Y0# 关D3
        else
          LED3 = 0;                       // Y1# 开D3
      }
      if(Recdata[0]=='G') 
      {     
        if(Recdata[1]=='0')
          LED2 = 1;                       // G0# 关D2     
        else     
          LED2 = 0;                       // G1# 开D2   
      }   
      if(Recdata[0]=='A')      
      {     
        if(Recdata[1]=='0')
        {  
          LED1 = 1;  
          LED3 = 1;        
          LED2 = 1;                        // A0# 关所有LED
        }  
        else
        {  
          LED1 = 0;  
          LED3 = 0;         
          LED2 = 0;                       // A1# 开所有LED 
        }
      }
      RXTXflag = 1;
      for(i=0;i<3;i++)
        Recdata[i]=' ';                   //清除刚才的命令
      datanumber = 0;                     //指针归0
    }      
  }//while
}

/**
  * @brief     串口(UART0)初始化函数
  * @param     None
  * @retval    None
  */
void initUART0(void)
{
  CLKCONCMD &= ~0x40;                           //设置系统时钟源为32MHZ晶振
  while(CLKCONSTA & 0x40);                      //等待晶振稳定
  CLKCONCMD &= ~0x47;                           //设置系统主时钟频率为32MHZ

  PERCFG = 0x00;                    //位置1 P0口
  P0SEL = 0x0c;                     //P0用作串口
  P2DIR &= ~0XC0;                               //P0优先作为UART0    


  U0CSR |= 0x80;                    //串口设置为UART方式
  U0GCR |= 11;              
  U0BAUD |= 216;                    //波特率设为115200
  UTX0IF = 1;                                   //UART0 TX中断标志初始置位1    

  U0CSR |= 0X40;                    //允许接收
  IEN0 |= 0x84;                     //开总中断,接收中断
}

/**
  * @brief     初始化LED IO口
  * @param     None
  * @retval    None
  */
void Init_LED_IO(void)
{

  P1DIR = 0x03;              //P10 P11 为输出 
  P0DIR = 0x10;                  //P04为输出
  LED1 = 1;
  LED3 = 1;      
  LED2 = 1;             //灭LED
}

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

注意:本实验如果觉得较复杂可以先来看看参考代码,先把参考带代码看懂,再来看本实验的相关代码。

2.6实验现象

串口设置如下图.

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

图3

串口字符控制灯状态表
表15串口字符控制灯状态表

第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED

本章参考代码

点击进入

相关标签: cc2530 串口