请选择 进入手机版 | 继续访问电脑版
查看: 4695|回复: 12

[LPC双核挑战赛] 一种基于电磁无损检测方法的管状零件现场缺陷定性检测仪

[复制链接]
  • TA的每日心情
    奋斗
    2022-3-11 00:40
  • 签到天数: 272 天

    [LV.8]以坛为家I

    9

    主题

    334

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    1543
    最后登录
    2022-7-12
    发表于 2018-6-11 01:08:33 | 显示全部楼层 |阅读模式
    本帖最后由 Litthins 于 2018-6-13 00:21 编辑

    LPC双核挑战赛 项目提交
    首先非常感谢论坛能给我们这么好的机会了解lpc54114这块优秀的板子。
    IMG_20180611_010315.jpg
    视频链接:LPC双核挑战赛 Litthins团队作品 欢迎大家来看!


    ——————————————我是分界线——————————————


    一种基于电磁无损检测方法的
    管状零件现场缺陷定性检测仪





    作者:邓承杰、尚亚期、鄢贵祥、李小高
    时间:2018年6月10日



    一.摘要
        管道在工业系统中有着十分关键的作用,很多工程现场都对管道质量有严格的要求。对于新生产的管状零件而言,铸件内部容易出现不可控的气泡或疏松缺陷,导致产品品质下降甚至出现废件,而在运行的管道时常需要检修,比如危险裂纹的检查,这时就需要用到无损检测技术,也就是在不损坏零件的前提下完成检验操作。在无损检测中,漏磁检测对管状零件横向和纵向裂纹的检验有很大的优势。本项目意在开发一种基于NXP LPC54114的电磁无损缺陷定性检测仪,力求可以在生产现场直接使用。其中步进电机的控制由M0+核实现,其他功能由M4核实现,包括ADC、USART等。并可配合PC软件(包含在附件中)实现3D立体可视化操作。

    二.结构设计
    IMG_20180611_010315.jpg
            为实现设计所要求的运动,设计了本传动机构,并通过3D打印技术打印了模型。但由于成本问题,机构设计存在着一些不足之处,这个成本之内,也算是比较优良的设计。现对其进行以下介绍,主要介绍其要实现的功能与作用。
    零件一.JPG
    底座:该结构用来固定四个电机,中间部分需要设计两个齿轮来实现电机转动位置的转移。
    主动轮:用来传递运动。底盘:该结构用来限制从动轮的自由度,使其实现平稳转动。
    凹圆槽:支撑转台以及转台上的零件。
    零件二.JPG
    螺线管:用于缠绕线圈,并可安装在三个凸台之上,而凸台则由于丝杠的旋转而实现上下移动,从而使线圈能够上下移动。右图结构为中间旋转部分,用来实现被检测工件的旋转,工件放在转台上即可实现旋转运动该机构使传感器的上下运动(通过四周三个步进电机实现)和零件的旋转运动(通过中间步进电机齿轮传动实现)成为可能,是扫描功能实现的基础。

    三.检测原理
    9.png
    无损检测原理:通有交流电的螺线管可在内部产生交变磁场,交变磁场可使置于螺线管内的导体表面产生周向涡电流,其原理如图所示。

    将被检测金属放入转台上,螺线管内的线圈通入交流电,根据电磁原理,有缺陷的金属导体会在缺陷处产生畸变磁场。安装在螺线管上的传感器将检测到的畸变信号传到电脑,然后经过处理进行显示。转台转动实现被检测金属周向检测,三个电机带动丝杠转动,支撑螺旋管向上运动,实现轴向检测。因此,本检测装置可以实现周向和轴向全方位检测。


    四.LPC54114部分
    sdk.JPG
    本作品使用IAR软件环境开发,所用sdk为NXP MCUXpresso SDK Builder创建。参考sdk中双核的demo,将四路步进电机的控制交由小核M0+实现,大核M4主要实现ADC0_3通道的电压信号采集,并将电压信号通过USART发送到PC端。具体使用到板上GPIO资源,ADC资源和USART资源。
    系统运行流程图.JPG
    硬件系统框架图.JPG
    具体系统运行流程图和硬件电路图如上图所示。开机上电后,初始化片上资源。主核在完成ADC和USART配置后,转到小核初始化片上GPIO,产生步进电机控制信号。同时,大核开始从ADC上读取霍尔元件的电压值,并经由USART发送给PC机。AD转换过程由预置信号采集数量确定,当采集到足够多的数据,则大核进入deepsleep/powerdown模式,可使小核停止产生步进电机控制信号,系统等待下次初始化,进行第二次信号采集。
    部分pin_mux.c文件(大核):
    1. void BOARD_InitPins_Core0(void) { /* Function assigned for the Cortex-M4F */
    2.   CLOCK_EnableClock(kCLOCK_Iocon);                           /* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */

    3.   const uint32_t port0_pin0_config = (
    4.     IOCON_PIO_FUNC1 |                                        /* Pin is configured as FC0_RXD_SDA_MOSI */
    5.     IOCON_PIO_MODE_INACT |                                   /* No addition pin function */
    6.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    7.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    8.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    9.     IOCON_PIO_SLEW_STANDARD |                                /* Standard mode, output slew rate control is enabled */
    10.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    11.   );
    12.   IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN0_IDX, port0_pin0_config); /* PORT0 PIN0 (coords: 31) is configured as FC0_RXD_SDA_MOSI */
    13.   const uint32_t port0_pin1_config = (
    14.     IOCON_PIO_FUNC1 |                                        /* Pin is configured as FC0_TXD_SCL_MISO */
    15.     IOCON_PIO_MODE_INACT |                                   /* No addition pin function */
    16.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    17.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    18.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    19.     IOCON_PIO_SLEW_STANDARD |                                /* Standard mode, output slew rate control is enabled */
    20.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    21.   );
    22.   IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN1_IDX, port0_pin1_config); /* PORT0 PIN1 (coords: 32) is configured as FC0_TXD_SCL_MISO */
    23. }
    24. void BOARD_InitADCUSARTPins(void)
    25. {
    26.     /* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */
    27.     CLOCK_EnableClock(kCLOCK_Iocon);
    28.    
    29.     const uint32_t port1_pin0_config = (/* Pin is configured as ADC0_3 */
    30.                                         IOCON_PIO_FUNC0 |
    31.                                         /* No addition pin function */
    32.                                         IOCON_PIO_MODE_INACT
    33.                                         /* Input function is not inverted */
    34.                                         /*IOCON_PIO_INV_DI*/);
    35.     /* PORT1 PIN0 (coords: 32) is configured as ADC0_3 */
    36.     IOCON_PinMuxSet(IOCON, 1U, 0U, port1_pin0_config);
    37.    
    38.     /* USART5 RX/TX pin */
    39.     IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN20_IDX, IOCON_MODE_INACT | IOCON_FUNC1 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//RX
    40.     IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN18_IDX, IOCON_MODE_INACT | IOCON_FUNC1 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//TX
    41. }
    复制代码
    部分小核主程序:
    1. /*******************************************************************************
    2. * Definitions
    3. ******************************************************************************/
    4. #define LED_INIT1() GPIO_PinInit(GPIO, BOARD_8_GPIO_PORT, BOARD_8_GPIO_PIN, &led_config);
    5. #define LED_HIGH1() GPIO_PinWrite(GPIO, BOARD_8_GPIO_PORT, BOARD_8_GPIO_PIN, 1);
    6. #define LED_LOW1() GPIO_PinWrite(GPIO, BOARD_8_GPIO_PORT, BOARD_8_GPIO_PIN, 0);
    7. #define LED_INIT2() GPIO_PinInit(GPIO, BOARD_9_GPIO_PORT, BOARD_9_GPIO_PIN, &led_config);
    8. #define LED_HIGH2() GPIO_PinWrite(GPIO, BOARD_9_GPIO_PORT, BOARD_9_GPIO_PIN, 1);
    9. #define LED_LOW2() GPIO_PinWrite(GPIO, BOARD_9_GPIO_PORT, BOARD_9_GPIO_PIN, 0);
    10. #define LED_INIT3() GPIO_PinInit(GPIO, BOARD_10_GPIO_PORT, BOARD_10_GPIO_PIN, &led_config);
    11. #define LED_HIGH3() GPIO_PinWrite(GPIO, BOARD_10_GPIO_PORT, BOARD_10_GPIO_PIN, 1);
    12. #define LED_LOW3() GPIO_PinWrite(GPIO, BOARD_10_GPIO_PORT, BOARD_10_GPIO_PIN, 0);
    13. #define LED_INIT4() GPIO_PinInit(GPIO, BOARD_11_GPIO_PORT, BOARD_11_GPIO_PIN, &led_config);
    14. #define LED_HIGH4() GPIO_PinWrite(GPIO, BOARD_11_GPIO_PORT, BOARD_11_GPIO_PIN, 1);
    15. #define LED_LOW4() GPIO_PinWrite(GPIO, BOARD_11_GPIO_PORT, BOARD_11_GPIO_PIN, 0);

    16. /*******************************************************************************
    17. * Prototypes
    18. ******************************************************************************/

    19. /*******************************************************************************
    20. * Code
    21. ******************************************************************************/

    22. /*!
    23. * @brief Function to create delay for Led blink.
    24. */
    25. void delay(void)
    26. {
    27.     volatile uint32_t i = 0;
    28.     for (i = 0; i < 15000; ++i)
    29.     {
    30.         __asm("NOP"); /* delay */
    31.     }
    32. }

    33. /*!
    34. * @brief Application-specific implementation of the SystemInitHook() weak function.
    35. */
    36. void SystemInitHook(void)
    37. {
    38.     /* Initialize MCMGR - low level multicore management library. Call this
    39.        function as close to the reset entry as possible to allow CoreUp event
    40.        triggering. The SystemInitHook() weak function overloading is used in this
    41.        application. */
    42.     MCMGR_EarlyInit();
    43. }

    44. /*!
    45. * @brief Main function
    46. */
    47. int main(void)
    48. {
    49.     uint32_t startupData, i;
    50.     mcmgr_status_t status;

    51.     /* Define the init structure for the output LED pin*/
    52.     gpio_pin_config_t led_config = {
    53.         kGPIO_DigitalOutput, 0,
    54.     };

    55.     /* Initialize MCMGR, install generic event handlers */
    56.     MCMGR_Init();

    57.     /* Get the startup data */
    58.     do
    59.     {
    60.         status = MCMGR_GetStartupData(&startupData);
    61.     } while (status != kStatus_MCMGR_Success);

    62.     /* Make a noticable delay after the reset */
    63.     /* Use startup parameter from the master core... */
    64.     for (i = 0; i < startupData; i++)
    65.         delay();

    66.     /* Init board hardware.*/
    67.     /* enable clock for GPIO */
    68.     CLOCK_EnableClock(kCLOCK_Gpio0);
    69.     CLOCK_EnableClock(kCLOCK_Gpio1);
    70.     BOARD_InitPins_Core1();
    71.     /* Configure LED */
    72.     LED_INIT1();
    73.     LED_INIT2();
    74.     LED_INIT3();
    75.     LED_INIT4();
    76.    
    77.     while (1)
    78.     {
    79.         LED_LOW4();
    80.         LED_HIGH1();
    81.         delay();
    82.         LED_LOW1();
    83.         LED_HIGH2();
    84.         delay();
    85.         LED_LOW2();
    86.         LED_HIGH3();
    87.         delay();
    88.         LED_LOW3();
    89.         LED_HIGH4();
    90.         delay();
    91.     }
    92. }
    复制代码
    部分大核主程序:
    1. #include "fsl_debug_console.h"
    2. #include "fsl_gpio.h"
    3. #include "board.h"
    4. #include "mcmgr.h"
    5. #include "fsl_usart.h"
    6. #include <stdbool.h>
    7. #include "fsl_common.h"
    8. #include "pin_mux.h"
    9. #include "fsl_device_registers.h"
    10. #include "fsl_adc.h"
    11. #include "fsl_clock.h"
    12. #include "fsl_power.h"

    13. /*******************************************************************************
    14. * Definitions
    15. ******************************************************************************/
    16. #define DEMO_USART USART5
    17. #define DEMO_USART_CLK_SRC kCLOCK_Flexcomm5
    18. #define DEMO_USART_CLK_FREQ CLOCK_GetFreq(kCLOCK_Flexcomm5)
    19. #define DEMO_ADC_BASE ADC0
    20. #define DEMO_ADC_SAMPLE_CHANNEL_NUMBER 3U

    21. /* Address of RAM, where the image for core1 should be copied */
    22. #define CORE1_BOOT_ADDRESS (void *)0x20010000

    23. #if defined(__CC_ARM)
    24. extern uint32_t Image$CORE1_REGION$Base;
    25. extern uint32_t Image$CORE1_REGION$Length;
    26. #define CORE1_IMAGE_START &Image$CORE1_REGION$Base
    27. #elif defined(__ICCARM__)
    28. extern unsigned char core1_image_start[];
    29. #define CORE1_IMAGE_START core1_image_start
    30. #elif defined(__GNUC__)
    31. extern const char m0_image_start[];
    32. extern const char *m0_image_end;
    33. extern int m0_image_size;
    34. #define CORE1_IMAGE_START ((void *)m0_image_start)
    35. #define CORE1_IMAGE_SIZE ((void *)m0_image_size)
    36. #endif

    37. /*******************************************************************************
    38. * Prototypes
    39. ******************************************************************************/
    40. /* USART user callback */
    41. void USART_UserCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);

    42. static void ADC_Configuration(void);

    43. #ifdef CORE1_IMAGE_COPY_TO_RAM
    44. uint32_t get_core1_image_size(void);
    45. #endif

    46. void delay(void)
    47. {
    48.     volatile uint32_t i = 0;
    49.     for (i = 0; i < 80000; ++i)
    50.     {
    51.         __asm("NOP"); /* delay */
    52.     }
    53. }
    54. /*******************************************************************************
    55. * Variables
    56. ******************************************************************************/
    57. usart_handle_t g_uartHandle;

    58. volatile bool rxBufferEmpty = true;
    59. volatile bool txBufferFull = false;
    60. volatile bool txOnGoing = false;
    61. volatile bool rxOnGoing = false;

    62. adc_result_info_t adcResultInfoStruct;

    63. /*******************************************************************************
    64. * Code
    65. ******************************************************************************/
    66. /* USART user callback */
    67. void USART_UserCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *userData)
    68. {
    69.     userData = userData;

    70.     if (kStatus_USART_TxIdle == status)
    71.     {
    72.         txBufferFull = false;
    73.         txOnGoing = false;
    74.     }

    75.     if (kStatus_USART_RxIdle == status)
    76.     {
    77.         rxBufferEmpty = false;
    78.         rxOnGoing = false;
    79.     }
    80. }

    81. static void ADC_ClockPower_Configuration(void)
    82. {
    83.     /* SYSCON power. */
    84.     POWER_DisablePD(kPDRUNCFG_PD_ADC0);     /* Power on the ADC converter. */
    85.     POWER_DisablePD(kPDRUNCFG_PD_VD7_ENA);  /* Power on the analog power supply. */
    86.     //POWER_DisablePD(kPDRUNCFG_PD_VREFP_SW); /* Power on the reference voltage source. */
    87.     //POWER_DisablePD(kPDRUNCFG_PD_TEMPS);    /* Power on the temperature sensor. */

    88.     /* Enable the clock. */
    89.     CLOCK_AttachClk(kFRO12M_to_MAIN_CLK);

    90.     /* CLOCK_AttachClk(kMAIN_CLK_to_ADC_CLK); */
    91.     /* Sync clock source is not used. Using sync clock source and would be divided by 2.
    92.      * The divider would be set when configuring the converter.
    93.      */

    94.     CLOCK_EnableClock(kCLOCK_Adc0); /* SYSCON->AHBCLKCTRL[0] |= SYSCON_AHBCLKCTRL_ADC0_MASK; */
    95. }

    96. #ifdef CORE1_IMAGE_COPY_TO_RAM
    97. uint32_t get_core1_image_size()
    98. {
    99.     uint32_t core1_image_size;
    100. #if defined(__CC_ARM)
    101.     core1_image_size = (uint32_t)&Image$CORE1_REGION$Length;
    102. #elif defined(__ICCARM__)
    103. #pragma section = "__sec_core"
    104.     core1_image_size = (uint32_t)__section_end("__sec_core") - (uint32_t)&core1_image_start;
    105. #elif defined(__GNUC__)
    106.     core1_image_size = (uint32_t)m0_image_size;
    107. #endif
    108.     return core1_image_size;
    109. }
    110. #endif

    111. /*!
    112. * @brief Application-specific implementation of the SystemInitHook() weak function.
    113. */
    114. void SystemInitHook(void)
    115. {
    116.     /* Initialize MCMGR - low level multicore management library. Call this
    117.        function as close to the reset entry as possible to allow CoreUp event
    118.        triggering. The SystemInitHook() weak function overloading is used in this
    119.        application. */
    120.     MCMGR_EarlyInit();
    121. }

    122. /*!
    123. * @brief Main function
    124. */
    125. int main(void)
    126. {
    127.     usart_config_t config;
    128.     usart_transfer_t xfer;
    129.     /* Initialize MCMGR, install generic event handlers */
    130.     MCMGR_Init();

    131.     /* Init board hardware.*/
    132.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    133.     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);
    134.     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM5);

    135.     RESET_PeripheralReset(kFC5_RST_SHIFT_RSTn);
    136.    
    137.     BOARD_InitPins_Core0();
    138.     BOARD_InitADCUSARTPins();
    139.     BOARD_BootClockFROHF48M();
    140.     BOARD_InitDebugConsole();
    141.    
    142.     PRINTF("\r\nThis is Primary Core!\r\n\n");
    143.    
    144.     USART_GetDefaultConfig(&config);
    145.     config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
    146.     config.enableTx = true;
    147.     config.enableRx = true;
    148.     PRINTF("USART Configured!\r\n");

    149.     USART_Init(DEMO_USART, &config, DEMO_USART_CLK_FREQ);
    150.     USART_TransferCreateHandle(DEMO_USART, &g_uartHandle, USART_UserCallback, NULL);

    151.     ADC_ClockPower_Configuration();
    152.     PRINTF("ADC Basic Function Configure!\r\n");

    153. #if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
    154. #if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
    155.     /* Calibration after power up. */
    156.     if (ADC_DoSelfCalibration(DEMO_ADC_BASE))
    157. #else
    158.     uint32_t frequency;
    159. #if defined(SYSCON_ADCCLKDIV_DIV_MASK)
    160.     frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk);
    161. #else
    162.     frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE);
    163. #endif /* SYSCON_ADCCLKDIV_DIV_MASK */
    164.     /* Calibration after power up. */
    165.     if (ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency))
    166. #endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
    167.     {
    168.         PRINTF("ADC_DoSelfCalibration() Done.\r\n");
    169.     }
    170.     else
    171.     {
    172.         PRINTF("ADC_DoSelfCalibration() Failed.\r\n");
    173.     }
    174. #endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */

    175.     /* Configure the converter and work mode. */
    176.     ADC_Configuration();
    177.     PRINTF("ADC Configured!\r\n");

    178. #ifdef CORE1_IMAGE_COPY_TO_RAM
    179.     /* Calculate size of the image  - not required on MCUXpresso IDE. MCUXpresso copies the secondary core
    180.        image to the target memory during startup automatically */
    181.     uint32_t core1_image_size;
    182.     core1_image_size = get_core1_image_size();
    183.     PRINTF("Copy Secondary core image to address: 0x%x, size: %d\n", CORE1_BOOT_ADDRESS, core1_image_size);

    184.     /* Copy Secondary core application from FLASH to the target memory. */
    185.     memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size);
    186. #endif

    187.     /* Boot Secondary core application */
    188.     PRINTF("Starting Secondary core.\r\n");
    189.     MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, 5, kMCMGR_Start_Synchronous);
    190.     PRINTF("This is secondary Core!\r\n");
    191.    
    192.     uint32_t count=0;
    193.     for(uint8_t i=0;i<10;i++)
    194.     delay();
    195.     while (1)
    196.     {
    197.         PRINTF("ADC Count = %d\r\n", count);
    198.         delay();
    199.         if(count>200)
    200.           break;
    201.         count=count+1;
    202.         /* Get the input from terminal and trigger the converter by software. */
    203.         void delay();
    204.         ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);

    205.         /* Wait for the converter to be done. */
    206.         while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &adcResultInfoStruct))
    207.         {
    208.         }
    209.         PRINTF("adcResultInfoStruct.result        = %d\r\n", adcResultInfoStruct.result);
    210.         PRINTF("\r\n");
    211.         
    212.         uint8_t ADCMSG[5];
    213.         ADCMSG[4]='\0';
    214.         ADCMSG[3]=adcResultInfoStruct.result%10+48;
    215.         ADCMSG[2]=adcResultInfoStruct.result/10%10+48;
    216.         ADCMSG[1]=adcResultInfoStruct.result/10/10%10+48;
    217.         ADCMSG[0]=adcResultInfoStruct.result/10/10/10%10+48;
    218.         xfer.data = ADCMSG;
    219.         xfer.dataSize = sizeof(ADCMSG)-1;
    220.         txOnGoing = true;
    221.         USART_TransferSendNonBlocking(DEMO_USART, &g_uartHandle, &xfer);
    222.     }
    223.     uint8_t ADCMSG[5];
    224.     ADCMSG[4]='\0';
    225.     ADCMSG[3]=88;
    226.     ADCMSG[2]=88;
    227.     ADCMSG[1]=88;
    228.     ADCMSG[0]=88;
    229.     xfer.data = ADCMSG;
    230.     xfer.dataSize = sizeof(ADCMSG)-1;
    231.     txOnGoing = true;
    232.     USART_TransferSendNonBlocking(DEMO_USART, &g_uartHandle, &xfer);
    233.     PRINTF("Electromagnetic Nondestructive Testing Completed!\r\n");
    234.     PRINTF("\r\n");
    235.    
    236.     POWER_EnterDeepPowerDown(0U);
    237. }

    238. static void ADC_Configuration(void)
    239. {
    240.     adc_config_t adcConfigStruct;
    241.     adc_conv_seq_config_t adcConvSeqConfigStruct;

    242. /* Configure the converter. */
    243. #if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
    244.     adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */
    245. #endif                                                     /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */
    246.     adcConfigStruct.clockDividerNumber = 1;                /* The divider for sync clock is 2. */
    247. #if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
    248.     adcConfigStruct.resolution = kADC_Resolution12bit;
    249. #endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */
    250. #if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL
    251.     adcConfigStruct.enableBypassCalibration = false;
    252. #endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL */
    253. #if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP
    254.     adcConfigStruct.sampleTimeNumber = 0U;
    255. #endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP */
    256. #if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE
    257.     adcConfigStruct.enableLowPowerMode = false;
    258. #endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE */
    259. #if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG
    260.     adcConfigStruct.voltageRange = kADC_HighVoltageRange;
    261. #endif /* FSL_FEATURE_ADC_HAS_TRIM_REG */
    262.     ADC_Init(DEMO_ADC_BASE, &adcConfigStruct);

    263. #if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL)
    264.     /* Use the temperature sensor input to channel 0. */
    265.     ADC_EnableTemperatureSensor(DEMO_ADC_BASE, true);
    266. #endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */

    267.     /* Enable channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER's conversion in Sequence A. */
    268.     adcConvSeqConfigStruct.channelMask =
    269.         (1U << DEMO_ADC_SAMPLE_CHANNEL_NUMBER); /* Includes channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER. */
    270.     adcConvSeqConfigStruct.triggerMask = 0U;
    271.     adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityPositiveEdge;
    272.     adcConvSeqConfigStruct.enableSingleStep = false;
    273.     adcConvSeqConfigStruct.enableSyncBypass = false;
    274.     adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence;
    275.     ADC_SetConvSeqAConfig(DEMO_ADC_BASE, &adcConvSeqConfigStruct);
    276.     ADC_EnableConvSeqA(DEMO_ADC_BASE, true); /* Enable the conversion sequence A. */
    277.     /* Clear the result register. */
    278.     ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
    279.     while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &adcResultInfoStruct))
    280.     {
    281.     }
    282.     ADC_GetConvSeqAGlobalConversionResult(DEMO_ADC_BASE, &adcResultInfoStruct);
    283. }
    复制代码

    五.PC上位机部分
    1.程序简介:
    计算机上位机部分总共有两部分,包括上位机与单片机的串口通讯部分,以及上位机的三维显示部分。上位机程序部分全部用Python语言编程,实现了其与下位机单片机C语言之间的完美配合。上位机程序包括了四个文件:usart.py,  xianshif.py,  qtf.py,  main.py其中调用了python中的第三方库有serial,time,sys, numpy,matplotlib,math,pyqt5。
    2.程序原理:
    usart.py文件中调用serial第三方库,更改串口号和波特率,实现单片机发送字符,上位机接收字符的功能,并将接受到的数据写入一个txt文件。xianshif.py 文件中调用qtf.py,用qtf.py中的SelectDialog类选择要读取的txt文件,导入文件后用matplotlib.pyplot分别绘制三维散点图(由于点比较多所以绘制出来的图形接近连续的三维立体图),三维雨图。
    3.程序详解:
    usart.py:先调用serial第三方库,编写recv函数,其功能为用serial.read_all()函数读取字符,并用return返回字符,每个字符读取时暂停20ms。接下来是主函数,serial.Serial(“com3”,115200,timeout=0.5),设置其接受数据为电脑的com3端口,波特率设置为115200(与单片机串口波特率相同);用isOpen()去查看是否成功打开串口;进入无限循环接受字符的模式,将接收到的四位字符打包成一个字符串,由于接受的顺序原因,需要将字符串对称调换,将所有的四位字符串转化为一个列表的格式,当接受到单片机发送过来的结束指令“X”字符时,将列表转换成字符串的形式储存在txt文件中,然后用sys.exit()函数退出主程序。
    qtf.py:调用pyqt5和os,sys第三方库。此程序包含两个类,第一个类SelectDialog()为选择文件的对话框,其中changepath()方法为启动选择文件的界面,initUi()方法可以作为显示调用哪个文件以及最终的确认;第二个类Example(),包含两个方法,一个initUi()是显示主窗口的方法(其中包含一个菜单方法,可以通过点击菜单选项退出程序),center()为让窗口居中显示的方法。

    Xianshif.py:调用numpy,matplotlib,math第三方库,以及qtf.py模块。程序先建立一个分成两部分,并且大小确定的画板;用pyqt5选择要调用的文件名称,储存为字符串,然后再用withopen()打开这个文件,然后逐行读取储存为数组a,然后用meshgrid()函数生成了绘制雨图所用到的x,y坐标,通过中间的一步步转换,可以最后求出三维散点图和三维雨图所对应的每个点的坐标,然后三维点图可以通过scatter()绘制,而三维雨图可以通过plot_surface()方法去绘制。(此程序还有一个闪光点,将一个二维平面卷起来变成三维图,并且在不用知道txt文件的行数和列数的条件下,可以在读取文件的时候自行判断,详情见程序。)

    六.作品总结
    本作品基本实现了上述流程图中的功能。但在开发过程中遭遇GND与3V3短接,板子直接冒烟,虽抢救及时,但板子失去带WIFI模块的能力,连上模块后电压会被拉低,然后系统失去响应。调试ADC模块真的不容易,参考很多文件,效果一直不太理想。本作品使用的霍尔传感器在工作中输出压差在70mV左右,要想获得更好的结果则需要外加放大器和滤波电路。由于信号类似于正弦信号,滤波效果不太理想,感兴趣的朋友建议尝试锁相放大器,求互相关函数可以得到较好效果。附完整程序,包括开发板代码和PC机客户端源程序。(开发板工程文件在“LPC双核挑战赛 Litthins团队作品\LPC54114J256\boards\lpcxpresso54114\multicore_examples\hello_world”)。

    LPC双核挑战赛 Litthins团队作品 高频信号发生器设计.zip (141.51 KB, 下载次数: 9)

    评分

    参与人数 1 +5 收起 理由
    NXP管管 + 5 很给力!

    查看全部评分

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-5-20 10:16
  • 签到天数: 1 天

    [LV.1]初来乍到

    0

    主题

    18

    帖子

    0

    注册会员

    Rank: 2

    积分
    130
    最后登录
    2021-9-4
    发表于 2018-6-11 01:29:30 | 显示全部楼层
    构思很巧妙,写的超详细,很有参考价值的
    干活啦
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-11 00:40
  • 签到天数: 272 天

    [LV.8]以坛为家I

    9

    主题

    334

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    1543
    最后登录
    2022-7-12
     楼主| 发表于 2018-6-11 10:20:09 | 显示全部楼层
    shanggelaile 发表于 2018-6-11 01:29
    构思很巧妙,写的超详细,很有参考价值的

    其实这个作品还有很多地方需要完善,更多的应该算是理论的复现。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    1

    帖子

    0

    新手上路

    Rank: 1

    积分
    4
    最后登录
    2018-6-11
    发表于 2018-6-11 14:59:35 来自手机 | 显示全部楼层
    真厉害(ง •̀_•́)ง
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32001
    最后登录
    2024-4-9
    发表于 2018-6-11 15:10:51 | 显示全部楼层
    真厉害(ง •̀_•́)ง
    签到签到
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    帖子

    0

    新手上路

    Rank: 1

    积分
    8
    最后登录
    2018-6-15
    发表于 2018-6-11 19:48:48 来自手机 | 显示全部楼层
    超厉害(ง •̀_•́)ง
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    帖子

    0

    新手上路

    Rank: 1

    积分
    8
    最后登录
    2018-6-15
    发表于 2018-6-11 19:50:13 来自手机 | 显示全部楼层
    很详细,产品创意很有现实意义
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-11 00:40
  • 签到天数: 272 天

    [LV.8]以坛为家I

    9

    主题

    334

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    1543
    最后登录
    2022-7-12
     楼主| 发表于 2018-6-11 21:26:24 | 显示全部楼层
    abc15935743eefb 发表于 2018-6-11 14:59
    真厉害(ง •̀_•́)ง

    谢谢支持
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-11 00:40
  • 签到天数: 272 天

    [LV.8]以坛为家I

    9

    主题

    334

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    1543
    最后登录
    2022-7-12
     楼主| 发表于 2018-6-11 21:27:07 | 显示全部楼层
    NXP管管 发表于 2018-6-11 15:10
    真厉害(ง •̀_•́)ง

    谢谢管管大大支持!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-3-11 00:40
  • 签到天数: 272 天

    [LV.8]以坛为家I

    9

    主题

    334

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    1543
    最后登录
    2022-7-12
     楼主| 发表于 2018-6-11 21:30:16 | 显示全部楼层
    yanguixiang 发表于 2018-6-11 19:48
    超厉害(ง •̀_•́)ง

    过奖了,其实我们这个离实际应用还有一段的距离,更像个演示模型。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-18 19:07 , Processed in 0.145334 second(s), 30 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表