Problème d'échec d'envoi ou de réception du bus CAN

Problème d'échec d'envoi ou de réception du bus CAN

Rencontré un tel problème lors du débogage: lors de l'utilisation de l' analyseur de bus CAN pour recevoir les données envoyées par la carte de débogage, les données ne peuvent pas être reçues. Mais le programme a eu un autre tableau similaire et tout était normal.

Analyse des causes

Étant donné que le programme ne pose aucun problème, j'ai pensé que c'était un problème matériel, donc la vérification des problèmes suivante a été lancée

  • Si le circuit de la carte de circuit imprimé est mal connecté, en particulier si RX et TX sont connectés à l'envers, si CANH et CANL sont connectés à l'envers et s'ils sont court-circuités
  • L'alimentation électrique de l'émetteur-récepteur est-elle normale?

Après inspection, aucun des problèmes ci-dessus n'a été détecté, utilisez donc un oscilloscope pour mesurer le niveau du bus

Insérez la description de l'image ici
Insérez la description de l'image ici

  • On constate qu'il y a un saut de niveau indiquant qu'il ne s'agit pas d'un problème de circuit matériel. Mon débit en bauds est de 125 Kbps, donc le temps de bit est de 8 microsecondes, donc la structure du message ci-dessus a 7 bits dominants et 11 bits récessifs, ce qui devrait être une trame d'erreur; mais après un certain temps, la forme d'onde change comme indiqué ci-dessous:

Insérez la description de l'image ici
Insérez la description de l'image ici
Le message devient un niveau dominant et récessif 25. Je ne sais toujours pas quel est ce format de niveau.

Problème logiciel

Puisqu'il n'y a aucun problème avec le matériel, commencez par le logiciel.

/*************************************************************/
/*                       CAN发送                            */
/*************************************************************/
Bool MSCANSendMsg(struct can_msg msg)
{
    
    
  unsigned char send_buf, sp;
    unsigned char num;    
   if(msg.len > 8)     // 检查数据长度
    return(FALSE);      //返回true和false所以要用bool型,在以后 if(fucn(x,y))//可以用来作if语句的判断,while(fucn(x,y))//也可以做循环条件的判断
  // 检查总线时钟是否同步
  if(CANCTL0_SYNCH==0)
    return(FALSE);
send_buf = 0;
  do
  {
    
    
    CANTBSEL=CANTFLG;      // 寻找空闲的缓冲器
    send_buf=CANTBSEL;//等待该寄存器有值,即等待相关报文缓冲器为空
    num++;
    if(num>10)
    break;
  }
  while(!send_buf); 
  // 写入标识符
  CANTIDR0 = (unsigned char)(msg.id>>3);//id为8位
  CANTIDR1 = (unsigned char)(msg.id<<5);
  
   if(msg.RTR)                 //Remote Transmission Request 远程传输请求
    // RTR = 阴性
    CANTIDR1 |= 0x10;
    
  // 写入数据
  for(sp = 0; sp < msg.len; sp++)
    *((&CANTDSR0)+sp) = msg.data[sp];//数据段寄存器,包含将要发送的数据

  // 写入数据长度
  CANTDLR = msg.len; 
  
  // 写入优先级
  CANTTBPR = msg.prty;         //ransmit Buffer Priority Register (TBPR)
  
  // 清 TXx 标志 (缓冲器准备发送)
  CANTFLG = send_buf;
  
  return(TRUE);
  
}

Lors du débogage, le programme entre toujours dans la boucle do while de recherche de tampons libres et ne peut pas sauter, donc une variable num est définie pour la faire augmenter à 10 et sauter hors de la boucle; mais cela ne fonctionne toujours pas , donc Je veux commencer par le programme d'initialisation CAN :

/*************************************************************/
/*                        初始化CAN                         */
/*************************************************************/

void INIT_CAN(void) //按照dz60寄存器改编的程序
{
    
    
  if(CANCTL0_INITRQ==0)      // 查询是否进入初始化状态   
    CANCTL0_INITRQ =1;        // 进入初始化状态

  while (CANCTL1_INITAK==0);  //等待进入初始化状态,初始化模式确认

  CANBTR0_SJW = 3;            //设置同步跳转宽度,总线计时寄存器,现在设为4
  CANBTR0_BRP = 3  ;            //设置波特率预分频器-prescaler value ,
  CANBTR1_TSEG_10 = 6;
  CANBTR1_TSEG_20 = 7;
        //设置时段1-7个和时段2-8个的Tq个数 ,总线频率为125kb/s,1/125K=bit time=(prescaler value)*(1+tseg1+tseg2)/Fcanclk=4*(7+8+1)/8M

// 关闭滤波器                                  
  CANIDMR0 = 0xFF;//不比较
  CANIDMR1 = 0xFF;
  CANIDMR2 = 0xFF;
  CANIDMR3 = 0xFF;
  CANIDMR4 = 0xFF;
  CANIDMR5 = 0xFF;
  CANIDMR6 = 0xFF;
  CANIDMR7 = 0xFF; 

  CANCTL1 = CANCTL1_CLKSRC_MASK | CANCTL1_CANE_MASK;             //使能MSCAN模块,设置为一般运行模式、使用总线时钟源 环回自测禁止
  

  CANCTL0 = 0x00;             //返回一般模式运行

  while(CANCTL1_INITAK);      //等待回到一般运行模式

  while(!CANCTL0_SYNCH);    //等待总线时钟同步

  CANRIER_RXFIE = 0;          //禁止接收中断
}

Changé deux positions

  • Modification de la largeur du saut de synchronisation en première position
 CANBTR0_SJW = 3;            //设置同步跳转宽度,总线计时寄存器,现在设为4

La largeur de saut de synchronisation est la limite supérieure de l'augmentation ou de la diminution du temps dans le segment de tampon afin de trouver la synchronisation dans le mécanisme de bus CAN. La base de la communication dans le bus est que le débit en bauds de chaque nœud est le même, mais le débit en bauds de chaque nœud ne peut pas être le même à 100%, de sorte que le bus CAN permet une légère déviation du débit en bauds de chaque nœud, et le réglage fin du temps de bit La vitesse de transmission peut être ajustée pour rendre le nœud cohérent avec la vitesse de transmission du bus. Par conséquent, plus la largeur du saut de synchronisation est grande, plus la plage de fluctuation de la vitesse de transmission est grande et plus le défaut est élevé taux de tolérance La vitesse de transmission requise pour le nœud est plus lâche.

  • La deuxième position change la durée du segment tampon un et du segment tampon deux
  CANBTR1_TSEG_10 = 6;
  CANBTR1_TSEG_20 = 7;

Réglez la durée du segment de tampon 1 à 7 Tq et la durée du segment de tampon 2 à 8 Tq, de sorte que le point d'échantillonnage soit au milieu du bit, ce qui est bon pour l'échantillonnage

  • Les données peuvent être bien reçues lors du débogage à nouveau:

Insérez la description de l'image ici

  • Résumé :

Je dois avoir un certain degré de jugement. Quand j'ai détecté une transition de niveau sur le bus pendant le débogage, je soupçonnais toujours qu'il s'agissait d'un problème matériel et j'ai perdu beaucoup de temps sur le circuit imprimé. Je ne m'attendais pas à changer de programme . Essayez de partir de directions différentes, n'utilisez pas la même méthode pour obtenir la même conclusion erronée.

Je suppose que tu aimes

Origine blog.csdn.net/xiaobaoAlex/article/details/103675003
conseillé
Classement