一个串口中断方式发送的问题

dbeva   2010-4-16 08:35 楼主
最近在弄一个家庭影院系统,在MTK解码芯片里(8032核心)实现从USB种读出文件然后给另一个MCU通过UART升级。之前用查询的方式实现了基本功能,但是有小概率出现死机问题。现在想用中断方式来发送和接收。代码如下,我在调发送时,用串口助手接收发现:比如要发0x55,0x56,0x57,0x58四个数据,但是在
接收端总是显示接收到4个0x00或者4个0x4.请路过的英雄帮忙看看问题,出在哪里。
#if 1
#define _USART_C_

/////////////////////////////////////////////////////////////////////
#define COM_RECV_BUF_SIZE 10
#define COM_SEND_BUF_SIZE 10
BYTE xdata _bComRecvBuf[COM_RECV_BUF_SIZE];
BYTE xdata _bComRecvBufWrPoint;
BYTE xdata _bComRecvBufRdPoint;
BYTE xdata _bComRecvBufNs;
#define COM_RECV_BUF_EMPTY()  (_bComRecvBufNs == 0)
#define COM_RECV_BUF_FULL()   (_bComRecvBufNs >= COM_RECV_BUF_SIZE)
BYTE xdata _bComSendBuf[COM_SEND_BUF_SIZE];
BYTE xdata _bComSendBufWrPoint;
BYTE xdata _bComSendBufRdPoint;
BYTE xdata _bComSendBufNs;
#define COM_SEND_BUF_EMPTY()  (_bComSendBufNs == 0)
#define COM_SEND_BUF_FULL()   (_bComSendBufNs >= COM_SEND_BUF_SIZE)
/////////////////////////////////////////////////////////////////////

void vUart_int_Service(void)  
{
  if(RI)
  {
    RI = 0;
    if(!COM_SEND_BUF_FULL())
    {
      _bComRecvBuf[_bComRecvBufWrPoint] = SBUF;
      _bComRecvBufNs++;
      _bComRecvBufWrPoint++;
      if(_bComRecvBufWrPoint >= COM_RECV_BUF_SIZE)
      {
        _bComRecvBufWrPoint = 0;
      }
    }
    else
    {
      // Notice!! It will caause date lost
    }
  }
  if(TI)
  {
    TI = 0;
    if(!COM_SEND_BUF_EMPTY())
    {
      _bComSendBufNs--;
      _bComSendBufRdPoint++;
      if(_bComSendBufRdPoint >= COM_SEND_BUF_SIZE)
      {
        _bComSendBufRdPoint = 0;
      }      
    }
    if(!COM_SEND_BUF_EMPTY())
    {
      SBUF = _bComSendBuf[_bComSendBufRdPoint];
    }
  }
}


#pragma disable
BYTE bGetRecvData(BYTE *pbRecvData) large
{
  if(COM_SEND_BUF_EMPTY())
  {
    return 0;
  }

  *pbRecvData = _bComRecvBuf[_bComRecvBufRdPoint];
  _bComRecvBufNs--;
  _bComRecvBufRdPoint++;
  if(_bComRecvBufRdPoint >= COM_RECV_BUF_SIZE)
  {
    _bComRecvBufRdPoint = 0;
  }
   
  return 1;
}

#pragma disable
BYTE bGetRecvNData(BYTE *pbRecvData, BYTE bNum) large
{
  BYTE i;
   
  if(bNum > _bComRecvBufNs)
  {
    return 0;
  }

  for(i = 0; i < bNum; i++)
  {
    *(pbRecvData + i) = _bComRecvBuf[_bComRecvBufRdPoint];
    _bComRecvBufNs--;
    _bComRecvBufRdPoint++;
    if(_bComRecvBufRdPoint >= COM_RECV_BUF_SIZE)
    {
      _bComRecvBufRdPoint = 0;
    }
  }
  return 1;
}


void vClrRecvBuf(void) large
{
  _bComRecvBufNs = 0;
  _bComRecvBufRdPoint = _bComRecvBufWrPoint;
}


#pragma disable
BYTE putbyte(BYTE bSendData) large
{
  BYTE fgSending;
   
  if(COM_SEND_BUF_FULL())
  {
    return 2;
  }
  _bComSendBuf[_bComSendBufWrPoint] = bSendData;
  fgSending = !COM_SEND_BUF_EMPTY();
  _bComSendBufNs ++;
  _bComSendBufWrPoint++;
  if(_bComSendBufWrPoint >= COM_SEND_BUF_SIZE)
  {
    _bComSendBufWrPoint = 0;
  }
   
  if(!fgSending)
  {
    SBUF = bSendData;
  }
   
  return 1;
}


