查看: 833|回复: 1

[求助] 怎么将LPC1778的CAN1通道通讯改为CAN2通道通讯

[复制链接]

该用户从未签到

1

主题

2

帖子

0

新手上路

Rank: 1

积分
12
最后登录
2022-2-11
发表于 2020-10-22 11:51:50 | 显示全部楼层 |阅读模式
   我现在手里已经有一套LPC1778芯片通过CAN1通道进行通讯的程序,然后想要将程序改为通过CAN2通道进行通讯,本来以为就简单的修改一下相关寄存器配置就行了,结果改了好久还是改不出来,因此希望万能的网友能够提供一下帮助,看看怎么改才能实现CAN2通道通讯。
这段程序能够实现提供CAN1通道发送程序,理论上来讲寄存器方面就只需要将IOCON和PCONP两个寄存器改一下就可以了,希望网友能指出其他要修改的方面。

#include <LPC177x_8x.h>
#include "can1.h"
#include "shell.h"
#define CAN_FILTER_MODE_WORK     0x00    // 工作模式
#define CAN_FILTER_MODE_CLOSE    0x01    // 关闭模式  不接收任务消息
#define CAN_FILTER_MODE_BYPASS   0x02   // 旁路模式  接收任务消息
uint32_t g_whileListEnable = 0;
typedef struct
{
    uint32_t id;  /**< ID of message, if bit 30 is set then this is extended frame */
    uint32_t  dlc; /**< Message data length */
    uint8_t data[8];  /**< Message data */
} message_object;
//uint32_t g_canTestCounter = 0 ;
typedef struct  {
  unsigned int    fti;               //  帧信息
  unsigned int    id;                //  id                     
  unsigned int    DAA;               /* A Data field */
  unsigned int    DAB;     /* B Data field */
} CAN1_msg;
uint32_t g_can1TxBufferHead = 0;
uint32_t g_can1TxBufferTail = 0;
//uint32_t g_can1RxBufferHead = 0;
//uint32_t g_can1RxBufferTail = 0;
#define CAN1_TX_BUFFER_LEN 8
//#define CAN1_RX_BUFFER_LEN 8
CAN1_msg g_can1TxBuffer[CAN1_TX_BUFFER_LEN];  
//CAN1_msg g_can1RxBuffer[CAN1_RX_BUFFER_LEN];
#define CAN_INT_Rx_DISABLE (LPC_CAN1->IER  &= ~(0x0001))
#define CAN_INT_Rx_ENABLE (LPC_CAN1->IER  |= (0x0001))
#define CAN_INT_Tx_DISABLE (LPC_CAN1->IER  &= ~(0x0002))
#define CAN_INT_Tx_ENABLE (LPC_CAN1->IER  |= (0x0002))
T_CAN_VERSION g_can1Version;
void CAN1_init(unsigned long clk, unsigned long baudrate, T_CAN_VERSION version)
{
    uint32_t result;
    uint8_t NT, TSEG1, TSEG2;
    uint32_t BRP;
    g_can1Version = version;

    LPC_IOCON->P0_0 &= ~0x07;
    LPC_IOCON->P0_0 |= 0x01;
   
    LPC_IOCON->P0_1 &= ~0x07;
    LPC_IOCON->P0_1 |= 0x01;
    /* Turn on power and clock for CAN1 */
    LPC_SC->PCONP |= ((uint32_t)(1<<13));
   
    LPC_CAN1->MOD = 1; // Enter Reset Mode
    LPC_CAN1->IER = 0; // Disable All CAN Interrupts
    LPC_CAN1->GSR = 0;
    /* Request command to release Rx, Tx buffer and clear data overrun */
    LPC_CAN1->CMR = (1 << 1) | (1 << 2) | (1 << 3);
   
    /* Read to clear interrupt pending in interrupt capture register */
    //i = LPC_CAN1->ICR;
    LPC_CAN1->MOD = 0;// Return Normal operating
   
    /* Set baudrate */
    result = clk / baudrate;
    /* Calculate suitable nominal time value
    * NT (nominal time) = (TSEG1 + TSEG2 + 3)
    * NT <= 24
    * TSEG1 >= 2*TSEG2
    */
    for(NT = 24; NT > 0; NT = NT-2)
    {
        if ((result%NT) == 0)
        {
            BRP = result / NT - 1;
            
            NT--;
            
            TSEG2 = (NT/3) - 1;
            
            TSEG1 = NT -(NT/3) - 1;
            
            break;
        }
    }
    /* Enter reset mode */
    LPC_CAN1->MOD = 0x01;
   
    /* Set bit timing
     * Default: SAM = 0x00;
     *          SJW = 0x03;
     */
    LPC_CAN1->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP;    //后面可能要改
   
    /* Return to normal operating */
    LPC_CAN1->MOD = 0;
   
    LPC_CAN1->MOD |= ((uint32_t)(1<<0));//Enter Reset mode
   
    LPC_CAN1->MOD |= ((uint32_t)(1<<2));
   
    LPC_CAN1->MOD &= ~ ((uint32_t)(1<<0));//Release Reset mode
   
    LPC_CANAF->AFMR = CAN_FILTER_MODE_BYPASS;
    LPC_CAN1->IER |= ((1 << 0) | (1 << 1));  //Enable RX TX Interrupt
NVIC_EnableIRQ(CAN_IRQn);

g_whileListEnable = 0;
}

