【龙芯1c库】封装CAN接口和使用示例

can使用还是比较广泛的,之前有网友在龙芯1b和龙芯1c上已经测试过了在裸机编程中使用CAN接口,这里把他们分享的程序贴上来,供大家参考。

龙芯1b上的测试程序在https://gitee.com/caogos/OpenLoongsonLib1b

龙芯1c上的测试程序在https://gitee.com/caogos/OpenLoongsonLib1c

据说,淘宝上的CAN模块TJA1050可以用。

这里,把龙芯1c的测试程序和封装的接口函数都贴上来

源码

test_can.c

/*
 * File      : test_can.c
测试硬件can驱动
1.test_cansend() 初始化CAN口(100K)后,以速率100K, 发送标准数据帧(1-8 共8个数据)和扩展数据帧(1-8 共8个数据)
2. candump() 打印出当前CAN寄存器值
3. 当收到数据,打印出来。
 */


#include "../lib/ls1c_public.h"
#include "../lib/ls1c_regs.h"
#include "../lib/ls1c_clock.h"
#include "../lib/ls1c_can.h"
#include "../lib/ls1c_pin.h"
#include "../lib/ls1c_irq.h"


CanRxMsg RxMessage;
CanTxMsg TxMessage;

void candump(void)
{
    CAN_TypeDef* CANx;
    unsigned char temp;
    CANx =  CAN0;

    temp =  CANx->MOD;
    printf("\r\ncan0->MOD= 0x%02x  \r\n",temp);   

    temp =  CANx->CMR;
    printf("\ncan0->CMR = 0x%02x  \r\n",temp);  

    temp =  CANx->SR;
    printf("\ncan0->SR = 0x%02x  \r\n",temp); 

    temp =  CANx->IR;
    printf("\ncan0->IR = 0x%02x  \r\n",temp); 

    temp =  CANx->IER;
    printf("\ncan0->IER = 0x%02x  \r\n",temp); 

    temp =  CANx->BTR0;
    printf("\ncan0->BTR0 = 0x%02x  \r\n",temp); 

    temp =  CANx->BTR1;
    printf("\ncan0->BTR1 = 0x%02x  \r\n",temp); 

    temp =  CANx->CDR;
    printf("\ncan0->CDR = 0x%02x  \r\n",temp); 

    temp =  CANx->RMCR;
    printf("\ncan0->RMCR = 0x%02x  \r\n",temp); 

    printf("\r\n验收代码:");
    temp =  CANx->IDE_RTR_DLC;
    printf("  0x%02x ",temp); 
    temp =  CANx->ID[0];
    printf("  0x%02x ",temp); 
    temp =  CANx->ID[1];
    printf("  0x%02x ",temp); 
    temp =  CANx->ID[2];
    printf("  0x%02x ",temp); 

    printf("\r\n验收屏蔽:");
    temp =  CANx->ID[3];
    printf("  0x%02x ",temp); 
    temp =  CANx->BUF[0];
    printf("  0x%02x ",temp); 
    temp =  CANx->BUF[1];
    printf("  0x%02x ",temp); 
    temp =  CANx->BUF[2];
    printf("  0x%02x ",temp); 

}

void ls1c_can0_irqhandler(int irq, void *param)  
{  
    CAN_TypeDef* CANx;
    int i;
    unsigned char status;
    CANx =  CAN0;
    /*读寄存器清除中断*/
   status = CANx->IR;
   printf("\r\ncan0 int happened!\r\n");
    /*接收中断*/
    if (( status & CAN_IR_RI) == CAN_IR_RI) 
    {
        /*清除RI 中断*/
       CAN_Receive(CANx, &RxMessage);
       CANx->CMR |= CAN_CMR_RRB; 
       CANx->CMR |= CAN_CMR_CDO; 
       printf("\r\ncan0 receive:\r\n");
       printf(" IDE=%d   RTR = %d DLC=%d  ",RxMessage.IDE, RxMessage.RTR ,RxMessage.DLC);
       if(RxMessage.IDE == CAN_Id_Standard)
       {
         printf("\r\n Standard ID= %02X  ",RxMessage.StdId);
       }
       else if(RxMessage.IDE == CAN_Id_Extended)
       {
         printf("\r\n Extended ID= %02X  ",RxMessage.ExtId);
       }

       if(RxMessage.RTR== CAN_RTR_DATA)
       {
         printf("\r\ndata= ");
         for(i=0;i<RxMessage.DLC;i++)
         {
           printf("0x%02X  ",RxMessage.Data[i]);
         }
       }
       else if(RxMessage.IDE == CAN_RTR_Remote)
       {
         printf("\r\nCAN_RTR_Remote  no data!");
       }
       printf("\r\n");
    }
    /*发送中断*/
    else if (( status  & CAN_IR_TI) == CAN_IR_TI) 
    {
       printf("\r\ncan0 send success! \r\n");
    }
}  

