1036|0

208

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【国民技术车规MCU N32A455开发板】03、熟悉LIN主从机通讯(收发数据) [复制链接]

1.概述

上节我们熟悉了国民技术N32A455的CAN通讯,本节我们来熟悉国民技术N32A455的LIN通讯,在汽车电子组网应用中,通常CAN会作为高速通讯的网络,而LIN则会作为低事通讯的网络,这两个网络相互配合,实现了车机整体的通讯网络。

 

N32A455的LIN其实是基于通用同步异步收发器(USART)的LIN模式实现的,通过RX\TX引脚与LIN收发芯片连接,通过LIN底层通讯协议,实现LIN的数据交互。

 

2.LIN协议

这部分在UM手册上并没有过多的去描述,只提及到了LIN的断开帧;但在我们使用LIN通讯时,必须要先搞懂LIN通讯协议哈,所以网罗了一些LIN的资料,供大家借鉴哦

LIN基础.pdf (871.46 KB, 下载次数: 11)
LIN总线系统简析.pdf (1.14 MB, 下载次数: 9)
LIN 规范 V1.2.pdf (1.14 MB, 下载次数: 8)
LIN-Spec-Pac2-1.pdf (21.56 MB, 下载次数: 16)

 

3.LIN示例程序

依据官方提供的LIN主、从机示例程序,例程功能如下:若接收到主机请求帧(0x3C)会打印接收到的8字节数据(0x0F);若接收到从机应答帧(0x3D)将发送8个字节应答数据(0x01)给到主机节点。

3.1.LIN主机实现

#include "main.h"
#include "lin_master.h"

M_LIN_EX_MSG M_TxMsg;

void SetFrameMsg(M_LIN_EX_MSG *dst_Msg, M_LIN_EX_MSG src_Msg)
{
    int i = 0;
    Memset(dst_Msg, 0, sizeof(M_LIN_EX_MSG));
    dst_Msg->Check = src_Msg.Check;
    dst_Msg->DataLen = src_Msg.DataLen;
    dst_Msg->Sync = src_Msg.Sync;
    dst_Msg->PID = src_Msg.PID;
    for(i = 0; i < src_Msg.DataLen; i++)
    {
        dst_Msg->Data[i] = src_Msg.Data[i];
    }
    log_info("SetFrameMsg ID:0x%02x\r\n", dst_Msg->PID);
}

void SetFramePID(M_LIN_EX_MSG *src_Msg)
{
    uint8_t p0 = 0, p1 = 0;
    uint8_t LIN_ID = src_Msg->PID, PID = 0x00;
    p0 = (LIN_ID & 0x01) ^ ((LIN_ID & 0x02) >> 1) ^ ((LIN_ID & 0x04) >> 2) ^ ((LIN_ID & 0x10) >> 4);//????
    p0 = p0 & 0x01;
    p1 = ~(((LIN_ID & 0x02) >> 1) ^ ((LIN_ID & 0x08) >> 3) ^ ((LIN_ID & 0x10) >> 4) ^ ((LIN_ID & 0x20) >> 5));
    p1 = p1 & 0x01;
    PID = (p1 << 7) | (p0 << 6) | LIN_ID;
    src_Msg->PID = PID;
    log_info("p0 = %02x;p1 = %02x;PID = %02x\r\n", p0, p1, PID);
}

uint8_t MasterGetCheckSum(uint8_t *pData, uint8_t len)
{
    uint16_t check_sum_temp = 0;
    uint8_t i;
    for(i = 0; i < len; i++)
    {
        check_sum_temp += pData[i];
        if(check_sum_temp > 0xFF)
        {
            check_sum_temp -= 0xFF;
        }
    }
    return (~check_sum_temp) & 0xFF;
}

void SetFrameChecksum(M_LIN_EX_MSG *Msg)
{
    uint8_t CheckSum = 0;
    uint8_t len = Msg->DataLen;
    if(Msg->Check)
    {
        CheckSum = MasterGetCheckSum(&Msg->PID, len + 1);
    }
    else
    {
        CheckSum = MasterGetCheckSum(Msg->Data, len);
    }
    if(len < 8)
    {
        Msg->Data[len] = CheckSum;
    }
    else
    {
        Msg->Check = CheckSum;
    }
}

