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_S