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 );
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# WPF布局

布局&#xff1a; 1、Grid: <Window x:Class"WpfApp2.MainWindow" xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d"http://schemas.microsoft.com…

matplotlib从起点出发(15)_Tutorial_15_blitting

0 位图传输技术与快速渲染 Blitting&#xff0c;即位图传输、块传输技术是栅格图形化中的标准技术。在Matplotlib的上下文中&#xff0c;该技术可用于&#xff08;大幅度&#xff09;提高交互式图形的性能。例如&#xff0c;动画和小部件模块在内部使用位图传输。在这里&#…

Drive Scope for Mac:硬盘健康监测分析工具

Drive Scope for Mac是一款专为Mac用户设计的硬盘健康监测与分析工具&#xff0c;致力于保障用户的数据安全。这款软件功能强大且操作简便&#xff0c;能够实时检测硬盘的各项指标&#xff0c;帮助用户及时发现并解决潜在问题。 Drive Scope for Mac 1.2.23注册激活版下载 Driv…

智慧化转型赋能园区创新:科技创新引领产业智慧化,打造高效发展新格局

在全球化和信息化浪潮的推动下&#xff0c;园区作为区域经济发展的重要引擎&#xff0c;正面临着前所未有的机遇与挑战。为应对这些挑战并把握机遇&#xff0c;园区需积极拥抱智慧化转型&#xff0c;通过科技创新引领产业智慧化&#xff0c;打造高效发展的新格局。本文将深入探…

设计模式之观察者模式(优先使用对象组合的原则)的C++实现

观察者模式又称订阅者发布者模式&#xff0c;本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式&#xff0c;这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类&#xff0c;减少了一层类的继承&#xff1b;当然&#xff0c;具体情况需要可根据需求…

【Hadoop】- MapReduce YARN的部署[8]

目录 一、部署说明 二、集群规划 三、MapReduce配置文件 四、YARN配置文件 五、分发配置文件 六、集群启动命令 七、查看YARN的WEB UI 页面 一、部署说明 Hadoop HDFS分布式文件系统&#xff0c;我们会启动&#xff1a; NameNode进程作为管理节点DataNode进程作为工作节…

分类神经网络3:DenseNet模型复现

目录 DenseNet网络架构 DenseNet部分实现代码 DenseNet网络架构 论文原址&#xff1a;https://arxiv.org/pdf/1608.06993.pdf 稠密连接神经网络&#xff08;DenseNet&#xff09;实质上是ResNet的进阶模型&#xff08;了解ResNet模型请点击&#xff09;&#xff0c;二者均是…

Hive基础5

一、窗口函数 聚合&#xff0c;取值函数 排序函数 over(partition by 分组字段 order by 字段 row between 起始行 and 结束行) /*创建部门表*/ CREATE TABLE dept (deptno INT PRIMARY KEY,dname VARCHAR(50) comment 部门名称,loc VARCHAR(50) comment 工作地点 ); ​ /*…

【数据结构】顺序表:与时俱进的结构解析与创新应用

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一、数据结构的概念 二、顺序表&#xff08;Sequence List&#xff09; 2.1 线性表的概念以及结构 2.2 顺序表分类 …

【OpenHarmony-NDK技术】简单将cJson移植到OpenHarmony中,并在c层修改参数值再返回json

1、cJson的简单介绍 cJson - github网址 概述 一般使用cJson是&#xff0c;需要将json文本转化为json对象–编码&#xff0c;将json对象转化为json文本–解析。 git clone https://github.com/DaveGamble/cJSON.git 后留意cJSON.h和cJSON.h两个文件。 1、cJson的介绍 cJso…

【Node.js】02 —— Path模块全解析

&#x1f31f;Node.js之Path模块探索&#x1f308; &#x1f4da;引言 在Node.js的世界中&#xff0c;path模块就像一把万能钥匙&#x1f511;&#xff0c;它帮助我们理解和操作文件与目录的路径。无论你是初入Node.js殿堂的新手&#xff0c;还是久经沙场的老兵&#xff0c;理…

Python exe 文件反编译为 Python 脚本

文章目录 前言版本反编译Python 可执行文件&#xff08;.exe&#xff09;反编译打包一个简单的 .exe 可执行文件提取 pyc 文件使用脚本提取使用工具提取 将 .pyc 文件转换为 Python 脚本入口运行类非入口运行类转换补全后的 pyc 文件uncompyle6 反编译在线工具 可能遇到的问题P…