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
    {
        
    }
}

 

posted on 2025-04-01 22:44  轩~邈  阅读(45)  评论(0)    收藏  举报