void ls1c_can1_irqhandler(int irq, void *param)  
{  
    CAN_TypeDef* CANx;
    int i;
    unsigned char status;
    CANx =  (CAN_TypeDef* )LS1C_REG_BASE_CAN1;
    /*读寄存器清除中断*/
   status = CANx->IR;
   printf("\r\ncan1 int happened!\r\n");
    /*接收中断*/
    if (( status & CAN_IR_RI) == CAN_IR_RI) 
    {
        /*清除RI 中断*/
       CAN_Receive(CANx, &RxMessage);
       CANx->CMR |= CAN_CMR_RRB; 
       CANx->CMR |= CAN_CMR_CDO; 
       printf("\r\ncan1 receive:\r\n");
       printf(" IDE=%d   RTR = %d DLC=%d  ",RxMessage.IDE, RxMessage.RTR ,RxMessage.DLC);
       if(RxMessage.IDE == CAN_Id_Standard)
       {
         printf("\r\n Standard ID= %02X  ",RxMessage.StdId);
       }
       else if(RxMessage.IDE == CAN_Id_Extended)
       {
         printf("\r\n Extended ID= %02X  ",RxMessage.ExtId);
       }

       if(RxMessage.RTR== CAN_RTR_DATA)
       {
         printf("\r\ndata= ");
         for(i=0;i<RxMessage.DLC;i++)
         {
           printf("0x%02X  ",RxMessage.Data[i]);
         }
       }
       else if(RxMessage.IDE == CAN_RTR_Remote)
       {
         printf("\r\nCAN_RTR_Remote  no data!");
       }
       printf("\r\n");
    }
    /*发送中断*/
    else if (( status  & CAN_IR_TI) == CAN_IR_TI) 
    {
       printf("\r\ncan1 send success! \r\n");
    }
}  

void Can_Config(CAN_TypeDef* CANx, Ls1c_CanBPS_t bps)
{
    unsigned char initresult;

    pin_set_purpose(54, PIN_PURPOSE_OTHER);
    pin_set_purpose(55, PIN_PURPOSE_OTHER);
    pin_set_remap(54, PIN_REMAP_THIRD);
    pin_set_remap(55, PIN_REMAP_THIRD);
    
    CAN_InitTypeDef        CAN_InitStructure;
  
    CAN_InitStructure.CAN_Mode = CAN_Mode_STM;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

    /* BaudRate= f(APB)/((1+BS1+BS2)(SJW*2*Prescaler))=126000000/[(1+7+2)*1*2*63]=100000=100K*/
    /* BPS     PRE   BS1   BS2   最低40K
       1M      9       4       2   
       800K    8       7       2   
       500K    9       11      2   
       250K    36      4       2   
       125K    36      11      2   
       100K    63      7       2   
       50K     63      16      3`  
       40K     63      16      8   
    */
    switch (bps)
    {
        case CAN1MBaud: 
            CAN_InitStructure.CAN_Prescaler = 9;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN800kBaud: 
            CAN_InitStructure.CAN_Prescaler = 8;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN500kBaud: 
            CAN_InitStructure.CAN_Prescaler = 9;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN250kBaud: 
            CAN_InitStructure.CAN_Prescaler = 36;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN125kBaud: 
            CAN_InitStructure.CAN_Prescaler = 36;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN100kBaud: 
            CAN_InitStructure.CAN_Prescaler = 63;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
        case CAN50kBaud: 
            CAN_InitStructure.CAN_Prescaler = 63;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
        break;
        case CAN40kBaud: 
            CAN_InitStructure.CAN_Prescaler = 63;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
        break;
        default: //100K
            CAN_InitStructure.CAN_Prescaler = 63;
            CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq;
            CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
        break;
    }
    initresult = CAN_Init(CANx, &CAN_InitStructure);// 配置成100K
	
    /*无验收屏蔽*/
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    
    CAN_FilterInitStructure.CAN_FilterId0  = 0x00;
    CAN_FilterInitStructure.CAN_FilterMaskId0 = 0xFF;
    CAN_FilterInitStructure.CAN_FilterId1  = 0x00;
    CAN_FilterInitStructure.CAN_FilterMaskId1 = 0xFF;
    CAN_FilterInitStructure.CAN_FilterId2  = 0x00;
    CAN_FilterInitStructure.CAN_FilterMaskId2 = 0xFF;
    CAN_FilterInitStructure.CAN_FilterId3  = 0x00;
    CAN_FilterInitStructure.CAN_FilterMaskId3 = 0xFF;
    CAN_FilterInit(CANx, &CAN_FilterInitStructure);	
	
    if( (CAN_TypeDef* )LS1C_REG_BASE_CAN0 == CANx)
    {
       /* 初始化CAN0接收中断*/
      irq_install(LS1C_CAN0_IRQ, ls1c_can0_irqhandler, NULL);  
      irq_enable(LS1C_CAN0_IRQ); 
     }
    else if( (CAN_TypeDef* )LS1C_REG_BASE_CAN1 == CANx)
    {
       /* 初始化CAN1接收中断*/
      irq_install(LS1C_CAN1_IRQ, ls1c_can1_irqhandler, NULL);  
      irq_enable(LS1C_CAN1_IRQ); 
    }
}

void test_cansend(void)
{
    unsigned char temp;

    Can_Config(CAN0, CAN100kBaud);

    int i;
    TxMessage.StdId = 1;
    TxMessage.ExtId = 1;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_Id_Standard;
    TxMessage.DLC = 8;
    for( i=0; i<8;i++)
    {
      TxMessage.Data[i] = i+1;
      printf("%02x ",  TxMessage.Data[i]);
    }
    CAN_Transmit(CAN0, &TxMessage);
    
    TxMessage.StdId = 1;
    TxMessage.ExtId = 2;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_Id_Extended;
    TxMessage.DLC = 8;
    for( i=0; i<8;i++)
    {
      TxMessage.Data[i] = i+1;
      printf("%02x ",  TxMessage.Data[i]);
    }
    CAN_Transmit(CAN0, &TxMessage);

  	
}



Ls1c_can.c

/*
 * File      : ls1c_can.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-01-06     sundm75       first version
 */


#include "ls1c_delay.h"
#include "ls1c_public.h"
#include "ls1c_can.h"

static unsigned char  set_reset_mode(CAN_TypeDef* CANx)
{
  unsigned char status;
  int i;

  /*检查复位标志*/
  status = CANx->MOD;

  /* 关闭中断 */
  CANx->IER = 0x00;
  
  for (i = 0; i < 100; i++)
  {
    if((status & CAN_Mode_RM) == CAN_Mode_RM)
        return 1;
  
    /* 设置复位*/
    CANx->MOD |=  ((unsigned char)CAN_Mode_RM);
  
    /*延时*/
    delay_us(10);

    /*检查复位标志*/
    status = CANx->MOD;
  }
  printf("\r\nSetting SJA1000 into reset mode failed!\r\n");
  return 0;  
}

static unsigned char  set_normal_mode(CAN_TypeDef* CANx)
{
  unsigned char status;
  int i;

  /*检查复位标志*/
  status = CANx->MOD;
  
  for (i = 0; i < 100; i++)
  {
    if((status & CAN_Mode_RM) != CAN_Mode_RM)
    {
      /*开所有中断 (总线错误中断不开)*/
      CANx->IER |= (~(unsigned char)CAN_IR_BEI);	
      return 1;
    }
    /* 设置正常工作模式*/
    CANx->MOD &= (~(unsigned char) CAN_Mode_RM); 
    /*延时*/
    delay_us(10); 
    status = CANx->MOD;	
  }
  printf("\r\nSetting SJA1000 into normal mode failed!\r\n");
  return 0;
}

static unsigned char  set_start(CAN_TypeDef* CANx)
{
  /*复位TX错误计数器*/
  CANx->TXERR = 0;
  /*复位RX错误计数器*/
  CANx->RXERR = 0;
  /*时钟分频寄存器: PeliCAN模式; CBP=1,中止输入比较器, RX0激活*/
  CANx->CDR = 0xC0;	
 
  return  set_normal_mode(CANx);  
}

 unsigned char CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
{
  unsigned char InitStatus = CAN_InitStatus_Failed;
  unsigned long wait_ack = 0x00000000;
  unsigned char status;

  status = CANx->MOD;
  if( status == 0xFF)
  {
    printf("\n Probe can0 failed \r\n");  	   
    return CAN_InitStatus_Failed;
  }

   /* 进入复位模式 */
  InitStatus = set_reset_mode(CANx);
  
  if((CAN_InitStruct->CAN_Mode & CAN_Mode_SM) == CAN_Mode_SM) 
  {
    /* 睡眠模式 1: 睡眠 0: 唤醒*/
    CANx->MOD|= (unsigned char)CAN_Mode_SM;    
  }
  else if((CAN_InitStruct->CAN_Mode & CAN_Mode_LOM) == CAN_Mode_LOM) 
  {
    /*只听模式 1:只听  0:正常 */
    CANx->MOD|= (unsigned char)CAN_Mode_LOM;    
  }
  else if((CAN_InitStruct->CAN_Mode & CAN_Mode_AFM) == CAN_Mode_AFM) 
  {
    /*单滤波模式 1:单 0: 双*/
    CANx->MOD |= (unsigned char)CAN_Mode_AFM;    
  }
  else if((CAN_InitStruct->CAN_Mode & CAN_Mode_STM) == CAN_Mode_STM) 
  {
    /*自检测模式 1:自检测  0:正常  */
    CANx->MOD |= (unsigned char)CAN_Mode_STM;    
  }
  
  /* 配置时钟频率 */
  CANx->BTR0 = (( unsigned char )( unsigned char )CAN_InitStruct->CAN_Prescaler -1) | \
               (unsigned char)CAN_InitStruct->CAN_SJW << 6;
  
  CANx->BTR1 = ((unsigned char)CAN_InitStruct->CAN_BS1) | \
               ((unsigned char)CAN_InitStruct->CAN_BS2 << 4) | \
               ((unsigned char)CAN_InitStruct->CAN_SJW<<7);

   /* 进入工作模式 */
  set_start(CANx);    
  
  /* 返回初始化结果 */
  return InitStatus;
}

 void CAN_FilterInit(CAN_TypeDef* CANx,  CAN_FilterInitTypeDef* CAN_FilterInitStruct)
{
   /* 进入复位模式 */
    set_reset_mode(CANx);

    CANx->IDE_RTR_DLC = CAN_FilterInitStruct->CAN_FilterId0;
    CANx->ID[0] = CAN_FilterInitStruct->CAN_FilterId1;
    CANx->ID[1] = CAN_FilterInitStruct->CAN_FilterId2;
    CANx->ID[2] = CAN_FilterInitStruct->CAN_FilterId3;
    CANx->ID[3] = CAN_FilterInitStruct->CAN_FilterMaskId0;
    CANx->BUF[0]= CAN_FilterInitStruct->CAN_FilterMaskId1;
    CANx->BUF[1]= CAN_FilterInitStruct->CAN_FilterMaskId2;
    CANx->BUF[2]= CAN_FilterInitStruct->CAN_FilterMaskId3;

   /* 进入工作模式 */
    set_start(CANx);
}

