搜索
bottom↓
回复: 13

马潮老师,您好,我的串口中断一直丢包,麻烦帮忙分析

[复制链接]

出0入0汤圆

发表于 2012-5-21 20:34:48 | 显示全部楼层 |阅读模式
//===============串口初始化=============
void uart0_init(void)
{
UCSR0B = 0x00;   //禁止发送和接收
UCSR0A = 0x00;   //倍速异步模式USX0=0
UCSR0C = 0x06;   //0000 0110,UCSZ01=1,UCSZ00=1;1位起始位,8位字符,1位停止位
UBRR0L = 25;     //设置波特率为19200
UBRR0H = 0;      //
UCSR0B = 0x98;   //使能发送和接收,使能串口中断

asm("sei");//打开全局中断
}

//***************   UART0 FUNCTION  ************************//
void UartSendHY502(unsigned char *cSendBuffer)
{
         unsigned char i;
         unsigned char cCheckSum = 0;

        UCSR0B &= ~(1<<RXCIE0); //禁止串口接收

        for(i=0;i<30;i++)
          g_cReceBuf[30] = 0;

        while(!(UCSR0A & (1<<UDRE0)));
         UDR0 = 0xAA; //发送包头 0xAA

    while(!(UCSR0A & (1<<UDRE0)));
         UDR0 = 0xBB; //发送包头 0xBB

        for (i=0; i<cSendBuffer[0]; i++)
         {
                 cCheckSum ^= cSendBuffer[i];

                while(!(UCSR0A & (1<<UDRE0)));
                 UDR0 = cSendBuffer[i]; //发送长度字、命令字、校验和

                if (cSendBuffer[i] == 0xAA)
                 {
                         while(!(UCSR0A & (1<<UDRE0)));
                     UDR0 = 0x00; //在0xAA后加0x00
                 }

        }

    while(!(UCSR0A & (1<<UDRE0)));
         UDR0 = cCheckSum; //发送校验字
         
        UCSR0B |= 1<<RXCIE0; //打开串口接收
}

SIGNAL(SIG_USART0_RECV)
{
     unsigned char i;
         unsigned char cReceivedData;
     unsigned char cCheckSum = 0;

        cReceivedData = UDR0;

        if(g_bReceAA)
         {
          g_bReceAA = 0;

         if(cReceivedData == 0xBB )
            g_cReceNum = 0;

         }//不接收包头AA BB

        else
          {
           if (0xAA == cReceivedData)
                 g_bReceAA = 1;

          g_cReceBuf[g_cReceNum++] = cReceivedData;

          if (g_cReceNum > g_cReceBuf[0])//代表所有数据已经接收完毕
            {
                  UCSR0B &= ~(1<<RXCIE0); //禁止串口接收,退出中断服务
                  cCheckSum = 0;

                 for (i=0; i <= g_cReceBuf[0]; i++)
                          cCheckSum ^= g_cReceBuf[i];

                 if (0 == cCheckSum)
                         {
                           g_bReceCommandOk = 1;//表示数据接收完毕        ,且接收无误                  
                          }
                  g_cReceNum = 0;
                  g_bReceAA = 0;                 
                 }

          }
}  

