我在玩STM32F1系列的單片機,做CAN通信測驗這塊的時候,單片機能夠對外發送CAN資料,使用PC和CAN工具能夠收到報文,但是用PC發送報文,單片機卻收不到(收到后點亮一個LED燈,但是一直不成功),哪位大神給解答一下,謝謝!
uj5u.com熱心網友回復:
最好上圖和程式。
說幾種情況:
1. STM32F1配置CAN環回模式進行通信測驗,看你的接收中斷及處理程式是否正常。
2. 檢查PC端CAN工具通訊引數是否和單片機一致。
3. 在PC端發送資料時,單片機是否也在發送資料占用總線,導致資料發不出去。
4. 檢查電路,不過通訊沒問題,電路一般沒問題。
僅供參考。
uj5u.com熱心網友回復:
補上圖:
代碼:
CAN模式初始化
void CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //打開CAN1時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //PA埠時鐘打開
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PA11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PA12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CAN單元設定
CAN_InitStructure.CAN_TTCM=DISABLE; //非時間觸發通信模式
CAN_InitStructure.CAN_ABOM=DISABLE; //軟體自動離線管理
CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通過軟體喚醒(清除CAN->MCR的SLEEP位)
CAN_InitStructure.CAN_NART=ENABLE; //使用報文自動傳送
CAN_InitStructure.CAN_RFLM=DISABLE; //報文不鎖定,新的覆寫舊的
CAN_InitStructure.CAN_TXFP=DISABLE; //優先級由報文識別符號決定
CAN_InitStructure.CAN_Mode= mode; //模式設定
CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳躍寬度(Tsjw)為tsjw+1個時間單位 CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范圍CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范圍CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //分頻系數(Fdiv)為brp+1
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置過濾器
CAN_FilterInitStructure.CAN_FilterNumber=0; //過濾器0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//過濾器0關聯到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活過濾器0
CAN_FilterInit(&CAN_FilterInitStructure);//濾波器初始化
#if CAN_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //FIFO0訊息掛號中斷允許.
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主優先級為1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次優先級為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
}
發送函式:
u8 CAN_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // 標準識別符號為0
TxMessage.ExtId=0x12; // 設定擴展標示符(29位)
TxMessage.IDE=0; // 使用擴展識別符號
TxMessage.RTR=0; // 訊息型別為資料幀,一幀8位
TxMessage.DLC=len; // 發送兩幀資訊
for(i=0;i<len;i++)
TxMessage.Data[i]=msg[i]; // 第一幀資訊
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; //等待發送結束
if(i>=0XFFF)return 1;
return 0;
}
接收函式:
u8 CAN_Receive_Msg(u8 *buf)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //沒有接收到資料,直接退出
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//讀取資料
for(i=0;i<RxMessage.DLC;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}
主函式:
int main()
{
u8 j=0;
u8 res;
u8 tbuf[8],char_buf[8];
u8 rbuf[8];
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷優先級分組 分2組
LED_Init();
USART1_Init(9600);
KEY_Init();
CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_Normal);//500Kbps波特率
while(1)
{
res=CAN_Send_Msg(tbuf,8);
if(res)
{
printf("Send Failed!\r\n");
}
else
{
printf("發送資料:%s\r\n",char_buf);
}
res=CAN_Receive_Msg(rbuf);
if(res)
{
led1=!led1;
for(j=0;j<res;j++)
{
char_buf[j]=rbuf[j]+0x30;
}
printf("接收資料:%s\r\n",char_buf);
}
}
}
uj5u.com熱心網友回復:
沒有定義這個引數 CAN_RX0_INT_ENABLE轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/17244.html
標籤:單片機/工控
