在线时间2 小时
UID3677861
注册时间2020-10-22
NXP金币0
该用户从未签到
新手上路
- 积分
- 12
- 最后登录
- 2022-2-11
|
我现在手里已经有一套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();
}
}
|
|