串口程序请教

[复制链接]
3170|18
 楼主| sytu_chyq 发表于 2009-12-24 09:15 | 显示全部楼层 |阅读模式
Uart0_RecvBlock(unsigned char *ptr,unsigned char size)
这个程序应该怎么实现比较好呢
比如:
Uart0_RecvBlock(unsigned char *ptr,unsigned char size)
{
  unsigned char i;                  
  for (i = 0; i < size; i++)
  {   
    while(!RI0);   // 等待接收一个字节数据完成
     RI0 = 0;          // 清除RI0标志位
    *ptr++ = SBUF0;   // 读取数据
  }
}
但要等待接收,而且当要接收的数据超过待接收的数据时要等待接收完;
怎样实现没有数据不等待呢
什么方法比较好
谢过先
kanke100 发表于 2009-12-24 09:18 | 显示全部楼层
中断接收加循环队列
 楼主| sytu_chyq 发表于 2009-12-24 11:06 | 显示全部楼层
那这个程序里要做什么呢。。
hab2000 发表于 2009-12-24 16:41 | 显示全部楼层
中断方式可以保证不丢数据,不死等!
电脑圆圆 发表于 2009-12-24 19:11 | 显示全部楼层
char Uart0_RecvBlock(unsigned char *ptr,unsigned char size)
{
  unsigned char i;                  
  for (i = 0; i < size; i++)
  {   
       while(!RI0)   // 等待接收一个字节数据完成
    {
           DelayHalfms();//具体看波特率定
           TimeCont++;
           if(TimeCont>2000)//1秒超时返回
           return i;//返回以接受数据个数
       }
       RI0 = 0;          // 清除RI0标志位
    *ptr++ = SBUF0;   // 读取数     
  }
}

评分

参与人数 1威望 +1 收起 理由
sytu_chyq + 1

查看全部评分

hotpower 发表于 2009-12-24 19:14 | 显示全部楼层
中断+FIFO
 楼主| sytu_chyq 发表于 2009-12-25 11:24 | 显示全部楼层
这个程序咋样呢

#define  RxBufMax   0x1F
#define  RxBufLen   32

unsigned char RxBuf[32];
unsigned char RxCount;
unsigned char PutFifoPt;
unsigned char GetFifoPt;
unsigned char TempFifo;

void InitialFifo(void)
{
RxCount = PutFifoPt = GetFifoPt = 0;   
}

void PutFifo(void)
{
if(RxCount < RxBufLen)   
{
  *(RxBuf + PutFifoPt) = SBUF0;
  PutFifoPt++;
  PutFifoPt = PutFifoPt & RxBufMax;
  RxCount++;  
}   
}

unsigned char GetFifo()
{
  ES0 = 0;
  TempFifo = *(RxBuf + GetFifoPt);
  GetFifoPt++;
  GetFifoPt = GetFifoPt & RxBufMax;
  RxCount--;  
  ES0 = 1;     
  return TempFifo;
}

unsigned char Uart0_RecvBlock(unsigned char *ptr,unsigned char size)
{
  unsigned char i;
  unsigned char len;  

if(len = RxCount)
{
  if(len > size) len = size;               
  for (i = 0; i < len; i++)
   *ptr++ = GetFifo();
}
return len;
}

void Uart0_ISR(void) interrupt 4
{
if (RI0)                                // 判断是否是接收中断
{
   RI0 = 0;                        // 清除接收中断标志       
  PutFifo();
}       
if (TI0)                                // 判断是否是发送完成中断
{
//        TI0 = 0;                                // 清除发送完成中断标志               
}         
}
 楼主| sytu_chyq 发表于 2009-12-25 11:26 | 显示全部楼层
DelayHalfms();
这个延时怎么确定啊
6# 电脑圆圆
电脑圆圆 发表于 2009-12-26 01:31 | 显示全部楼层
这里我用半毫秒
延迟要比传输一字节所用的时间小,比如9600bps时传输一字节为1/1200s,最好用0.2ms这样,不要延迟1ms以上否则可能来不及接收而被覆盖从而丢帧
bit06haozi 发表于 2009-12-28 16:14 | 显示全部楼层
7楼正解
bit06haozi 发表于 2009-12-28 16:16 | 显示全部楼层
中断只收数,存储在FIFO
我有现成的例子,如需要站短吧
 楼主| sytu_chyq 发表于 2009-12-29 08:59 | 显示全部楼层
11# bit06haozi
改为6楼正解,呵呵
我七楼的程序是中断加FIFO的啊
有啥需要完善的啊
有程序上来看看啊
谢谢
 楼主| sytu_chyq 发表于 2009-12-29 09:03 | 显示全部楼层
如果要接收大量数据而缓存又没办法那么大,一般是怎么做的呢
JerryWu75 发表于 2009-12-29 16:54 | 显示全部楼层
可以考虑用中断重入的方法.
Interrupt ISR_UART()
{
if(Buff A未满&&没有数据待处理){
    读入数据到Buff A;
   如果Buff A满,则设定Buff A数据待处理标志;
} else if(Buff B未满&&没有数据待处理){
    读入数据到Buff B;
   如果Buff B满,则设定Buff B数据待处理标志;
} else {
   丢弃数据;
}
/* 在这里要将中断返回地址替换为DataPrc的地址, 并将原返回地址压到堆栈的更下层,由DataPrc程序结束后返回该地址*/
如果DataPrc已经退出则将DataPrc的地址压入堆栈;
设定DataPrc忙标志;
中断返回;
}
Void DataPrc(void)
{
if(Buff A数据待处理){
     处理Buff A数据;
    清除Buff A数据待处理标志;
}
if(Buff BA数据待处理){
     处理Buff B数据;
    清除Buff B数据待处理标志;
}
清除DataPrc忙标志;
返回;    /* 这里将返回接收中断发生前的程序地址 */
}

评分

参与人数 1威望 +1 收起 理由
sytu_chyq + 1

查看全部评分

 楼主| sytu_chyq 发表于 2009-12-30 16:55 | 显示全部楼层
15# JerryWu75
谢谢
这样做是为了解决什么问题
要等到缓存满了才处理数据?
古道热肠 发表于 2009-12-30 17:32 | 显示全部楼层
看看我发的这贴,自信能比较好的解决您此类问题。
https://bbs.21ic.com/icview-150846-1-1.html
JerryWu75 发表于 2009-12-31 10:50 | 显示全部楼层
关于15#的算法,不一定要数据满后才处理,这取决与你的需要。这个算法的思想是一个占先多任务的设计,即在有数据时你可以及时地进行处理,没有数据时可以做其他的事情!
5880527 发表于 2009-12-31 11:58 | 显示全部楼层
上面有的方法也够差劲的,就不要去误导楼主了
t86964988 发表于 2009-12-31 16:33 | 显示全部楼层
用中断!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

223

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部