void can1Wirte()
{
    if ((LPC_CAN1->GSR & (1<<2))&&(g_can1TxBufferHead != g_can1TxBufferTail))
    {      
     LPC_CAN1->TFI1 =  g_can1TxBuffer[g_can1TxBufferHead].fti;
      
     LPC_CAN1->TID1 =  g_can1TxBuffer[g_can1TxBufferHead].id;      /* Write CAN message identifier */
     LPC_CAN1->TDA1 =  g_can1TxBuffer[g_can1TxBufferHead].DAA;     /* Write first 4 data bytes */     
   LPC_CAN1->TDB1 =  g_can1TxBuffer[g_can1TxBufferHead].DAB;     /* Write second 4 data bytes */      
   
   g_can1TxBufferHead++;
  if (g_can1TxBufferHead >= CAN1_TX_BUFFER_LEN)
     {
         g_can1TxBufferHead = 0;
     }
  LPC_CAN1->CMR  = 0x21;                           /* Start transmission without loop-back */
}
}
// 在CAN0上发送数据帧
CAN1_BOOL CAN1_sndDataFrame(unsigned long id, unsigned char * data, unsigned long len)
{
    uint32_t i, next,gsr, FTI1;
uint8_t canData[8];
    if (len > 8)
{
     return CAN1_FALSE;
}
    if (g_can1Version == CAN_VERSION_2_0_A)
    {
        if (id & 0xFFFFF800)
        {
            return CAN1_FALSE;
        }
    }
    else
    {
        if (id & 0xE0000000)
        {
            return CAN1_FALSE;
        }
    }
    CAN_INT_Tx_DISABLE;
   
    /* Transmit Channel 1 is available */
    /* Write frame informations and frame data into its CANxTFI1,
    * CANxTID1, CANxTDA1, CANxTDB1 register */
    FTI1 &= ~ 0x000F0000;
   
    FTI1 |= (len) << 16;
   
    FTI1 &= ~(1 << 30);
   
    if (g_can1Version == CAN_VERSION_2_0_A)
    {
        FTI1 &= ~(1UL << 31);
    }
    else
    {
        FTI1 |= (1UL << 31); //set bit FF
    }
    next = g_can1TxBufferTail + 1;
    if (next >= CAN1_TX_BUFFER_LEN)
    {
        next = 0;
    }
if (next == g_can1TxBufferHead)
{
     return CAN1_FULL;
}
g_can1TxBuffer[g_can1TxBufferTail].fti = FTI1;   //  数据帧信息
    g_can1TxBuffer[g_can1TxBufferTail].id = id;
    for (i = 0; i < len; i++)
    {
     canData = data;
}
    for (i = len; i < 8; i++)
    {
     canData = 0;
}
g_can1TxBuffer[g_can1TxBufferTail].DAA = ((uint32_t)canData[0] | ((uint32_t)canData[1] << 8)
                                          | ((uint32_t)canData[2] << 16) | ((uint32_t)canData[3] << 24));
g_can1TxBuffer[g_can1TxBufferTail].DAB = ((uint32_t)canData[4] | ((uint32_t)canData[5] << 8)
                                          | ((uint32_t)canData[6] << 16) | ((uint32_t)canData[7] << 24));
    g_can1TxBufferTail = next;
    gsr = LPC_CAN1->GSR;
CAN_INT_Tx_ENABLE;
if(gsr & (0x01<<2))
{
     can1Wirte();
}

    return CAN1_TRUE;
}

/*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
/*********************************************************************//**
* @brief  CAN_IRQ Handler, control receive message operation控制接收消息操作
* param[in] none
* @return   none
**********************************************************************/
void CAN_IRQHandler(void)
{
    uint32_t icr, gsr;
    icr = LPC_CAN1->ICR;                           /* clear interrupts */
    if (icr & 0x01)  // 有接收中断
    {
        gsr =LPC_CAN1->GSR;
        
        if (gsr & 0x01)   //释放
        {
//              CAN1_ReceiveMsg();            //接受中断  
        }
    }
if(icr & (1 << 1))
{
     can1Wirte();
}
}

我知道答案 目前已有1人回答
回复

使用道具 举报

该用户从未签到

656

主题

6312

帖子

0

超级版主

Rank: 8Rank: 8

积分
19949
最后登录
2024-4-20
发表于 2020-10-23 16:42:30 | 显示全部楼层
如果本身的CAN模块是可以的,只是修改了CAN2不行,那么说明你还有哪些地方没有修改好。
你看看CAN2的时钟,是否已经使能,还有CAN的bit率之类的,你可以测试下CAN2的引脚波形是否有了,还有关键的,你CAN2的引脚配置了没有?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2024-4-20 23:35 , Processed in 0.109931 second(s), 21 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表