STM32 CAN外设简介:
1、bxCAN外设可以自动发送CAN报文和按照过滤器自动接收CAN报文,程序只需处理报文数据,无需关注电平细节;
2、STM32的CAN外设最高支持1Mbps;
3、(1)3个可配置优先级的发送邮箱;
(2)2个三级深度的接收FIFO;
(3)两个过滤器组,每组14个过滤器;
(4)CAN_Rx 采用 PA11引脚,CAN_Tx 采用 PA12引脚


4、发送邮箱和接收FIFO的状态转换

5、14个报文接收过滤器配置


6、3种测试工作模式

7、环回测试实验

main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "MyCAN.h"
int main(void)
{
uint8_t uiKeyNum;
OLED_Init();
Key_Init();
MyCAN_Init();
OLED_ShowString(2,1,"RxID:");
OLED_ShowString(3,1,"Leng:");
OLED_ShowString(4,1,"Data:");
while(1)
{
uiKeyNum = Key_GetNum();
if(1 == uiKeyNum)
{
uint8_t TxData[]= {0x11, 0x22};
MyCAN_Transmit(0x123, 2, TxData);
}
if(MyCAN_ReceiveFlag())
{
uint32_t RxID;
uint8_t RxLength;
uint8_t RxData[8];
MyCAN_Receive(&RxID, &RxLength, RxData);
OLED_ShowHexNum(2, 6, RxID, 3);
OLED_ShowHexNum(3, 6, RxLength, 1);
OLED_ShowHexNum(4, 6, RxData[0], 2);
OLED_ShowHexNum(4, 9, RxData[1], 3);
}
}
}
MyCAN.c
#include "stm32f10x.h" // Device header
void MyCAN_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
CAN_InitTypeDef CAN_InitStructure;
CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
CAN_InitStructure.CAN_Prescaler = 48;
CAN_InitStructure .CAN_BS1 = CAN_BS1_2tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_Init(CAN1, &CAN_InitStructure);
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void MyCAN_Transmit(uint32_t uiID, uint8_t uiLength, uint8_t *puiData)
{
CanTxMsg TxMessage;
TxMessage.StdId = uiID;
TxMessage.ExtId = uiID;
TxMessage.IDE = CAN_Id_Standard;
TxMessage.RTR = CAN_RTR_Data;
TxMessage.DLC = uiLength;
for(uint8_t uiLoop = 0; uiLoop < uiLength; uiLoop++)
{
TxMessage.Data[uiLoop] = puiData[uiLoop];
}
uint8_t TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
while(CAN_TransmitStatus(CAN1, TransmitMailbox) != CAN_TxStatus_Ok);
}
uint8_t MyCAN_ReceiveFlag(void)
{
if ( 0 < CAN_MessagePending(CAN1, CAN_FIFO0))
{
return 1;
}
return 0;
}
void MyCAN_Receive(uint32_t *uiID, uint8_t *uiLength, uint8_t *puiData)
{
CanRxMsg RxMessage;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
if(RxMessage.IDE == CAN_Id_Standard)
{
*uiID = RxMessage.StdId;
}
else if(RxMessage.IDE == CAN_Id_Extended)
{
*uiID = RxMessage.ExtId;
}
if(RxMessage.RTR == CAN_RTR_Data)
{
*uiLength = RxMessage.DLC;
for(uint8_t uiLoop = 0; uiLoop < RxMessage.DLC; uiLoop++)
{
puiData[uiLoop] = RxMessage.Data[uiLoop];
}
}
else
{
}
}
STM32 CAN外设
浙公网安备 33010602011771号