600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > ⭐❤️zigbee无线通信模块的深入浅出❤️⭐

⭐❤️zigbee无线通信模块的深入浅出❤️⭐

时间:2021-09-10 06:47:26

相关推荐

⭐❤️zigbee无线通信模块的深入浅出❤️⭐

zigbbe实验

zigbee是什么zigbee模块的选择1.实验一:点灯**代码演示**实验现象2.实验二:按键控制灯代码演示实验现象3.实验三:外部中断代码演示实验现象4.实验四:定时器中断代码演示实验现象5.实验五:串口通信代码演示实验现象

zigbee是什么

类似于蓝牙或者lora等等,属于物联网终端得一种无线通信技术。

蓝牙:距离较短,功耗低,组网数量不错,数据传输不大。

WiFi:数据量比较大,功耗比较大,比较耗电,无线局域网得数量不大。

zigbee:功耗低,休眠几个ua,也可以进行组网,单网络组网数目比较大。

这三种无线模块的载波都是2.4G频率,穿透能力较差

zigbee模块的选择

一般来说,TI公司和silicon公司的zigbee模块做得比较好

TI:

芯片特点是比较便宜,但是组网没有slilicon稳定,一般学习都使用TI公司生产的

TI方案zigbee协议栈(ZSTACK)

silicon公司模块:

特点组网目前来说是最稳定的,但是比较贵

我们通常使用zigbee是用TI公司生产的CC253X系列的模块,我们可以把它当成一个普通的单片机来进行学习,对后面的协议栈分析打下铺垫。

CC2530F256 CPU:8051 RAM:8K Byte Flash: 256K Byte, 工作频率无线通信32M,数据通信量是非常少

250K bps(bit 每秒)芯片的供电电压通常是3.3V

1.实验一:点灯

CC2530 的I/O 控制口一共有21 个,分成3 组,分别是P0、P1 和P2;由图可知,P1_0 与P1_1 分别控制LED1和LED2

相关寄存器

P1DIR(P1 方向寄存器,P0DIR 同理)

P1SEL(P1 功能选择寄存器,P0SEL 同理)

我们只需要配置该引脚的输出方向和功能即可

代码演示

#define LED0 P1_0#define LED1 P1_1void GPIO_init(){P1SEL = P1SEL & ~0x03;P1DIR = P1DIR | 0x03; LED0 = 0;LED1 = 0;}void DelayMs(unsigned int msec)//大约1ms延时{for(unsigned int x = msec;x > 0;x --){for(unsigned int y = 620;y > 0;y --){asm("NOP");} }}void main(void){GPIO_init(); while(1){DelayMs(500);LED0 = 1;DelayMs(500);LED0 = 0;DelayMs(500);LED1 = 1;DelayMs(500);LED1 = 0;}}

实验现象

两个灯交互闪烁

2.实验二:按键控制灯

从原理图可知,按键没有按下时是高电平,按下之后是低电平,因为接地了。我们需要对P00和P01引脚进行操作

代码演示

#include <iocc2530.h>#define LED0 P1_0#define LED1 P1_1#define K1 P0_0#define K2 P0_1void GPIO_init(){P1SEL = P1SEL & ~0x03;//设置P1_0,P1_1为普通IO口P1DIR = P1DIR | 0x03;//设置P1_0,P1_1为输出模式P0SEL = P0SEL & ~0x03;//设置P1_0,P1_1为普通IO口P0DIR = P0DIR & ~0x03;//设置P1_0,P1_1为输入模式LED0 = 0;LED1 = 0;}void DelayMs(unsigned int msec)//大约1ms延时{for(unsigned int x = msec;x > 0;x --){for(unsigned int y = 620;y > 0;y --){asm("NOP");} }}void main(void){GPIO_init(); while(1){if(K1 == 0)LED0 = 1;elseLED0 = 0;if(K2 == 0){DelayMs(100);//延时消斗if(K2 == 0){LED1 = ~LED1;}while(K2 == 0);} }}

实验现象

K1按键控制led0的亮灭,k2按键控制led1的亮灭

3.实验三:外部中断

相关寄存器

P0IEN:各个控制口的中断使能,0 为中断禁止,1 为中断使能。

P0INP:设置各个I/O 口的输入模式,0 为上拉/下拉,1 为三态模式。

PICTL:D0~D3 设置各个端口的中断触发方式,0 为上升沿触发,1 为下降沿x发。

IEN1:中断使能1,0 为中断禁止,1 为中断使能。

P0IFG:中断状态标志寄存器,当输入端口有中断请求时,相应的标志位将置1。

代码演示

