stm32 can bus 总结
1.初始化CAN參數(shù)
/* CAN init function */
void MX_CAN_Init(void)
{
? CAN_FilterConfTypeDef filter;
? hcan.Instance = CAN1;
? hcan.Init.Prescaler = 3;
//? hcan.Init.Mode = CAN_MODE_NORMAL;
? hcan.Init.Mode = CAN_MODE_LOOPBACK;
? hcan.Init.SJW = CAN_SJW_1TQ;
? hcan.Init.BS1 = CAN_BS1_12TQ;
? hcan.Init.BS2 = CAN_BS2_2TQ;
? hcan.Init.TTCM = DISABLE;
? hcan.Init.ABOM = DISABLE;
? hcan.Init.AWUM = DISABLE;
? hcan.Init.NART = DISABLE;
? hcan.Init.RFLM = DISABLE;
? hcan.Init.TXFP = ENABLE;
? //在cube生成的基礎(chǔ)上添加以下三項(xiàng),用于保存收發(fā)的內(nèi)容
? hcan.pTxMsg = &CAN_TX_MSG;? //用于保存要發(fā)送的內(nèi)容
? hcan.pRxMsg = &CAN_RX0_MSG;? //對(duì)應(yīng)fifo0接收
? hcan.pRx1Msg = &CAN_RX1_MSG; //對(duì)應(yīng)fifo1接收
? if (HAL_CAN_Init(&hcan) != HAL_OK)??
? {
??? _Error_Handler(__FILE__, __LINE__);
? }
? filter.FilterNumber=1;
? filter.FilterMode=CAN_FILTERMODE_IDMASK;
? filter.FilterScale=CAN_FILTERSCALE_32BIT;
? filter.FilterIdHigh=0x0000;
? filter.FilterIdLow=0x0000;
? filter.FilterMaskIdHigh=0x0000;
? filter.FilterMaskIdLow=0x0000;
? filter.FilterFIFOAssignment=CAN_FIFO0;
? filter.FilterActivation=ENABLE;
?
? if(? HAL_CAN_ConfigFilter(&hcan,&filter) != HAL_OK) //剛開始因?yàn)闆]有加過濾配置,導(dǎo)致數(shù)據(jù)一直收不到,所以接收中斷進(jìn)不去。
? {
????? Error_Handler();
? }
?? ?
? if(HAL_CAN_Receive_IT(&hcan,CAN_FIFO0) != HAL_OK) // 打開接收中斷(注意cube自動(dòng)生成的中斷處理會(huì)再次清除中斷使能,所以只能接受一次,想要反復(fù)接收每次接收萬要重新打開)
? {
????? Error_Handler();
? }
}
?
2.初始化IO
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
? GPIO_InitTypeDef GPIO_InitStruct;
? if(canHandle->Instance==CAN1)
? {
? /* USER CODE BEGIN CAN1_MspInit 0 */
? /* USER CODE END CAN1_MspInit 0 */
??? /* CAN1 clock enable */
??? __HAL_RCC_CAN1_CLK_ENABLE();
?
??? /**CAN GPIO Configuration?? ?
??? PB8???? ------> CAN_RX
??? PB9???? ------> CAN_TX
??? */
??? GPIO_InitStruct.Pin = CAN_RX_Pin;
??? GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
??? GPIO_InitStruct.Pull = GPIO_NOPULL;
??? HAL_GPIO_Init(CAN_RX_GPIO_Port, &GPIO_InitStruct);
??? GPIO_InitStruct.Pin = CAN_TX_Pin;
??? GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
??? GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
??? HAL_GPIO_Init(CAN_TX_GPIO_Port, &GPIO_InitStruct);
??? __HAL_AFIO_REMAP_CAN1_2(); //參考手冊(cè),PB8,PB9要重映射IO
??? /* CAN1 interrupt Init */
??? HAL_NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 0, 0);
??? HAL_NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
??? HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
??? HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
//??? HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);??????? //結(jié)合上面初始化,這里FIFO1的中斷用不上
//??? HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
//??? HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
//??? HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
? /* USER CODE BEGIN CAN1_MspInit 1 */
? /* USER CODE END CAN1_MspInit 1 */
? }
}
3.發(fā)送
? hcan.pTxMsg->StdId=0x00;?? ?
?? ??? ??? ?hcan.pTxMsg->ExtId=0x0000;
?? ??? ??? ?hcan.pTxMsg->IDE=CAN_ID_EXT;
?? ??? ??? ?hcan.pTxMsg->RTR=CAN_RTR_DATA;
?? ??? ??? ?hcan.pTxMsg->DLC=2;
?? ??? ??? ?hcan.pTxMsg->Data[0]=0x12;
?? ??? ??? ?hcan.pTxMsg->Data[1]=0x89;
?? ??? ??? ?hal_status = HAL_CAN_Transmit_IT(&hcan); //用這個(gè)不會(huì)卡死
?? ??? ??? ?if(hal_status != HAL_OK)
?? ??? ??? ?{
?? ??? ??? ??? ?Error_Handler();
?? ??? ??? ?}
4.關(guān)于SCE中斷,不是很了解,后面再更新吧。
?
5.重點(diǎn)摘要,用于幫助制定通訊協(xié)議。要關(guān)注過濾寄存器,屏蔽寄存器。
在當(dāng)今的CAN應(yīng)用中, CAN網(wǎng)絡(luò)的節(jié)點(diǎn)在不斷增加,并且多個(gè)CAN常常通過網(wǎng)關(guān)連接起來,因
此整個(gè)CAN網(wǎng)中的報(bào)文數(shù)量(每個(gè)節(jié)點(diǎn)都需要處理)急劇增加。除了應(yīng)用層報(bào)文外,網(wǎng)絡(luò)管理和診
斷報(bào)文也被引入。
● 需要一個(gè)增強(qiáng)的過濾機(jī)制來處理各種類型的報(bào)文(注:過濾機(jī)制就是為了應(yīng)對(duì)報(bào)文數(shù)量太多的痛點(diǎn))
此外,應(yīng)用層任務(wù)需要更多CPU時(shí)間,因此報(bào)文接收所需的實(shí)時(shí)響應(yīng)程度需要減輕。
● 接收FIFO的方案允許CPU花很長時(shí)間處理應(yīng)用層任務(wù)而不會(huì)丟失報(bào)文 (注:FIFO是為了緩解CPU接收?qǐng)?bào)文所需的實(shí)時(shí)響應(yīng)的程度)
屏蔽位模式
在屏蔽位模式下,標(biāo)識(shí)符寄存器和屏蔽寄存器一起,指定報(bào)文標(biāo)識(shí)符的任何一位,應(yīng)該按照
“必須匹配”或“不用關(guān)心”處理。
標(biāo)識(shí)符列表模式
在標(biāo)識(shí)符列表模式下,屏蔽寄存器也被當(dāng)作標(biāo)識(shí)符寄存器用。因此,不是采用一個(gè)標(biāo)識(shí)符加一
個(gè)屏蔽位的方式,而是使用2個(gè)標(biāo)識(shí)符寄存器。接收?qǐng)?bào)文標(biāo)識(shí)符的每一位都必須跟過濾器標(biāo)識(shí)符
相同。
?
應(yīng)用程序選擇1個(gè)空置的發(fā)送郵箱;設(shè)置標(biāo)識(shí)符,數(shù)據(jù)長度和待發(fā)送數(shù)據(jù);
然后對(duì)CAN_TIxR寄存器的TXRQ位置’1’,來請(qǐng)求發(fā)送。 TXRQ位置’1’后,郵箱就不再是空郵
箱,軟件對(duì)郵箱寄存器就不再有寫的權(quán)限。 TXRQ位置1后,郵箱馬上
進(jìn)入掛號(hào)狀態(tài),并等待成為最高優(yōu)先級(jí)的郵箱 。一旦郵箱成為最高優(yōu)先級(jí)的
郵箱,其狀態(tài)就變?yōu)?span style="font-size:14pt;">預(yù)定發(fā)送狀態(tài)。一旦CAN總線進(jìn)入空閑狀態(tài),預(yù)定發(fā)送郵箱中的報(bào)文就馬
上被發(fā)送(進(jìn)入發(fā)送狀態(tài))。一旦郵箱中的報(bào)文被成功發(fā)送后,它馬上變?yōu)?strong>空置郵箱 。
當(dāng)有超過1個(gè)發(fā)送郵箱在掛號(hào)時(shí),發(fā)送順序由郵箱中報(bào)文的標(biāo)識(shí)符決定。如果標(biāo)識(shí)符的值相等,那么郵箱號(hào)小的報(bào)文先被發(fā)送。
在接收一個(gè)報(bào)文時(shí),其標(biāo)識(shí)符首先與配置在標(biāo)識(shí)符列表模式下的過濾器相比較;如果匹配上,報(bào)文就被存放到相關(guān)聯(lián)的FIFO中,并且所匹配的過濾
器的序號(hào)被存入過濾器匹配序號(hào)中。如同例子中所顯示,報(bào)文標(biāo)識(shí)符跟#4標(biāo)識(shí)符匹配,因此報(bào)文內(nèi)容和FMI4被存入FIFO。
如果沒有匹配,報(bào)文標(biāo)識(shí)符接著與配置在屏蔽位模式下的過濾器進(jìn)行比較。
如果報(bào)文標(biāo)識(shí)符沒有跟過濾器中的任何標(biāo)識(shí)符相匹配,那么硬件就丟棄該報(bào)文,且不會(huì)對(duì)軟件
有任何打擾
?
轉(zhuǎn)載于:https://www.cnblogs.com/zhanghonglang/p/8919181.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的stm32 can bus 总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 仿vue的前端自定义cmd命令拉取项目脚
- 下一篇: python 编码文件json.load