1751|2

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【HC32F4A0开发板】CAN1通信测试 [复制链接]

 

这篇来学习下CAN1通信收到测试,开发板通过CAN1向外发送数据,开发板上的CAN1收到数据后。从串口输出接收到CAN信息。

 

一、硬件电路部分

1.1、CAN1收发器电路

1.2、CAN1通信MCU端口

CAN1使用MCU的PD4和PD5端口。

二、程序

 

2.1、can.c

#include "main.h"
#include "can.h"

uint8_t can1_rx_flag=0;

void CAN1_IrqCallback(void)
{
    stc_can_error_info_t stcErr;

    (void)CAN_GetErrorInfo(CAN1_UNIT, &stcErr);
//    DDL_Printf("---> CAN error type: %u, %s\r\n", stcErr.u8ErrorType, m_s8ErrorTypeStr[stcErr.u8ErrorType]);

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_BUS_OFF) == SET) {
        DDL_Printf("BUS OFF.\r\n");
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_RX_BUF_OVF) == SET) {
        DDL_Printf("RX overflow.\r\n");
        /* Call CAN_GetRxFrame() to get the received frame, then this flag cleared. */
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_TX_BUF_FULL) == SET) {
        DDL_Printf("TX buffer full.\r\n");
    }

    if (CAN_GetStatus(CAN1_UNIT, CAN_FLAG_TX_ABORTED) == SET) {
        DDL_Printf("TX aborted.\r\n");
        CAN_ClearStatus(CAN1_UNIT, CAN_FLAG_TX_ABORTED);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_STB_TX) == SET) {
        //DDL_Printf("STB transmitted.\r\n");
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_STB_TX);
        //m_u8STBTxFlag = 1U;
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_PTB_TX) == SET) {
        DDL_Printf("PTB transmitted.\r\n");
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_PTB_TX);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_RX) == SET) {
        /* Received frame can be read here. */
        //DDL_Printf("Received a frame.\r\n");
        can1_rx_flag=1;
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_RX);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_RX_BUF_WARN) == SET) {
        /* Received frames can be read here. */
        DDL_Printf("RX buffer warning.\r\n");
        //m_u8RxFlag = 1U;
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_RX_BUF_WARN);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_RX_BUF_FULL) == SET) {
        /* Received frames can be read here. */
        DDL_Printf("RX buffer full.\r\n");
        //m_u8RxFlag = 1U;
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_RX_BUF_FULL);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_RX_OVERRUN) == SET) {
        DDL_Printf("RX buffer overrun.\r\n");
        //m_u8RxFlag = 1U;
        CAN_ClearStatus(CM_CAN1, CAN_FLAG_RX_OVERRUN);
    }

    if (CAN_GetStatus(CM_CAN1, CAN_FLAG_TEC_REC_WARN) == SET) {
        DDL_Printf("TEC or REC reached warning limit.\r\n");
    }
}

void can1_txbuf(u32 id, u32 dlc, u8 *txbuf)
{
	stc_can_tx_frame_t can1_tx1;
	u8 i=0;
	can1_tx1.u32Ctrl 	= 0x0UL;
	can1_tx1.u32ID 		= id;
	can1_tx1.IDE     	= 0U;
  can1_tx1.DLC     	= dlc;
	for(i=0;i<dlc;i++)
	{
		can1_tx1.au8Data[i] = txbuf[i];
	}
	CAN_FillTxFrame(CM_CAN1, CAN_TX_BUF_STB, &can1_tx1);
	CAN_StartTx(CM_CAN1, CAN_TX_REQ_STB_ONE);
}

static void CanCommClockConfig(void)
{
    CLK_SetCANClockSrc(CLK_CAN1, CLK_CANCLK_SYSCLK_DIV6);
}

static void CanPinConfig(void)
{
    GPIO_SetFunc(GPIO_PORT_D, GPIO_PIN_05, GPIO_FUNC_60);
    GPIO_SetFunc(GPIO_PORT_D, GPIO_PIN_04, GPIO_FUNC_61);
}

