微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > ZIGBEE串口通信学习总结

ZIGBEE串口通信学习总结

时间:10-02 整理:3721RD 点击:
/*本程序目的是通过串口0实现串口接收和发送信息
在学习过程中一定要对应着寄存器功能手册来学习
编程,不会的就百度一下
主讲:王加辉
*/
#include<iocc2530.h>
#define LED1 P1_0
#define LED2 P1_1
char temp; /*定义字符型temp全局变量,用来临时存储由串口助手发来的字符*/
void init_LED() //初始化LED灯
{
P1DIR|=0X03; /*P1DIR为P1方向寄存器,用来设置P1口各端口为输出还是输入端口,
我们在这里配置了P1_0和P1_1为输出端口*/

P1SEL&=0X03; /*P1SEL为P1功能选择寄存器,其功能为设置P1各端口为普通I/O口,
还是启用其外设功能,在这里我们配置P1_1和P1_0普通I/O口 */

P1INP&=0X03; /*P1INP为P1输入模式寄存器,其作用就是设置相应P1I/O口的上拉打开
还是保持三态,复位后默认为P1INP=0x00,所以这里可以不用设置*/
}

void init_CLKCON() //初始化时钟
{
CLKCONCMD&=0X40; /*CLKCONCMD为时钟控制寄存器,在这里我们设置主时钟源为32M晶振*/
while(CLKCONSTA&0x40);/*CLKCONSTA为时钟状态寄存器,我们用while语句来等待晶振稳定为32M*/
CLKCONCMD&=0X47; //这里我们是在选择时钟速率为32MHZ
}

void init_UART0() //初始化串口0
{
P0SEL=0X3C; //这里我们是在选择P0_2、P0_3、P0_4、P0_5为串口
P2DIR&=0XC0; /*在这里我们设置串口0的优先级大于串口1,即优先使用串口0*/
PERCFG=0X00; /*PERCFG为接口控制寄存器,这里我们选择串口0位置1,即
用P0_2口为TX,P0_3口为RX*/

U0CSR|=0XC0; /*UOCSR为UART0控制和状态寄存器,在这里我们可以控制和查看
串口0的状态,我们设置UART0的工作方式为异步通信模式即UART
模式,并且打开其接收器使能端,允许串口接收数据*/
/*下面我们来设置串口0的波特率*/
U0GCR|=11; /*U0GCR为UART0通用控制寄存器,在这里我们设置BAUD_E的值为11*/
U0BAUD|=216; /*U0BAUD为UART0的波特率控制寄存器,在这里我们设置BAUD_M的值为216*/
UTX0IF=0; //UTX0IF为串口0发送中断标志位,这里我们对其置零
IEN0|=0X84; //这里我们开总中断和串口0中断
}

void send(char *character,int length)//数据输出函数
{
int i;
for(i=0;i<length;i++)
{
U0DBUF=*character++; //输出字符
while(UTX0IF==0); /*等待字符完成输出,因为串口通信每输出一次数据TX中断标志位就会自动置一*/
UTX0IF=0; //软件将TX中断标志位置一
}
}
void main()
{
char code[50]={0}; //定义字符数组并对其清空
temp=0; //初始化temp值
int datanumber=0,flog=0;//databumber用来计算输入了多少个字符
init_LED(); //调用初始化函数
init_CLKCON();
init_UART0();
while(1)
{
/*输入程序*/
if(flog==0)/*判断flog的值来选择输入还是输出字符信息,flog为0是输入,为1是输出*/
{
If(temp!=0)/* 通过判断temp值是否为空来判断是否有字符输入*/
{
LED1=0;
LED2=1;
if((temp!='#')&&(datanumber<50)) /*在我们这个程序中以#为输入结束标志,并且一次最多允许输入50个字符信息*/
{
code[datanumber]=temp; //将temp的值存入字符数组中
datanumber++;
}
else
{
flog=1; //进入输出程序
}
temp=0;
} /*每输入一个字符我们都要对temp清空一次,防止非人为地重复输入*/
}
/*输出程序*/
if(flog==1)
{
LED1=1;
LED2=0;
U0CSR&=0X40; /*因为在输出时TX中断标志位会自动置一产生中断,所以
在进入输出函数之前我们先关闭串口中断并关闭串口接收允许位*/
IEN0&=0x04;
send(code,datanumber); //进入输出函数
U0CSR|=0x40; //重新打开串口中断和串口接收允许位
IEN0|=0X04;
flog=0; //进入输入状态
datanumber=0; //字符数清零
temp=0;
}
}
}

#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void) /*串口中断函数,在从串口助手输入字符信息时,RX中断允许位会被自动置一,单片机会自动进入到这里*/
{
URX0IF=0; /*我们需要软件对RX中断允许位清零,防止产生中断死循环*/
temp=U0DBUF; //将输入的字符赋给temp
}

/*到这里串口的信息传输讲完了,祝你学习愉快*/