unsigned char  CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
    int i;
    if (TxMessage->IDE == CAN_Id_Extended)
    {
        CANx->ID[0]= TxMessage ->ExtId>> 21;
        CANx->ID[1]= TxMessage ->ExtId>> 13;
        CANx->ID[2]= TxMessage ->ExtId>> 5;
        CANx->ID[3]= TxMessage ->ExtId<<3;
        CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\
            (TxMessage ->RTR & 0x01) << 6 |\
            (TxMessage ->DLC & 0x0F);
        for( i=0;i<TxMessage ->DLC; i++)
        {
           CANx->BUF[i]= TxMessage->Data[i];
        }
    }
    else if (TxMessage->IDE ==CAN_Id_Standard)
    {
        CANx->ID[0]= TxMessage ->StdId>> 3;
        CANx->ID[1]= TxMessage ->StdId<< 5;
        CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\
            (TxMessage ->RTR & 0x01) << 6 |\
            (TxMessage ->DLC & 0x0F);
        CANx->ID[2]= TxMessage ->Data[0];
        CANx->ID[3]= TxMessage ->Data[1];
        for( i=0;i<TxMessage ->DLC-2; i++)
        {
           CANx->BUF[i]= TxMessage->Data[i+2];
        }
    }
    CANx->CMR = CAN_CMR_TR ;
}

void CAN_Receive(CAN_TypeDef* CANx,  CanRxMsg* RxMessage)
{
  /* 获取 IDE */
  RxMessage->IDE = (CANx->IDE_RTR_DLC  & 0x80)>>7;
  /* 获取 RTR */
  RxMessage->RTR = (CANx->IDE_RTR_DLC  & 0x40)>>4;
  /* 获取 DLC */
  RxMessage->DLC= (CANx->IDE_RTR_DLC  & 0x0F);
  if (RxMessage->IDE == CAN_Id_Standard)
  {
    RxMessage->StdId = CANx->ID[0]<<3 |CANx->ID[1]>>5 ;
    /* 获取数据 */
    RxMessage->Data[0] = (unsigned char)CANx->ID[2];
    RxMessage->Data[1] = (unsigned char)CANx->ID[3];
    RxMessage->Data[2] = (unsigned char)CANx->BUF[0];
    RxMessage->Data[3] = (unsigned char)CANx->BUF[1];
    RxMessage->Data[4] = (unsigned char)CANx->BUF[2];
    RxMessage->Data[5] = (unsigned char)CANx->BUF[3];
    RxMessage->Data[6] = (unsigned char)CANx->BUF[4];
    RxMessage->Data[7] = (unsigned char)CANx->BUF[5];
  }
  else  if (RxMessage->IDE == CAN_Id_Extended)
  {
    RxMessage->ExtId= CANx->ID[0]<<21 |CANx->ID[1]<<13|CANx->ID[2]<<5|CANx->ID[3]>>3 ;
    /* 获取数据 */
    RxMessage->Data[0] = (unsigned char)CANx->BUF[0];
    RxMessage->Data[1] = (unsigned char)CANx->BUF[1];
    RxMessage->Data[2] = (unsigned char)CANx->BUF[2];
    RxMessage->Data[3] = (unsigned char)CANx->BUF[3];
    RxMessage->Data[4] = (unsigned char)CANx->BUF[4];
    RxMessage->Data[5] = (unsigned char)CANx->BUF[5];
    RxMessage->Data[6] = (unsigned char)CANx->BUF[6];
    RxMessage->Data[7] = (unsigned char)CANx->BUF[7];
  }  
}



Ls1c_can.h

/*
 * File      : ls1c_can.h
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:  (Pelican Mode) 
 * Date           Author       Notes
 * 2018-01-06     sundm75       first version
 */

#ifndef __OPENLOONGSON_CAN_H
#define __OPENLOONGSON_CAN_H

#define CAN0               ( (CAN_TypeDef* )LS1C_REG_BASE_CAN0)
#define CAN1               ( (CAN_TypeDef* )LS1C_REG_BASE_CAN1)

