新手上路
- 积分
- 27
- 金钱
- 27
- 注册时间
- 2019-5-23
- 在线时间
- 6 小时
|
有哪位大神帮忙看看CAN通信存在异常,芯片采用的是SN65HVD230DRG4(用TJA1050可以正常收发数据,用SN65HVD230DRG4就收发不了数据了,RS引脚通过一个电阻拉到的低电平),以下附代码,请哪位大神帮忙指点指点
#include "main.h"
unsigned char can1_rec_flag = 0;
unsigned char CAN1_DATA[8];
unsigned char can2_rec_flag = 0;
unsigned char CAN2_DATA[8];
//格式: 波特率 CAN_SJW CAN_BS1 CAN_BS2 CAN_Prescaler
const unsigned int CAN_baud_table[CAN_BAUD_NUM][5] =
{
//波特率, CAN_SJW, CAN_BS1, CAN_BS2,CAN_Prescaler
{5, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,450}, //未通
{10, CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_2tq, 400}, //未通
{15, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,150}, //15K
{20, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,200}, //20k
{25, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,90}, //25k
{40, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,100}, //40k
{50, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,45}, //50k
{62, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,36}, //62.5k
{80, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,50}, //80k
{100, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,45}, //100K
{125, CAN_SJW_1tq,CAN_BS1_13tq, CAN_BS2_2tq,18}, //125K
{200, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,20}, //200K
{250, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,9}, //250k
{400, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,10}, //400K
{500, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,9}, //500K
{666, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,8}, //未通
{800, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,5}, //800K
{1000,CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,4}, //1000K
};
void CAN_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); //使能PORTA时钟
// GPIO_PinRemapConfig(GPIO_Remap2_CAN1,ENABLE); //复用引脚设置
// GPIO_PinRemapConfig(GPIO_Remap_CAN2,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //使能CAN1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); //使能CAN2时钟
/* Configure CAN1 pin: RX->PA11上拉输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN1 pin: TX->PA12复用推挽 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN1 pin: RS->PA15复用推挽 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN2 pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure CAN2 pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RS_OFF;
}
void CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; /* 时间触发禁止, 时间触发:CAN硬件的内部定时器被激活,并且被用于产生时间戳 */
CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
CAN_InitStructure.CAN_AWUM = DISABLE; /* 自动唤醒禁止,有报文来的时候自动退出休眠 */
CAN_InitStructure.CAN_NART = ENABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文 */
CAN_InitStructure.CAN_TXFP = ENABLE; /* 发送优先级 0---由标识符决定 1---由发送请求顺序决定 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 模式 */
CAN_Baud_Process(250,&CAN_InitStructure);//波特率250K
// CAN_Init(CAN1,&CAN_InitStructure);
// CAN_Init(CAN2,&CAN_InitStructure);
if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)
{
/* 初始化时先设置CAN_MCR的初始化位 */
/* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式 */
}
if (CAN_Init(CAN2,&CAN_InitStructure) == CANINITFAILED)
{
/* 初始化时先设置CAN_MCR的初始化位 */
/* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式 */
}
//CAN1滤波器设置
CAN_FilterInitStructure.CAN_FilterNumber = 0; ///* 过滤器组 */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; ///* 能够通过该过滤器的报文存到fifo0中 */
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
//CAN2滤波器设置
CAN_FilterInitStructure.CAN_FilterNumber = 14; ///* 过滤器组 */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; ///* 能够通过该过滤器的报文存到fifo0中 */
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
CAN_ITConfig(CAN2,CAN_IT_FMP0, ENABLE); /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
}
/***********************************************************************
文件名称:CAN_Baud_Process
功 能:计算波特率,返回
编写时间:2013.4.25
编 写 人:
注 意:
CAN_SJW : CAN_SJW_1tq - CAN_SJW_4tq 不能比任何一相位缓冲段长
CAN_BS1 : CAN_BS1_1tq - CAN_BS1_16tq
CAN_BS2 : CAN_BS2_1tq - CAN_BS2_8tq
CAN_Prescaler : 1 - 1024
配置说明:
CAN_SJW + CAN_BS1 / (CAN_SJW + CAN_BS1 + CAN_BS2)
0.75 baud > 800k
0.80 baud > 500k
0.875 baud <= 500k
baud = 36 / (CAN_SJW + CAN_BS1 + CAN_BS2) / CAN_Prescaler
***********************************************************************/
void CAN_Baud_Process(unsigned int Baud,CAN_InitTypeDef *CAN_InitStructure)
{
unsigned int i = 0;
for(i = 0;i < CAN_BAUD_NUM;i ++)
{
if(Baud == CAN_baud_table[i][0])
{
CAN_InitStructure->CAN_SJW = CAN_baud_table[i][1];
CAN_InitStructure->CAN_BS1 = CAN_baud_table[i][2];
CAN_InitStructure->CAN_BS2 = CAN_baud_table[i][3];
CAN_InitStructure->CAN_Prescaler = CAN_baud_table[i][4];
break;
}
}
}
void CAN1_TX(unsigned int ID,unsigned char Data)
{
unsigned char i;
CanTxMsg TxMessage;
TxMessage.StdId=ID; //标准标识符为0x00
TxMessage.ExtId=0x0000; //扩展标识符0x0000
TxMessage.IDE = CAN_ID_STD; //使用标准标识符
TxMessage.RTR = CAN_RTR_DATA; /* 设置为数据帧 */
TxMessage.DLC = 8; /* 数据长度, can报文规定最大的数据长度为8字节 */
CAN1_DATA[0]=Data;
for(i = 0;i < 8; i ++)
{
TxMessage.Data[i] = CAN1_DATA[i];//can_send_data[i];
}
CAN_Transmit(CAN1,&TxMessage); /* 返回这个信息请求发送的邮箱号0,1,2或没有邮箱申请发送no_box */
}
/*********扩展标识符发送************/
//void CanExtIdSend(CanMsgTypeDef msg)
void CanExtIdSend(unsigned int Exid,unsigned char Data1,unsigned char Data2,unsigned char Data3,unsigned char Data4)
{
unsigned char i;
CanTxMsg TxMessage;
TxMessage.StdId=0; //标准标识符为0x00
TxMessage.ExtId=Exid; //扩展标识符0x0000
TxMessage.IDE = CAN_ID_EXT; //使用扩展标识符
TxMessage.RTR = CAN_RTR_DATA; /* 设置为数据帧 */
TxMessage.DLC = 4; /* 数据长度, can报文规定最大的数据长度为8字节 */
CAN1_DATA[0]=Data1;
CAN1_DATA[1]=Data2;
CAN1_DATA[2]=Data3;
CAN1_DATA[3]=Data4;
for(i = 0;i < 4; i ++)
{
//TxMessage.Data[i] = msg.data[i];//can_send_data[i];
TxMessage.Data[i] = CAN1_DATA[i]; //can_send_data[i];
}
CAN_Transmit(CAN1,&TxMessage); /* 返回这个信息请求发送的邮箱号0,1,2或没有邮箱申请发送no_box */
}
//CAN1中断程序
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI=0;
RxMessage.Data[0]=0x00;
CAN_Receive(CAN1,CAN_FIFO0, &RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
if((RxMessage.StdId==0x22)&&(RxMessage.Data[0]==0xbb))
{
LED2_ON;
}
can1_rec_flag = 1;
CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0); /* 清除挂起中断 */
// SEI();//打开总中断
}
void CAN2_TX(unsigned int ID,unsigned char Data)
{
unsigned char i;
CanTxMsg TxMessage;
TxMessage.StdId=ID; //标准标识符为0x00
TxMessage.ExtId=0x0000; //扩展标识符0x0000
TxMessage.IDE = CAN_ID_STD;//使用标准标识符
TxMessage.RTR = CAN_RTR_DATA; /* 设置为数据帧 */
TxMessage.DLC = 8; /* 数据长度, can报文规定最大的数据长度为8字节 */
CAN2_DATA[0]=Data;
for(i = 0;i < 8; i ++)
{
TxMessage.Data[i] = CAN2_DATA[i];//can_send_data[i];
}
CAN_Transmit(CAN2,&TxMessage); /* 返回这个信息请求发送的邮箱号0,1,2或没有邮箱申请发送no_box */
}
//CAN2中断程序
void CAN2_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI=0;
RxMessage.Data[0]=0x00;
CAN_Receive(CAN2,CAN_FIFO0, &RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
//if((RxMessage.StdId==0x11)&&(RxMessage.Data[0]==0xaa)) { LED2_ON;}
can2_rec_flag = 1;
CAN_ClearITPendingBit(CAN2,CAN_IT_FMP0); /* 清除挂起中断 */
// SEI();//打开总中断
}
|
|