您的位置:首页 > 其它

Zigbee基础实验——可变内存空间的串口通讯

2014-06-16 10:14 323 查看

1、前言

最近在耍Zigbee,看到基础实验中的串口通讯,发现很多教程都比较的简单,大部分的串口数据都是固定大小的数组,所以本文主要介绍如何实现接收可变长度的串口数据,如果我写的有不对的地方或需要改进的地方,希望各位朋友能够指出,万分感谢

2、基本思路

要实现接收可变长度的串口数据关键就是存放串口数据的缓存数组变量要可变,并且能够知道什么时候保持缓存数组的大小,什么时候改变缓存数组的大小,在本文中我的思路较为简单,首先设置一个变量dataLength用于存放缓存数据中有效数据长度,另外再定义一个变量dataCount用于存放缓存数据总数据长度,当(dataCount - dataLength)< 2时表示有效数据长度快接近缓存数据上限,那么此时就要扩大缓存数据的大小,这里我采用的方法是重新申请一块内存空间,大小为原来缓存数据大小的2倍,然后把现在缓存数据中存放的所有值转存到新的内存空间,并把原来内存空间给释放,最后让缓存空间的指针指向新申请的内存空间,当串口数据处理完毕,再用上面同样的方法把串口缓存数据恢复为初始大小,以减少内存浪费。

3、解决方案

Step1:初始化必要的全局变量

char serial0Tmp = 0; // 串口接收的临时变量
uchar UART0RXFLAG = 1, UART0TXFLAG = 0; // UART0接收、发送标记位
char *serial0Data = 0; // 接收到的串口缓存数据
uchar dataLength = 0; // 有效串口数据长度
uchar dataCount = 10; // 串口数据总长度

Step2:初始化串口缓存数组

// 初始化数组空间
serial0Data = (char*)malloc(sizeof(char) * dataCount);
// 初始化数组值
memset(serial0Data, 0, sizeof(char) * dataCount);

Step3:初始化2530串口寄存器

// 初始化数组空间
serial0Data = (char*)malloc(sizeof(char) * dataCount);
// 初始化数组值
memset(serial0Data, 0, sizeof(char) * dataCount);

CLKCONCMD &= ~0x40; // 设置系统时钟为32MHz
while(CLKCONSTA & 0x40); // 等待系统时钟稳定
CLKCONCMD &= ~0x47; // 设置系统主时钟频率为32MHz

PERCFG &= ~0x01; // 设置UART0为位置0
PERCFG |= 0x02; // 设置UART1为位置1
P0SEL |= 0x3C; // 设置P0_2、P0_3、P0_4、P0_5为第二功能
P2DIR &= ~0xC0; // 设置P0的优先级为UART0

U0CSR |= 0xC0; // 设置UART0为UART模式,并且能够接受数据
U1CSR |= 0xC0; // 设置UART1为UART模式,并且能够接受数据

U0GCR |= 11; // 设置UART0波特率为115200
U0BAUD |= 216;
U1GCR |= 11; // 设置UART1波特率为115200
U1BAUD |= 216;

UTX0IF = 0; // 设置UART0 发送中断标志初始为0
UTX1IF = 0; // 设置UART1 发送中断标志初始为0

IEN0 |= 0x8C; // 打开总中断,并打开UART0和UART1的接受中断使能

Step4:初始化串口接收中断处理函数

#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
URX0IF = 0; // 清空接收标记位,准备下一次接收
serial0Tmp = U0DBUF;
}

Step5:串口数据发送函数

void uart0Send_String(char* data, int length)
{
int j = 0;
for(j = 0; j < length; j++)
{
U0DBUF = *data; // 数据从串口发送
data++;
while(UTX0IF == 0); // 等待数据发送结束
UTX0IF = 0; // 清空数据发送标记位
}
}

Step6:串口的接收和发送处理

while(1)
{
if(UART0RXFLAG)
{
if(serial0Tmp)
{
if(serial0Tmp != '#')
{
// 如果当前已存数据接近上限时则重新分配空间
if((dataCount - dataLength) < 2)
{
// 重置串口缓存数组的指针
serial0Data -= dataLength;
// 新缓存数组的大小为原来的2倍
dataCount *= 2;
// 申请新的串口缓存数组
char *dataTmp = (char*)malloc(sizeof(char) * dataCount);
// 初始化串口缓存数组为0
memset(dataTmp, 0, sizeof(char) * dataCount);
// 把原来串口数组中的数据拷贝到新的数组中
memcpy(dataTmp, serial0Data, sizeof(char) * dataLength);
// 释放原来的缓存数组空间
free(serial0Data);
// 把新的缓存数组控件的首地址给到缓存数组的指针
serial0Data = dataTmp;
// 移动缓存数组的指针到新的位置
serial0Data += dataLength;
}
// 继续存储串口数据
*serial0Data = serial0Tmp;
// 指针往后移动一位
serial0Data++;
// 有效数据大小加1
dataLength++;
}
else
{
UART0TXFLAG = 1; // 打开数据发送
UART0RXFLAG = 0; // 关闭数据接收
}
serial0Tmp = 0;
}
}
if(UART0TXFLAG)
{
U0CSR &= ~0x40; // 禁止UART0接收数据
// 重置缓存数组的指针
serial0Data -= dataLength;
// 发送串口数据
uart0Send_String(serial0Data, dataLength);

// 恢复串口接收数据空间大小
dataCount = 10;
// 释放缓存数组的控件
free(serial0Data);
// 重新申请默认大小的控件
serial0Data = (char*)malloc(sizeof(char) * dataCount);
memset(serial0Data, 0, sizeof(char) * dataCount);
dataLength = 0; // 有效数据长度复位

U0CSR |= 0x40; // 允许UART0接收数据
UART0TXFLAG = 0; // 关闭数据发送
UART0RXFLAG = 1; // 打开数据接收
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