ZigBee快速入门03

时钟配置

CC2530时钟特点

  • CC2530在正常运行的时候需要一个高频时钟信号和一个低频的时钟信号
    高频时钟信号,主要供给CPU,保证程序的运行。
    低频时钟信号,主要供给看门狗、睡眠定时器等偏上外设。
  • 时钟信号的来源:
    高频信号有2个,芯片内部的16M RC电路,外接的32M石英晶振
    低频信号也有2个,芯片内部的32K RC电路,外接的32.768K石英晶振。
  • CC2530芯片默认上电的时候,是内部的2个RC电路作为高频和低频的时钟来源
  • 在用串口,特别是无线通信的时候,必须要用32M的石英晶振作为高频时钟来源
  • 高频时钟源特点:
    2高频时钟源可以同时起振产生高频时钟信号;
    而2个低频时钟源,某一时刻只能有1个起振,并且起振的这个时钟源供给CC2530

系统高频时钟源切换

  1. 让2个高频时钟源起振
  2. 等待目标时钟源振荡稳定
  3. 延时63us一小段时间
  4. 不分频输出
  5. 选中目标高频时钟源作为系统主时钟
  6. 确认一下当前工作的系统时钟是不是所选的高频时钟

时钟相关寄存器

时钟系统总览
zg0301
SLEEPCMD寄存器
OSC_PD:高频32MHz和16MHz掉电设置(复位为1)
0:两个振荡器都已上电
1:没有被CLKCONCMD.OSC位选中的掉电

SLEEPCMD寄存器的位 7 6:3 2 1:0
名称 OSC32K_CALDIS OSC_PD MODE[1:0]

SLEEPSTA寄存器

SLEEPSTA寄存器的位 7 6:5 4:3 2:1 0
名称 OSC32K_CALDIS RST[1:0] CLK32K

CLKCONCMD寄存器

CLKCONCMD寄存器的位 7 6 5:3 2:0
名称 OSC32K OSC TICKSPD[2:0] CLKSPD

CLKCONSTA寄存器

CLKCONSTA寄存器的位 7 6 5:3 2:0
名称 OSC32K OSC TICKSPD[2:0] CLKSPD

代码

void Cfg32M() {
    SLEEPCMD &= 0xFB; // 1111 1011   让SLEEPCMD的第2位为0
    while((SLEEPSTA & 0x40) == 0); //0100 0000   SLEEPSTA寄存器的第6位为1表示32M 时钟源稳定
    CLKCONCMD &= 0xF8; //1111 1000   把寄存器CLKCONCMD的低3位设置为000,表示不分频输出
    CLKCONCMD &= 0xBF; //1011 1111   把寄存器CLKCONCMD的第6位 清0,设置32M作为系统主时钟
    while((CLKCONSTA & 0x40) == 1); //0100 0000   如果读CLKCONSTA这个寄存器的第6位为0,表示32M的时钟源已经作为了当前的系统主时钟
    SLEEPCMD |= 0x04; // 0000 0100   16M时钟掉电
}

串口配置

配置步骤

  1. 指定串口的IO位置
  2. 相应IO配置成片上外设功能
  3. 8个数据位,1个停止位,无流控,无校验确立
  4. 设置波特率
  5. 开CPU中断,对应串口接收中断

串口相关寄存器

外设IO引脚映射(CC2530具有2个串口,且每个串口都可以配置选择控制脚)
zg0302
zg0303
外设控制寄存器PERCFG
0:备用位置1,1:备用位置2

PERCFG寄存器的位 7 6 5 4 3:2 1 0
名称 T1CFG T3CFG T4CFG U1CFG U0CFG

串口控制和状态寄存器UxCSR(x=0,1)
MODE:模式选择,0表示SPI模式,1表示UART模式
RE:接受使能,0表示接收关闭,1表示接收使能

UxCSR寄存器的位 7 6 5 4 3 2 1 0
名称 MODE RE SLAVE FE ERR RX_BYTE TX_BYTE ACTIVE

串口普通控制寄存器UxGCR(x=0,1)

UxGCR寄存器的位 7 6 5 4:0
名称 CPOL CPHA ORDER BAUD_E[4:0]

串口波特率控制寄存器UxBAUD(x=0,1)

UxBAUD寄存器的位 7:0
名称 BAUD_M[7:0]

串口收发数据缓冲寄存器UxDBUF(x=0,1)
读:接收数据,写:发送数据

UxDBUF寄存器的位 7:0
名称 DATA[7:0]

32MHz系统时钟波特率设置
zg0304
TCON寄存器

TCON寄存器的位 7 6 5 4 3 2 1 0
名称 URX1IF ADCIF URX0IF IT1 RFERRIF IT0

代码

#include <iocc2530.h>

void Cfg32M(){
    SLEEPCMD &= 0xFB; // 1111 1011
    while((SLEEPSTA & 0x40) == 0); //0100 0000
    CLKCONCMD &= 0xF8; //1111 1000
    CLKCONCMD &= 0xBF; //1011 1111
    while((CLKCONSTA & 0x40) == 1); //0100 0000
    SLEEPCMD |= 0x04; // 0000 0100
}


void Uart0Cfg(){
    PERCFG &= 0xFE; // 1111 1110
    P0SEL |= 0x0C; // 0000 1100

    U0CSR |= 0xC0; //1100 0000

    U0GCR = 11;
    U0BAUD = 216;  //set baudrate

    URX0IE = 1;
    EA = 1;
}

int main()
{
    Cfg32M();
    Uart0Cfg();

    while(1);
}

#pragma vector=URX0_VECTOR
__interrupt void UART0_ISR(){
    char ch;
    URX0IF = 0;   //串口0来数据的标志位,硬件会置1,软件手动清零
    ch = U0DBUF;  //从接收寄存器中取字节存入变量ch

    U0DBUF = ch;  //将变量ch中的值赋给串口0发送寄存器
    while(UTX0IF == 0);
    UTX0IF = 0;
}

猜你喜欢

转载自blog.csdn.net/Star_ID/article/details/121410485