查看: 906|回复: 0

[项目分享] 【N32电机控制大赛】基于N32G455的交互式手柄钥匙

[复制链接]
  • TA的每日心情
    开心
    2024-2-3 08:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2023-4-16 20:33:30 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 codingtuzi 于 2023-4-16 20:34 编辑

    【N32电机控制大赛】基于N32G455的交互式手柄钥匙

    背景介绍:
    在工业智能制造中,机械装置越来越多地应用于车间,场矿。随之带来的操作人员权限认证与操作记录保存的需求也就日益突出。非法人员,未授权人员使用机器进行违规,危险操作;操作人员违反操作手册操作,事后追究,事故分析等问题很难清晰理清。现有权鉴方式多为传统的机械钥匙,存在易丢失,易冒用,无法追踪等风险,而对日志记录功能,基本处于空缺状态。
    基于上述背景,本次项目实验设计利用国民技术加密算法库完成操作人员权限管理,利用N32G455芯片丰富的外设通讯能力操控目标设备。
    方案简介:
    1.       由单一操控的手柄升级为可操作,可认证的手柄钥匙;
    2.       使用CAN 2.0B外设与目标控制器通讯,完成目标设备的待机与实时操作;
    3.       双摇杆与按键联合,保留了易操作性,便于操作人员上手使用;
    4.       兼具数据记录仪功能,类似事故的“黑匣子”可用于现场回放;
    5.       通过N32板载的加密算法,实现人员认证与权限管理
    方案亮点:
    1.       在MCU中使用非对称加密方式加密密钥,不会泄露密码数据
    2.       丰富的外设,如CAN 2.0和RS485物理层协议
    3.       可对操作指令进行数据保存,可通过AES对称方式加密保存
    4.       在强大的安全加密算法下,数据以低成本的TF卡形式保存。有效降低部署成本,让追溯更易普及
    硬件设计框图
    N32G455软件流程图-第 3 页.drawio (1).png
    硬件模块设计摇杆
    在对需求做市场调研时,对于机械手臂的操作,最常用的即为摇杆,操作幅度,力馈均可以较好的给操作人员带来便捷与稳定的控制。另外一种,类似于虚拟现实中的手套,体验感与科技感十足,但成本与技术门槛较高。本次设计中,采用指控摇杆的方案,成本与技术均可,体验感又保持在一定高度。
    双轴摇杆采用103电位器开关实现,在设计中使用两路ADC对电压进行采集。
      
    功能
      
    引脚
    备注
      
    摇杆x轴
      
    PC0

      
    摇杆y轴
      
    PC1


    CAN外设
    对于电机控制,首选CAN通讯。养分信号的物理层协议可以屏蔽掉共模信号的干扰。CAN 2.0B的高带宽,又可以满足电机控制的实时与高精度控制。CAN控制器的Filter功能又可以最大限度的减少总线数据的影响,MCU也更专注于处理算法,专注于处理自己相关的控制信息。
    与非网24.png
    RS485通讯
    在本次设计中,保留了低速,低成本的RS485通讯方案。此方案预留主要目的在对控制器进行固件升级,控制器配置数据更新等操作。可以将控制器连接到物联网,网关等边缘设备上。
    与非网25.png
    SPI外设(SDIO外设)
    本次设计中有一项为日志的数据保存。对SD卡的读写物理层上驱动可以选用SDIO和SPI两种模式。考虑时间与精力上的原因,第一阶段实现SPI模式的驱动;第二阶段再实现SDIO模式。
      
    功能
      
    引脚
    备注
      
    SPI1 MOSI
      
    PA5

      
    SPI1 SCLK
      
    PA7

      
    SPI1 MISO
      
    PA6

      
    SD select
      
    PA4


    软件模块设计
    本次软件架构相对简单,使用FreeRTOS嵌入式操作系统,来实现所有需求。
    任务划分
    根据设计需求,我本次将任务划分如下:
    l  按键和摇杆,两者均是对电机的操作,只是采样形式不同,因此划分在同一个任务之中。以周期20ms采样,并进行滤波与去抖算法
    l  CAN通讯发送,在人机交互过程中,在对按键进行采集确认后,通过队列的方式接收按键键码与数值,进行封装后在CAN总线网络上发送
    l  CAN通讯接收,接收到设备的数据。将有效数据收集后,转存到TF卡
    按键和摇杆
    摇杆采集的为模拟量,因此,在本次设计上,以阶段阈值的方式实现,即分为3档速度。
    1. void bsp_adc_init(void)
    2. {
    3.   GPIO_InitType GPIO_InitStructure;
    4.   ADC_InitType ADC_InitStructure;

    5.   RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1, ENABLE);
    6.   ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16);
    7.   RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8);

    8.   /* Configure PC0 PC1 as analog input -------------------------*/
    9.   GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    10.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    11.   GPIO_InitPeripheral(GPIOC, &GPIO_InitStructure);

    12.   /* ADC configuration ------------------------------------------------------*/
    13.   ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT;
    14.   ADC_InitStructure.MultiChEn = DISABLE;
    15.   ADC_InitStructure.ContinueConvEn = DISABLE;
    16.   ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE;
    17.   ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
    18.   ADC_InitStructure.ChsNumber = 1;
    19.   ADC_Init(ADC1, &ADC_InitStructure);

    20.   /* Enable ADC */
    21.   ADC_Enable(ADC1, ENABLE);
    22.   /*Check ADC Ready*/
    23.   while (ADC_GetFlagStatusNew(ADC1, ADC_FLAG_RDY) == RESET)
    24.     ;
    25.   /* Start ADC calibration */
    26.   ADC_StartCalibration(ADC1);
    27.   /* Check the end of ADC calibration */
    28.   while (ADC_GetCalibrationStatus(ADC1))
    29.     ;
    30. }
    复制代码
    CAN通讯
    使用CAN1外设,设置500kbps的标准帧模式
    1. void bsp_can_init(void)
    2. {
    3.   GPIO_InitType GPIO_InitStructure;
    4.   CAN_InitType CAN_InitStructure;

    5.   GPIO_ConfigPinRemap(GPIO_RMP1_CAN2, ENABLE);

    6.   /* Configure CAN1 RX pin */
    7.   GPIO_InitStructure.Pin = GPIO_PIN_5;
    8.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    9.   GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
    10.   /* Configure CAN1 TX pin */
    11.   GPIO_InitStructure.Pin = GPIO_PIN_6;
    12.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    13.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    14.   GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);

    15.   GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
    16.   RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN2, ENABLE);
    17.   /* CAN register init */
    18.   CAN_DeInit(CAN2);
    19.   /* Struct init*/
    20.   CAN_InitStruct(&CAN_InitStructure);
    21.   /* CAN cell init */
    22.   CAN_InitStructure.TTCM = DISABLE;
    23.   CAN_InitStructure.ABOM = DISABLE;
    24.   CAN_InitStructure.AWKUM = DISABLE;
    25.   CAN_InitStructure.NART = DISABLE;
    26.   CAN_InitStructure.RFLM = DISABLE;
    27.   CAN_InitStructure.TXFP = ENABLE;
    28.   CAN_InitStructure.OperatingMode = OPERATINGMODE;
    29.   CAN_InitStructure.RSJW = CAN_BIT_RSJW;
    30.   CAN_InitStructure.TBS1 = CAN_BIT_BS1;
    31.   CAN_InitStructure.TBS2 = CAN_BIT_BS2;
    32.   CAN_InitStructure.BaudRatePrescaler = CAN_BAUDRATEPRESCALER; // 500K
    33.   /*Initializes the CAN */
    34.   CAN_Init(CAN1, &CAN_InitStructure);
    35.   CAN_Filter_Init();
    36.   CAN_NVIC_Config();
    37. }
    复制代码
    RS485通讯
    1. void bsp_usart_init(void)
    2. {

    3.   USART_InitType USART_InitStructure;
    4.   GPIO_InitType GPIO_InitStructure;
    5.   NVIC_InitType NVIC_InitStructure;
    6.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    7.   uart_rx.length = 0;
    8.   uart_rx.state = rx_state_idle;
    9.   /* Enable the USARTy Interrupt */
    10.   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    11.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    12.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    13.   NVIC_Init(&NVIC_InitStructure);

    14.   // RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_AFIO, ENABLE);
    15.   /* Enable USARTy and USARTz Clock */
    16.   RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE);

    17.   /* Configure USARTx Tx as alternate function push-pull */
    18.   GPIO_InitStructure.Pin = GPIO_PIN_9;
    19.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    20.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    21.   GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    22.   /* Configure USARTx Rx as input floating */
    23.   GPIO_InitStructure.Pin = GPIO_PIN_10;
    24.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    25.   GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    26.   /* USARTy and USARTz configuration ------------------------------------------------------*/
    27.   USART_InitStructure.BaudRate = 9600;
    28.   USART_InitStructure.WordLength = USART_WL_8B;
    29.   USART_InitStructure.StopBits = USART_STPB_1;
    30.   USART_InitStructure.Parity = USART_PE_NO;
    31.   USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    32.   USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;

    33.   // USART_ConfigInt(USART1, USART_INT_RXDNE, ENABLE);
    34.   // USART_ConfigInt(USART1, USART_INT_IDLEF, ENABLE);

    35.   /* Configure USARTx */
    36.   USART_Init(USART1, &USART_InitStructure);
    37.   /* Enable the USARTx */
    38.   USART_Enable(USART1, ENABLE);
    39. }
    复制代码
    SPI通讯
    SD卡操作状态流转图:
    与非网26.png


    1. void bsp_spi_init(void)
    2. {
    3.   GPIO_InitType GPIO_InitStructure;
    4.   SPI_InitType SPI_InitStructure;
    5.   /* PCLK2 = HCLK/2 */
    6.   RCC_ConfigPclk2(RCC_HCLK_DIV2);
    7.   RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_SPI1 | RCC_APB2_PERIPH_AFIO, ENABLE);

    8.   /* Configure SPIy pins: SCK, MISO and MOSI ---------------------------------*/
    9.   GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_7;
    10.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    12.   GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    13.   GPIO_InitStructure.Pin = GPIO_PIN_6;
    14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    15.   GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    16.   /* SPI1 Config -------------------------------------------------------------*/
    17.   SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
    18.   SPI_InitStructure.SpiMode = SPI_MODE_MASTER;
    19.   SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;
    20.   SPI_InitStructure.CLKPOL = SPI_CLKPOL_HIGH;
    21.   SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
    22.   SPI_InitStructure.NSS = SPI_NSS_SOFT;
    23.   SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_256;
    24.   SPI_InitStructure.FirstBit = SPI_FB_MSB;
    25.   SPI_InitStructure.CRCPoly = 7;
    26.   SPI_Init(SPI1, &SPI_InitStructure);

    27.   /* Enable SPIy */
    28.   SPI_Enable(SPI1, ENABLE);
    29. }
    复制代码
    实物照片
    DSCN5392.jpg

    DSCN5394.jpg

    DSCN5397.jpg



    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-4-29 09:16 , Processed in 0.108917 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.