void MasterSendBytes(uint8_t *pBuf, uint8_t Len)
{
    USART_Break_Frame_Send(USARTx);
    while(Len--)
    {
        while(USART_Flag_Status_Get(USARTx, USART_FLAG_TXC ) == RESET);
        USART_Data_Send(USARTx, *pBuf++);
    }
    while(USART_Flag_Status_Get(USARTx, USART_FLAG_TXC ) == RESET);
}

void MasterSendFrame(M_LIN_EX_MSG     Msg)
{
    if(Msg.DataLen)
    {
        MasterSendBytes(&Msg.Sync, Msg.DataLen + 3);
    }
    else
    {
        MasterSendBytes(&Msg.Sync, 2);
    }
}

void FrameHandle(void)
{
    uint8_t tmp_PID  = M_TxMsg.PID;
    SetFramePID(&M_TxMsg);
    switch (tmp_PID)
    {
    case 0x3C://Master request frame
        SetFrameChecksum(&M_TxMsg);
        break;
    case 0x3D://Slave reply frame
        M_TxMsg.DataLen = 0;
        break;
    default:
        break;
    }
    MasterSendFrame(M_TxMsg);
}

static ErrorStatus USART_ByteReceive(uint8_t *Data, uint32_t TimeOut)
{
    uint32_t Counter = 0;
    while((USART_Flag_Status_Get(USARTx, USART_FLAG_RXDNE) == RESET) && (Counter != TimeOut))
    {
        Counter++;
    }
    if(Counter != TimeOut)
    {
        *Data = (uint8_t)USART_Data_Receive(USARTx);
        return SUCCESS;
    }
    else
    {
        return ERROR;
    }
}

uint32_t Master_RecData(uint8_t *pdata, uint8_t length)
{
    int i = 0;
    uint8_t Data = 0;
    uint32_t number = 0;
    while(i < length)
    {
        i++;
        if((USART_ByteReceive(&Data, SC_RECEIVE_TIMEOUT)) == SUCCESS)
        {
            pdata[number] = Data;
            number++;
        }
    }
    return number;
}

ErrorStatus WaitFrameRes(uint8_t *dst_data, uint8_t length)
{
    //int i = 0;
    int datalen = 0;
    uint8_t recv_data[16];
    uint8_t CheckSum = 0;
    datalen = Master_RecData(recv_data, 16);
    if(datalen)
    {
#if 0
        log_info("recv_data:");
        for(i = 1; i < datalen; i++)
        {
            log_info("0x%x\r\n", recv_data[i]);
        }
#endif
        CheckSum = MasterGetCheckSum(recv_data, datalen - 1);
        log_info("CheckSum:0x%x\r\n", CheckSum);
        if(CheckSum == recv_data[datalen - 1])
        {
            if( (datalen - 2) > length)
            {
                Buffercopy(dst_data, &recv_data[0], length);
            }
            else
            {
                Buffercopy(dst_data, &recv_data[0], datalen - 1);
            }
            return SUCCESS;
        }
    }
    return ERROR;
}

void TestMasterReqFrame(void)
{
    int i = 0;
    M_LIN_EX_MSG CurLINTxMsg;
    CurLINTxMsg.Check = CLASSIC;
    CurLINTxMsg.DataLen = 8;
    CurLINTxMsg.Sync = 0x55;
    CurLINTxMsg.PID = 0x3C;
    for(i = 0; i < CurLINTxMsg.DataLen; i++)
    {
        CurLINTxMsg.Data[i] = 0x0F;
    }
    SetFrameMsg(&M_TxMsg, CurLINTxMsg);
    FrameHandle();

}

void TestSlaveResFrame(void)
{
    M_LIN_EX_MSG CurLINTxMsg;
    CurLINTxMsg.Check = CLASSIC;
    CurLINTxMsg.DataLen = 0;
    CurLINTxMsg.Sync = 0x55;
    CurLINTxMsg.PID = 0x3D;
    SetFrameMsg(&M_TxMsg, CurLINTxMsg);
    FrameHandle();
}

