nrf52840使用GPIO驱动LED实现摩尔斯密码
nrf52840使用GPIO驱动LED实现摩尔斯密码
本文将介绍如何使用nRF52840开发板的GPIO驱动LED实现摩尔斯密码。通过本实验,读者将掌握开发环境的搭建、裸机工程的新建,熟悉GPIO驱动LED灯的软件编程流程,并了解LED发光二极管驱动原理。
nRF52840 是 Nordic Semiconductor 公司开发的一款高性能、多协议无线片上系统(SoC)。它基于 32 位 ARM® Cortex®-M4 处理器,支持多种无线通信协议,包括 Bluetooth Low Energy (BLE)、Thread、Zigbee、ANT、2.4 GHz 硬件协议以及专有协议。nRF52840 专为物联网(IoT)、可穿戴设备、智能家居设备和工业应用而设计,具备卓越的低功耗性能和强大的计算能力。
实验1 GPIO驱动LED实现摩尔斯密码
实验目的
- 掌握开发环境的搭建、裸机工程的新建
- 熟悉GPIO驱动LED灯的软件编程流程
- 了解LED发光二极管驱动原理
实验环境
nrf52840、keil、电脑
实验资源
LED是发光二极管的简称,在很多设备上常用它来作为一种简单的人机接口,通过LED向用户指示设备的不同工作状态,习惯上将这种指示状态的LED称为LED指示灯。而我们实训所用的开发板上设计了4个LED指示灯,可通过编程驱动LED指示灯点亮、熄灭和闪烁,从而达到状态指示的目的,LED指示灯驱动电路如下图所示:
实验要求
- 搭建开发环境
- 新建配置裸机工程
- GPIO驱动LED闪烁
- 摩尔斯密码:用“声光”( LED灯和蜂鸣器)传递密文“abandon”和“absolute”
实验步骤
编写驱动 LED 闪烁的程序,再此基础上,更进一步,编写摩尔斯电码的程序。
想要设置led的点亮和熄灭,需要一下几个步骤。
1、初始化:配置用于驱动LED指示灯D1的管脚,即配置P0.13为输出
nrf_gpio_cfg_output(LED_1);
2、LED指示灯D1初始状态设置为熄灭,即引脚P0.13为输出高电平
nrf_gpio_pin_set(LED_1);
然后使用以下函数对led进行操控。
1、P0.13输出高电平,熄灭指示灯D1
nrf_gpio_pin_set(LED_1);
2、P0.13输出低电平,点亮指示灯D1
nrf_gpio_pin_clear(LED_1);
设置一个信号元为300ms,则一个短摩尔斯信号为:300ms,长摩尔斯信号为:900ms,使用延迟函数,来控制时间。
软件流程图如下:
字母A-Z和数字1-9的摩尔斯电码如下:
展示实验运行结果和结论,需要有文字描述和截图。
本次实训任务主要是熟悉掌握裸机工程的新建及配置,在创建好工程的基础上进行LED灯不同功能的实现。
在编写LED灯两道实验题目时,我收获最深的就是如何创建函数以及调用函数,调用函数的好处在于使程序模块化,结构清晰,整洁简便,不需要频繁敲重复的代码,读起来更简单易懂。
在本次实验中,我成功点亮了LED灯,并且使用LED灯和蜂鸣器模拟摩斯密码。在本次实验中,我遇到了一些问题,但通过查找手册,便可以解决了。在编写完代码后,灯没有亮,后面查看后我发现我使用了toupper函数,用于将一个小写字母转换为对应的大写字母。如果传入的字符已经是大写字母或不是字母,则返回原字符不变。结果我发现我忘记引用它的头文件了,于是添加上ctype.h后便可以正常点亮。另外在驱动蜂鸣器响的时候,不会响,后面查看手册上的例程后发现,没有对蜂鸣器的io口进行配置,在main函数里添加 nrf_gpio_cfg_output(BEEP_PIN);
nrf_gpio_pin_clear(BEEP_PIN);这两个函数后,就可以正常驱动。
通过本次任务,我成功实现了使用 GPIO 驱动 LED 闪烁和蜂鸣器,并通过摩尔斯电码传递密文 “abandon” 和 “absolute”。这不仅锻炼了对 GPIO 操作的理解,还加深了对摩尔斯电码的应用和实现。整个过程中,我们使用了 SDK 提供的库函数和工具,确保了代码的高效性和可靠性。
LED1灯和蜂鸣器按照设定的摩尔斯电码闪烁和响。
实验代码如下:
#define BEEP_PIN NRF_GPIO_PIN_MAP(1,7)
// 摩尔斯电码表
const char *morse_code[] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--.."
};
void led_on(void) {
bsp_board_led_on(1);
nrf_gpio_pin_write(NRF_GPIO_PIN_MAP(1,7), 1);//高电平蜂鸣器响
}
void led_off(void) {
bsp_board_led_off(1);
nrf_gpio_pin_write(NRF_GPIO_PIN_MAP(1,7), 0);//低电平蜂鸣器不响
}
void send_dot(void) {
led_on();
nrf_delay_ms(300); // 点的持续时间
led_off();
nrf_delay_ms(600); // 点之间的间隔
}
void send_dash(void) {
led_on();
nrf_delay_ms(900); // 划的持续时间
led_off();
nrf_delay_ms(600); // 划之间的间隔
}
void send_char(char c) {
if (c >= 'A' && c <= 'Z') {
const char *code = morse_code[c - 'A'];
while (*code) {
if (*code == '.') {
send_dot();
} else if (*code == '-') {
send_dash();
}
code++;
}
nrf_delay_ms(2100); // 字符之间的间隔
}
}
void send_string(const char *str) {
while (*str) {
send_char(toupper(*str));
str++;
}
}
int main(void)
{
const char *message1 = "abandon";
const char *message2 = "absolute";
//配置UICR_REGOUT0寄存器,设置GPIO输出3.3V电压
gpio_output_voltage_setup_3v3();
//初始化log程序模块,因为本例中没有加入UART相关的文件,因此只能用RTT打印
log_init();
//配置用于驱动LED指示灯D1 D2 D3 D4的引脚脚,即配置P0.13~P0.16为输出,并将LED的初始状态设置为熄灭
bsp_board_init(BSP_INIT_LEDS);
nrf_gpio_cfg_output(BEEP_PIN);
nrf_gpio_pin_clear(BEEP_PIN);
//LOG打印启动信息
NRF_LOG_INFO("led blinky example started");
NRF_LOG_FLUSH();
while(true)
{
send_string(message1);
nrf_delay_ms(2000); // 消息之间的间隔
send_string(message2);
nrf_delay_ms(2000); // 消息之间的间隔
}
}