【胜达ZigBee深入浅出】zigbee从入门到砸开发板之CC2530(二)

zigbee从入门到砸开发板之CC2530(二)

4、时钟

概述

1、CC2530在正常运行的时候需要一个高频时钟信号和一个低频的时钟信号

  • 高频时钟信号,主要供给CPU,保证程序的运行。
  • 低频时钟信号,主要供给看门狗、睡眠定时器等偏上外设。

2、时钟信号的来源;

  • 高频信号有2个,芯片内部的16M RC电路;外接的32M石英晶振
  • 低频信号也有2个来源,芯片内部的32K RC电路,外接的32.768K石英晶振。

3、CC2530芯片默认上电的时候,是内部的2个RC电路作为高频和低频的时钟来源。

4、如果我们在用串口,特别是无线通信的时候,必须要用32M的石英晶振作为高频时钟来源。

5、高频时钟源特点:

  • 2个高频时钟源可以同时起振产生高频时钟信号,但只有一个有效。
  • 而2个低频时钟源,某一时刻只能有1个起振,并且起振的这个时钟源供给CC2530.

CLKCONCMD 时钟控制命令寄存器

CLKCONCMD76543210
OSC32KOSCTICKSPDTICKSPDTICKSPDCLKSPDCLKSPDCLKSPD

OSC:系统时钟源选择位:【0:32MHZ的XOSC】【1:16MHZ的RCOSC】

CLKSPD:时钟速度(不能高于OSC设置的系统时钟设置)(可以为任意值,受OSC位的限制,如果OSC==1 ,无论本位是多少,都会还原成16MHZ)[000:为32MHZ,000+1:为32/2MHZ,…]

CLKCONSTA 时钟控制状态寄存器

CLKCONSTA76543210
OSC32KOSCTICKSPDTICKSPDTICKSPDCLKSPDCLKSPDCLKSPD

控制命令发出后,通过本寄存器查询是否完成设置

切换系统时钟源步骤

  • 起振两个高频时钟源,并等待稳定起振
  • 延时一段时间
  • 设置时钟源(不分频、选外部32MHZ),并查询是否设置成功

1、让SLEEPCMD的第2位为0;
2、SLEEPSTA寄存器的第6位为1表示32M 时钟源稳定
3、超过63微秒延时
4、把寄存器CLKCONCMD的低3位 设置为000,表示不分频输出
5、把寄存器CLKCONCMD的第6位 清0,设置32M作为系统主时钟
6、如果读CLKCONSTA这个寄存器的第6位为0,表示32M的时钟源已经作为了当前的系统主时钟,程序可以往下运行了。

关于SLEEPCMD、SLEEPSTA两个寄存器

这两个寄存器用于电源管理与复位中,这里由于需要起振两个时钟源,所以需要设置下。

SLEEPCMD.2:默认为1,代表关闭不用的RC振荡器

SEELPSTA.6(SEELPSTA.XOSC_STB):【0:32MHZ晶振上电不稳定】【1:32MHZ晶振上电稳定】

实例

#include<iocc2530.h>
#include"74LS164_8LED.h"
void delayus()
{
    char k=63;
    while(k--);
}
void delay()
{
  int i,j;
     for(i=0;i<1000;i++)
       for(j=0;j<800;j++);
}

void Init32M()
{
   SLEEPCMD &=0xFB;//1111 1011 开启2个高频时钟源
   while(0==(SLEEPSTA & 0x40));// 0100 0000 等待32M稳定
   delayus();
   CLKCONCMD &=0xF8;//1111 1000 不分频输出
   CLKCONCMD &=0XBF;//1011 1111 设置32M作为系统主时钟
   while(CLKCONSTA & 0x40); //0100 0000 等待32M成功成为当前系统主时钟
}
void main()
{
     char i;
     LS164_Cfg();
     Init32M();
     while(1)
     {
         for(i=0;i<10;i++)
         {
            LS164_BYTE(i);
            delay();
         }
     }
}
=============================================================================
#ifndef __74LS164_8LED_H__
#define __74LS164_8LED_H__
#include<ioCC2530.h>
#define  LS164_DATA  P1_3
#define  LS164_CLK   P1_2
#define  UCHAR  unsigned char 
void LS164_Cfg();
void LS164_BYTE(UCHAR Data);//P1.3  DATA   P1.2  CLK
#endif
=============================================================================
#include<ioCC2530.h>
#include"74LS164_8LED.h"
static UCHAR LED_Map[]={0x3f,0x06,0x5b,0x4f,
                        0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f,0x00,0xFF};
void LS164_Cfg()
{
    P1SEL &=~0x0C;//xxxx 00xx  配置为普通IO模式
    P1DIR |=0x0C;//xxxx 11xx   配置为输出模式
}
void LS164_BYTE(UCHAR Index) //P1.3  DATA   P1.2  CLK
{  
    UCHAR i=0;
    UCHAR Data=LED_Map[Index];
    for(;i<8;i++)
    {
        if(0x80 & Data)
        {
            LS164_DATA=1;            
        }
        else
        {
            LS164_DATA=0; 
        }
        Data=Data << 1;
        LS164_CLK=0;
        LS164_CLK=1;
    }
}

5、串口

概述

CC2530具有两个串行通信接口:USART0 USART1。具有UART和SPI两种模式(主要用UART模式)

UART模式

异步通信

两种接口选择方式:

  • 双线接口:RXD TXD
  • 四线接口:RXD TXD RTS CTS

PERCFG寄存器配置串口备用位置

USARTx有两个备用位置

USART0:【P0.2-RX; P0.3-TX】【P1.4-RX; P1.5-TX】

USART1:【P0.5-RX; P0.4-TX】【P1.7-RX; P1.6-TX】

PERCFG76543210
------U1CFGU0CFG

UxCFG:【0:地址一;1:地址二】

UxCSR寄存器配置串口工作状态

UxCSR76543210
MODERESLAVEFEFRRRX_BYTETX_BYTEACTIVE

MODE:模式选择【0-SPI模式】【1-UART模式】

RE:启动UART接收器【1-启动】

UxUCR寄存器

UxUCR76543210
FLUSHFLOWD9BIT9PARITYSPBSTOPSTART

UxDBUF寄存器

串口数据发送与接收缓冲器

BAUD_M寄存器

波特率小数部分的值

UxGCR通用控制寄存器

UxGCR的低四位 == BAUD_E:波特率指数部分的值

【小结】由BAUD_M、BAUD_E设置波特率;例如: U0GCR =8;U0BAUD=59;

串口中断相关

串口中断使能: URXxIE=1; UTXxIE=1;

串口中断标志位:URXxIF; UTXxIF;

串口功能实现步骤

  • 指定串口的IO位置
  • 对IO配置成片上外设功能
  • 确立传输方式
  • 确定波特率
  • 开中断

实例

#include<ioCC2530.h>
char ch;
void Cfg32M()
{
    SLEEPCMD &=0xFB; //fB 0 00 让2个时钟源都起振
    while(0==(SLEEPSTA & 0x40));  //  0100 0000  如果32M 晶振供电且稳定了,那么程序往下运行
    CLKCONCMD &=0xF8; //1111 1000 不分频输出

    CLKCONCMD &=0xBF;//1011 1111 让32M作为系统主时钟供给CPU
    while(1==(CLKCONSTA & 0x40));//如果32M确实供给CPU在工作,那么程序往下执行
    SLEEPCMD |=0x40;// 0000 0100 
}
void UartCfg()
{//串口0的备用位置1配置成波特率9600
   PERCFG &=0xFE;//1111 1110 选中串口0的的备用位置1
   P0SEL  |=0x0C;       //0000 1100 P0_2 p0_3为偏上外设功能
   
   U0CSR |=0Xc0;
   
    
   U0GCR =8;
   U0BAUD=59;
   EA=1;
   URX0IE=1;
}

void main()
{
  Cfg32M();
  UartCfg();
    while(1);
}

#pragma vector=URX0_VECTOR
__interrupt void sdfs(void)
{
    
    URX0IF=0;//串口0来数据的标志位,硬件会置1,我们软件要清0
    ch=U0DBUF;//从接受寄存器里取字节存入变量ch
    
    U0DBUF=ch;//把变量ch里的值赋给串口0发送数据寄存器
    while(0==UTX0IF);
    UTX0IF=0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值