#include "exit.h"#include "exit.h"#define LED0 P1_0#define LED1 P1_1#define KEY0 P0_0#define KEY1 P0_1void DelayMs(unsigned int msec)//大约1ms延时{for(unsigned int x = msec;x > 0;x --){for(unsigned int y = 620;y > 0;y --){asm("NOP");} }}void led_init(void){P1SEL &= ~0x03 ; //清0第一次 第一为0,代表工作在普通模式P1DIR |= 0x03; //第一位为1,输出,否则输入P1_0= 0;//关LEDP1_1= 0;}//外部中断void exit_init(void){//按键寄存器的操作,设置为普通模式和输入模式P0SEL &= ~0x03;P0DIR &= ~0x03;//P0IEN:各个控制口的中断使能,0 为中断禁止,1 为中断使能。P0IEN |= 0x03;//P0INP:设置各个I/O 口的输入模式,0 为上拉/下拉,1 为三态模式P0INP &= ~0x03;//PICTL:D0~D3 设置各个端口的中断触发方式,0 为上升沿触发,1 为下降沿触发PICTL |= 0x01;//下降沿触发//IEN1:中断使能1,0 为中断禁止,1 为中断使能。//P0IFG:中断状态标志寄存器,当输入端口有中断请求时,相应的标志位将置1。 P0IFG &= ~0x03; //P0.0中断标志清0 P0IE = 1; //P0中断使能 EA = 1;//总中断使能 }#pragma vector = P0INT_VECTOR__interrupt void P0_ISR(void){EA=0;if((P0IFG & 0x02 ) >0 ) //按键中断 ,p0_1{P0IFG &= ~0x02;//P0.1中断标志清0LED1 = !LED1;}P0IF = 0; //P0中断标志清0EA = 1;//开中断if((P0IFG & 0x01 ) >0 ) //按键中断 ,p0_0{P0IFG &= ~0x01;//P0.0中断标志清0LED1 = !LED1;}P0IF = 0; //P0中断标志清0EA = 1;//开中断void main(void){led_init();ext_init();while(1);//通过while循环等待中断,}}

实验现象

主要用到了中断,该中断可以需要配置多个寄存器,假设配置p01,需要开启总中断,然后是设置p0的中断位,后面通过读取P0IFG 这个寄存器的值来判断是否产生了中断

连续按下CC2530主板上K1按键,会发现当按键被按下时,LED的亮灭状态会发生改变。

4.实验四:定时器中断

定时器1 是一个16 位定时器,具有定时器/计数器/脉宽调制功能。它有3 个单独可编程 输入捕获/输出比较 信道,每一个信道都可以用来当做PWM 输出或用来捕获输入信号的边沿时间。

定时器有一个很重要的概念:操作模式。

操作模式包含:自由运行模式(free-running)、 模模式(modulo)和 正计数/倒计数模式(up-down)。本次实验学习到的新寄存器:

T1CTL:定时器1 的控制,D1D0 控制运行模式,D3D2 设置分频划分值。

T1STAT:定时器1 的状态寄存器,D4~D0 为通道4~通道0 的中断标志,D5 为溢出标志位,当计数到最终技术值是自动置1。

T1CCTL0:D1D0 为捕捉模式选择:00 为不捕捉,01 为上升沿捕获,10 为下降沿捕获,11 为上升或下降沿都捕获。

IRCON:中断标志4,;0 为无中断请求。1 为有中断请求。

在配置寄存器之前还需要配置时钟频率相关的寄存器

CLKCONCMD:时钟频率控制寄存器。D7 位为32KHZ 时间振荡器选择,0 为32KRC 震荡,1 为32K 晶振。

D6 位为系统时钟选择。0 为32M 晶振,1 为16M RC 震荡。当D7 位为0 时D6 必须为1。

D5~D3 为定时器输出标记。000 为32MHZ,001 为16MHZ,010 为8MHZ,011 为4MHZ,100 为2MHZ,101 为 1MHZ,110 为500KHZ,111 为250KHZ。默认为001。需要注意的是:当D6 为1 时,定时器频率最高可采用频率为16MHZ。

D2~D0:系统主时钟选择:000 为32MHZ,001 为16MHZ,010 为8MHZ,011 为4MHZ,100 为2MHZ,101 为1MHZ,110 为500KHZ,111 为250KHZ。当D6 为1 时,系统主时钟最高可采用频率为16MHZ。

CLKCONSTA:时间频率状态寄存器。

D7 位为当前32KHZ 时间振荡器频率。0 为32KRC 震荡,1 为32K 晶振。

D6 位为当前系统时钟选择。0 为32M 晶振,1 为16M RC 震荡。

D5~D3 为当前定时器输出标记。000 为32MHZ,001 为16MHZ,010 为8MHZ,011 为4MHZ,100 为2MHZ,101 为 1MHZ,110 为500KHZ,111 为250KHZ。

D2~D0 为当前系统主时钟。000 为32MHZ,001 为16MHZ,010 为8MHZ,011 为4MHZ,100 为2MHZ,101 为1MHZ,110 为500KHZ,111 为250KHZ。

代码演示

