这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【FRDM-MCXN947评测】-传感器远程采集与控制

共1条 1/1 1 跳转至

【FRDM-MCXN947评测】-传感器远程采集与控制

菜鸟
2024-12-02 11:40:23     打赏

一、项目框图

如下是系统简易框图。

image.png

本次用到的外设模块:RED LED, GREEN LED, BUTTON SW3, I3C p3t1755, TouchPad "E1"


2. LED:

FRDM-MCXN947开发板有个RGB的三色小灯,电路原理图如下:

image.png

const port_pin_config_t port0_10_pinB12_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields [15:0] are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT0, 10U, &port0_10_pinB12_config);

    const port_pin_config_t port0_27_pinE10_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields [15:0] are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT0_27 (pin E10) is configured as PIO0_27 */
    PORT_SetPinConfig(PORT0, 27U, &port0_27_pinE10_config);	
		
		    const port_pin_config_t port1_2_pinC4_config = {/* Internal pull-up/down resistor is disabled */
                                                    kPORT_PullDisable,
                                                    /* Low internal pull resistor value is selected. */
                                                    kPORT_LowPullResistor,
                                                    /* Fast slew rate is configured */
                                                    kPORT_FastSlewRate,
                                                    /* Passive input filter is disabled */
                                                    kPORT_PassiveFilterDisable,
                                                    /* Open drain output is disabled */
                                                    kPORT_OpenDrainDisable,
                                                    /* Low drive strength is configured */
                                                    kPORT_LowDriveStrength,
                                                    /* Pin is configured as PIO1_2 */
                                                    kPORT_MuxAlt0,
                                                    /* Digital input enabled */
                                                    kPORT_InputBufferEnable,
                                                    /* Digital input is not inverted */
                                                    kPORT_InputNormal,
                                                    /* Pin Control Register fields [15:0] are not locked */
                                                    kPORT_UnlockRegister};
    /* PORT1_2 (pin C4) is configured as PIO1_2 */
    PORT_SetPinConfig(PORT1, 2U, &port1_2_pinC4_config);	

之后调用初始化函数:

		LED_RED_INIT(LOGIC_LED_OFF);
LED_GREEN_INIT(LOGIC_LED_OFF);
LED_BLUE_INIT(LOGIC_LED_OFF);

至此,LED部分的驱动完成。在后面的设计中,红色和绿色小灯将由网页直接控制,蓝色小灯会有触摸板E1来控制。


3 按键

FRDM开发板的SW3可以用作ISP功能,也可以当作普通的按键。

image.png

配置引脚:

    const port_pin_config_t port0_6_pinC14_config = {/* Internal pull-up resistor is enabled */
                                                    kPORT_PullUp,
                                                    /* Low internal pull resistor value is selected. */
                                                    kPORT_LowPullResistor,
                                                    /* Fast slew rate is configured */
                                                    kPORT_FastSlewRate,
                                                    /* Passive input filter is disabled */
                                                    kPORT_PassiveFilterDisable,
                                                    /* Open drain output is disabled */
                                                    kPORT_OpenDrainDisable,
                                                    /* Low drive strength is configured */
                                                    kPORT_LowDriveStrength,
                                                    /* Pin is configured as PIO0_6 */
                                                    kPORT_MuxAlt0,
                                                    /* Digital input enabled */
                                                    kPORT_InputBufferEnable,
                                                    /* Digital input is not inverted */
                                                    kPORT_InputNormal,
                                                    /* Pin Control Register fields [15:0] are not locked */
                                                    kPORT_UnlockRegister};
   /* PORT0_6 (pin C14) is configured as PIO0_6 */
   PORT_SetPinConfig(PORT0, 6U, &port0_6_pinC14_config);

接下来类似LED,进行初始化SW3:

/********************* SW3 INIT BEGIN *************************************************************/		

/* Define the init structure for the input switch pin */
   gpio_pin_config_t sw_config = {
       kGPIO_DigitalInput,
       0,
   };

   GPIO_PinInit(BOARD_SW_GPIO, BOARD_SW_GPIO_PIN, &sw_config);
/********************* SW3 INIT DONE *************************************************************/


4 温度传感器

FRDM-MCXN947开发板上有一颗i3c接口的温度传感器。这个i3c是i2c的升级版。

I3C,全称为Improved Inter-Integrated Circuit,是一种由MIPI联盟发布的通信总线接口标准。作为I2C(Inter-Integrated Circuit)的升级版,I3C不仅继承了I2C的2线传输特性,还在性能、功耗和扩展性方面进行了显著的改进。