/************************** main function start here *******************************/
int main(void)
{           
    uchar CardSN[] = {0x02,0x02};
         uchar cStatus;
         uchar *cPa;

        uart0_init();
         
         cPa = CardSN;
         UartSendHY502(cPa);                   //发送指令
         _delay_ms(200);                        // delay for module execution
         cStatus = !g_bReceCommandOk;   
            //一下为显示部分
         if((g_cReceBuf[1] != cPa[1])|| (cStatus != 0x00))   //判断是否接收完毕,及接收的是否正确
         {
           ……
         }
         else
         {
            ……
         }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2012-5-21 20:35:58 | 显示全部楼层
期望马潮老师的回复,大家有经验的过来发表建议哦……

出0入0汤圆

发表于 2012-5-21 20:57:11 | 显示全部楼层
你的每帧数据有且只有一个0xaa吗?

还有不要重复发帖子。

出0入0汤圆

 楼主| 发表于 2012-5-21 21:39:02 | 显示全部楼层
谢谢回复。

刚才我解决了困扰了两周的问题,不过还是很感谢您。

新手不了解这些规则,而且看马潮老师的那个帖子较晚,就又发了一遍。以后不会再犯这样的错误了。

出0入0汤圆

发表于 2012-5-24 11:57:33 | 显示全部楼层
关于这一类的帖子哪边有?

出0入0汤圆

 楼主| 发表于 2012-5-24 15:22:01 | 显示全部楼层
你可以上网搜下,这方面的问题大家问的很多

出0入0汤圆

发表于 2012-5-24 17:34:05 | 显示全部楼层
应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:

    (1)、我从来不使用查询方式的发送数据
           缺点:响应太慢,占用宝贵的CPU时间
           我一直使用中断方式发送数据
    (2)、我从来不在接收中断里做大量的判断和处理工作
            缺点:可能会造成数据丢失
            我一直在主程序中判断和处理接收的数据。
     下面是我的接收中断代码

#pragma interrupt_handler USART1_RI_ISR:iv_USART1_RX
void USART1_RI_ISR(void)
{
        INT8U ch;
        INT8U status;

        status = UCSR1A;
        ch = UDR1;
        if (USART1_receCount < MSCOMM_BUFFER_LENGTH)
                USART1_mscomm_buffer[USART1_receCount++] = ch;
        else
                USART1_receCount = 0;
        if (status & 0x1C)
                USART1_checkoutError = 2;
}



    下面是我的发送中断代码
   
#pragma interrupt_handler USART1_TX_ISR:iv_USART1_TX
void USART1_TX_ISR(void)
{
    if (USART1_sendPosi < USART1_sendCount)
                UDR1 = USART1_send_buffer[USART1_sendPosi++];
        else
                RS485_RECIVE_enable();
}        



//下面的代码在主程序中执行,用于发送第1个字节,同时开启发送中断
void USART1_Begin_Send(void)
{
        RS485_SEND_enable();
        NOP();                                                //        --------|       
        NOP();                                                //                        |
        NOP();                                                //                        |-----------等待总线释放
        NOP();                                                //                        |
        NOP();                                                //        --------|
    USART1_sendPosi = 0;
        UDR1 = USART1_send_buffer[USART1_sendPosi++];
}

出0入0汤圆

 楼主| 发表于 2012-5-24 20:54:13 | 显示全部楼层
十分感谢高手的建议,我一定谨记在心!
初学者,在这方面没有经验……
谢谢高手让我成长!

出0入4汤圆

发表于 2012-11-5 22:32:03 | 显示全部楼层
谢谢楼上的各位

出0入0汤圆

发表于 2012-11-15 20:59:48 | 显示全部楼层
mark一下关于串口中断的,有空看看那

出0入0汤圆

发表于 2012-11-16 09:00:18 | 显示全部楼层
ba_wang_mao 发表于 2012-5-24 17:34
应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:

你好,能看到你的这个完整的代码吗,
我主要是想知道你的main函数中是怎么对
USART1_mscomm_buffer[]处理的,
假设你正在处理的过程中,又有新的接收中断到来, USART1_mscomm_buffer[]中的数据又变化了怎么做的

出0入0汤圆

发表于 2013-3-28 20:56:17 | 显示全部楼层
表示很钦佩!!!!

出0入0汤圆

发表于 2013-3-29 08:34:50 | 显示全部楼层
mark 今天测试一下

出0入0汤圆

发表于 2013-3-29 10:45:37 | 显示全部楼层
ba_wang_mao 发表于 2012-5-24 17:34
应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:

你好,能够把你的RS485_RECIVE()这个函数是怎么实现的,给看看吗
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 19:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表