Funpack4-1基于DWM3001CDK开发板的NFC控制灯效功能开发
一、项目概述
第一次参与Funpack活动。,Qorvo 的 DWM3001CDK 集成了DWM3001C (UWB) 模块和Nordic的蓝牙芯片nRF52833。之前使用过Nordic的蓝牙芯片,是基于nRF SDK开发的。这次借这个机会,学习一下nrfconnect SDK的开发。
项目实现了基于nRF52833的NFC功能的读写,可通过NFC控制LED灯显示不同的灯效。
二、硬件介绍
开发板主要有一下硬件模块:
- DWM3001C模组可用于双向测距和 TDoA 应用
- 集成Nrf52833 MCU 可实现蓝牙通信和NFC通信
- 有LED灯和按键
- 板载jlink ,可方便调试
- 集成运动传感器LIS2DH12TR
总体来说,板卡虽小,集成的功能还是很强大的。
三、开发环境搭建
之前没有使用过nRFconnect sdk开发环境,这一搭建了一下。
使用工具:
- Visual Studio Code:https://code.visualstudio.com/
- nRF command line tools:https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools/Download#infotabs
- nRF Util: https://www.nordicsemi.com/Products/Development-tools/nRF-Util/Download?lang=en#infotabs
- SEGGER J-Link: https://www.segger.com/downloads/jlink
- west,git和Python。
安装过程中需要使用科学上网。 可以使用多次west update 最终将所有的文件clone下来。
本次项目使用的是最新的SDK v2.9.2
参考资料:开发你的第一个nRF Connect SDK(NCS)/Zephyr应用程序
三、项目开发过程
1. 例程参考
使用SDK中的例程 v2.9.1\nrf\samples\nfc\writable_ndef_msg,此例程实现了NFC功能的NDEF协议的数据读写。
2. 设备树更新
DWM3001CDK开发板上的按键和led的IO口与nRF52833DK板载的按键和led的IO口一致,需要重新适配。
工程文件的根目录添加 app.overlay文件,编译的时候就根据该文件中的设备树来编译。其内容如下:
/ {
pwmleds {
compatible = "pwm-leds";
status = "okay";
led0_r: led_pwm_0 {
pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_NORMAL>;
label = "LED0 Red";
};
led1_r: led1_pwm_0 {
pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_NORMAL>;
label = "LED1 Red";
};
led0_g: led_pwm_1 {
pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_NORMAL>;
label = "LED0 Green";
};
led0_b: led_pwm_2 {
pwms = <&pwm0 3 PWM_MSEC(1) PWM_POLARITY_NORMAL>;
label = "LED0 Blue";
};
};
};
&uart0_default {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 19)>, <NRF_PSEL(UART_RX, 0, 15)>;
};
};
&led0 {
gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
};
&led1 {
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
};
&led2 {
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
};
&led3 {
gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
};
/delete-node/ &{/pin-controller/uart0_default/group2/};
&spi3_default {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 0, 23)>, <NRF_PSEL(SPIM_MOSI, 0, 21)>;
};
};
&spi3_sleep {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 0, 23)>, <NRF_PSEL(SPIM_MOSI, 0, 21)>;
low-power-enable;
};
};
&uart0_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 6)>, <NRF_PSEL(UART_RX, 0, 8)>, <NRF_PSEL(UART_CTS, 0, 7)>;
low-power-enable;
};
};
&button0 {
gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
};
&pwm0_default{
group1 {
psels = <NRF_PSEL(PWM_OUT0, 0, 14)>,
<NRF_PSEL(PWM_OUT1, 0, 22)>,
<NRF_PSEL(PWM_OUT2, 0, 4)>,
<NRF_PSEL(PWM_OUT3, 0, 5)>;
nordic,invert;
};
};
&pwm0_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 0, 14)>,
<NRF_PSEL(PWM_OUT1, 0, 22)>,
<NRF_PSEL(PWM_OUT2, 0, 4)>,
<NRF_PSEL(PWM_OUT3, 0, 5)>;
low-power-enable;
};
};
3. 程序流程图
整个程序框架还是比较简单的。主要是接收到按键或者NFC写入的事件,驱动LED灯展示不同的灯效。
4. 程序实现
4.1 main函数
初始化按键和led,PWM,启动NFC功能,在while中只根据状态机处理灯效:
pwm_led_process();
4.2 按键回调,实现每按键依次,灯效状态机切换到下一个状态。
void button_changed(uint32_t button_state, uint32_t has_changed)
{
if(button_state)
{
led_effect ++;
if(led_effect >= EFFECT_MAX)
led_effect = EFFECT_OFF;
}
}
4.3 nfc刷卡回调,使用NFC调试工具,将文本数据 '0' '1' '2' '3' '4' 写入到NFC中,在nfc回调中,根据接收到的数值切换不同的灯效状态机
static void nfc_callback(void *context,
nfc_t4t_event_t event,
const uint8_t *data,
size_t data_length,
uint32_t flags)
{
ARG_UNUSED(context);
ARG_UNUSED(data);
ARG_UNUSED(flags);
switch (event) {
case NFC_T4T_EVENT_FIELD_ON:
break;
case NFC_T4T_EVENT_FIELD_OFF:
break;
case NFC_T4T_EVENT_NDEF_READ:
break;
case NFC_T4T_EVENT_NDEF_UPDATED:
if (data_length > 0) {
led_effect = ndef_msg_buf[9]-'0';
printk("led_effect %d\n", led_effect);
if(led_effect >= EFFECT_MAX)
{
led_effect = 0;
}
}
break;
default:
break;
}
}
四、 项目中遇到的问题和解决
项目本身比较简单,主要是这次学习了nrf connect SDK的使用,设备树的添加和修改,PWM驱动的LED的实现。多次查资料,最终实现的任务
五、 对本活动的心得体会
第一次参加Funpack活动,先使用了比较简单的项目练练。对于活动中另外几项任务,有时间的话,也争取实现一下。希望后面有先活动,也积极参与一下,持续学习。