Funpack3-4任务二基于FRDM-MCXN947开发板的嵌入式web服务器
该项目使用了FRDM-MCXN947开发板 和lwip技术使用c语言编写,实现了嵌入式web服务器的设计,它的主要功能为:通过网页可以实时读取传感器数据和控制led和蜂鸣器。
标签
嵌入式系统
Funpack活动
开发板
LwIp
wjhgbpqm
更新2024-09-09
杭州电子科技大学
39

Funpack3-4任务二基于FRDM-MCXN947开发板的嵌入式web服务器

一 、硬件介绍

     FRDM-MCXN947是一款紧凑且可扩展的开发板,可让您快速基于MCX N94x MCU开展原型设计。板卡上集成行业标准的接口,可轻松使用MCU的I/O、集成的开放标准串行接口、外部闪存和板载MCU-Link调试器,具体结构如图1所示

image.png

 

 

图1.FRDM-MCXN947结构框图

二、开发环境搭建

这里使用的开发环境是MCUXpresso IDE 的开发环境,SDK的版本为2.14.0,使用的引脚功能配置工具为MCUXpresso Config Tools v15.1,开发过程中直接使用MCUXpresso IDE的引脚配置工具会找不芯片的,将为MCUXpresso Config Tools v15.1中的芯片数据导出,导入MCUXpresso IDE的引脚配置工具。

三、任务说明

这里主要有3个任务如下

任务1:

• 实现USB多协议HUB。板卡上集成了HS-USB接口,要求使用CAN口和UART口向MCU发送信息,通过USB显示出数据;从USB端可以指定向CAN和UART发送数据,并从对应端口发送出去。

任务2:

• 使用板卡上的以太网接口连接到电脑上并通过以太网和电脑通信,实现数据传输。要求电脑可以获取到板卡上的温度,触摸和按键信息,并可以通过电脑控制板卡上的RGB LED灯(有搭配扩展模块,传感器类的在电脑上显示数据,执行器类的能用电脑控制其工作)。

任务3:

• 使用eIQ NPU 实现机器学习加速。可以自己搭配摄像头模组,若无模组可以使用调试器的串口向MCU直接发送图像或者相应的音频数据,进行测试。要求使用eIQ 实现图像分类或者音频分类,自行搭建可用的NN结构,实现鞋子or帽子检测或者音频的鼓声or钢琴检测。

这里完成的主要是任务二硬件部分使用了nRF7002-DK的网络芯片模块;软件部分通过MCUXpresso IDE进行开发。


四、功能概述

4.1. 传感器数据监控

  • 温度传感器: 显示当前的温度数据,并附带单位(°C)。
  • 触摸传感器: 显示触摸传感器的当前状态或值。
  • 按键状态: 显示按键的当前状态(如按下或松开)。
  • 浊度传感器: 显示当前的水浊度值。

自动数据刷新

通过JavaScript中的setTimeout()函数,网页会每隔一秒自动向服务器请求传感器数据,从而实现数据的实时更新。

4.2.GPIO控制

  • RGB LED灯开关控制
  • 蜂鸣器 开关控制。

具体web的索引界面的界面如图2所示,GPIO控制界面如图3所示,传感器监控界面如图4。

image.png

图2.web的索引界面

image.png

图3.GPIO控制

image.png

图4.传感器监控界面

五、 软件设计流程

5.1.前端设计

  • HTML: 使用HTML构建了基本的网页结构,包括标题、表格、和描述文字。表格用于显示传感器的数据。
  • CSS: 通过引入CSS样式表,定义了表格的样式,使得网页的外观简洁美观。
  • JavaScript: 编写了用于与服务器交互的JavaScript代码,负责发送请求、接收并解析数据,并动态更新网页内容。

5.2. 嵌入式服务器设计

  • CGI脚本: 每个传感器的数据通过独立的CGI脚本来获取。例如temperature.cgi获取温度数据,touch.cgi获取触摸传感器数据,button.cgi获取按键状态数据,turbidity.cgi获取浊度数据。
  • 数据传输与解析: 前端通过JavaScript的make_request函数向服务器发送GET请求,服务器返回相应的传感器数据,JavaScript接收到数据后通过parse_vars函数解析并更新HTML元素的内容。
  • 嵌入式服务器: 使用lwip的网络协议栈,和板载的ETH芯片实现了一个微型嵌入式服务器,处理CGI传过来的数据。

5.3. 数据处理与展示

  • 数据接收与解析: 使用alertContents函数接收服务器的响应数据,根据请求的URL确定数据的类型,并将数据传递给相应的parse_vars函数。
  • 动态更新页面: 通过获取到的数据,使用document.getElementById().innerHTML来更新页面上的传感器值,实现动态数据展示。

5.4. 整体流程

  1. 网页加载:
    • 网页加载时,JavaScript的window.onload事件会触发loop()函数,开始定时获取传感器数据。
  2. 数据请求与接收:
    • 每隔一秒,JavaScript会向服务器发送一次GET请求,请求不同的CGI脚本获取各个传感器的数据。
    • 当服务器响应时,alertContents()函数会被调用,解析返回的数据并根据不同的传感器类型将数据更新到对应的HTML元素中。
  3. 数据显示:
    • 网页表格中的传感器值会随着数据的更新自动刷新,用户可以实时查看到最新的传感器状态。

