1223619_ja-JP

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

1223619_ja-JP

1223619_ja-JP

LPC55S16 LINの基本的な使用例

はじめに

この例の目的は、1つのデバイスがマスタとして、もう1つのデバイスがスレーブとして動作する2つのデバイス間の基本的なLIN通信を示すことです。この例で使用する2つのデバイスはLPC55S16 EVKです。

LINマスタは特定のパブリッシャ・フレームとサブスクライバ・フレームを送信します。LINスレーブはマスタデータを検出し、それに応じてデータをフィードバックします。

この記事では主にソフトウェア側に焦点を当てます。ハードウェアについてはhttps://community.nxp.com/t5/LPC-Microcontrollers-Knowledge/LPC54608-LIN-master-basic-usage-sharing/...をご参照ください。

LINマスタの例

LINマスタはLINパブリッシャ・データとサブスクライバIDデータを送信します。ソフトウェアのコードはSDK_2.8.2_LPCXpresso55S16 usart_interrupt_rb_transferプロジェクトから変更されています。コードの詳細は以下のとおりです。

/* USART callback */
void FLEXCOMM3_IRQHandler()
{
	  if(DEMO_USART->STAT & USART_STAT_RXBRK_MASK) // detect LIN break
	     {
	       Lin_BKflag = 1;
	       cnt = 0;
	       state = RECV_DATA;
	       DisableLinBreak;
	     }
	    if((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
	     {
	       USART_ClearStatusFlags(DEMO_USART,kUSART_TxError | kUSART_RxError);
	    	 rxbuff[cnt] = USART_ReadByte(DEMO_USART);;

	         switch(state)
	         {
	            case RECV_SYN:
	                          if(0x55 == rxbuff[cnt])
	                          {
	                              state = RECV_PID;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_PID:
	                          if(0xAD == rxbuff[cnt])
	                          {
	                              state = SEND_DATA;
	                          }
	                          else if(0XEC == rxbuff[cnt])
	                          {
	                              state = RECV_DATA;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_DATA:
	                         Sub_rxbuff[recdatacnt++]= rxbuff[cnt];
	                          if(recdatacnt >= 3) // 2 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	            case SEND_DATA:
	                          recdatacnt++;
	                          if(recdatacnt >= 4) // 2 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	         default:break;
	         }
	         cnt++;
	     }


	    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
	      exception return operation might vector to incorrect interrupt */
	#if defined __CORTEX_M && (__CORTEX_M == 4U)
	    __DSB();
	#endif
}

void Lin_Master_Publisher(void)
{
    unsigned int i=0;
    unsigned char ch =0xa0;//dummy byte
//===============================LIN master send=====================

       DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
       while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
      	 USART_WriteBlocking(DEMO_USART,&ch,1);//dummy data

            break;  //just send one byte, otherwise, will send 16 bytes
        }
       DEMO_USART->CTL &= ~(USART_CTL_TXBRKEN_MASK); //disable TX break

       // Send the sync byte 0x55.
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X55);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
       //protected ID
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0Xad);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data1
       while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X01);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data2
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X02);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        //Data3
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X03);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
        // checksum byte
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X4c);//0X4c
            break;  //just send one byte, otherwise, will send 16 bytes
        }

}

void Lin_Master_Subscribe(void)
{
  unsigned int i=0;

unsigned char ch=0xf0;//dummy byte

     DEMO_USART->CTL |= USART_CTL_TXBRKEN_MASK;//enable TX break;
     while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
      {
    	 USART_WriteBlocking(DEMO_USART,&ch,1);

          break;  //just send one byte, otherwise, will send 16 bytes
      }
       DEMO_USART->CTL &= ~(USART_CTL_TXBRKEN_MASK); //disable TX break

       // Send the syncy byte 0x55.
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X55);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
       //protected ID
        while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
        {
            USART_WriteByte(DEMO_USART, 0X3C);
            break;  //just send one byte, otherwise, will send 16 bytes
        }
	       state = RECV_DATA;
}

ここでの主なタスクはLIN breakフィールドの生成と検出でした。

詳しく見てみましょう。パブリッシャおよびサブスクライバ・フレームにLIN breakフィールドを生成するには、まずTx breakを設定し、次にダミーのバイトを送信してからTx breakを無効にします。ダミー・バイトの送信に使用される関数はUSART_WriteBlockingで、USART_WriteByteはダミー・バイト以外のデータ送信に使用されるものです。これは、ダミー・バイトの中でUSART_WriteByteを使用すると他の例のように連続したlowにならなかったためです。この理由はまだ判明していません。分かり次第こちらに更新いたします。


LINスレーブの例

LINスレーブはマスタからLINパブリッシャ・データとサブスクライバIDデータを受信し、必要に応じて応答します。ソフトウェアのコードはSDK_2.8.2_LPCXpresso55S16 usart_interrupt_rb_transferプロジェクトから変更されています。詳細なコードは以下の通りです。

void FLEXCOMM3_IRQHandler()
{
 if(DEMO_USART->STAT & USART_STAT_RXBRK_MASK) // detect LIN break
	     {
	       Lin_BKflag = 1;
	       cnt = 0;
	       state = RECV_SYN;
	       DisableLinBreak;
	     }

	    if((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
	     {
	       USART_ClearStatusFlags(DEMO_USART,kUSART_TxError | kUSART_RxError);
	    	 rxbuff[cnt] = USART_ReadByte(DEMO_USART);;

	         switch(state)
	         {
	            case RECV_SYN:
	                          if(0x55 == rxbuff[cnt])
	                          {
	                              state = RECV_PID;
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_PID:
	                          if(0xAD == rxbuff[cnt])
	                          {
	                              state = RECV_DATA;
	                          }
	                          else if(0X3C == rxbuff[cnt])
	                          {
	                              state = SEND_DATA;
	                              senddata();
	                          }
	                          else
	                          {
	                              state = IDLE;
	                              DisableLinBreak;
	                          }
	                          break;
	            case RECV_DATA:
	                          recdatacnt++;
	                          if(recdatacnt >= 4) // 3 Bytes data + 1 Bytes checksum
	                          {
	                              recdatacnt=0;
	                              state = RECV_SYN;
	                              EnableLinBreak;
	                          }
	                          break;
	         default:break;

	         }

	         cnt++;
	     }


	    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
	      exception return operation might vector to incorrect interrupt */
	#if defined __CORTEX_M && (__CORTEX_M == 4U)
	    __DSB();
	#endif
}

void senddata(void)
{
	        {

	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X01);
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }
	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X02);
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }
	         while (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(DEMO_USART))
	         {
	             USART_WriteByte(DEMO_USART, 0X10);// 0X10 correct 0Xaa wrong
	             break;  //just send one byte, otherwise, will send 16 bytes
	         }

	           recdatacnt=0;
	           state = RECV_SYN;
	           EnableLinBreak;
	        }
}

ここにマスターとスレーブのコードを添付いたします。

お役に立てば幸いです。

LPC55xx
Tags (1)
No ratings
Version history
Last update:
‎01-05-2026 02:00 AM
Updated by: