打印

求助:古老串口中断问题

[复制链接]
2044|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dong2007|  楼主 | 2010-3-19 23:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
老问题不好意思拿出来说事,在坛子里搜了一堆串口问题没看出个所以然。
在圈圈书里是直接在中断里清标志
void UartISR(void) interrupt 4
{
if(RI)    //收到数据
  {
   RI=0;   //清中断请求
  }
else      //发送完一字节数据
  {
   TI=0;
   Sending=0;  //清正在发送标志
  }
}

用UartPutChar()发送一个字节是可以收到的,但连续发一个数组里的数据就收不到了,为何进了中断就出不来了呢?
for(i=0;i<50;i++)
{
  UartPutChar(get[i]);
}
//或者用发送字符串函数:Prints(get);

相关帖子

沙发
dong2007|  楼主 | 2010-3-19 23:47 | 只看该作者
在UartPutChar()函数里加个
computer00发表于 2007-8-18 12:13 | 只看该作者 回复 引用 返回版面 TOP  得分:0
7楼:
偶喜欢while(!TI);TI=0;

可以解决问题,但中断函数里不是已经清标志位TI了吗?为何非得在这里清标志位?

使用特权

评论回复
板凳
dong2007|  楼主 | 2010-3-19 23:51 | 只看该作者
我发现
古道热肠发表于 2009-9-20 11:07 | 只看该作者 回复 引用 评分 报告 返回版面 TOP  得分:0
19楼: 经测试,2楼和3楼两位网友提出的方法完全可行,再次感谢!
贴上测试代码

/****************************************************************************/
/*                                                                          */
/*       SERIAL.C:  Interrupt Controlled Serial Interface                   */
/*                                                                          */
/****************************************************************************/
//采用中断接收串口数据
//发送数据到串口可使用<stdio.h>定义的函数
//有疑义可访问bbs.21ic.com进行讨论。
//测试:古道热肠
#include <reg52.h>
#include <stdio.h>
volatile unsigned char UartIsSending;

char putchar (char ucWriteData)
{
SBUF=ucWriteData;
UartIsSending=1;
while(UartIsSending);
return (ucWriteData);
}

volatile unsigned char UartIsSending;
void UartIsr(void) interrupt 4
{
if(TI) //发送中断
{
    UartIsSending=0;
    TI=0;
}
if(RI) //接收中断
{
  RI=0;
}
}
/****************************************************************************/
/*       serial_init: initialize serial interface                           */
/****************************************************************************/
serial_init ()  
{
  SCON  = 0x50;                      /* mode 1: 8-bit UART, enable receiver */
  TMOD |= 0x20;                      /* timer 1 mode 2: 8-Bit reload        */
  TH1   = 0xf3;                      /* reload value 2400 baud              */
  TR1   = 1;                         /* timer 1 run                         */
  ES=1;
}
void Delay(void)
{
unsigned char ucDelayCount;
for(ucDelayCount=0; ucDelayCount<0xFF; ucDelayCount++)
{
  ;
}
}

void main(void)
{
serial_init();
EA = 1;
while(1)
{
  putchar('8');
  putchar('\n');
  Delay();
  printf("welcome to http://www.21ic.com/n");
}
}

在printf("welcome to http://www.21ic.com/n");里如果把函数里的字符串放在一个数组里就不行了!

使用特权

评论回复
地板
itelectron| | 2010-3-20 08:18 | 只看该作者
不是有所长 的 什么 环行  队列 用于 串口么?

偶也等大牛 说说 怎么用串口 的

我是中断用串口 接收

发送在主循环里

使用特权

评论回复
5
dong2007|  楼主 | 2010-3-20 21:11 | 只看该作者
看来我得倒腾已下 环行  队列

使用特权

评论回复
6
dong2007|  楼主 | 2010-3-20 21:22 | 只看该作者
看来我得倒腾已下 环行  队列

使用特权

评论回复
7
xwj| | 2010-3-20 21:39 | 只看该作者
发送和接收都应该用中断的,
应该学会事件驱动的概念,比如收到这个字节后应该做什么呢?当然是发送下一个字节;而如果发送完了呢?当然是设置标志后退出啦

“while(!TI);TI=0;”可不是什么好方法,只是作为一本书上的教程,可不能写的太详细了,只能举个示例,否而那本书得拖成多长多厚啊?

使用特权

评论回复
8
古道热肠| | 2010-3-20 23:20 | 只看该作者
遇到的串口通讯半双工的较多,现在的习惯是,接收用中断,发送用printf函数,但是printf函数是要求先查TI为0后,然后将下一个数据送入SBUF,所以必段先将TI=1,如此一来,串口中断又无法使用了,解决的办法一个是3楼所举例程,还有一个办法是重载putchar()函数,重载后能够使中断接收函数和printf共存。
因为发送数据的时间通常是可预知的,俺还是推荐发送时用printf完成,虽然其采用的是查询返回。但是接收必段用中断,中断中用状态机实现起来较为方便,但要求串口中断的处理时间小于一字符的长度,如果中断耗时太多,会丢接收的数据的。

使用特权

评论回复
9
古道热肠| | 2010-3-20 23:26 | 只看该作者
可看看我以前发在侃单片机版的一个贴子,对中断接收的状态跳转作了详细的介绍:https://bbs.21ic.com/viewthread.p ... 3%E7%83%AD%E8%82%A0

使用特权

评论回复
10
dong2007|  楼主 | 2010-3-21 03:40 | 只看该作者
3点起来感谢楼上几位的教导,感谢!!!

使用特权

评论回复
11
西楚小无赖| | 2010-3-23 17:26 | 只看该作者
额晕了,呵呵,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

185

帖子

0

粉丝