image.png

初始化代码:

/********************* i3c INIT BEGIN *************************************************************/		

   PRINTF("\r\nI3C master read sensor data example.\r\n");

   I3C_MasterGetDefaultConfig(&masterConfig);
   masterConfig.baudRate_Hz.i2cBaud          = EXAMPLE_I2C_BAUDRATE;
   masterConfig.baudRate_Hz.i3cPushPullBaud  = EXAMPLE_I3C_PP_BAUDRATE;
   masterConfig.baudRate_Hz.i3cOpenDrainBaud = EXAMPLE_I3C_OD_BAUDRATE;
   masterConfig.enableOpenDrainStop          = false;
   masterConfig.disableTimeout               = true;
   I3C_MasterInit(EXAMPLE_MASTER, &masterConfig, I3C_MASTER_CLOCK_FREQUENCY);

   /* Create I3C handle. */
   I3C_MasterTransferCreateHandle(EXAMPLE_MASTER, &g_i3c_m_handle, &masterCallback, NULL);

   result = p3t1755_set_dynamic_address();
   if (result != kStatus_Success)
   {
       PRINTF("\r\nP3T1755 set dynamic address failed.\r\n");
   }

   p3t1755Config.writeTransfer = I3C_WriteSensor;
   p3t1755Config.readTransfer  = I3C_ReadSensor;
   p3t1755Config.sensorAddress = SENSOR_ADDR;
   P3T1755_Init(&p3t1755Handle, &p3t1755Config);

char tempVal[15]={'\0'};
/********************* i3c INIT END *************************************************************/


5 触摸板E1

FRDM开发板上的E1是一个触摸板,原理图如下:

image.png

TSI模块初始化:

/********************* tsi touch pad INIT BEGIN *************************************************************/		
   /* Configure LPTMR */
   LPTMR_GetDefaultConfig(&lptmrConfig);
   /* TSI default hardware configuration for self-cap mode */
   TSI_GetSelfCapModeDefaultConfig(&tsiConfig_selfCap);

   /* Initialize the LPTMR */
   LPTMR_Init(LPTMR0, &lptmrConfig);
   /* Initialize the TSI */
   TSI_InitSelfCapMode(APP_TSI, &tsiConfig_selfCap);
   /* Enable noise cancellation function */
   TSI_EnableNoiseCancellation(APP_TSI, true);

   /* Set timer period */
   LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(LPTMR_USEC_COUNT, LPTMR_SOURCE_CLOCK));

   NVIC_EnableIRQ(TSI0_IRQn);
   TSI_EnableModule(APP_TSI, true); /* Enable module */

   PRINTF("\r\nTSI_V6 Self-Cap mode Example Start!\r\n");
   /*********  CALIBRATION PROCESS ************/
   memset((void *)&buffer, 0, sizeof(buffer));
   TSI_SelfCapCalibrate(APP_TSI, &buffer);
   /* Print calibrated counter values */
   for (i = 0U; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++)
   {
       PRINTF("Calibrated counters for channel %d is: %d \r\n", i, buffer.calibratedData[i]);
   }
/********** HARDWARE TRIGGER SCAN ********/
   PRINTF("\r\nNOW, comes to the hardware trigger scan method!\r\n");
   PRINTF("After running, touch pad %s each time, you will see LED toggles.\r\n", PAD_TSI_ELECTRODE_1_NAME);
   TSI_EnableModule(APP_TSI, false);
   TSI_EnableHardwareTriggerScan(APP_TSI, true);
   TSI_EnableInterrupts(APP_TSI, kTSI_EndOfScanInterruptEnable);
   TSI_ClearStatusFlags(APP_TSI, kTSI_EndOfScanFlag);

   TSI_SetSelfCapMeasuredChannel(APP_TSI,
                                 BOARD_TSI_ELECTRODE_1); /* Select BOARD_TSI_ELECTRODE_1 as detecting electrode. */
   TSI_EnableModule(APP_TSI, true);
   INPUTMUX_AttachSignal(INPUTMUX0, 0U, kINPUTMUX_Lptmr0ToTsiTrigger);
   LPTMR_StartTimer(LPTMR0); /* Start LPTMR triggering */  
   


其中,TSI模块开启硬件中断:


void TSI0_IRQHandler(void)
{
   if (TSI_GetSelfCapMeasuredChannel(APP_TSI) == BOARD_TSI_ELECTRODE_1)
   {
       if (TSI_GetCounter(APP_TSI) > (uint16_t)(buffer.calibratedData[BOARD_TSI_ELECTRODE_1] + TOUCH_DELTA_VALUE))
       {
           LED1_TOGGLE(); /* Toggle the touch event indicating LED */
           s_tsiInProgress = true;
       }
   }

   /* Clear endOfScan flag */
   TSI_ClearStatusFlags(APP_TSI, kTSI_EndOfScanFlag);
   SDK_ISR_EXIT_BARRIER;
}

至此,TSI模块初始化完毕。


三、增加LwIp HTTPD服务器:

FRDM-MCXN947开发板的固件库提供了Lwip httpsrv这个例程,里面有个简单的http服务器,本文拿来参考其中的初始化代码:

		
   CLOCK_AttachClk(MUX_A(CM_ENETRMIICLKSEL, 0));
   CLOCK_EnableClock(kCLOCK_Enet);
   SYSCON0->PRESETCTRL2 = SYSCON_PRESETCTRL2_ENET_RST_MASK;
   SYSCON0->PRESETCTRL2 &= ~SYSCON_PRESETCTRL2_ENET_RST_MASK;

   MDIO_Init();

   g_phy_resource.read  = MDIO_Read;
   g_phy_resource.write = MDIO_Write;

   time_init();

   /* Set MAC address. */
#ifndef configMAC_ADDR
   (void)SILICONID_ConvertToMacAddr(&enet_config.macAddress);
#endif

   /* Get clock after hardware init. */
   enet_config.srcClockHz = EXAMPLE_CLOCK_FREQ;

#if LWIP_IPV4
   IP4_ADDR(&netif_ipaddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3);
   IP4_ADDR(&netif_netmask, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3);
   IP4_ADDR(&netif_gw, configGW_ADDR0, configGW_ADDR1, configGW_ADDR2, configGW_ADDR3);
#endif /* LWIP_IPV4 */

   lwip_init();

#if LWIP_IPV4
   netif_add(&netif, &netif_ipaddr, &netif_netmask, &netif_gw, &enet_config, EXAMPLE_NETIF_INIT_FN, ethernet_input);
#else
   netif_add(&netif, &enet_config, EXAMPLE_NETIF_INIT_FN, ethernet_input);
#endif /* LWIP_IPV4 */
   netif_set_default(&netif);
   netif_set_up(&netif);

#if LWIP_IPV6
   netif_create_ip6_linklocal_address(&netif, 1);
#endif /* LWIP_IPV6 */

   while (ethernetif_wait_linkup(&netif, 5000) != ERR_OK)
   {
       PRINTF("PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
   }

   //httpd_init();
http_server_init();

#if LWIP_IPV6
   set_ipv6_valid_state_cb(netif_ipv6_callback);
#endif /* LWIP_IPV6 */

   PRINTF("\r\n***********************************************************\r\n");
   PRINTF(" HTTP Server example\r\n");
   PRINTF("***********************************************************\r\n");
#if LWIP_IPV4
   PRINTF(" IPv4 Address     : %u.%u.%u.%u\r\n", ((u8_t *)&netif_ipaddr)[0], ((u8_t *)&netif_ipaddr)[1],
          ((u8_t *)&netif_ipaddr)[2], ((u8_t *)&netif_ipaddr)[3]);
   PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&netif_netmask)[0], ((u8_t *)&netif_netmask)[1],
          ((u8_t *)&netif_netmask)[2], ((u8_t *)&netif_netmask)[3]);
   PRINTF(" IPv4 Gateway     : %u.%u.%u.%u\r\n", ((u8_t *)&netif_gw)[0], ((u8_t *)&netif_gw)[1],
          ((u8_t *)&netif_gw)[2], ((u8_t *)&netif_gw)[3]);
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
   print_ipv6_addresses(&netif);
#endif /* LWIP_IPV6 */
   PRINTF("***********************************************************\r\n");

   while (1)
   {

       /* Poll the driver, get any outstanding frames */
       ethernetif_input(&netif);

       sys_check_timeouts(); /* Handle all system timeouts for all core protocols */
   }


在本设计中,使用CGI和SSI技术,来实现网页控制LED灯,以及把温度传感器数据上报到网页的目标。

其中CGI部分是嵌入在网页html代码中的,定义如下:

<form method="get" action="/leds.cgi"><input value="1" name="led" type="checkbox">RED ON<br>
<input value="2" name="led" type="checkbox">RED OFF<br>
<input value="3" name="led" type="checkbox">GREEN ON<br>
<input value="4" name="led" type="checkbox">GREEN OFF
<br>
<br>
<input value="Send" type="submit"> </form>

