Microchip 32位MCU CAN驱动图文教程-附源码

文章目录

    • 创建一个新的32位MCU工程
    • Microchip MCC Harmony配置界面说明
    • 在MCC下配置系统的时钟
    • 在MCC下配置所需要使用的模块
      • 配置调试打印模块
      • 配置CAN模块
      • 配置管脚功能
      • 修改系统堆栈大小
      • 生成代码
    • 添加用户代码

创建一个新的32位MCU工程

确保电脑上已经安装最新的MPlab X IDE、XC32编译器和MCC harmony软件仓库,比如当前所使用的MPlab X IDE版本是V6.20

  • 打开MPlab X IDE后,选择File->New Project:
    在这里插入图片描述
  • 选择Application Project,点击下一步:
    在这里插入图片描述
  • 选择需要选择的器件型号,比如本教程选用的ATSAME54P20 MCU,点击下一步:
    在这里插入图片描述
  • 选择交叉编译工具,点击下一步:
    在这里插入图片描述
  • 输入工程名称和选择存储路径,最后点击完成Finish
    在这里插入图片描述
  • 需要确保本地电脑上已经下载了Microchip MCC Harmony针对于所使用MCU型号的软件包,可以从github或者国内的gitee进行下载,并在MPlab X IDE里面进行配置。
    • 配置过程可以通过Tools -> Option进入
      在这里插入图片描述

Microchip MCC Harmony配置界面说明

Microchip MCC harmony提供图形化的配置界面,能够方便的增减各种外设驱动库、中间件,提供图形化的系统时钟、管脚、DMA、事件系统和网络协议栈的配置,当完成配置后能够一键生成代码。
在这里插入图片描述

  • 在官方SAME54 Xplained Pro开发板上完成以下配置目标
    • 采用外部12MHz晶振输入
    • 提供40M clock给CAN模块
    • CAN工作在500kbps速率,采样点为75%
    • 使用RX FIFO0来接收标准帧,FIFO1接收扩展帧
    • 标准帧过滤器(Classic、Range模式)设置参考(只接收ID为0x1D00x1D7和0x1F00x1F8的帧)
    • 扩展帧过滤器(Classic、Range模式)设置参考(只接收ID为0x1FFF1240~0x1FFF1248的帧)

在MCC下配置系统的时钟

在Plugins里面打开Clock Configuration
在这里插入图片描述
打开时钟配置界面后,将看到以下的配置界面:
在这里插入图片描述
外部无源晶振输入的配置(外部12MHz晶振输入接在XOSC1上):
在这里插入图片描述
XOSC CTRL配置的高级选项:
在这里插入图片描述
MCU通用时钟发生器1~4的配置:
在这里插入图片描述
通用时钟发生器GCLK2的配置:
在这里插入图片描述
通用时钟发生器GCLK3的配置:
在这里插入图片描述
MCU锁相环 FDPLL0的配置:
在这里插入图片描述
FDPLL0的高级配置:
在这里插入图片描述
外设时钟的配置:
在这里插入图片描述

在MCC下配置所需要使用的模块

配置调试打印模块

添加SERCOM2模块,选择MCC Resource Management -> Device Resources -> Libraries -> Harmony -> Peripherals -> SERCOM -> SERCOM2
在这里插入图片描述
配置SERCOM2模块,在Project Graph界面下左键单击新添加的SERCOM2模块
在这里插入图片描述
一个SERCOM模块有4个PAD,PAD0~3,参考SAME54开发板原理图,打印用的串口PAD1为RX,PAD0为TX,所以配置SERCOM2的Receive/Transmit Pinout需要和原理图保持一致
在这里插入图片描述
添加STDIO模块,选择MCC Resource Management -> Device Resources -> Libraries -> Harmony -> Tools -> STDIO
在这里插入图片描述
配置STDIO模块
在这里插入图片描述
将STDIO和SERCOM2关联起来,右键点击STDIO组件下的粉色边框,选择Satisfiers下的SERCOM2即可
在这里插入图片描述
STDIO标准打印接口绑定到SERCOM2,STDIO调试信息将输出到SERCOM2口
在这里插入图片描述

配置CAN模块

添加CAN1模块,选择MCC Resource Management -> Device Resources -> Libraries -> Harmony -> Peripherals -> CAN -> CAN1
在这里插入图片描述

  • 对添加的CAN1模块进行配置:
    • 满足过滤规则的帧将存储在指定的FIFO中
    • 提供40M clock给CAN模块
    • CAN工作在500 kbps速率,采样点为75%
    • 使用RX FIFO0来接收标准帧,FIFO1接收扩展帧
    • 如果需要将CAN工作速率修改为250 kbps,只需Bit Rate手动输入250即可
      在这里插入图片描述
      在这里插入图片描述
  • CAN1模块标准帧过滤器设置规则如下:
    • 满足过滤规则的标准帧将存储在指定的RX FIFO0中
    • 只接收帧ID在0x1D0 ~ 0x1D7范围内的帧(过滤器0用Classic方式实现)
    • 只接收帧ID在0x1F0 ~ 0x1F8范围内的帧(过滤器1用Range方式实现)
  • CAN1模块扩展帧过滤器设置规则如下:
    • 满足过滤规则的扩展帧将存储在指定的RX FIFO1中
    • 只接收帧ID在0x1FFF1230 ~ 0x1FFF1237范围内的帧(过滤器0用Classic方式实现)
    • 只接收帧ID在0x1FFF1240 ~ 0x1FFF1248范围内的帧(过滤器1用Range方式实现)
      在这里插入图片描述
      在这里插入图片描述

配置管脚功能

配置STDIO打印用到的SERCOM口TX、RX管脚,CAN1模块用到的CAN1_TX、CAN1_RX和CAN收发器standby控制管脚PC13
在这里插入图片描述
在Project Graph界面下,打开Pin Configuration
在这里插入图片描述
随后在Pin Setting下对所需要的管脚进行配置
在这里插入图片描述

修改系统堆栈大小

从Project Graph界面下,点击System模块,从右边配置树中修改Heap Size
在这里插入图片描述

生成代码

在这里插入图片描述

添加用户代码

在main.c文件下,首先添加PLIB CAN驱动需要用到CAN消息缓存buffer和变量的定义。很多变量需要在回调函数中使用,而回调函数是在中断处理代码中被调用,因此需要定义为volatile类型,参考代码如下图所示:

/* CAN message storage buffer definition */
uint8_t Can1MessageRAM[CAN1_MESSAGE_RAM_CONFIG_SIZE] __attribute__((aligned (32)));

/* Standard identifier id[28:18]*/
#define WRITE_ID(id) (id << 18)
#define READ_ID(id)  (id >> 18)

//static uint8_t g_txFiFo[MCAN1_TX_FIFO_BUFFER_SIZE]; /* CAN TX message buffer */
static uint8_t g_rxFiFo0[CAN1_RX_FIFO0_SIZE];      /* CAN FIFO 0 RX buffer */
static uint8_t g_rxFiFo1[CAN1_RX_FIFO1_SIZE];      /* CAN FIFO 1 RX buffer */

static volatile bool    g_txdone  = false;         /* CAN TX completion flag */
static volatile bool    g_rx0done = false;         /* FIFO 0 got new message */
static volatile bool    g_rx1done = false;         /* FIFO 1 got new message */
static volatile uint8_t g_rxnum0 = 0;              /* FIFO 0 new message number */
static volatile uint8_t g_rxnum1 = 0;              /* FIFO 0 new message number */

随后定义CAN PLIB驱动中用到的RX FIFOx接收完成回调函数和TX FIFO发送完成回调函数,其中使用RX FIFO0用于存储标准帧,RX FIFO1用于存储扩展帧。需要在CAN驱动初始化的时候注册FIFO发送完成和接收完成的回调函数。需要注意的是,回调函数是在中断上下文中执行:

static void CAN1_TXFIFO_Txdone(uintptr_t contextHandle)
{
    g_txdone = true;
}

