ZigBee学习笔记(基础篇)

前言

搬运个人博客内容,还有几天就到期了,这是年初写的。而且那时候由于一起疫情无法返校,没有实验器材,在学习过程没有实践,所以对于具体使用还十分生疏,也没有做相关项目。对于逐渐忘记的zigbee,我想在这里记录下,以便后续学习的需要。


基本概念

ZigBee,也称紫蜂,是一种低速短距离传输的无线网上协议,底层是采用IEEE 802.15.4标准规范的媒体访问层与物理层。主要特色有低速、低耗电、低成本、支持大量网上节点、支持多种网上拓扑、低复杂度、快速、可靠、安全。

Zigbee模块主要基于TI CC2530芯片实现,其中有5根与下载有关,构成下载电路。工作电压为2~3.6V(最好用3.3V)。关于IO口,一共有21个通用IO口,又分为三组P0(8个引脚)、P1(8)、P2(5)。
图1

关于IO设置

相关寄存器:PxSEL、PxDIR、PxINP。 Px(x分别对应0、1、2,用来控制对应的IO口组)3种寄存器。

PxSEL寄存器

PxSEL寄存器(x=0、1)相应的一个IO口,决定它是普通IO口还是片上外设,0表示普通IO口,1表示片上外设。(普通IO口与片上外设的区别:普通IO口又叫GPIO,可以任意设置这个IO口的高低状态;而片上外设不能被任意控制,必须要通过控制器去控制)
在这里插入图片描述

P2SEL寄存器
同样也是0表示普通IO、1表示片上外设 注意:其中P2组只有5个IO口,但是P2_1 P2_2是用于下载程序用的,所以,这两个IO不需要配置,因此P2SEL的低3位分别对应P2_0 P2_3 、P2_4。

在这里插入图片描述

PxDIR寄存器

共8位,每一位对应具体的IO组中的相应的一个IO,决定它是输入还是输出,0表示输入,1表示输出。(P2只有五位,低五位照常,高五位不管)(图片参考图2、图3)

PxINP寄存器

在输入的模式时,8位,每一位对应具体的IO组中的相应的一个IO,决定它是上下拉模式还是三态,0表示上下拉模式,1表示三态。(在上下拉模式的时候,需要P2INP后面的3位决定,0表示上拉,1表示下拉)


以下为练习代码



#include<iocc2530.h>

void main()
{
/* P1SEL &=0xFE;// 1111 1110 让P1_0处于普通IO,非偏上外设模式
P1DIR |=0x01;//0000 0001 让P1_0处于输出状态非输入状态
P1_0=1;*/

P0SEL &=0xEF;// 1110 1111
P0DIR |=0x10;//0001 0000

P0SEL &=0xBF;// 1011 1111
P0DIR &=0xBF;

P0INP &=0xBF;//让P0_6处于上下拉模式;
P2INP &=0xDF;//1101 1111 让P0组处于上拉模式
while(1)
{
if(1==P0_6)
{//检测到的是高电平
P0_4=0;
}
else
{//检测到的P0_6外部是低电平
P0_4=1;
}
}

中断

外部中断配置
初始化IO口工作在普通IO上拉输入状态
打开IO口组中断
打开组内对应的具体某IO口中断
上升沿还是下降沿触发
开总中断EA=1


步骤2、3参考下图

在这里插入图片描述

步骤4涉及寄存器PICTL,0代表上升沿,1代表下降沿。
在这里插入图片描述

中断函数

参考代码如下:

#pragma vector = PxINT_VECTOR //PxIFG 和 PxIF清零
_unterrupt void anyname() 
{

PxIFG=0;
PxIF=0;
}

练习代码如下:


#include<iocc2530.h>
#define uchar unsigned char
void delay(uchar u)
{
while(u--);
}
void main()
{
P0SEL &= 0xDF ;//1101 1111 P0_5
P0DIR &= 0xDF ;//1101 1111 P0_5
P0INP &= 0xDF ;//1101 1111 P0_5
P2INP &= 0xDF ;//1101 1111 P0_5

EA = 1;
P0IE = 1;// P1IE如果要设置为1,不能直接用PIE=1,IEN2 |= 0x10 ;// 0001 0000
// IEN |=0x01 ;
P0IEN |= 0x20 ;//0010 0000 设置三个试能标志位,让相应的中断合上
PICTL |= 0x01;//下降沿触发

P1DIR |= 0x01;
while(1);
}

#pragma vector= P0INT_VECTOR
__interrupt void timeduan ()
{
if(P0IFG &= 0x20)//P0组的5发生外部中断
{
delay(1000);
if(0 == P0_5)
{
P1_0 ^=1 ;
}
}
P0IFG = 0;
P0IF = 0;
}

时钟

基本概念:

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

系统高频时钟源切换步骤:



让2个高频时钟源起振;//让SLEEPCMD的第2位为0;    

等待目标时钟源振荡稳定;// SLEEPSTA寄存器的第6位为1表示32M 时钟源稳定

延时一小段时间63us;// 超过63微秒延时

不分频输出;//把寄存器CLKCONCMD的低3位 设置为000,表示不分频输出

选中目标高频时钟源作为系统主时钟;//把寄存器CLKCONCMD的第6位 清0,设置32M作为系统主时钟  

确认一下当前工作的系统时钟是不是所选的高频时钟;//如果读CLKCONSTA这个寄存器的第6位为0,表示32M的时钟源已经作为了当前的系统主时钟,程序可以往下运行了。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


练习代码3如下:

#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();
}
}
}

串口时钟

具体步骤:

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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

串口中断函数

样例:

#pragma vector=URX0_VECTOR
__interrupt void anyname(void)
{
    
    URX0IF=0;
    ch=U0DBUF;
    
    U0DBUF=ch;
    while(UTX0IF==0);
    UTX0IF=0;
}

波特率设置函数

//波特率设置参考上表

void Uart0Cfg()
{
   PERCFG &=~0x01;
   P0SEL  |=0x0C;       
   
   U0CSR |=0Xc0;
   
   U0GCR =8;
   U0BAUD=59;
   URX0IE=1;
   EA=1;
   
}

练习代码如下:

#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;
}

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ORI2333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值