static void CanInitConfig(void)
{
    stc_can_init_t stcCanInit;
    stc_can_filter_config_t astcFilter[CAN_FILTER_NUM] = {
        {CAN_FILTER1_ID, CAN_FILTER1_ID_MASK, CAN_FILTER1_ID_TYPE},
        {CAN_FILTER2_ID, CAN_FILTER2_ID_MASK, CAN_FILTER2_ID_TYPE},
        {CAN_FILTER3_ID, CAN_FILTER3_ID_MASK, CAN_FILTER3_ID_TYPE},
    };

    /* Initializes CAN. */
    (void)CAN_StructInit(&stcCanInit);
    stcCanInit.stcBitCfg.u32Prescaler = 2U;
    stcCanInit.stcBitCfg.u32TimeSeg1  = 15U;
    stcCanInit.stcBitCfg.u32TimeSeg2  = 5U;
    stcCanInit.stcBitCfg.u32SJW       = 5U;
    stcCanInit.pstcFilter             = astcFilter;
    stcCanInit.u16FilterSelect        = CAN_FILTER_SEL;
    stcCanInit.u8WorkMode             = CAN_WORK_MD_NORMAL;

    /* Enable peripheral clock of CAN. */
    FCG_Fcg1PeriphClockCmd(CAN1_PERIPH_CLK, ENABLE);
    (void)CAN_Init(CAN1_UNIT, &stcCanInit);
    /* Enable the interrupts, the status flags can be read. */
    CAN_IntCmd(CAN1_UNIT, CAN_INT_ALL, DISABLE);
    /* Enalbe the interrupts that needed. */
    CAN_IntCmd(CAN1_UNIT, CAN_INT_SEL, ENABLE);
}

static void CanIrqConfig(void)
{
    stc_irq_signin_config_t stcIrq;

    stcIrq.enIntSrc    = CAN1_INT_SRC;
    stcIrq.enIRQn      = CAN1_INT_IRQn;
    stcIrq.pfnCallback = &CAN1_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrq);
    NVIC_ClearPendingIRQ(stcIrq.enIRQn);
    NVIC_SetPriority(stcIrq.enIRQn, CAN1_INT_PRIO);
    NVIC_EnableIRQ(stcIrq.enIRQn);
}

static void CanPhyEnable(void)
{
    BSP_IO_Init();
    BSP_CAN_STB_IO_Init();

    /* Set PYH STB pin as low. */
    BSP_CAN_STBCmd(EIO_PIN_RESET);
}

void init_can(void)
{
		CanCommClockConfig();
    CanPinConfig();
    CanInitConfig();
    CanIrqConfig();
    CanPhyEnable();
}

2.2、can.h

#ifndef _CAN_H
#define _CAN_H
#include "main.h"

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
/* Unit definition of CAN in this example. */
#define CAN_SEL_UNIT1                   (0U)
#define CAN_SEL_UNIT2                   (1U)

/* Select a CAN unit. */
#define CAN_UNIT_SEL                    (CAN_SEL_UNIT1)

/* Definitions according to 'CAN_UNIT_SEL'. */
#if (CAN_UNIT_SEL == CAN_SEL_UNIT1)
#define CAN1_UNIT                        (CM_CAN1)
#define CAN1_PERIPH_CLK                  (FCG1_PERIPH_CAN1)

#define CAN1_TX_PORT                     (GPIO_PORT_D)
#define CAN1_TX_PIN                      (GPIO_PIN_05)
#define CAN1_TX_PIN_FUNC                 (GPIO_FUNC_60)

#define CAN1_RX_PORT                     (GPIO_PORT_D)
#define CAN1_RX_PIN                      (GPIO_PIN_04)
#define CAN1_RX_PIN_FUNC                 (GPIO_FUNC_61)

#define CAN1_CLK_UNIT                    (CLK_CAN1)
#define CAN1_CLK_SRC                     (CLK_CANCLK_SYSCLK_DIV6)

#define CAN1_INT_PRIO                    (DDL_IRQ_PRIO_03)
#define CAN1_INT_SRC                     (INT_SRC_CAN1_HOST)
#define CAN1_INT_IRQn                    (INT092_IRQn)

#elif (CAN_UNIT_SEL == CAN_SEL_UNIT2)
#define CAN_UNIT                        (CM_CAN2)
#define CAN_PERIPH_CLK                  (FCG1_PERIPH_CAN2)

#define CAN_TX_PORT                     (GPIO_PORT_D)
#define CAN_TX_PIN                      (GPIO_PIN_07)
#define CAN_TX_PIN_FUNC                 (GPIO_FUNC_62)

#define CAN_RX_PORT                     (GPIO_PORT_D)
#define CAN_RX_PIN                      (GPIO_PIN_06)
#define CAN_RX_PIN_FUNC                 (GPIO_FUNC_63)

#define CAN_CLK_UNIT                    (CLK_CAN2)
#define CAN_CLK_SRC                     (CLK_CANCLK_SYSCLK_DIV6)

#define CAN_INT_PRIO                    (DDL_IRQ_PRIO_03)
#define CAN_INT_SRC                     (INT_SRC_CAN2_HOST)
#define CAN_INT_IRQn                    (INT092_IRQn)
#else
#error "The unit is NOT supported!!!"
#endif

/* CAN interrupt type selection. */
#define CAN_INT_SEL                     (CAN_INT_STB_TX      | \
                                         CAN_INT_PTB_TX      | \
                                         CAN_INT_RX_BUF_WARN | \
                                         CAN_INT_RX_BUF_FULL | \
                                         CAN_INT_RX_OVERRUN  | \
                                         CAN_INT_RX)

/* Acceptance filter. */
#define CAN_FILTER_SEL                  (CAN_FILTER1 | CAN_FILTER2 | CAN_FILTER3)
#define CAN_FILTER_NUM                  (3U)

#define CAN_FILTER1_ID                  (0x701UL)
#define CAN_FILTER1_ID_MASK             (0x0UL)
#define CAN_FILTER1_ID_TYPE             (CAN_ID_STD)        /*!< Only accept frames with standard ID 0x701. */

#define CAN_FILTER2_ID                  (0x12131415UL)
#define CAN_FILTER2_ID_MASK             (0x000000F0UL)
#define CAN_FILTER2_ID_TYPE             (CAN_ID_EXT)        /*!< Accept frames with extended ID 0x121314x5. */

#define CAN_FILTER3_ID                  (0x1A1B1C1DUL)
#define CAN_FILTER3_ID_MASK             (0x0000000FUL)
#define CAN_FILTER3_ID_TYPE             (CAN_ID_STD_EXT)    /*!< Accept frames with extended ID 0x1A1B1C1x, \
                                                                 standard ID 0x41x(0x1A1B1C1D & 0x7FF(standard ID mask)). */
/* Message ID definitions. */
#define CAN_TX_ID1                      (0x601UL)
#define CAN_TX_ID1_IDE                  (0U)

#define CAN_TX_ID2                      (0x602UL)
#define CAN_TX_ID2_IDE                  (0U)

#define CAN_TX_ID3                      (0x1020301UL)
#define CAN_TX_ID3_IDE                  (1U)

#define CAN_TX_ID4                      (0x1030402UL)
#define CAN_TX_ID4_IDE                  (1U)

#define CAN_TX_ID5                      (0x1030503UL)
#define CAN_TX_ID5_IDE                  (1U)

/* Size of the TX data. */
#define CAN_TX_DLC                      (CAN_DLC8)
#define CAN_TX_DATA_SIZE                (8U)

/* Timeout value */
#define CAN_TX_TIMEOUT_MS               (100U)

/* TX process */
#define CAN_TX_PROCESS_PTB              (1U)
#define CAN_TX_PROCESS_STB              (2U)
#define CAN_TX_PROCESS_PTB_STB          (3U)

/* Number of RX frame */
#define CAN_RX_FRAME_NUM                (8U)

extern uint8_t can1_rx_flag;

void init_can(void);
void can1_txbuf(u32 id, u32 dlc, u8 *txbuf);
void can1_rxbuf(stc_can_rx_frame_t rxbuf);

#endif

2.3、mian.c

#include "main.h"
#include "lcd.h"
#include "sram.h"
#include "timer0.h"
#include "led.h"
#include "touch.h"
#include "can.h"


stc_touchpad_data_t touchdat;
void SysTick_Handler(void)
{
    SysTick_IncTick();
		led1_tog();
}

int32_t main(void)
{
	uint8_t can_txbuf[8];
	stc_can_rx_frame_t can_rxbuf;
	uint16_t u=0;
	uint8_t i=0;
	uint16_t cord[6]={WHITE, BLUE, BRED, GBLUE, RED, YELLOW};
	/* Register write enable for some required peripherals. */
	LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);

	BSP_CLK_Init();
	/* EXCLK 60MHz */
	CLK_SetClockDiv(CLK_BUS_EXCLK, CLK_EXCLK_DIV4);
	DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_Preinit);
	BSP_IO_Init();
	BSP_LED_Init();
	BSP_LCD_IO_Init();
	
	init_led();
	init_touch();
	init_lcd();
	init_sram();
	init_timer0();
	init_can();
	SysTick_Init(1000U);

	LL_PERIPH_WP(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
	POINT_COLOR=RED;       
	LCD_Clear(WHITE);
	//sram_test();
	
	for(u=0;u<8;u++)
	{
		can_txbuf[u]=0;
	}
	
	u=0;
	for (;;) 
	{
		TOUCHPAD_Read(&touchdat);
		if (touchdat.enPointPress == SET)
		{
			DDL_Printf("x: %d, y: %d \r\n",touchdat.stcPoint.u16X,touchdat.stcPoint.u16Y );
		}
		BSP_LED_Toggle(LED_RED);
		SysTick_Delay(500U);
		BSP_LED_Toggle(LED_BLUE);
		SysTick_Delay(500U);
		u++;
		if(u>250)
		{
			u=0;
		}
		can_txbuf[0]=u;
		can_txbuf[1]=u+1;
		can_txbuf[2]=u+2;
		can_txbuf[3]=u+3;
		can1_txbuf(0x301, CAN_DLC8, can_txbuf);
		
		if(can1_rx_flag==1)
		{
			can1_rx_flag=0;
			CAN_GetRxFrame(CM_CAN1, &can_rxbuf);
			DDL_Printf("CAN received ID %.8x:\r\n", (unsigned int)can_rxbuf.u32ID);
			
			for (i = 0; i < (uint8_t)can_rxbuf.DLC; i++) 
			{
					DDL_Printf(" %.2x.", can_rxbuf.au8Data[i]);
					can_rxbuf.au8Data[i] = 0U;
			}
			DDL_Printf("\r\n");
		}
	}
}

 

三、程序运行

 

串口收到的数据和CAN软件收发的数据

 

 

最新回复

去找了点资料看看型号功能对照表,说是针对不同的应用场景来设计其MCU, 说什么汽车电子板块还没有完善,不是很理解   详情 回复 发表于 2023-3-13 21:40
点赞 关注
 
 

回复
举报

6972

帖子

11

TA的资源

版主

沙发
 

66666,can用起来强大,汽车必备。

 
 
 

回复

4854

帖子

3

TA的资源

版主

板凳
 

去找了点资料看看型号功能对照表,说是针对不同的应用场景来设计其MCU, 说什么汽车电子板块还没有完善,不是很理解

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表