5.5. 扩展性

  • 可以很方便地扩展更多的传感器。只需要在HTML中增加新的行,在JavaScript中添加对应的CGI请求和解析逻辑,即可实现对更多传感器的监控。


5.6.程序介绍

软件设计的整体框图如图5所示。

image.png

图5.软件设计的整体框图

软件的实现流程如6所示,主要分为六块内容,包括外设初始化,传感器和GPIO控制的CGI程序编写,前端界面的编写(使用makefsdata工具转化成16进制的数组)、操作系统(freertos)、LWIP(网络协议栈)。

image.png


图6.软件流程图

程序首先是时钟的初始化、GPIO的初始化、温度接口的初始化、网络接口的初始化、LED灯的初始化、按键的初始化、adc读取触摸板和浊度传感器的初始化、最后使用FreeRTOS的任务创建API创建了main_task任务。

主函数的程序如下:


int main(void)

{

CLOCK_EnableClock(kCLOCK_InputMux);

/* attach 12 MHz clock to FLEXCOMM0 (debug console) */

CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

BOARD_InitBootPins();

BOARD_InitBootClocks();

BOARD_InitDebugConsole();

init_eth();

p351755_init();

LED_RED_INIT(LOGIC_LED_OFF);

LED_GREEN_INIT(LOGIC_LED_OFF);

LED_BLUE_INIT(LOGIC_LED_OFF);

BUZZER_INIT(LOGIC_BUZZER_OFF);

button_init();

adc0_clock_and_vref();

adc0_with_irq_drv_init();

/* create server task in RTOS */

if (xTaskCreate(main_task, "main", HTTPD_STACKSIZE, NULL, HTTPD_PRIORITY, NULL) != pdPASS)

{

PRINTF("main(): Task creation failed.", 0);

__BKPT(0);

}

// /* run RTOS */

vTaskStartScheduler();

/* should not reach this statement */

while(1)
{
}

}

main_task函数主要做了两件事 :1、LWIP协议栈的初始化、2、http服务器的初始化。

具体程序如下:

static void main_task(void *arg)

{

LWIP_UNUSED_ARG(arg);

stack_init();

http_server_socket_init();

vTaskDelete(NULL);

}

http服务器的初始化中核心部分是cgi_lnk_tbl数组,其中储存的是一些回调函数(用于处理js请求的cgi)。

http服务器的初始化具体代码如下:

void http_server_socket_init(void)

{

HTTPSRV_PARAM_STRUCT params;

uint32_t httpsrv_handle;

/* Init Fs*/

HTTPSRV_FS_init(httpsrv_fs_data);

/* Init HTTPSRV parameters.*/

memset(&params, 0, sizeof(params));

params.root_dir = "";

params.index_page = "/index.html";

params.cgi_lnk_tbl = cgi_lnk_tbl;

/* Init HTTP Server.*/

httpsrv_handle = HTTPSRV_init(&params);

if (httpsrv_handle == 0)

{

PRINTF(("HTTPSRV_init() is Failed"));

}

}

cgi_lnk_tbl中分别为温度、触摸板、浊度传感器的回调函数以及控制GPIO和按键的回调函数,函数的具体实现请参考附件中httpsrv_freertos.c的代码。

cgi_lnk_tbl具体内容如下:

const HTTPSRV_CGI_LINK_STRUCT cgi_lnk_tbl[] = {

{"temperature",cgi_temperature},

{"touch",cgi_touch},

{"turbidity",cgi_turbidity},

{"gpio_control",cgi_gpio_control},

{"button",cgi_button},

{0, 0} // DO NOT REMOVE - last item - end of table

};

以上是服务器后端处理的部分,前端的页面使用html搭配css和js来进行编写,具体实现了三个html页面:index.html、sensor_cgi.html(显示传感器数值)、gpio_cgi.html(控制gpio口),使用httpsrv.css进行样式控制,使用request.js处理cgi的请求,以上这些实现通过makefsdata工具转化成数组,写入板子的flash。由于程序代码太长,这里仅展示index.html的具体代码,其余代码不再展示,详细代码请参考附件内容。

index.html具体实现了一个目录索引的功能,可以点击GPIO控制和传感器数值读取的按键跳转至gpio_cgi.html和sensor_cgi.html的子页面。

index.html具体代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>Funpack第三季第四期</title>
    <link rel="stylesheet" href="httpsrv.css">
</head>
<body>
    <h2>Funpack第三季第四期项目展示</h2>
    <img src="Funpack.png" alt="Funpack Logo" style="max-width: 100%; height: auto;">
    <div class="form-container">
        <button type="button" onclick="location.href='gpio_cgi.html'">GPIO控制</button>
        <button type="button" onclick="location.href='sensor_cgi.html'">传感器数值读取</button>
    </div>
</body>
</html>

六.结果与总结

6.1结果

板子连接上电脑后,打开软件,把程序下载到FRDM-MCXN947,打开浏览器,输入192.168.102连接上嵌入式web服务器,点击相应的按钮,可以控制LED和蜂鸣器,以及读取传感器数据,详细演示在视频里。

6.2总结

使用FRDM-MCXN947学习到了NXP芯片的开发流程以及gpio、lwip、eth、CGI技术、以及web服务器的搭建,感谢电子森林和得捷提供这么好的平台。

附件下载
MCXN947_Project.7z
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号