void TestLinMaster(void)
{
    int i = 0, count = 0;
    uint8_t recv_data[8];
    TestMasterReqFrame();
    delay_xms(20);
    while(count < 4)
    {
        Memset(recv_data, 0, 8);
        TestSlaveResFrame();
        if(WaitFrameRes(recv_data, 8) == SUCCESS)
        {
            log_info("recv_data:\r\n");
            for(i = 0; i < 8; i++)
            {
                log_info("recv_data[%d] = 0x%x\r\n", i, recv_data[i]);
            }
            break;
        }
        else
        {
            log_info("slave no response!!\r\n");
            count++;
        }
    }
}


#include <stdio.h>
#include "main.h"



static uint8_t max_ms = 116;
/**
*\*\name    delay_xms.
*\*\fun     delay program.
*\*\param   nms
*\*\return  none
**/
void delay_xms(uint32_t nms)
{
    uint16_t i;
    uint16_t count_1 = nms / max_ms;
    uint16_t count_2 = nms % max_ms;
    if(0 == count_1)
    {
        systick_delay_ms(nms);
    }
    else
    {
        for(i = 0; i < count_1; i++)
        {
            systick_delay_ms(max_ms);
        }
        if(count_2 != 0)
        {
            systick_delay_ms(count_2);
        }
    }
}

/**
*\*\name    Memset.
*\*\fun     memery set a value.
*\*\param   s source
*\*\param   c value
*\*\param   count number
*\*\return  s
**/
void *Memset(void *s, s8 c, u32 count)
{
    s8 *xs = (s8 *) s;
    while (count--)         // clear 17byte buffer
    {
        *xs++ = c;
    }
    return s;
}

/**
*\*\name    Buffercopy.
*\*\fun     Compares two buffers.
*\*\param   pBuffer1
*\*\param   pBuffer2
*\*\param   buffer's length
*\*\return  s
**/
void Buffercopy(uint8_t *dest, uint8_t *src, uint16_t BufferLength)
{
    while (BufferLength--)
    {
        *dest = *src;
        dest++;
        src++;
    }
}

/**
*\*\name    main.
*\*\fun     Main program.
*\*\param   none
*\*\return  none
**/
int main(void)
{

    USART_InitType USART_InitStructure;    

    log_init();
    printf("\r\n test LIN master mode\r\n");

    /* System Clocks Configuration */
    RCC_Configuration();

    /* NVIC configuration */
    NVIC_Configuration();

    /* Configure the GPIO ports */
    GPIO_Configuration();

    /* USARTx configuration ------------------------------------------------------*/
    USART_InitStructure.BaudRate            = 9600;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    /* Configure USARTx */
    USART_Initializes(USARTx, &USART_InitStructure);
    /* Enable the USARTx LIN mode*/
    USART_LIN_Break_Detect_Length_Set(USARTx,USART_LINBDL_10B);
    USART_LIN_Enable(USARTx);
    /* Enable the USARTx */
    USART_Enable(USARTx);

    while (1)
    {
        TestLinMaster();
        delay_xms(500);
    }
}

/**
*\*\name    RCC_Configuration.
*\*\fun     Configures the different system clocks.
*\*\param   none
*\*\return  none
**/
void RCC_Configuration(void)
{
    /* Enable GPIO clock */
    GPIO_AHBClkCmd(USARTx_GPIO_CLK);
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);

    /* Enable USARTx Clock */
    USART_APBxClkCmd(USARTx_CLK);
}