void vClrSendBuf(void)large
{
  _bComSendBufNs = 0;
  _bComSendBufRdPoint = _bComSendBufWrPoint;
}


void vInitUART(unsigned char bBaudRateMod) large
{

_STCL_Flag.inbufsign=0;
_STCL_Flag.out_buf_full=0;
_STCL_Flag.out_finish=0;
_STCL_Flag.in_buf_full=0;
_STCL_Flag.in_finish=0;

/*--------------------------------------------------------------------------------------
Setup TIMER1 to generate the proper baud rate.
---------------------------------------------------------------------------------------*/
SM0 = 0; SM1 = 1;               /* serial port MODE 1 */
SM2 = 0;
REN = 1;                        /* enable serial receiver */
/*---------------------------------------------------------------------------------------
Clear transmit interrupt and buffer.
--------------------------------------------------------------------------------------*/
TI = 0;                             /* clear transmit interrupt */
RI = 0;
/*---------------------------------------------------------------------------------------
Set timer 1 up as a baud rate generator.
---------------------------------------------------------------------------------------*/
TR1 = 0;                            /* stop timer 1 */
ET1 = 0;                            /* disable timer 1 interrupt */

//  PCON &=0x7f; // 表示baud rate / 2
PCON |=0x80;    /*/ 表示baud rate = 真实的 baud rate*/
TMOD &= ~0xF0;                      /* clear timer 1 mode bits */
TMOD |= 0x20;                       /* put timer 1 into MODE 2 */

/*---------------------------------------------------------------------------------------
//:    1. the real speed clock of 80C32 is 22Mhz(Philips mode set) (can't support 76.8Kbps)
//:    2. Baud rate   Timer Count (0xFF-n)   PCON.7 (double speed)   timing-error-ratio
//:       300         190(189.972)              0                 0.01%
//:       600         190(189.972)              1                 0.01%
//:      1200         94(94.486)                1                 0.51%
//:      2400         47(46.743)                1                 0.55%
//:      3600         31(30.829)                1                 0.56%
//:      7200         15(14.914)                1                 0.57%
//:      9600         11(10.936)                1                 0.59%
//:     14400         7(6.957)                  1                 0.62%
//:     19200         5(4.968)                  1                 0.65%
//:     28800         3(2.979)                  1                 0.72%
//:     38400         2(1.984)                  1                 0.81%
//:     57600         1(0.989)                  1                 1.08%
//:    115200         0(-0.005)                 1                 0.50%
---------------------------------------------------------------------------------------*/


TH1 = 0xFF-UART_BAUDRATE_9600 ;//(unsigned char) (256 - (22000000 / (16L * 12L * baudrate)));
TL1 = 0xFF-UART_BAUDRATE_9600;

TR1 = 1;                            /* start timer 1 */
//ET1 = 0;
ES = 1;
}

#endif

   

回复评论 (8)

接收到数据,数据是乱的应该有两种可能
波特率是错的,建议你用你的波特率设置固定发几个数据,用好的串口线之类的设备电脑串口接收,如果电脑接收数据正常就说明是你电路上串口出来后到电脑的那个连接设备有问题或者是T,R线不对,要是电脑接收不正常就有可能比特率设置不正确
点赞  2010-4-16 15:24
你最好把程序 注释一下吧  主要看  波特率  停止位 有没有设置错  包括用串口精灵调试的时候
点赞  2010-4-25 14:26
没有看程序,但就你所说多半是波特率,接收停止位的问题,或者你把串口的接收孔用导线相连用串口助手进行检查,再逐一排查。想深入学习推荐网站www.pubembed.com,咨询QQ:1042625805,胡老师
点赞  2010-4-26 15:30
你的程序写得也行,不过,不是很美

我建议你用我的解决方案。
直接去这里看看:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4023698&bbs_id=9999


最直接解决就是去这里。
http://item.taobao.com/auction/item_detail-0db2-4f09e6476eb55c8fe0a317d59cfb3b33.htm
点赞  2010-5-10 16:07
学习
UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
点赞  2010-5-10 19:08
你最好把程序 注释一下吧
再看看中断向量是不是对的。
点赞  2010-5-13 14:38
路过,帮顶,,看现象,是波特率设置不匹配的问题。。。。。
点赞  2010-5-13 18:51
波特率误差不能大于3%,换晶振11.815?
点赞  2010-5-13 19:33
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复