打印
[AVR单片机]

ATMEGA128双串口问题

[复制链接]
7609|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sqjh1988|  楼主 | 2013-3-26 10:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用单片机的双串口来实现数据的中转站功能,即128的串口0连接身份*读卡器,通过对其发送指令附带返回值由串口0接收,再由128串口1发送到电脑上,现在的问题是串口0和ISP下载线同时用着会对数据的接收有影响吗?现在串口0只能接收到三个返回的数据,但是要求的返回值远远大于三个,不知道是程序问题还是复用问题,希望看到的都能给指点迷津。。。。拜托。。。。


//*************************************************************************
//                串口相关中断服务子程序
//*************************************************************************
                                     //数据发送结束中断向量
SIGNAL(SIG_USART0_TRANS)             //中断服务程序
{
   delay_ms(10);                   //相关操作

}

                                   //数据接收结束中断向量
SIGNAL(SIG_USART0_RECV)            //中断服务程序
{
        uchar temp;
    temp=UDR0;
        table33[t]=temp;
        t++;
        if(t>7)
        {
                UCSR0B=0XE0;//禁止接收
                UCSR1B=0XF8;//发送中断允许
                m=0;
        }
       
   
}
/*uchar USART_Receive()
{
        uchar temp;
        while(!(UCSR1A&(1<<RXC)));
        return UDR1;
        temp=UDR1;
        table00[j]=temp;
       
        j++;
        data_do(0xff);
        UCSR0B=0XF8;//发送中断允许
        if(j>14)
        {
                j=0;
                UCSR1B=0XE0;//禁止接收
                UCSR0B=0XF8;//发送中断允许
        }

}*/
                                  //数据寄存器空中断向量
SIGNAL(SIG_USART0_DATA)           //中断服务程序
{        
                if(i<=2)
                {
                           UDR0=table4[i];
                           i++;
                }
                  else
                   {
                    UCSR0B=0XF0;//禁止发送
                        t=0;
                   }
}
                                     //数据发送结束中断向量
SIGNAL(SIG_USART1_TRANS)             //中断服务程序
{
   delay_ms(10);                   //相关操作
}


                                  //数据寄存器空中断向量
SIGNAL(SIG_USART1_DATA)           //中断服务程序
{
    uchar temp;
        temp=table33[m];                       
        UDR0=temp; //发送数据到数据寄存器
           m++;
           if(m>6)
           {
               UCSR0B=0Xc0;//禁止发送
             m=0;
   }
}
//*************************************************************************
//                        74HC573控制数码管动态扫描显示函数,显示采集到的温度
//*************************************************************************

/*void Display_Uart(uint data_b,uint data_s,uint data_g)
{
         uchar i,j;
         system_init();
     j=0x01;                    //此数据用来控制位选
for(i=0;i<5;i++)               //用后3位数码管来显示
  {
     D_LE1;                     
     W_LE1;                     
     Data_IO=~j;               
     W_LE0;                     
         j=(j<<1);
     Data_IO=0x00;           
     D_LE0;                     
     delay_ms(1);               
  }
     D_LE1;                    
     W_LE1;                    
     Data_IO=~j;               
     W_LE0;                    
         j=(j<<1);
     Data_IO=table[A1];         
     D_LE0;                    
     delay_ms(1);              

     D_LE1;                     
     W_LE1;                     
     Data_IO=~j;               
     W_LE0;                     
         j=(j<<1);
     Data_IO=table[A2];            
     D_LE0;                     
     delay_ms(1);   
         
         D_LE1;                     
     W_LE1;                     
     Data_IO=~j;               
     W_LE0;                     
         j=(j<<1);
     Data_IO=table[A3];            
     D_LE0;                     
     delay_ms(1);                                      

}*/

//****************************** ************************************** *****
//                        主程序
//*************************************************************************
void main()
{
  system_init();                             //系统初始化
  usart0_init();                            //usart串口初始化配置
//  usart0_init();
  usart_tx_data=0xff;
  SREG|=0x80;                            //开启全局中断
  i=0;
  while(1)
{  
                                 
         SREG=0x00;                               //关中断,PD口做IO口用,才能正常显示数码管
         Display_Uart(A1,A2,A3);                  //显示接收到的数据  
         SREG|=0x80;                              //开中断,用于下次接收中断

  }
}

相关帖子

沙发
2014luoluo| | 2013-3-27 17:07 | 只看该作者
没用Atmega128,我上次也找双串口的单片机,用的是Atmega162单片机,DIP40,单价20元一枚,楼主Atmega128多少钱?

使用特权

评论回复
板凳
qin552011373| | 2013-3-27 22:53 | 只看该作者
ISP下载线和串口0是共用IO的?没用过像128这么高端的avr

使用特权

评论回复
地板
sqjh1988|  楼主 | 2013-3-28 10:03 | 只看该作者
2014luoluo 发表于 2013-3-27 17:07
没用Atmega128,我上次也找双串口的单片机,用的是Atmega162单片机,DIP40,单价20元一枚,楼主Atmega128多少 ...

买的成套的开发板,三百多大洋。。。。:)

使用特权

评论回复
5
sqjh1988|  楼主 | 2013-3-28 10:04 | 只看该作者
qin552011373 发表于 2013-3-27 22:53
ISP下载线和串口0是共用IO的?没用过像128这么高端的avr

嗯,一个第二功能,一个第三功能,:)