/**
*\*\name    NVIC_Configuration.
*\*\fun     Configures the nested vectored interrupt controller.
*\*\param   none
*\*\return  none
**/
void NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;

    NVIC_Priority_Group_Set(NVIC_PER2_SUB2_PRIORITYGROUP);
    /* Enable the USARTx Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USARTx_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);

}

/**
*\*\name    GPIO_Configuration.
*\*\fun     Configures the different GPIO ports.
*\*\param   none
*\*\return  none
**/
void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;

    /* Initialize GPIO_InitStructure */
    GPIO_Structure_Initialize(&GPIO_InitStructure);    

    /* Configure USARTx Tx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTx_TxPin;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Tx_GPIO_AF;
    GPIO_Peripheral_Initialize(USARTx_GPIO, &GPIO_InitStructure);   

    /* Configure USARTx Rx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTx_RxPin;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Rx_GPIO_AF;
    GPIO_Peripheral_Initialize(USARTx_GPIO, &GPIO_InitStructure); 
}

 

3.2.LIN从机实现

#include "main.h"
#include "lin_driver.h"

LIN_STATE LinRxState = IDLE;
uint8_t LINRxDataIndex = 0;
LIN_EX_MSG LINRxDataBuffer[2];//双缓冲接收数据,可以减少数据出错概率
uint8_t IDType[64] = {ID_TYPE_SR};
uint8_t GotMsgFlag = 0;
LIN_EX_MSG *pLINMsg;
LIN_EX_MSG LINTxMsg;

void LIN_SendBytes(uint8_t *pBuf, uint8_t Len)
{
    while(Len--)
    {
        while(USART_GetFlagStatus(USARTz, USART_FLAG_TXC ) == RESET);
        USART_SendData(USARTz, *pBuf++);
    }
    while(USART_GetFlagStatus(USARTz, USART_FLAG_TXC ) == RESET);
}

uint8_t LIN_GetCheckSum(uint8_t *pData, uint8_t len)
{
    uint16_t check_sum_temp = 0;
    uint8_t i;
    for(i = 0; i < len; i++)
    {
        check_sum_temp += pData[i];
        if(check_sum_temp > 0xFF)
        {
            check_sum_temp -= 0xFF;
        }
    }
    return (~check_sum_temp) & 0xFF;
}

void LIN_SetResp(uint8_t ID, uint8_t *pData, uint8_t Len, uint8_t CheckType)
{
    uint8_t i = 0;
    uint8_t CheckSum = 0;
    if(Len > 8)
    {
        Len = 8;
    }
    LINTxMsg.PID = GET_PID(ID);
    for(i = 0; i < Len; i++)
    {
        LINTxMsg.Data[i] = pData[i];
    }
    if(CheckType)
    {
        CheckSum = LIN_GetCheckSum(&LINTxMsg.PID, Len + 1);
    }
    else
    {
        CheckSum = LIN_GetCheckSum(LINTxMsg.Data, Len);
    }
    if(Len < 8)
    {
        LINTxMsg.Data[Len] = CheckSum;
    }
    else
    {
        LINTxMsg.Check = CheckSum;
    }
    LINTxMsg.DataLen = Len;
}

void LIN_EX_RxAsync(uint8_t data)
{
    switch(LinRxState)
    {
    case IDLE:
        break;
    case SYNCH:
        if(data == 0x55)
        {
            LINRxDataBuffer[LINRxDataIndex].Sync = 0x55;
            LinRxState = ID_LEN;
        }
        else
        {
            LinRxState = IDLE;
        }
        break;
    case ID_LEN:
        if(GET_PID(data) == data)
        {
            LINRxDataBuffer[LINRxDataIndex].PID = data;
            LINRxDataBuffer[LINRxDataIndex].DataLen = 0;
            if(IDType[data & 0x3F] == ID_TYPE_SR)
            {
                LinRxState = DATA_GET;
            }
            else
            {
                //接收到主机发送的帧头,从机模式发送数据
                if(((LINTxMsg.PID & 0x3F) == (data & 0x3F)) && (LINTxMsg.DataLen > 0))
                {
                    LIN_SendBytes(LINTxMsg.Data, LINTxMsg.DataLen + 1);
                    LINTxMsg.DataLen = 0;
                }
                LinRxState = IDLE;
            }
        }
        else
        {
            LinRxState = IDLE;
        }
        break;
    case DATA_GET:
        LINRxDataBuffer[LINRxDataIndex].Data[LINRxDataBuffer[LINRxDataIndex].DataLen] = data;
        LINRxDataBuffer[LINRxDataIndex].Check = data;
        LINRxDataBuffer[LINRxDataIndex].DataLen++;
        if(LINRxDataBuffer[LINRxDataIndex].DataLen >= 8)
        {
            LinRxState = CHECKSUM;
        }
        else
        {
            LinRxState = DATA_GET;
        }
        break;
    case CHECKSUM:
        LINRxDataBuffer[LINRxDataIndex].Check = data;
        pLINMsg = &LINRxDataBuffer[LINRxDataIndex];
        GotMsgFlag = 1;
        LINRxDataIndex = (LINRxDataIndex + 1) % 2;
        LinRxState = IDLE;
        break;
    default:
        break;
    }
}

void LIN_IRQHandler(void)
{
    //BREAK中断
    if(USART_GetIntStatus(USARTz, USART_INT_LINBD) == SET)
    {
        USART_ClrIntPendingBit(USARTz, USART_INT_LINBD);//清除LIN间隔场检测标志位
        //读状态寄存器和数据寄存器是为了清除FE标志
        USARTz->STS;
        USARTz->DAT;
        LinRxState = SYNCH;
        return;
    }
    //接收数据中断
    if (USART_GetIntStatus(USARTz, USART_INT_RXDNE)  == SET)
    {
        USART_ClrIntPendingBit(USARTz, USART_INT_RXDNE); //清除接收中断标志位
        if(USART_GetIntStatus(USARTz, USART_INT_FEF) == RESET)
        {
            LIN_EX_RxAsync((uint8_t)USART_ReceiveData(USARTz));
        }
    }
}

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] 执行主机下发的命令
  * @param  pData 收到的数据,该函数会默认读取8字节数据
  * @param  pFunResp 命令响应函数指针,需要自己实现
  * @retval 无
  */