网页预览如下:

image.png

在勾选RED ON,然后点击SEND后,MCXN947就会接受到相应的以太网报文并进行解析:

const char * LEDS_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
{
//printf("\r\n inside httpd_cgi_ssi.c line 132. LEDS_CGI_Handler was Called.");
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n *************************************************************"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\ninside httpd_cgi_ssi.c line 132. LEDS_CGI_Handler was Called."));

 uint32_t i=0;
 
 /* We have only one SSI handler iIndex = 0 */
 if (iIndex==0)
 {
   /* All LEDs off */
LED_RED_OFF();
LED_GREEN_OFF();
   
   /* Check cgi parameter : example GET /leds.cgi?led=2&led=4 */
   for (i=0; i<iNumParams; i++)
   {
     /* check parameter "led" */
     if (strcmp(pcParam[i] , "led")==0)  
     {
//printf("\r\n inside httpd_cgi_ssi.c line 148. led received.");

       /* Switch LED1 ON if 1 */
       if(strcmp(pcValue[i], "1") ==0) {
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ********>>>> LED FOUND <<<<<<**"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n            matched led1"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ***************************"));
LED_RED_ON();
}
         
         
       /* Switch LED2 ON if 2 */
       else if(strcmp(pcValue[i], "2") ==0){
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ********>>>> LED FOUND <<<<<<**"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n matched led2"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ***************************"));
LED_RED_OFF();
}
         //BSP_LED_On(LED2);
       
       /* Switch LED3 ON if 3 */
       else if(strcmp(pcValue[i], "3") ==0){
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ********>>>> LED FOUND <<<<<<**"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n matched led3"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ***************************"));
LED_GREEN_ON();
}
       
       /* Switch LED4 ON if 4 */
       else if(strcmp(pcValue[i], "4") ==0){
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ********>>>> LED FOUND <<<<<<**"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n matched led4"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ***************************"));
LED_GREEN_OFF();
}//<--END OF IF -->
     }
   }//<--END OF FOOR LOOP-->
 }//<--END OF IF(INDEX == 0)-->
 /* uri to send after cgi call*/
 return "/NXPMCXN947LED.html";  
}


SSI技术用于把触摸,按键以及温度信息上报给浏览器:

注意<!--#b-->这其中的b就是一个变量,后面可以在代码里去更新这个值,然后由于网页是定时刷新的,所以浏览器那边也可以看到最近更新的值。

利用这种方式,b代表button; t代表温度;s代表触摸传感器。

image.png


SSI部分对应的代码:

u16_t Button_Handler(int iIndex, char *pcInsert, int iInsertLen)
{
 /* We have only 3 SSI handler, iIndex = 0 */
static uint32_t tempCnt = 0;
static double temperature;

switch(iIndex){
case 0:
if((0 == GPIO_PinRead(BOARD_SW3_GPIO, BOARD_SW3_GPIO_PIN))){
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ********>>>> BUTTON PRESSED <<<<<<**"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n            SW3 (P0_6)"));
LWIP_DEBUGF(HTTPD_DEBUG, ("\r\n ***************************"));
/* prepare data to be inserted in html */
*pcInsert       = (char)(66);
*(pcInsert + 1) = (char)(84);
*(pcInsert + 2) = (char)(78);
*(pcInsert + 3) = (char)(45);
*(pcInsert + 4) = (char)(79);
*(pcInsert + 5) = (char)(78);
*(pcInsert + 6) = (char)(32);
}else{
/* prepare data to be inserted in html */
*pcInsert       = (char)(66);
*(pcInsert + 1) = (char)(84);
*(pcInsert + 2) = (char)(78);
*(pcInsert + 3) = (char)(45);
*(pcInsert + 4) = (char)(79);
*(pcInsert + 5) = (char)(70);
*(pcInsert + 6) = (char)(70);
}

/* 7 characters need to be inserted in html*/
return 7;
break;

case 1:
P3T1755_ReadTemperature(&p3t1755Handle, &temperature);
sprintf(pcInsert, "%.3f", temperature);
return strlen(pcInsert);
break;

case 2:
if(true == s_tsiInProgress){
sprintf(pcInsert, "%s", "Touch Detected..");
s_tsiInProgress = false;
}else{
sprintf(pcInsert, "%s", "..");
}
return strlen(pcInsert);
break;

default:
break;

}
 return 0;
}


image.png

项目效果:

EEPW mcxn947实物展示.zip




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]