本帖最后由 北方. 于 2020-1-8 11:45 编辑
一、项目名称:NFC门锁
二、项目概述:
本系统是基于双核LPC55S69为主控芯片的NFC门锁,采用I2C端口读取NFC读卡器的数据,经过身份验证后,启动伺服电机控制门锁开锁。延时后再次扫描读卡器,如果没有更新并保持的最新读卡器数据后,控制伺服电机返回,关闭门锁。
补充说明:原计划的门锁是采用Tensorflow Lite的智能门锁项目,用摄像头扫描,捕捉人体接近并启动图片识别功能,符合安全身份认证后,开启门锁。原计划中,NFC门锁是其中的一个多重身份验证工具,运行在Core0在低功耗运行。CV识别运行在core1,高速执行。LPC55S69本身功能强大,可以胜任告诉图片读取的功能,但是在导入tensorflow lite的过程中,发现了公版model的问题,就是这个系统太大,不能支持MCU的运行。tensorflow lite对于内存的最小要求是1M内存,680k闪存已经足够大,但是不能支持经过测试的公版model(如mobileNet-0.25x0.25执行flatten后仍然有1.68M)。自行设计model并训练更小的模型,在性能上不能得到验证,所以在提交截止期之前,只能实现现有的功能。感谢本次挑战赛的开发过程,引出了一个有趣的新题目,就是如何在高性能MCU上执行大的模型运行,如VGG这样的深度网络模型,后续仍然继续沿着这个思路开发,力争在这个板子上实现公版模型的适用。经过多次实验,已经有了初步的设计框架:在不启动MMU功能的情况下,如何构建一个SWAP空间,仍然能够快速实现扩址访问,只需要再做一个overlay的内存管理库就可以了。
三、作品实物图 NFC读卡器的链接I2C NFC读卡器的型号 链接9G伺服电机 读卡器读取NFC卡的ID信息
四、演示视频 动态演示这个程序执行过程
五、项目文档 5.1 使用的硬件包括 - LPC55S69 dev board - NFC tag reader ID-12LA, 5.2 主要的代码如下:其中实现servo控制使用了ctime库,定义一个50Hz的占空比再2.5%~12.5%可调的PWM信号来控制伺服电机。 - int main(void)
- {
- i2c_master_config_t masterConfig;
- status_t reVal = kStatus_Fail;
- uint8_t deviceAddress = 0x01U;
-
- ctimer_config_t config;
- uint32_t srcClock_Hz;
- uint32_t timerClock;
- uint8_t updatedutyCyclePercent;
- /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
- CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
- /* attach 12 MHz clock to FLEXCOMM8 (I2C master) */
- CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
- /* Use 12 MHz clock for some of the Ctimers */
- CLOCK_AttachClk(kFRO_HF_to_CTIMER2);
-
- /* reset FLEXCOMM for I2C */
- RESET_PeripheralReset(kFC4_RST_SHIFT_RSTn);
- BOARD_InitPins();
- BOARD_BootClockPLL150M();
- BOARD_InitDebugConsole();
-
- /* CTimer0 counter uses the AHB clock, some CTimer1 modules use the Aysnc clock */
- srcClock_Hz = CTIMER_CLK_FREQ;
- PRINTF("CTimer example to generate a PWM signal\r\n");
- CTIMER_GetDefaultConfig(&config);
- timerClock = srcClock_Hz / (config.prescale + 1);
- CTIMER_Init(CTIMER, &config);
- /* Get the PWM period match value and pulse width match value of 50hz PWM signal with 2.5%~12.5% dutycycle , 20ms peoriod*/
- CTIMER_GetPwmPeriodValue(50, 10, timerClock);
- CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, false);
- CTIMER_StartTimer(CTIMER);
- //CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent);
-
- PRINTF("\r\nI2C board2board polling -- Master transfer.\r\n");
- g_master_txBuff[0] = I2C_DATA_LENGTH - 1U;
- for (uint32_t i = 1U; i < I2C_DATA_LENGTH; i++)
- {
- g_master_txBuff[i] = i - 1;
- }
- I2C_MasterGetDefaultConfig(&masterConfig);
- /* Change the default baudrate configuration */
- masterConfig.baudRate_Bps = I2C_BAUDRATE;
- /* Initialize the I2C master peripheral */
- I2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);
- /* Wait until the slave is ready for transmit, wait time depend on user's case.
- Slave devices that need some time to process received byte or are not ready yet to
- send the next byte, can pull the clock low to signal to the master that it should wait.*/
- for (uint32_t i = 0U; i < WAIT_TIME; i++)
- {
- __NOP();
- }
- PRINTF("Receive sent data from slave :");
-
- while (1)
- {
- for (uint32_t i = 0U; i < WAIT_TIME; i++)
- { __NOP(); }
- /* Receive blocking data from slave */
- if (kStatus_Success == I2C_MasterStart(EXAMPLE_I2C_MASTER, I2C_MASTER_SLAVE_ADDR_7BIT, kI2C_Write))
- {
- reVal = I2C_MasterReadBlocking(EXAMPLE_I2C_MASTER, g_master_rxBuff, I2C_DATA_LENGTH - 1, kI2C_TransferDefaultFlag);
- if (reVal != kStatus_Success)
- {
- return -1;
- }
- reVal = I2C_MasterStop(EXAMPLE_I2C_MASTER);
- if (reVal != kStatus_Success)
- {
- return -1;
- }
- }
- for (uint32_t i = 0U; i < 4; i++)
- //for (uint32_t i = 0U; i < I2C_DATA_LENGTH - 1; i++)
- {
- if (i % 8 == 0)
- {
- PRINTF("\r\n");
- }
- PRINTF("0x%2x ", g_master_rxBuff[i]);
- if (g_master_rxBuff[i]== g_match_id[i] ){g_master_rxBuff[I2C_DATA_LENGTH-1]=127;}
- }
- PRINTF("\r\n\r\n");
-
- // LOCK_UNLOCK, refreshed every loop and return to LOCK off status,
- updatedutyCyclePercent= LOCK_ON ? (g_master_rxBuff[I2C_DATA_LENGTH-1]==127):LOCK_OFF;
- g_pulsePeriod = (g_pwmPeriod * (100 - updatedutyCyclePercent)) / 100;
- CTIMER_UpdatePwmDutycycle(CTIMER, CTIMER_MAT_OUT, g_pulsePeriod);
- }
- // PRINTF("\r\nEnd of I2C example .\r\n");
- }
复制代码
keil工程项目如下, |