/*本程序目的是通过串口0实现对单片机LED灯点亮的操作,
在学习过程中一定要对应着寄存器功能手册来学习
编程,不会的就百度一下
主讲:王加辉
*/
#include<iocc2530.h>
#define LED1 P1_0
#define LED2 P1_1
char temp; //定义字符型temp全局变量,用来临时存储由串口助手发来的字符
void init_LED() //初始化LED灯
{
P1DIR|=0X03; /*P1DIR为P1方向寄存器,用来设置P1口各端口为输出还是输入端口,
我们在这里配置了P1_0和P1_1为输出端口*/

P1SEL&=0X03; /*P1SEL为P1功能选择寄存器,其功能为设置P1各端口为普通I/O口,
还是启用其外设功能,在这里我们配置P1_1和P1_0普通I/O口 */

P1INP&=0X03; /*P1INP为P1输入模式寄存器,其作用就是设置相应P1I/O口的上拉打开
还是保持三态,复位后默认为P1INP=0x00,所以这里可以不用设置*/
}

void init_CLKCON() //初始化时钟
{
CLKCONCMD&=0X40; //CLKCONCMD为时钟控制寄存器,在这里我们设置主时钟源为32M晶振
while(CLKCONSTA&0x40);//CLKCONSTA为时钟状态寄存器,我们用while语句来等待晶振稳定为32M
CLKCONCMD&=0X47; //这里我们是在选择时钟速率为32MHZ
}

void init_UART0() //初始化串口0
{
P0SEL=0X3C; //这里我们是在选择P0_2、P0_3、P0_4、P0_5为串口
P2DIR&=0XC0; //在这里我们设置串口0的优先级大于串口1,即优先使用串口0
PERCFG=0X00; /*PERCFG为接口控制寄存器,这里我们选择串口0位置1,即
用P0_2口为TX,P0_3口为RX*/

U0CSR|=0XC0; /*UOCSR为UART0控制和状态寄存器,在这里我们可以控制和查看
串口0的状态,我们设置UART0的工作方式为异步通信模式即UART
模式,并且打开其接收器使能端,允许串口接收数据*/
/*下面我们来设置串口0的波特率*/
U0GCR|=11; //U0GCR为UART0通用控制寄存器,在这里我们设置BAUD_E的值为11
U0BAUD|=216; //U0BAUD为UART0的波特率控制寄存器,在这里我们设置BAUD_M的值为216
UTX0IF=0; //UTX0IF为串口0发送中断标志位,这里我们对其置零
IEN0|=0X84; //这里我们开总中断和串口0中断
}

void main()
{
char code[3]={0}; //定义字符数组并对其清空
temp=0; //初始化temp值
int datanumber=0,flog=0;//databumber用来计算输入了多少个字符
init_LED(); //调用初始化函数
init_CLKCON();
init_UART0();
while(1)
{
/*输入程序*/
if(flog==0)/*判断flog的值来选择输入还是输出字符信息,flog为0是输入,为1是输出*/
{
if(temp!=0)/*通过判断temp值是否为空来判断是否有字符输入*/
{
if((temp!='#')&&(datanumber<50)) /*在我们这个程序中以#为输入结束标志,并且一次最多允许输入50个字符信息*/
{
code[datanumber]=temp; //将temp的值存入字符数组中
datanumber++;
}
else
{
flog=1; //进入输出程序
}
temp=0; //每输入一个字符我们都要对temp清空一次,防止非人为地重复输入
}
}
/*输出程序*/
if(flog==1)
{
if(code[0]=='L')/*判断第一个字符是不是L*/
{
switch(code[1]-48) /*先提取出第二个字符,然后用case语句判断*/
{
case 1:
{
LED1=LED1; /*对LED1取反*/
break;
}
case 2:
{
LED2=LED2; /*对LED2取反*/
break;
}
}
}
flog=0; //进入输入状态
datanumber=0; //字符数清零
temp=0;
}
}
}

#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void) //串口中断函数,在从串口助手输入字符信息时,RX中断允许位会被自动置一,单片机会自动进入到这里
{
URX0IF=0; //我们需要软件对RX中断允许位清零,防止产生中断死循环
temp=U0DBUF; //将输入的字符赋给temp
}

/*到这里串口的信息传输讲完了,祝你学习愉快*/

呵呵,谢谢分享

我只是做了自己能做的小事,CC2530的详细学习资料不多,我以后在录制些视频哈,哈哈

呵呵,楼主加了官方zigbee技术群嘛?

我加了好多的群,不知道哪个是官方的呦,哈哈

官方群是多少啊,小哥

欢迎加入官方zigbee技术群,也希望楼主能多分享心的243090717

先收藏再说

正在研读协议栈,没法详细和同志分享,等我能够随意使用时,再来和大家分享

楼主,可以请教你一下吗?:UART0可用位置1(即P0_2,P0_3)和位置2(即P1_4,P1_5),但是如果用位置2串口初始化如何设置?
void InitUART(void)
{
PERCFG = 0x01; //位置2 P1口
P1SEL = 0x30; //P1_4,P1_5用作串口(外部设备功能)
P2SEL &= 0X40; //P1优先作为UART0


U0CSR |= 0x80; //设置为UART方式
U0GCR |= 8;
U0BAUD |= 59; //波特率设为9600
UTX0IF = 0; //UART0 TX中断标志初始置位0
}
我这样设置希望能用位置2即通过P1口来进行串口通信,但是结果不行,请你指点一下,谢谢

学习了,

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top