基于FRDM-MCXN947使用以太网接口控制板卡
1.任务要求
使用板卡上的以太网接口连接到电脑上并通过以太网和电脑通信,实现数据传输。要求电脑可以获取到板卡上的温度,触摸和按键信息,并可以通过电脑控制板卡上的RGB LED灯
2.任务分析
(1)想要实现板卡的网络通讯,需要我们使用到lwip协议的开发这里我们是基于板卡自带的实例程序进行修改。
(2)可以获得板卡上的温度,触摸和按键信息,这里我们分别通过板卡的实例程序分别得知,相关外设的驱动程序,之后我们可以通过串口发送到电脑端来获取我们知道的数据。
(3)控制板卡上的RGB灯,我们可以知道RGB灯的本质就是控制三色灯的亮度大小来决定的,所以我们就可以通过开启或者关闭红蓝绿三色灯来实现RGB灯的操作。
3.任务流程图
3.1 配置我们的LED灯按键控制
GPIO_PinInit(BOARD_SW_GPIO, BOARD_SW_GPIO_PIN, &sw_config);
/* Init output LED GPIO. */
GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);
while (1)
{
if (g_ButtonPress)
{
PRINTF(" %s is pressed \r\n", BOARD_SW_NAME);
/* Toggle LED. */
GPIO_PortToggle(BOARD_LED_GPIO, 1U << BOARD_LED_GPIO_PIN);
/* Reset state of button. */
g_ButtonPress = false;
}
}
这里我们选取板子实例的GPIO输入中断来作为我们的GPIO来配置我们的LED灯的控制。根据这个实例进行我们的修改。
3.2 获取板卡上的温度
这里我们是通过板卡自带的历程,temperature_measurenment的历程通过ADC采集来实现我们对温度ADC的采集实现我们温度的实时检测。通过相关引脚开启,和串口的发送我们可以知道当前实时的温度数据。
while (1)
{
GETCHAR();
g_LpadcConversionCompletedFlag = false;
LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */
while (false == g_LpadcConversionCompletedFlag)
{
}
PRINTF("Current temperature: %6.3f\r\n", (double)g_CurrentTemperature);
}
3.3 触摸按键的检测
这里我们根据板卡上的tsi_V6_self_cap历程作为我们的触摸按键分析历程,这里我们通过板卡上的电极可以判断我们当前触摸按键是否按下。在历程中给出俩个操作方法,一种是轮询查询我们的电极状态,一种是使用我们的中断来判断我们的触摸按键的状态。这里我们使用中断的方式查询我们的触摸按键是否按下。
PRINTF("\r\nNOW, comes to the software trigger scan using polling method!\r\n");
TSI_EnableHardwareTriggerScan(APP_TSI, false); /* Enable software trigger scan */
TSI_DisableInterrupts(APP_TSI, kTSI_EndOfScanInterruptEnable);
TSI_ClearStatusFlags(APP_TSI, kTSI_EndOfScanFlag);
TSI_SetSelfCapMeasuredChannel(APP_TSI, BOARD_TSI_ELECTRODE_1);
TSI_StartSoftwareTrigger(APP_TSI);
while (!(TSI_GetStatusFlags(APP_TSI) & kTSI_EndOfScanFlag))
{
}
PRINTF("Channel %d Normal mode counter is: %d \r\n", BOARD_TSI_ELECTRODE_1, TSI_GetCounter(APP_TSI));
配置我们的中断初始相关函数,实现我们对触摸按键的判断。
3.4 lwip网络协议添加
这里我们lwip根据:[野火]LwIP应用开发实战指南—基于STM32 — [野火]LwIP应用开发实战指南—基于野火STM32 文档 (embedfire.com)来进行配置。
这里我们创建套接字来实现我们的功能,最后根据识别字符串来实现我们的相关操作。
#define TCP_PORT 5001
static void lwip_tcp_task(void *arg)
{
LWIP_UNUSED_ARG(arg);
int err, sock;
struct timeval timeout = {.tv_sec = 1, .tv_usec = 0};
struct sockaddr_in server_addr, client_addr;
int connected = -1;
socklen_t sin_size = sizeof(struct sockaddr_in);
char *recv_cmd;
ssize_t recv_cmd_len;
char unknown_cmd_str[] = "Unknown command\n";
recv_cmd = (char *)pvPortMalloc(LWIP_RECV_DATA_SIZE);
LWIP_ERROR("no memory.", recv_cmd != NULL, goto __exit;);
sock = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
LWIP_ERROR("socket build failed.", sock >= 0, return;);
err = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
LWIP_ERROR("setting receive timeout failed.", err == 0, goto __exit;);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = lwip_htons(TCP_PORT);
memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* Socket bind */
err = lwip_bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
LWIP_ERROR("bind failed.", err == 0, goto __exit;);
/* Listen */
err = lwip_listen(sock, 5);
LWIP_ERROR("listen failed.", err == 0, goto __exit;);
while (1)
{
...
}
vTaskDelete(NULL);
__exit:
if (recv_cmd)
vPortFree(recv_cmd);
if (sock >= 0)
lwip_close(sock);
vTaskDelete(NULL);
}
最后我们的大体内容为这些。
4.效果演示
实时显示按键,触摸按键板卡的状态,板卡通过TCP传输返回电脑上。
控制三色灯,在上位机输入对应blue open我们的板卡会接收到数据,将我们的蓝色的小灯开启
反之我们在上位机输入blue close,板卡接收到数据之后,将蓝色小灯给关闭
5.总结收获
第一次接触到恩智浦板卡,在第一次上手的过程搭建自己的环境,根据案例开发完成自己的小项目,在此过程中对网络协议的开发有了进一步的认识,之后在不断开发的过程中,感谢电子森林给予平台让我们能更好学习到电子信息的知识。
项目代码:链接:https://pan.baidu.com/s/1C38wagYpeeCo6nIPf7VGUg?pwd=lled
提取码:lled