有哪位大神幫忙看看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[0])
{
CAN_InitStructure->CAN_SJW = CAN_baud_table[1];
CAN_InitStructure->CAN_BS1 = CAN_baud_table[2];
CAN_InitStructure->CAN_BS2 = CAN_baud_table[3];
CAN_InitStructure->CAN_Prescaler = CAN_baud_table[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 = CAN1_DATA;//can_send_data;
}
CAN_Transmit(CAN1,&TxMessage); /* 回傳這個資訊請求發送的郵箱號0,1,2或沒有郵箱申請發送no_box */
}
uj5u.com熱心網友回復:
量量硬體管腳轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/59982.html
標籤:硬件使用
上一篇:求佬指教(驅動板)