#define CAN_InitStatus_Failed              ((unsigned char)0x00) /*!< CAN initialization failed */
#define CAN_InitStatus_Success             ((unsigned char)0x01) /*!< CAN initialization OK */

/* 非应答溢出时间次数 */
#define INAK_TIMEOUT        ((unsigned long)0x00000FFF)

#define CAN_SJW_1tq                 ((unsigned char)0x00)  /*!< 1 time quantum */
#define CAN_SJW_2tq                 ((unsigned char)0x01)  /*!< 2 time quantum */
#define CAN_SJW_3tq                 ((unsigned char)0x02)  /*!< 3 time quantum */
#define CAN_SJW_4tq                 ((unsigned char)0x03)  /*!< 4 time quantum */

#define CAN_BS1_1tq                 ((unsigned char)0x00)  /*!< 1 time quantum */
#define CAN_BS1_2tq                 ((unsigned char)0x01)  /*!< 2 time quantum */
#define CAN_BS1_3tq                 ((unsigned char)0x02)  /*!< 3 time quantum */
#define CAN_BS1_4tq                 ((unsigned char)0x03)  /*!< 4 time quantum */
#define CAN_BS1_5tq                 ((unsigned char)0x04)  /*!< 5 time quantum */
#define CAN_BS1_6tq                 ((unsigned char)0x05)  /*!< 6 time quantum */
#define CAN_BS1_7tq                 ((unsigned char)0x06)  /*!< 7 time quantum */
#define CAN_BS1_8tq                 ((unsigned char)0x07)  /*!< 8 time quantum */
#define CAN_BS1_9tq                 ((unsigned char)0x08)  /*!< 9 time quantum */
#define CAN_BS1_10tq                ((unsigned char)0x09)  /*!< 10 time quantum */
#define CAN_BS1_11tq                ((unsigned char)0x0A)  /*!< 11 time quantum */
#define CAN_BS1_12tq                ((unsigned char)0x0B)  /*!< 12 time quantum */
#define CAN_BS1_13tq                ((unsigned char)0x0C)  /*!< 13 time quantum */
#define CAN_BS1_14tq                ((unsigned char)0x0D)  /*!< 14 time quantum */
#define CAN_BS1_15tq                ((unsigned char)0x0E)  /*!< 15 time quantum */
#define CAN_BS1_16tq                ((unsigned char)0x0F)  /*!< 16 time quantum */

#define CAN_BS2_1tq                 ((unsigned char)0x00)  /*!< 1 time quantum */
#define CAN_BS2_2tq                 ((unsigned char)0x01)  /*!< 2 time quantum */
#define CAN_BS2_3tq                 ((unsigned char)0x02)  /*!< 3 time quantum */
#define CAN_BS2_4tq                 ((unsigned char)0x03)  /*!< 4 time quantum */
#define CAN_BS2_5tq                 ((unsigned char)0x04)  /*!< 5 time quantum */
#define CAN_BS2_6tq                 ((unsigned char)0x05)  /*!< 6 time quantum */
#define CAN_BS2_7tq                 ((unsigned char)0x06)  /*!< 7 time quantum */
#define CAN_BS2_8tq                 ((unsigned char)0x07)  /*!< 8 time quantum */

#define CAN_Id_Standard           0
#define CAN_Id_Extended           1
#define CAN_RTR_DATA               0
#define CAN_RTR_Remote            1

/*!< CAN 控制状态寄存器 */
/************************** CAN_MOD 寄存器位定义*******************************/
#define CAN_Mode_RM                 ((unsigned char)0x01)  /*!< 复位模式 */
#define CAN_Mode_LOM                ((unsigned char)0x02)  /*!< 只听模式 1:只听  0:正常  */
#define CAN_Mode_STM                ((unsigned char)0x04)  /*!< 正常工作模式1:自检测  0:正常  */
#define CAN_Mode_AFM                ((unsigned char)0x08)  /*!< 单/双滤波模式 1:单 0: 双*/
#define CAN_Mode_SM                 ((unsigned char)0x10)  /*!< 睡眠模式1: 睡眠 0: 唤醒 */