#include "time.h"#include <iocc2530.h>#define LED0 P1_0#define LED1 P1_1#define K1P0_0unsigned char counter;void SysClockInit(void){unsigned int i;SLEEPCMD &= ~0x04; //都上电while(!(CLKCONSTA & 0x40));//晶体振荡器开启且稳定for (i=0; i<504; i++) asm("NOP");//适当延时CLKCONCMD &= ~0x47; //选择32MHz晶体振荡器SLEEPCMD |= 0x04; }//IRCON:中断标志4,;0 为无中断请求。1 为有中断请求。void time1_init(void){//T1CTL:定时器1 的控制,D1D0 控制运行模式,D3D2 设置分频划分值。T1CTL = 0x05 ;//自由运行和8分频//T1STAT:定时器1 的状态寄存器,D4~D0 为通道4~通道0 的中断标志,D5 为溢出标志位,当计数到最终技术值是自动置1。T1STAT =0x21; ////T1CCTL0:D1D0 为捕捉模式选择:00 为不捕捉,01 为上升沿捕获,10 为下降沿捕获,11 为上升或下降沿都捕获。T1CCTL0 |=0x01; //上升沿捕捉IEN1 |=0X02;EA = 1;//开启中断}#pragma vector = T1_VECTOR__interrupt void T1_ISR(void){EA = 0;if(counter>30){counter=0; LED0 = !LED0;LED1 = !LED1;}counter++;T1IF = 0;//清除中断位EA = 1;//开启中断}void main(void){SysClockInit();led_init();time1_init();while(1); }

实验现象

当某个中断发送后会进入这个向量中断表执行相对应的函数

精确控制LED 灯的闪烁间隔为2s,即:亮1s → 暗1s → 亮1s→ 暗1s(即从暗转亮的时刻间隔为1s)。

5.实验五:串口通信

相关寄存器

U0CSR:USART0 控制与状态。

D7 为工作模式选择,0 为SPI 模式,1 为USART 模式。

D6 为UART 接收器使能,0 为禁用接收器,1 为接收器使能。

D5 为SPI 主/从模式选择,0 为SPI 主模式,1 为SPI 从模式。

D4 为帧错误检测状态,0 为无错误,1 为出现出错。

D3 为奇偶错误检测,0 为无错误出现,1 为出现奇偶校验错误。

D2 为字节接收状态,0 为没有收到字节,1 为准备好接收字节。

D1 为字节传送状态,0 为字节没有被传送,1 为写到数据缓冲区的字节已经被发送。

D0 为USART 接收/传送主动状态,0 为USART 空闲,1 为USART 忙碌。

U0GCR:USART0 通用控制寄存器。

D7 为SPI 时钟极性:0 为负时钟极性,1 为正时钟极性;

D6 为SPI 时钟相位:

D5 为传送为顺序:0 为最低有效位先传送,1 为最高有效位先传送。

D4~D0 为波特率设置

代码演示

对串口进行配置的时候先要配置好系统的时钟,然后设置相应串口的配置,如波特率 校验位等等,最后在开启相关串口的中断,通过U0DBUF这个寄存器来接受和发送数据,当这个串口收到数据时,会产生接收中断,并接收一个字符

#include <iocc2530.h>#define LED0 P1_0#define LED1 P1_1unsigned char Flag_RX,temp;void led_init(void){P1SEL &= ~0x03;//P1.0 P1.1为普通 I/O 口P1DIR |= 0x03; //输出 LED0 = 0; //关LEDLED1 = 0;}void SysClock_Init(void){SLEEPCMD &= ~0x04; //都上电while(!(CLKCONSTA & 0x40));//晶体振荡器开启且稳定CLKCONCMD &= ~0x47; //选择32MHz晶体振荡器SLEEPCMD |= 0x04;}//接着初始化串口,代码为:void uart0_init(void){PERCFG = 0x00; //位置1 P0口 P0SEL = 0x3c; //P0_2,P0_3,P0_4,P0_5用作串口,第二功能 P2DIR &= ~0XC0;//P0 优先作为UART0 ,优先级U0CSR |= 0x80; //UART 方式 U0GCR |= 11; //U0GCR与U0BAUD配合U0BAUD |= 216; // 波特率设为115200 UTX0IF = 0;//UART0 TX 中断标志初始置位1 (收发时候)U0CSR |= 0X40; //允许接收 IEN0 |= 0x84; // 开总中断,接收中断 }//串口发送字节函数void Uart_Send_char(char ch){U0DBUF = ch;while(UTX0IF == 0);UTX0IF = 0;}//串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,将接收到的数据赋值给变量temp. #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) {LED0 = 1;URX0IF = 0; // 清中断标志 temp = U0DBUF; Flag_RX = 1;}void main(void){SysClock_Init();led_init();uart0_init();while(1){LED0 = 0;if(Flag_RX){LED1 = 1;Flag_RX = 0;Uart_Send_char(temp);LED1 = 0;} }}

实验现象

发送什么数据给单片机单片机将会返回给相应的数据给pc端

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。