时钟
协议栈都是用的32M晶振工作的,所以在学习串口使用之前,应该学习一下如何调时钟
- cc2530在运行过程中需要一个高频时钟信号和一个低频时钟信号,
- 高频时钟信号主要供给cpu保证程序运行,16Mhz RC(这也是为什么定时器计算分频时是以16为基准)电路芯片内部、32Mhz外接石英晶振
低频时钟信号看门狗,睡眠定时器等片上外设,芯片内部的32k rc电路,外接32.768k石英晶振 - cc2530默认上电时,是内部的2个rc电路作为高频和低频的时钟来源。
- 如果我们在用串口,特别是无线通信的时候,必修要用32M的石英晶振作为高频时钟来源(怎么样从16M切换到32M呢)
- 高频时钟源特点:
2高频时钟源可以同时起振产生高频时钟信号;
而2个低频时钟源,某一时刻只能有1个起振,并且起振的这个时钟源供给cc2530
系统高频时钟源切换步骤:
1 让SLEEPCMD 第2位为0,表示开启2个高频时钟源;
2 SLEEPSTA寄存器的第6位为1表示32M时钟源稳定;
3 超过63us延时;
4 把寄存器CLKCONCMD的第3位设置为000,表示不分配输出;
5 把寄存器CLKCONCMD的第6位清0,设置32M作为系统主时钟;
6 如果读寄存器CLKCONSTA第6位为1,则表示32M的时钟源已经作为了当前的系统主时钟,程序可以往下运行。
void Init32M(){
SLEEPCMD &= 0xfb;//1111 1011 开启2个高频时钟源
while((SLEEPSTA & 0x40)==0);//0100 0000 SLEEPSTA寄存器的第6位为1表示32M时钟源稳定;
delay63us();//超过63us延时
CLKCONCMD &= 0xF8;//1111 1000,把寄存器CLKCONCMD的第3位设置为000,表示不分频输出;
CLKCONCMD &= 0xBF;//1011 1111,把寄存器CLKCONCMD的第6位清0,设置32M作为系统主时钟;
while((CLKCONSTA & 0x40)==0);//0100 0000 等待32M成功成为当前系统主时钟
}
串口
协议栈都是用的32M晶振工作的,所以在学习串口使用之前,应该学习一下如何调时钟
注意:
- 每个工程都需要重新配置一遍 Project->Option,不配置是不能烧录的
- 对于下载是用仿真器,但是对于串口的收发测试连接,需要连串口 usb 口
- 下面的示例没有提到如何改校验位、停止位和数据位(默认为 8-NONE-1)
#include <iocc2530.h>
void Cfg32M(){
SLEEPCMD &= 0xFB;//1111 1011 开启2个高频时钟源
while(0 == (SLEEPSTA & 0x40));//0100 0000 SLEEPSTA寄存器的第6位为1表示32M时钟源稳定
CLKCONCMD &= 0xF8;//1111 1000,把寄存器CLKCONCMD的第3位设置为000,表示不分配输出;
CLKCONCMD &= 0xBF;//1011 1111,把寄存器CLKCONCMD的第6位清0,设置32M作为系统主时钟;
while(0==(CLKCONSTA & 0x40));//0100 0000 等待32M成功成为当前系统主时钟
SLEEPCMD |= 0x40;
}
void UartCfg(){
PERCFG = 0x00; //位置1 P0口
P0SEL = 0x0c; //P0用作串口
P2DIR &= ~0XC0; //P0优先作为UART0
U0CSR |= 0x80; //USART模式选择为UART方式 1000 0000(还可以设置成SPI)
U0GCR |= 8; //U0GCR和U0BAUD共同决定了波特率值
U0BAUD |= 59; //波特率设为9600
UTX0IF = 1; //UART0 TX中断标志初始置位1
U0CSR |= 0X40; //Bit[6]UART接收器使能:1接收器使能
IEN0 |= 0x84; //开总中断,接收中断
}
void main(){
Cfg32M(); //改上电默认的16M晶振为32M晶振
UartCfg(); //串口相关的寄存器配置
while(1){
}
}
/****************************************************************
串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp.然后再发出去
****************************************************************/
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
char temp;
URX0IF = 0;//串口0中断标志位,当接受中断时置1,软件清0,为下一次中断准备
temp = U0DBUF; //从接受寄存器里取字节存入变量ch
U0DBUF = temp;//把变量temp的值赋给串口0发送数据寄存器
while(0==UTX0IF);//当UTX0IF为1时发送结束(接收时中断,发送时也中断)
UTX0IF = 0;//中断完毕后再次将中断清0,为下一次中断准备
}