/************************** CAN_CMR 寄存器位定义*******************************/
 #define  CAN_CMR_TR                         ((unsigned char)0x01)         /*!< 发送请求 1: 当前信息被发送  0: 空 */
 #define  CAN_CMR_AT                         ((unsigned char)0x02)         /*!< 中止发送 1: 等待发送的信息取消  0: 空缺  */
 #define  CAN_CMR_RRB                        ((unsigned char)0x04)         /*!< 释放接收缓冲器  1:释放  0: 无动作 */
 #define  CAN_CMR_CDO                        ((unsigned char)0x08)         /*!< 清除数据溢出  1:清除  0: 无动作    */
//#define  CAN_CMR_GTS                        ((unsigned char)0x10)         /*!STD模式< 睡眠: 1:进入睡眠  0: 唤醒  */
 #define  CAN_CMR_SRR                        ((unsigned char)0x10)         /*!< 自接收请求  1:  0:   */
 #define  CAN_CMR_EFF                        ((unsigned char)0x80)         /*!< 扩展模式 1:扩展帧 0: 标准帧  */

/************************** CAN_SR 寄存器位定义********************************/
 #define  CAN_SR_BBS                         ((unsigned char)0x01)         /*!< 接收缓存器状态1: 满  0: 空 */
 #define  CAN_SR_DOS                         ((unsigned char)0x02)         /*!< 数据溢出状态 1: 溢出  0: 空缺  */
 #define  CAN_SR_TBS                         ((unsigned char)0x04)         /*!< 发送缓存器状态1: 释放  0: 锁定 */
 #define  CAN_SR_TCS                         ((unsigned char)0x08)         /*!< 发送完毕状态1: 完毕  0: 未完毕    */
 #define  CAN_SR_RS                          ((unsigned char)0x10)         /*!< 接收状态1: 接收  0: 空闲  */
 #define  CAN_SR_TS                          ((unsigned char)0x20)         /*!< 发送状态1:  发送 0:  空闲*/
 #define  CAN_SR_ES                          ((unsigned char)0x40)         /*!< 出错状态1:出错 0: 正常 */
 #define  CAN_SR_BS                          ((unsigned char)0x80)         /*!< 总线状态1: 关闭  0: 开启  */
 
/************************** CAN_IR 中断寄存器位定义****************************/
 #define  CAN_IR_RI                          ((unsigned char)0x01)         /*!< 接收中断 */
 #define  CAN_IR_TI                          ((unsigned char)0x02)         /*!< 发送中断 */
 #define  CAN_IR_EI                          ((unsigned char)0x04)         /*!< 错误中断 */
 #define  CAN_IR_DOI                         ((unsigned char)0x08)         /*!< 数据溢出中断  */
 #define  CAN_IR_WUI                         ((unsigned char)0x10)         /*!< 唤醒中断 */
 #define  CAN_IR_EPI                         ((unsigned char)0x20)         /*!< 错误消极中断 */
 #define  CAN_IR_ALI                         ((unsigned char)0x40)         /*!< 仲裁丢失中断 */
 #define  CAN_IR_BEI                         ((unsigned char)0x80)         /*!< 总线错误中断  */
 
/************************* CAN_IER 中断使能寄存器位定义************************/
 #define  CAN_IER_RIE                         ((unsigned char)0x01)        /*!< 接收中断使能 */
 #define  CAN_IER_TIE                         ((unsigned char)0x02)        /*!< 发送中断使能 */
 #define  CAN_IER_EIE                         ((unsigned char)0x04)        /*!< 错误中断使能 */
 #define  CAN_IER_DOIE                        ((unsigned char)0x08)        /*!< 数据溢出中断使能  */
 #define  CAN_IER_WUIE                        ((unsigned char)0x10)        /*!< 唤醒中断使能 */
 #define  CAN_IER_EPIE                        ((unsigned char)0x20)        /*!< 错误消极中断使能 */
 #define  CAN_IER_ALIE                        ((unsigned char)0x40)        /*!< 仲裁丢失中断使能 */
 #define  CAN_IER_BEIE                        ((unsigned char)0x80)        /*!< 总线错误中断使能  */
 
