|
楼主 |
发表于 2013-11-24 08:04:18
|
显示全部楼层
循环队列写得把自己都绕晕了,对字符串发送代码有2个不理解:
1、为什么发送字符串使用循环队列;
2、为什么在在UartSendChar对SBUF赋值,在中断函数里也对SBUF赋值。
看了《数据结构》后,我觉得开源PLC字符串发送写得有问题,不过简单测试了一下,居然是能够工作的。
借鉴http://home.eeworld.com.cn/my/space-uid-139222-blogid-28925.html的例子。
虽然源代码能够工作,我还是利用循环队列定义中的入队出对修改了一下(参考黄国瑜版《数据结构》c语言),肯定有问题,入队和出对都放在同一个函数里。
#define OutLEN 30
volatile unsigned char UartSendBuffer[OutLEN]; //发送缓冲
volatile unsigned char front=0; //最后由中断传输出去的字节位置,总是指向空的
volatile unsigned char rear=0; //最后放入发送缓冲区的字节位置 volatile unsigned char UartSendBufferemptyFlag=1; //缓冲区数据发完标志 发完=1
volatile unsigned char UartSendBufferHaveDataFlag=0; //发送缓冲区非空标志 有=1
把指针更改为数组序号,原因是为了 +1求余就可以循环。
void UartSendchar(unsigned char ucdata)
{
rear=(rear+1)%OutLEN;
while(front==rear) //队列已满
{
front=(front+1)% OutLEN;
SBUF=UartSendBuffer[front];
}
UartSendBuffer[rear]=ucdata; // 放字节进入缓冲区
UartSendBufferHaveDataFlag=1;
// 缓冲区开始为空,置为有,启动发送
if (UartSendBufferHaveDataFlag)
{
front=(front+1)% OutLEN;
SBUF=UartSendBuffer[front]; // 未发送完继续发送
// 最后传出去的字节位置加1
if (front==rear)
UartSendBufferHaveDataFlag=0; // 数据发送完置发送缓冲区空标志
}
}
void Uart(void) interrupt 4 using 2
{
if(TI)
{
TI=0;
}
if(RI)
{
RI = 0;
}
}
这个一样可以测试通过,感觉发送字符就不需要缓冲。为何多此一举?暂时先理解到这里,因为这个模块已经可以工作了。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|