void BOOT_ExecutiveCommand(uint8_t *pData, FUN_RESP pFunResp)
#if 1
{
    int i = 0;
    log_info("BOOT_ExecutiveCommand\r\n");
    for( i = 0; i < 8; i++)
    {
        log_info("pData[%d] = %02x \r\n", i, pData[i]);
        pData[i] = 0x1;
    }
    pFunResp(pData, 8);
}
#endif


#include <stdio.h>
#include "main.h"

/** @addtogroup N32A45X_StdPeriph_Examples
 * @{
 */
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

static uint8_t max_ms = 116;
extern uint8_t IDType[64];
extern uint8_t GotMsgFlag;
extern LIN_EX_MSG *pLINMsg;

void delay_xms(uint32_t nms)
{
    uint16_t i;
    uint16_t count_1 = nms / max_ms;
    uint16_t count_2 = nms % max_ms;
    if(0 == count_1)
    {
        systick_delay_ms(nms);
    }
    else
    {
        for(i = 0; i < count_1; i++)
        {
            systick_delay_ms(max_ms);
        }
        if(count_2 != 0)
        {
            systick_delay_ms(count_2);
        }
    }
}

/**
 * @brief  Compares two buffers.
 * @param  pBuffer1, pBuffer2: buffers to be compared.
 * @param BufferLength buffer's length
 * [url=home.php?mod=space&uid=784970]@return[/url] PASSED: pBuffer1 identical to pBuffer2
 *         FAILED: pBuffer1 differs from pBuffer2
 */
void Buffercopy(uint8_t *dest, uint8_t *src, uint16_t BufferLength)
{
    while (BufferLength--)
    {
        *dest = *src;
        dest++;
        src++;
    }
}

void LIN_RespData(uint8_t *pData, uint8_t Len)
{
    LIN_SetResp(MSG_SEND_ID, pData, Len, CHECK_TYPE);
}

/**
 * @brief  Main program
 */