typedef enum 
{
	CAN1MBaud=0,    // 1 MBit/sec
	CAN800kBaud,    // 800 kBit/sec
	CAN500kBaud,    // 500 kBit/sec
	CAN250kBaud,    // 250 kBit/sec
	CAN125kBaud,    // 125 kBit/sec
	CAN100kBaud,    // 100 kBit/sec
	CAN50kBaud,     // 50 kBit/sec
	CAN40kBaud,     // 40 kBit/sec
}Ls1c_CanBPS_t;

typedef struct
{
   unsigned char MOD;
   unsigned char CMR;
   unsigned char SR;
   unsigned char IR;
   unsigned char IER;
   unsigned char reserved0;
   unsigned char BTR0;
   unsigned char BTR1;
   unsigned char OCR;
   unsigned char reserved[2];
   unsigned char ALC;
   unsigned char ECC ;
   unsigned char EMLR;
   unsigned char RXERR;
   unsigned char TXERR;
   unsigned char IDE_RTR_DLC;
   unsigned char ID[4];
   unsigned char BUF[8];
   unsigned char RMCR;
   unsigned char CDR;
} CAN_TypeDef;

typedef struct
{
  unsigned char  CAN_Prescaler;    /* 波特率分频系数1 to 31. */  
  unsigned char  CAN_Mode;         /*0x10:睡眠0x08:单,双滤波 0x40:正常工作0x20:只听 0x01:复位*/
  unsigned char  CAN_SJW;          /*同步跳转宽度 */
  unsigned char  CAN_BS1;          /*时间段1计数值*/
  unsigned char  CAN_BS2;          /*时间段2计数值*/ 
  
} CAN_InitTypeDef;

typedef struct
{
  unsigned char  CAN_FilterId0;        /*验收代码0*/
  unsigned char  CAN_FilterMaskId0;    /*验收屏蔽0*/
  unsigned char  CAN_FilterId1;        /*验收代码1*/
  unsigned char  CAN_FilterMaskId1;    /*验收屏蔽1*/
  unsigned char  CAN_FilterId2;        /*验收代码2*/
  unsigned char  CAN_FilterMaskId2;    /*验收屏蔽2*/
  unsigned char  CAN_FilterId3;        /*验收代码3*/
  unsigned char  CAN_FilterMaskId3;    /*验收屏蔽3*/
} CAN_FilterInitTypeDef;

typedef struct
{
  unsigned long StdId;  /* 11位ID*/
  unsigned long ExtId;  /*29位ID**/
  unsigned char IDE;    /*IDE: 标识符选择
                                     该位决定发送邮箱中报文使用的标识符类型
                                     0: 使用标准标识符
                                     1: 使用扩展标识符*/
  unsigned char RTR;     /*远程发送请求
                                       0: 数据帧
                                       1: 远程帧*/
  unsigned char DLC;     /*数据帧长度*/
  unsigned char Data[8]; /*8字节数据*/
} CanRxMsg;

typedef struct
{
  unsigned long StdId;  /* 11位ID*/
  unsigned long ExtId;  /*29位ID**/
  unsigned char IDE;    /*IDE: 标识符选择
                                     该位决定发送邮箱中报文使用的标识符类型
                                     0: 使用标准标识符
                                     1: 使用扩展标识符*/
  unsigned char RTR;     /*远程发送请求
                                       0: 数据帧
                                       1: 远程帧*/
  unsigned char DLC;     /*数据帧长度*/
  unsigned char Data[8]; /*8字节数据*/
} CanTxMsg;

unsigned char CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
void CAN_FilterInit(CAN_TypeDef* CANx,  CAN_FilterInitTypeDef* CAN_FilterInitStruct);
unsigned char CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
void CAN_Receive(CAN_TypeDef* CANx,  CanRxMsg* RxMessage);

#endif



猜你喜欢

转载自blog.csdn.net/caogos/article/details/79824787