static void CAN1_RXFIFO0_Rxdone(uint8_t numberOfMessage, uintptr_t contextHandle)
{
    g_rx0done = true;
    g_rxnum0  = numberOfMessage;
}

static void CAN1_RXFIFO1_Rxdone(uint8_t numberOfMessage, uintptr_t contextHandle)
{
    g_rx1done = true;
    g_rxnum1  = numberOfMessage;
}

在CAN驱动初始化的时候需要调用GPIO PC13的clear操作,用于将CAN收发器ATA6561跳出standby模式。同时提供一个打印接收的CAN数据帧的函数,用来观察收到的CAN数据帧。打印函数的参数定义如下:
.fifonum – CAN RX FIFO通道号:
.numberofMessage——接收的消息数量:
.rxBuf——接收消息的缓存区首地址:
.rxBufLen——单条消息缓存区的长度:

static inline void CAN1_Demo_Initialization(void)
{
    GPIO_PC13_Clear();
    CAN1_TxFifoCallbackRegister(CAN1_TXFIFO_Txdone, 0);
    CAN1_RxFifoCallbackRegister(CAN_RX_FIFO_0, CAN1_RXFIFO0_Rxdone, 0);
    CAN1_RxFifoCallbackRegister(CAN_RX_FIFO_1, CAN1_RXFIFO1_Rxdone, 0);
}

/* Print Rx Message */
static void print_message(CAN_RX_FIFO_NUM fifonum, uint8_t numberOfMessage, 
                          CAN_RX_BUFFER *rxBuf, uint8_t rxBufLen)
{
    uint8_t msgLength = 0;
    uint32_t id = 0;

    for (uint8_t count = 0; count < numberOfMessage; count++)
    {
        /* Print message to Console */
        printf(" Rx FIFO%d: ", 
                fifonum == CAN_RX_FIFO_0 ? 0:1);
        id = rxBuf->xtd ? rxBuf->id : READ_ID(rxBuf->id);
        msgLength = rxBuf->dlc;
        printf(" Message - ID=0x%x Length=%d\r\n", (unsigned int)id, (unsigned int)msgLength);
        rxBuf += rxBufLen;
    }
}

在while(1)主循环中添加以下代码,判断RX FIFOx是否有接收到新的数据帧,如果有则清除标记位并记录当前收到的帧数,需要注意的是加入临界区保护代码。读取CAN数据帧时,先将用户帧缓存内容清零,然后从FIFO中读取指定数量的帧到缓存区,最后打印接收的帧内容:

int main ( void )
{
    uint8_t rx_num;
    
    /* Initialize all modules */
    SYS_Initialize ( NULL );

    printf(" ------------------------------ \r\n");
    printf("            CAN Demo            \r\n");
    printf(" ------------------------------ \r\n");
    
    /* Set Message RAM Configuration */
    CAN1_MessageRAMConfigSet(Can1MessageRAM);
    
    CAN1_Demo_Initialization();
    
    while ( true )
    {
        /* Maintain state machines of all polled MPLAB Harmony modules. */
        SYS_Tasks ( );

        if (g_rx0done)
        {
            __disable_irq();
            g_rx0done = false;
            rx_num    = g_rxnum0;
            __enable_irq();
            
            memset(g_rxFiFo0, 0x00, (rx_num * CAN1_RX_FIFO0_ELEMENT_SIZE));
            if (CAN1_MessageReceiveFifo(CAN_RX_FIFO_0, rx_num, 
                                        (CAN_RX_BUFFER *)g_rxFiFo0) == true)
            {
                print_message(CAN_RX_FIFO_0, rx_num, (CAN_RX_BUFFER *)g_rxFiFo0,
                              CAN1_RX_FIFO0_ELEMENT_SIZE);
            }
            else
            {
                printf(" Error in FIFO0 received message\r\n");
            }
        }
        
        if (g_rx1done)
        {
            __disable_irq();
            g_rx1done = false;
            rx_num    = g_rxnum1;
            __enable_irq();
            
            memset(g_rxFiFo1, 0x00, (rx_num * CAN1_RX_FIFO1_ELEMENT_SIZE));
            if (CAN1_MessageReceiveFifo(CAN_RX_FIFO_1, rx_num, (CAN_RX_BUFFER *)g_rxFiFo1) == true)
            {
                print_message(CAN_RX_FIFO_1, rx_num, (CAN_RX_BUFFER *)g_rxFiFo1,
                              CAN1_RX_FIFO1_ELEMENT_SIZE);
            }
            else
            {
                printf(" Error in FIFO1 received message\r\n");
            }
        }
    }

    /* Execution should not come here during normal operation */

    return ( EXIT_FAILURE );
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/563283.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】探索Qt框架:跨平台GUI开发的利器

文章目录 1. Qt框架概述1.1. Qt框架的优点1.2. Qt框架支持的系统1.3. Qt开发环境 2. 搭建 Qt 开发环境2.1. Qt SDK 的下载和安装2.2. 新建项目: 3. Qt 框架内容简介总结 在当今软件开发领域&#xff0c;跨平台性和用户界面的友好性是至关重要的。而Qt框架作为一款跨平台的C图形…

西安大秦软件

西安大秦软件 大秦软件 想做小程序、APP、Web 系统&#xff0c;请找我&#xff0c;包您满意&#xff01; 刘大强 &#xff08;销售经理&#xff09; 电话&#xff1a;198 8892 6712 微信&#xff1a;198 8892 6712 欢迎咨询 西安大秦时代网络科技有限公司

认知觉醒 PDF电子版 下载

认知觉醒 PDF电子版 开启自我改变的原动力 周岭 / 人民邮电出版社 / 2020-10 链接&#xff1a;https://pan.baidu.com/s/1EHUK_AhvE5TWAZsYXFQ5QA?pwdwrho 提取码&#xff1a;wrho

面试后,公司如何决定你的去留

在现代职场中&#xff0c;求职者在经历了一系列严格的面试流程后&#xff0c;往往会进入一段等待期。在这段时间里&#xff0c;他们满怀希望地等待企业的最终反馈。但有一个现象普遍存在&#xff1a;无论面试过程如何&#xff0c;最终决定权总是掌握在公司手中&#xff0c;由公…

【Python性能优化】list、array与set

list、array与set 详述测试代码 详述 本文对比 list 与 set 在插入和取值时的性能差异&#xff0c;以提供一条什么时候该选择什么数据类型的建议。先上结果&#xff1a; array 与 list 的不同&#xff1a; 内存方面 array 是 C array 的包装&#xff0c;它直接存储数据&#xf…

Llama 3大模型发布!快速体验推理及微调

Meta&#xff0c;一家全球知名的科技和社交媒体巨头&#xff0c;在其官方网站上正式宣布了一款开源的大型预训练语言模型——Llama-3。 据了解&#xff0c;Llama-3模型提供了两种不同参数规模的版本&#xff0c;分别是80亿参数和700亿参数。这两种版本分别针对基础的预训练任务…

JVM-垃圾收集算法

前言 在 Java 中&#xff0c;垃圾收集&#xff08;Garbage Collection&#xff09;是一种自动管理内存的机制&#xff0c;它负责在运行时识别和释放不再被程序使用的内存&#xff0c;从而避免内存泄漏和悬空引用问题。本篇文章将介绍三种常见的垃圾收集算法。 标记-清除&…

OCT2Former: A retinal OCT-angiography vessel segmentationtransformer论文总结

论文(COMPUT METH PROG BIO)&#xff1a;OCT2Former: A retinal OCT-angiography vessel segmentation transformer 源码&#xff1a;https://github.com/coreeey/OCT2Former 一、摘要 背景与目的&#xff1a;视网膜血管分割在视网膜疾病自动筛查与诊断中起着重要作用。如何分…

2024 抖音欢笑中国年(五):Wasm、WebGL 在互动技术中的创新应用

前言 随着 Web 前端技术的不断发展&#xff0c;越来越多的新兴技术方案被引入到 Web 开发中&#xff0c;其中 Wasm 和 WebGL 作为前端领域的两大利器&#xff0c;为开发者带来了更多的可能性。 本文将结合2024 年抖音欢笑中国年的部分项目&#xff0c;重点介绍如何利用 Wasm 和…

TCP 协议特性

1. TCP 基本认识 TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。 面向连接&#xff1a;一定是「一对一」才能连接&#xff0c;不能像 UDP 协议可以一个主机同时向多个主机发送消息&#xff0c;也就是一对多是无法做到的&#xff1b; 可靠的&#xff1a;无论的网络链…

【批量区域识别内容重命名】批量识别图片区域文字并重命名,批量图片部分识别内容重命文件,PDF区域识别提取重命名

我们在工作和生活中经常遇到这样的需求&#xff1a;比如将以下的图片区域识别进行重命名&#xff0c;批量识别后改成以时间和工作内容重命名&#xff0c;便于日后检索&#xff0c;快速查询 首先我们拍摄照片用到的是水印相机&#xff0c;这里的文字呢我们需要加个背景&#xff…

C++模版初阶----函数模版、类模版

C模版初阶 1. 泛型编程2. 函数模板2.1 函数模板概念2.2函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 函数模版的匹配原则 3. 类模板3.1 类模板的定义格式3.2 类模板的实例化 总结 1. 泛型编程 泛型编程 : 编写与类型无关的通用代码&#xff0c;是代码复用的一种手段…

利用STM32 HAL库实现USART串口通信,并通过printf重定向输出“Hello World“

一、开发环境 硬件&#xff1a;正点原子探索者 V3 STM32F407 开发板 单片机&#xff1a;STM32F407ZGT6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F4 V1.27.1 上一篇使用STM32F407的HAL库只需1行代码实现US…

#STM32F407VET6(天空星)标准库和HAL驱动ILI9341

一、驱动方式&#xff1a;软件SPI&#xff0c;屏幕像素320*240 二、标准库含触摸&#xff0c;HAL库不含触摸 三、立创参考的文档 【立创天空星ST32F407VET6】模块移植手册 - 飞书云文档 (feishu.cn)https://lceda001.feishu.cn/wiki/MFNpw4STVi5ImikkcH1clWrlnqb 四、引脚分…

HIVE无法启动问题

​ 启动不了hive 一直在加载中&#xff01; 问题&#xff1a;当我们打开电脑 想要学习hive时 我们却发现 它一直卡在启动页面 true一直后没有信息或者报错 原因&#xff1a;我们在之前学习时 在配置hdfs的高可用时&#xff08;High Availability 简称HA&#xff09; 高可用…

2024第十五届蓝桥杯省赛C++A组程序设计题解

ps&#xff1a;没有答案&#xff0c;考场上的代码&#xff0c;不一定对&#xff0c;大佬们轻喷&#xff0c;可以提供点更好的思路~ 试题C&#xff1a;训练士兵 解题思路 对于每次训练&#xff0c;需要考虑采用士兵单独训练还是组团训练的方式&#xff0c;故每次训练将所需训练…

【网站项目】“最多跑一次”小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

面试(06)————MySQL篇

目录 问题一&#xff1a;在MySQL中&#xff0c;如何定位慢查询&#xff1f; 方案一&#xff1a;开源工具 方案二&#xff1a;MySQL自带慢日志 模拟面试 问题二&#xff1a;这个SQL语句执行很慢&#xff0c;如何分析的呐&#xff1f; 模拟面试 问题三&#xff1a;了解过索引…

2024 IDM最新破解版及软件介绍

*IDM&#xff1a;信息时代的高效管理工具** 在快节奏的现代社会中&#xff0c;随着信息的爆炸式增长&#xff0c;如何高效、有序地管理信息成为每个人都需要面对的挑战。IDM&#xff0c;作为一种信息管理工具&#xff0c;正在逐渐受到人们的青睐。 IDM&#xff0c;全称Inform…

Android 出现4G模块无法上网问题

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…