切换系统高频时钟源
CC2530在正常运行的时候需要一个高频时钟信号和一个低频的时钟信号
- 高频时钟信号:主要供给给CPU,保证程序的运行
- 低频时钟信号:主要供给看门狗,睡眠定时器等偏上外设
时钟信号来源
- 高频信号两个来源:芯片内部的16M RC电路;外接的32M石英晶振
- 低频信号两个来源:芯片内部的32K RC电路,外接的32.768K石英晶振
CC2530默认上电的时候,是内部的2个RC电路作为高频和低频的时钟来源
如果我们在用串口,特别是无线通信的时候,必须要用32M的石英晶振作为高频时钟来源,16M比32M的速度慢,为32M的1/2
高频时钟源特点:
- 两个高频时钟源可以同时起振产生高频时钟信号
- 而两个低频时钟源,某一时刻只能有1个起振,并且起振能的这个时钟源供给CC2530
切换步骤:
1、2个高频时钟源起振; 让SLEEPCMD的第2位为0;
SLEEPCMD &=0xFB;//1111 1011 开启2个高频时钟源
2、待目标时钟源振荡稳定;SLEEPSTA寄存器的第6位为1表示32 时钟源稳定
while(0==(SLEEPSTA & 0x40));// 0100 0000 等待32M稳定
3、 延时一小段时间63us(不定); 超过63微秒延时
void delayus()//调用函数实现
{
char k=63;
while(k--);
}
4、不分频输出; 把寄存器CLKCONCMD的低3位 设置为000,表示不分频输出
CLKCONCMD &=0xF8;//1111 1000 不分频输出
5、 选中目标高频时钟源作为系统主时钟; 把寄存器CLKCONCMD的第6位 清0,设置32M作为系统主时钟
CLKCONCMD &=0XBF;//1011 1111 设置32M作为系统主时钟
6、确认一下当前工作的系统时钟是不是所选的高频时钟;如果读CLKCONSTA这个寄存器的第6位为0,表示32M的时钟源已经作为了当前的系统主时钟,程序可以往下运行了。
while(CLKCONSTA & 0x40); //0100 0000 等待32M成功成为当前系统主时钟
数码管测试
32M代码:
#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);//数码管显示函数,i为几,数码管显示几
delay();
}
}
}
16M代码:
#include <iocc2530.h>
#include"74LS164_8LED.h"
void delay()
{
int i,j;
for(i=0;i<1000;i++)
for(j=0;j<800;j++);
}
void main()
{
char i;
LS164_Cfg();
while(1)
{
for(i=0;i<10;i++)
{
LS164_BYTE(i);
delay();
}
}
}
另外附上74LS164_8LED 数码管显示的代码,把代码添加到工程里即可
74LS164_8LED.h
#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
74LS164_8LED.c
#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;
}
}
USB转串口配置
CC2530具备两个串口,且每个串口都可以配置选择控制脚
步骤:
1、指定串口的IO位置
PERCFG &=0xFE;//1111 1110 选中串口0的的备用位置1
2、相应IO配置成偏上外设功能
P0SEL |=0x0C; //0000 1100 P0_2 p0_3为偏上外设功能
3、8个数据位,1个停止位,无流控,无校验确立
U0CSR |=0Xc0;
4、波特率设置
U0GCR =8;
U0BAUD=59;
5、开CPU中断,对应串口接收中断
EA=1;
URX0IE=1;//结尾为0或8则可以直接选择赋值
USART0接收字符利用中断服务函数
当一个字节由串口接收到C2530,字节会保存到U0DBUF寄存器,同时接收中断标志URX0IF位会置1
可以利用中断服务程序来接收该字符串
中断服务函数
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
总测试代码
#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 UART0_ISR(void)
{
URX0IF=0;//串口0来数据的标志位,硬件会置1,我们软件要清0
ch=U0DBUF;//从接受寄存器里取字节存入变量ch
U0DBUF=ch;//把变量ch里的值赋给串口0发送数据寄存器
while(0==UTX0IF);
UTX0IF=0;
}
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues