Renesas瑞萨A4M2和STM32 CAN通信

2023-05-16

刚好拿到一块瑞萨开发板,捣鼓玩下CAN,顺便试下固件升级。

A4M2 工程创建

详细可以参考,我之前写的文章 Renesa 瑞萨 A4M2 移植文件系统FAT32
在这里插入图片描述
CAN0 配置信息,使能FIFO,接收标准帧 ID为0x50,数据帧。
在这里插入图片描述

代码

void can_Init(void)
{
    fsp_err_t err = R_CAN_Open(&g_can0_ctrl, &g_can0_cfg);
}

/* CAN 中断回调函数 */
void can_callback(can_callback_args_t * p_args)
{
    switch (p_args->event)
    {
        case CAN_EVENT_RX_COMPLETE: //接收完成中断
        {
            can_rx_complete_flag = true;    //can接收到数据

            /* 读取接收帧 */
            memcpy(&can_rx_frame, &(p_args->frame), sizeof(can_frame_t));

            break;
        }
        case CAN_EVENT_TX_COMPLETE: //传输完成中断
        {
            can_tx_complete_flag = true;    //can数据发送完成
            break;
        }
        case CAN_EVENT_ERR_BUS_OFF:          /* Bus error event. (bus off) */
        case CAN_EVENT_ERR_PASSIVE:          /* Bus error event. (error passive) */
        case CAN_EVENT_ERR_WARNING:          /* Bus error event. (error warning) */
        case CAN_EVENT_BUS_RECOVERY:         /* Bus error event. (bus recovery) */
        case CAN_EVENT_MAILBOX_MESSAGE_LOST: /* Overwrite/overrun error */
        {
            can_err_status_flag = true;     //设置标志位

            /* 获取错误状态 */
            can_err_status = (can_error_t) p_args->error;

            break;
        }
        default:
        {
            break;
        }
    }
}

发送数据

can_tx_frame.id               = 0x48;//发送ID
can_tx_frame.type             = CAN_FRAME_TYPE_DATA;
can_tx_frame.data_length_code = 8;  //一次最多发送8个字节
memcpy((uint8_t*)&can_tx_frame.data[0], (uint8_t*)"########", 8);
err = R_CAN_Write(&g_can0_ctrl, CAN_MAILBOX_NUMBER_0, &can_tx_frame);
/* Error trap */
if (FSP_SUCCESS != err)
{
		CAN_MSG_PRINTF("CAN Write API FAILED");
		//while(1);
}
/* 等待传输完成 */
while ((true != can_tx_complete_flag) && (--time_out));
can_tx_complete_flag = false;

//typedef struct st_can_frame
//{
//    uint32_t         id;                           ///< CAN ID.
//    can_id_mode_t    id_mode;                      ///< Standard or Extended ID (IDE).
//    can_frame_type_t type;                         ///< Frame type (RTR).
//    uint8_t          data_length_code;             ///< CAN Data Length Code (DLC).
//    uint32_t         options;                      ///< Implementation-specific options.
//    uint8_t          data[CAN_DATA_BUFFER_LENGTH]; ///< CAN data.
//} can_frame_t;

//接收数据
while (false == can_rx_complete_flag);
can_rx_complete_flag = false;
printf("%s",can_rx_frame.data)

STM32 CAN工程

CAN外设初始化

#define TX_CAN_UPDATE 0x50
#define RX_CAN_UPDATE 0x48

u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{

  	GPIO_InitTypeDef GPIO_InitStructure; 
	  CAN_InitTypeDef        CAN_InitStructure;
  	CAN_FilterInitTypeDef  CAN_FilterInitStructure;
   	NVIC_InitTypeDef  NVIC_InitStructure;
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟	                   											 

  	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟	
	
    //初始化GPIO
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
	
	  //引脚复用映射配置
	  GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
	  GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
	  
  	//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

	 u32 ID1 = RX_CAN_UPDATE;
	 u32 ID2 = TX_CAN_UPDATE;

    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList; 
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    ID1 %= (1 << 11);
    ID2%= (1 << 11);
    //标准帧的帧ID长度是11位,帧ID的范围是000-7FF。
    //扩展帧的帧ID长度是29位,帧ID的范围是0000 0000-1FFF FFFF
    CAN_FilterInitStructure.CAN_FilterIdHigh = ID1  << 5; 
    CAN_FilterInitStructure.CAN_FilterIdLow = CAN_ID_STD | CAN_RTR_DATA;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = ID2 << 5;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = CAN_ID_STD | CAN_RTR_DATA;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; 
    CAN_FilterInit(&CAN_FilterInitStructure);
		

	 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.		    
  
  	NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
	return 0;
}   

void CAN1_RX0_IRQHandler(void)
{
	u8 i =0;
	CanRxMsg msg;
	CAN_Receive(CAN1, CAN_FIFO0, &msg);

	if(msg.IDE == CAN_ID_STD && msg.StdId == RX_CAN_UPDATE)
	{
		for(i=0;i<msg.DLC;i++){
			Rx_Buffer[i] = msg.Data[i];
		}
	}

以上配置只会收到数据帧的ID为0x50和0x48,其他都会被过滤掉。
关于这部分,可以看我之前写 STM32 CAN通信理解(是半双工还是全双工?)

开发版间CAN通信发送和接收都正常。

在这里插入图片描述
OTA也正常。
在这里插入图片描述
使用CAN通信,主要是想为固件升级教程,使用CAN做通信升级做些准备。后面有空持续更新这个系列教程 MCU固件升级系列1(STM32)
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Renesas瑞萨A4M2和STM32 CAN通信 的相关文章

  • 处理器指令周期执行时间

    我的猜测是 no operation 内在 ARM 指令应花费 1 168 MHz 来执行 前提是每个NOP在一个时钟周期内执行 我想通过文档验证这一点 有关处理器指令周期执行时间的信息是否有标准位置 我试图确定 STM32f407IGh6
  • c项目makefile多重定义错误

    这个问题是一个对应于创建的repexthis问题 在我的嵌入式 C 项目中 我有两个独立的板 我想为每个板创建两个 c 文件 master c 和 Slave c 其中包含自己的特定main 功能 我使用 stm32cumbemx 生成带有
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