int main(void)
{
    USART_InitType USART_InitStructure;
    log_init();
    printf("\r\n test LIN slave mode\r\n");
    /* System Clocks Configuration */
    RCC_Configuration();
    /* NVIC configuration */
    NVIC_Configuration();
    /* Configure the GPIO ports */
    GPIO_Configuration();
    /* USARTy and USARTz configuration ------------------------------------------------------*/
    USART_InitStructure.BaudRate            = 9600;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    /* Configure USARTy and USARTz */
    USART_Init(USARTz, &USART_InitStructure);
    /* Enable the USARTz LIN mode*/
    USART_ConfigLINBreakDetectLength(USARTz, USART_LINBDL_10B);
    USART_EnableLIN(USARTz, ENABLE);
    /* Enable USARTz Receive and Transmit interrupts */
    USART_ConfigInt(USARTz, USART_INT_RXDNE, ENABLE);
    //USART_ConfigInt(USARTz, USART_INT_TXDE, ENABLE);
    USART_ConfigInt(USARTz, USART_INT_LINBD, ENABLE);
    /* Enable the USARTz */
    USART_Enable(USARTz, ENABLE);
    //配置从机ID模式
    IDType[MSG_RECEIVE_ID & 0x3F] = ID_TYPE_SR;
    IDType[MSG_SEND_ID & 0x3F] = ID_TYPE_SW;
    while (1)
    {
        if(GotMsgFlag)
        {
            BOOT_ExecutiveCommand(pLINMsg->Data, LIN_RespData);
            GotMsgFlag = 0;
        }
    }
}

/**
 * @brief  Configures the different system clocks.
 */
void RCC_Configuration(void)
{
    /* Enable GPIO clock */
    RCC_EnableAPB2PeriphClk(USARTz_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
    /* Enable  USARTz Clock */
    USARTz_APBxClkCmd(USARTz_CLK, ENABLE);
}

/**
 * @brief  Configures the different GPIO ports.
 */
void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;
    /* Configure USARTz Rx as input floating */
    GPIO_InitStructure.Pin = USARTz_RxPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);
    /* Configure USARTz Tx as alternate function push-pull */
    GPIO_InitStructure.Pin = USARTz_TxPin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitPeripheral(USARTz_GPIO, &GPIO_InitStructure);
    
    /* Configure TJA1027 SLP as ouput  push-pull */
    GPIO_InitStructure.Pin = SLP_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitPeripheral(SLP_GPIO, &GPIO_InitStructure);
    GPIO_SetBits(SLP_GPIO,SLP_Pin);
    
#ifdef _USART2_   
    GPIO_ConfigPinRemap(GPIO_RMP3_USART2, ENABLE);
    GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_NO_NJTRST, ENABLE);
#endif
#ifdef _USART4_   
    GPIO_ConfigPinRemap(GPIO_RMP3_UART4, ENABLE);
#endif    
    
}

/**
 * @brief  Configures the nested vectored interrupt controller.
 */
void NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USARTz Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USARTz_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}



#ifdef USE_FULL_ASSERT

/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param file pointer to the source file name
 * @param line assert_param error line source number
 */
void assert_failed(const uint8_t *expr, const uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    while (1)
    {
    }
}

#endif

 

4.测试

4.1.测试环境

由于没有2块N32A455开发板,所以我找了一块N32G430C8L7_STB_V1.0开发板作为LIN主机,搭配N32A455开发板作为LIN从机一起测试;但是N32G430C8L7_STB_V1.0开发板上并没有板载LIN收发芯片,所以我们还是通过交叉连接USART的RX和TX,对LIN的通讯功能进行测试,毕竟功能OK,其它只是固定的外围硬件电路,关系不大!

 

4.2.测试结果

 

5.注意事项

5.1、当使用N32A455的USART作为LIN模式通讯时,以下配置位必须全部被清零 :USART_CTRL2.STPB[1:0] 、USART_CTRL2.CLKEN 、USART_CTRL3.SCMEN 、USART_CTRL3.HDMEN 、USART_CTRL3.IRDAMEN。

5.2.在 LIN 模式下发送数据时,数据长度只能配置为 8 位。

此帖出自汽车电子论坛
点赞 关注
个人签名We are a team and we work as a team !

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表