使用特权

评论回复
6
qin552011373| | 2013-3-28 18:50 | 只看该作者
sqjh1988 发表于 2013-3-28 10:04
嗯,一个第二功能,一个第三功能,

先试试看了,不行的话下载完后直接吧isp拔下

使用特权

评论回复
7
sqjh1988|  楼主 | 2013-3-29 10:59 | 只看该作者
qin552011373 发表于 2013-3-28 18:50
先试试看了,不行的话下载完后直接吧isp拔下

试过了,那样也不行,我把波特率改成1200数据就能全部接收了,但是现在必须要用115200的波特率,有什么其他的办法吗

使用特权

评论回复
8
qin552011373| | 2013-3-29 11:01 | 只看该作者
sqjh1988 发表于 2013-3-29 10:59
试过了,那样也不行,我把波特率改成1200数据就能全部接收了,但是现在必须要用115200的波特率,有什么其 ...

是不是因为干扰?换根有屏蔽的线或者比较短的线试试

使用特权

评论回复
9
sqjh1988|  楼主 | 2013-3-29 11:17 | 只看该作者
qin552011373 发表于 2013-3-29 11:01
是不是因为干扰?换根有屏蔽的线或者比较短的线试试

单片机串口和身份*读卡器串口我直接用三根线连得,距离很短的,就是单片机给读卡器发送的指令读卡器有收到,但是读卡器返回的指令单片机没有接收完全,我在网上搜了搜,说有个FIFO缓冲器设置接收字节个数的,会不会是这个问题?但是我这返回值才十五个数据啊,应该够得,都弄了快两个星期了,还是没搞定,快纠结死了。

使用特权

评论回复
10
qin552011373| | 2013-3-29 14:38 | 只看该作者
sqjh1988 发表于 2013-3-29 11:17
单片机串口和身份*读卡器串口我直接用三根线连得,距离很短的,就是单片机给读卡器发送的指令读卡器有收 ...

收一个立即存一个试试

使用特权

评论回复
11
sqjh1988|  楼主 | 2013-3-29 15:06 | 只看该作者
qin552011373 发表于 2013-3-29 14:38
收一个立即存一个试试

发送出去的是一串指令,回来的也是一串指令,串口1接收程序里面就是把接收的数据放到一个数组里,是不是返回值太多,单片机来不及处理,本来应该收到十五个数据的,但是只收到了前两个和最后一个,数据部分貌似全没了,有没有对串口1接收一串数据程序改进的办法,我在网上看的基本上都是这样接收的。

使用特权

评论回复
12
dqyubsh| | 2013-3-29 21:29 | 只看该作者
串行程序写的太简单了,至少也应该是带缓冲操作,更好的方式是遵从MODBUS一类的成熟协议。建议研究一下AVRLIB,这个库有完整的缓冲区操作的函数。貌似官网也有缓冲区操作的例子。

还有,128可以JTAG,而不仅仅是ISP。买个仿真器,往往会事半功倍,极大地提高效率。

使用特权

评论回复
13
qin552011373| | 2013-3-29 22:02 | 只看该作者
void uart_recevice(void)
{
  if(USART_READ() == 0x5a)  //检测数据包头,如果正确则准备开始接收数据
  {                                                        //数据接收的第一位在此已经读出,将从第二位开始接收数据
    i1 = 1;
    ready_receive=1;
  }
  for(;(ready_receive==1) && (i1 < 4);)  //数据包头正确,开始进入数据接收处理函数
  {
    data[i1]=USART_READ();    //接收数据包
    i1++;
  }
  if(data[3] == 0x5b)  //数据包接收完毕,发送接收成功协议
  {
    ready_receive=0;
        USART_Transmit(0x5a);
        USART_Transmit(0x50);
        USART_Transmit(0x00);
        USART_Transmit(0x50);
        USART_Transmit(0x5b);
        }

}

使用特权

评论回复
14
qin552011373| | 2013-3-29 22:03 | 只看该作者
上面是我以前test串口的代码,可以加上包头和包尾,检测正确再存,不正确发命令让重新发

使用特权

评论回复
15
chu888| | 2013-3-30 13:30 | 只看该作者
软件串口可以啊

使用特权

评论回复
16
yhhsky| | 2013-3-30 14:10 | 只看该作者

使用特权

评论回复
17
sqjh1988|  楼主 | 2013-4-1 14:24 | 只看该作者
yhhsky 发表于 2013-3-30 14:10

:loveliness::loveliness::loveliness::loveliness::loveliness::loveliness:

使用特权

评论回复
18
sqjh1988|  楼主 | 2013-4-1 14:40 | 只看该作者
chu888 发表于 2013-3-30 13:30
软件串口可以啊

不明白。。。。

使用特权

评论回复
19
qin552011373| | 2013-4-1 21:28 | 只看该作者
sqjh1988 发表于 2013-4-1 14:32
多谢版主,今天把程序稍微改改重新试了试,就可以了,不知道什么原因呢,可能是我在中断服务函数里面加进 ...

中断里面一般只放一个检测的标志位,都是在主函数里面完成的,恭喜你完成任务,知识和能力又上一层楼

使用特权

评论回复
20
qin552011373| | 2013-4-1 21:56 | 只看该作者
以后欢迎常来  结贴散分吧

使用特权

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

本版积分规则

2

主题

23

帖子

0

粉丝