打印
[AVR单片机]

AVR里如何用485接收一个数组(一组数据包)?

[复制链接]
1254|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chongchudb|  楼主 | 2015-9-30 20:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 chongchudb 于 2015-10-6 15:19 编辑

目前可以发送一个数组,或者接受一个十六进制数。想接收一个发送来的数组却怎么都不行。
// 发送的数据为: B4 B5 04 00 01 31 03 0B
uchar i=0,j=0;
uchar recei[8];   
/*主函数里面的大循环*/
    while(1)
     {
                     if(i < 8)        
                   {
                                   temp = receive1();    //receive1()为接收函数
                                  recei[i++] = temp;
                                   delay();                                                                                                               
                   }
                   delay();
                      for(j = 0; j <= i; j++)
                                   putchar1(recei[j]);     // putchar1为发送函数
        }        
// 接收到的数据是:B4 00 B4 B5 00 B4 B5 0B 00      
求解。。         



相关帖子

沙发
SD10A| | 2015-10-1 10:54 | 只看该作者
发送的时候   注意是写0XB4

使用特权

评论回复
板凳
元方义城| | 2015-10-8 15:15 | 只看该作者
接收处理写在中断里就可以了,例如这样:#pragma interrupt_handler uart_rx0:19
void uart_rx0(void)
{
    static uchar EP;
        String0[EP]=UDR0;
        EP++;
        if(String0[0]!=0xB4)
        {
          EP=0;
        }
        if(EP==9)  //String0[EP]==0x03&&
        {
         EP=0;
         flag0=1;
        }  
}
在while主循环中只要判断flag0是不是等于1就可以了。接收数组量随便你弄多少个

使用特权

评论回复
地板
chongchudb|  楼主 | 2015-10-8 20:39 | 只看该作者
SD10A 发表于 2015-10-1 10:54
发送的时候   注意是写0XB4

发送的时候,勾选上了“十六进制发送”。
还有的是,我的程序有的时候发送后,最多只能接收4组数据,而且是:第1位、第2位、第3位和最后一位。(例如:发送B4 B5 04 00 01 31 03 0B,接收的只能是:B4 B5 04 0B)。。。感觉好尴尬,这是怎么回事?

使用特权

评论回复
5
chongchudb|  楼主 | 2015-10-8 20:53 | 只看该作者
元方义城 发表于 2015-10-8 15:15
接收处理写在中断里就可以了,例如这样:#pragma interrupt_handler uart_rx0:19
void uart_rx0(void)
{

我用的128接收中断,所以中断参照你给的是这么写的。
#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
void uart1_rx_isr(void)
{
         static uchar EP;
         recei[EP++] = receive1();                                    // 串口【接收】发送的数据                       
         delay();

     if(recei[0]!= 0xB4)
     {            EP = 0;     }
     if(EP == 9)  
     {     EP = 0;      flag0 = 1;     }
}

主函数是这么写的。
void main(void)
{
         init_devices();       // 端口初始化
         delay();                                                                 //延时         
         while(1)
          {
                     RS485_UNEN;                                            // 将MAX485切换到【接收】数据模式
                    RS485UNEN_DDR;                                                         
                   if(flag0 == 1)
                   {                          
                         RS485_EN;                                           // 将MAX485切换到【发送】数据模式
                        putchar1(recei[EP++]);                   // 发送数据
                       delay();                  
                   }
          }                                 
}
现在发送完,什么都不接收了:'(哪里不对的。。

使用特权

评论回复
评论
SD10A 2015-10-11 10:36 回复TA
中断接收的时候要选对中断向量,同时 是UDR0 UDR1也要弄对, 
SD10A 2015-10-11 09:59 回复TA
EP是中断中的局部变量,你放在main函数里编译能通过?? 
6
元方义城| | 2015-10-10 09:28 | 只看该作者
chongchudb 发表于 2015-10-8 20:53
我用的128接收中断,所以中断参照你给的是这么写的。
#pragma interrupt_handler uart1_rx_isr:iv_USART1_ ...

首先没有数据接收,你要查原因出在哪,建议一开始不要用485,直接用串口助手看单片机是否发送正确。还有你的使能部分中断使能,IO使能都要查。

使用特权

评论回复
7
SD10A| | 2015-10-11 10:31 | 只看该作者
简单写了下,没有编译,你试验下
volatile uchar EP=0;


#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC

void uart1_rx_isr(void)
{
       uchar tmp=0;
        tmp=UDR0;
       if((EP==0)&&tmp==0xB4)
        {
          recei[0]=tmp;
           EP++;
         }
        else
               {   
                                     if((EP==0) && (tmp != 0xB4))
                             return;//若接收的不是0xB4,则接收数据有问题,不保存,直接抛弃。
                    if((EP>0) && (EP<8))  //EP在1-7中  就是已经保存过协议头0xB4了,接着保存数据就好了
                              {
                                recei[EP==tmp;
                              EP++;
                              }
                        else   //大于等于8。此处不会=0,因为等于0的情况在前面已经做处理了
                                            {
                                              EP = 0;      flag0 = 1;   
                                            }       
                }
      
      
}

主函数是这么写的。
void main(void)
{
         init_devices();       // 端口初始化
         delay();                                                                 //延时         
         while(1)
          {  
RS485UNEN_DDR;
                     RS485_UNEN;                                            // 将MAX485切换到【接收】数据模式
                                                                           
                   if(flag0 == 1)
                   {                          
                         RS485_EN;                                           // 将MAX485切换到【发送】数据模式
                        putchar1(recei[EP++]);                   // 发送数据
                       delay();                  
                   }
          }                                 
}


使用特权

评论回复
8
tian111111| | 2015-10-18 13:52 | 只看该作者
这个可以用MDOBUS协议的吧

使用特权

评论回复
9
chongchudb|  楼主 | 2015-10-19 13:14 | 只看该作者
tian111111 发表于 2015-10-18 13:52
这个可以用MDOBUS协议的吧

可以举个MODBUS的例子吗?我看了Modbus的原理,但是用起来还是不会用

使用特权

评论回复
10
tian111111| | 2015-10-25 22:46 | 只看该作者
我也没学会呢 正在学  就是有两个校验码 比如你发送  01 02 03 后面带校验码  CRC或者其他 两个字节  是用前面的数据 代入多项式得出来的  其实原理很简单

使用特权

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

本版积分规则

3

主题

13

帖子

0

粉丝