任务介绍
SAME51J20A Curiosity Nano 评估套件(EV76S68A)是用于评估 SAME51J20A 微控制器(MCU)的硬件平台。该评估套件可轻松访问 SAME51J20A 的功能,以将器件集成到定制设计中。Curiosity Nano 系列评估套件包括一个板载 Nano 调试器,因此无需外部工具即可对 SAME51J20A 器件进行编程。SAM E51 高性能微控制器系列面向工业和通用应用,使用带浮点单元 (FPU) 的 32 位 ARM Cortex-M4 处理器,运行频率高达 120 MHz,高达 1 MB 的带 ECC 的双面板闪存,以及高达 256 KB 的带 ECC 的 SRAM。
本次任务主要基于SAME51J20A Curiosity Nano评估板使用Arduino框架开发,实现板载按键控制LED呼吸闪烁,以及传感器数据串口显示波形应用。
1.1硬件连接
首先硬件开发板需要将SAME51J20A的USB接口引出来,方便用于Arduino的开发上传应用固件。SAME51J20A的USB引脚为PA24和PA25。如下图所示位置。
将USB引出后效果如下:
再就是连接Adafruit LIS3DH三轴加速度传感器模块,Adafruit LIS3DH使用I2C接口。
整体接线引脚如下:
1.2 Arduino添加新开发板SAME51J20A Curiosity Nano
接下来实现如何使用ARDUINO来开发。这里我参考了Adafruit 的Feather M4 CAN开发板的定义,这个板子使用的是SAME51系列MCU。
首先我们要下载arduino开发的bootloader固件。bootloader固件在如下图所示路径,框起来的即是。
这里我们先在arduino中选择Adafruit 的Feather M4 CAN,然后在Tools菜单下的Burn Bootloader即可下载bootloader固件。下载固件时需要接板载的USB接口的nano下载器下载。
下载成功后就可以通过MCU的USB接口来开发ARDUINO应用代码了。
为了选择一个新的开发板类型,我们可以参考Adafruit 的Feather M4 CAN开发板的定义,实现开发板SAME51J20A Curiosity Nano选择开发。在boards.txt中定义一个新开发板。这样就可以在ARDUINO开发板管理器中选择我们新定义的开发板SAME51J20A Curiosity Nano。
然后就是复制一份variants/feather_m4_can下文件夹,修改文件夹名称为新的开发板,方便我们修改ARDUINO的引脚序号内容来适配我们新加的开发板。之后我们就可以选择我们新添加的开发板来开发了。
1.3 arduino软件程序编写
通过查看SAME51J20A Curiosity Nano开发板的电路图可知板载按键和LED指示灯的GPIO引脚分别为PA15,PA14.。
下面查看PA14和PA15在arduino中序号为多少。下面图所示为我修改的引脚序号:PA14对应LED灯为13号。PA15对应按键为4号。
整个程序软件流程如下:
接下来是编写代码实现LED灯闪烁和按键控制。
const int buttonPin = 4; // 按键连接引脚
const int ledPin = 13; // LED连接引脚(必须是PWM引脚)
unsigned long prevUpdateTime = 0; // 记录上次更新时间
unsigned long LisRefreshTime = 0; // 记录上次更新时间
int lis_init_flag;
float brightness = 0; // 当前亮度(0-255)
int speedMode = 0; // 速度模式:0=慢速,1=中速,2=快速
const float speeds[] = {0.001, 0.004, 0.008}; // 速度系数(越小越慢)
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // 启用内部上拉(按下低电平)
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
unsigned long currentMillis = millis();
// 非阻塞式按键检测(按下低电平)
if (digitalRead(buttonPin) == LOW) {
delay(50); // 防抖
if (digitalRead(buttonPin) == LOW) {
speedMode = (speedMode + 1) % 3; // 切换速度模式(0→1→2→0...)
while (digitalRead(buttonPin) == LOW); // 等待按键释放
Serial.print("Speed Mode: "); // 调试输出
Serial.println(speedMode);
lis_init_flag = 0;
}
}
// 非阻塞式呼吸灯(sin()非线性渐变)
if (currentMillis - prevUpdateTime >= 10) { // 固定10ms更新一次亮度
prevUpdateTime = currentMillis;
// 用sin()计算亮度(范围0-255)
brightness = 127 + 127 * sin(millis() * speeds[speedMode]);
analogWrite(ledPin, (int)brightness); // 写入PWM
}
}
然后就是Adafruit LIS3DH三轴加速度传感器模块程序代码编写。首先在lib库搜索安装Adafruit LIS3DH 库。
然后在点灯代码中添加传感器的读取代码。使用非阻塞方式读取。整个代码如下:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
const int buttonPin = 4; // 按键连接引脚
const int ledPin = 13; // LED连接引脚(必须是PWM引脚)
unsigned long prevUpdateTime = 0; // 记录上次更新时间
unsigned long LisRefreshTime = 0; // 记录上次更新时间
int lis_init_flag;
float brightness = 0; // 当前亮度(0-255)
int speedMode = 0; // 速度模式:0=慢速,1=中速,2=快速
const float speeds[] = {0.001, 0.004, 0.008}; // 速度系数(越小越慢)
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // 启用内部上拉(按下低电平)
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
lis_init_flag = 0;
}
void loop() {
unsigned long currentMillis = millis();
// 非阻塞式按键检测(按下低电平)
if (digitalRead(buttonPin) == LOW) {
delay(50); // 防抖
if (digitalRead(buttonPin) == LOW) {
speedMode = (speedMode + 1) % 3; // 切换速度模式(0→1→2→0...)
while (digitalRead(buttonPin) == LOW); // 等待按键释放
Serial.print("Speed Mode: "); // 调试输出
Serial.println(speedMode);
lis_init_flag = 0;
}
}
// 非阻塞式呼吸灯(sin()非线性渐变)
if (currentMillis - prevUpdateTime >= 10) { // 固定10ms更新一次亮度
prevUpdateTime = currentMillis;
// 用sin()计算亮度(范围0-255)
brightness = 127 + 127 * sin(millis() * speeds[speedMode]);
analogWrite(ledPin, (int)brightness); // 写入PWM
}
//传感器
if (currentMillis - LisRefreshTime >= 25) { // 固定100ms更新一次亮度
LisRefreshTime = currentMillis;
if(0 == lis_init_flag)
{
if (lis.begin(0x18)) // change this to 0x19 for alternative i2c address
{
Serial.println("LIS3DH found!");
Serial.print("Range = "); Serial.print(2 << lis.getRange());
Serial.println("G");
Serial.print("Performance mode set to: ");
switch (lis.getPerformanceMode()) {
case LIS3DH_MODE_NORMAL: Serial.println("Normal 10bit"); break;
case LIS3DH_MODE_LOW_POWER: Serial.println("Low Power 8bit"); break;
case LIS3DH_MODE_HIGH_RESOLUTION: Serial.println("High Resolution 12bit"); break;
}
// lis.setDataRate(LIS3DH_DATARATE_50_HZ);
Serial.print("Data rate set to: ");
switch (lis.getDataRate()) {
case LIS3DH_DATARATE_1_HZ: Serial.println("1 Hz"); break;
case LIS3DH_DATARATE_10_HZ: Serial.println("10 Hz"); break;
case LIS3DH_DATARATE_25_HZ: Serial.println("25 Hz"); break;
case LIS3DH_DATARATE_50_HZ: Serial.println("50 Hz"); break;
case LIS3DH_DATARATE_100_HZ: Serial.println("100 Hz"); break;
case LIS3DH_DATARATE_200_HZ: Serial.println("200 Hz"); break;
case LIS3DH_DATARATE_400_HZ: Serial.println("400 Hz"); break;
case LIS3DH_DATARATE_POWERDOWN: Serial.println("Powered Down"); break;
case LIS3DH_DATARATE_LOWPOWER_5KHZ: Serial.println("5 Khz Low Power"); break;
case LIS3DH_DATARATE_LOWPOWER_1K6HZ: Serial.println("1.6 Khz Low Power"); break;
}
lis_init_flag = 1;
}
}else
{
lis.read(); // get X Y and Z data at once
// Then print out the raw data
Serial.print("X:"); Serial.print(lis.x);
Serial.print(" Y:"); Serial.print(lis.y);
Serial.print(" Z:"); Serial.print(lis.z);
Serial.println();
#if 0
/* Or....get a new sensor event, normalized */
sensors_event_t event;
lis.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
Serial.print(" \tY: "); Serial.print(event.acceleration.y);
Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
Serial.println(" m/s^2 ");Serial.println();
#endif
}
}
}
下面编译上传到MCU中看看效果。
传感器的数据波形图: