发 帖  
原厂入驻New

【大联大世平NXP KE16Z 开发板试用体验】+ 应用:CAN输出的测距模组数据转换器 - 结项

2020-8-30 09:48:33  22
分享
0
本帖最后由 TLLED 于 2020-8-30 09:49 编辑

    项目:CAN输出的测距模组数据转换器;
    描述:手上这个测距模组使用的串口TTL输出,实际应用时需要将N多个测距模组的数据采集后,通过处理使用can通信输出,将数据输出送到系统进行处理,我这个小项目就是将采集的一组距离信息经过处理后,使用CAN数据。


    一、硬件
   
    NXP KE16Z64VLF4,采用 ARM Cortex-M0+ 处理器,最高 48 MHz 的主频, 具有低功耗、高性能的特点,采用此平台的原因是此芯片性价比高,功能齐全,兼容 3.3V 和 5V,拥有 64 kB Flash,8 kB SRAM,1 x I²C,1 x SPI,3 x UART,1 x CAN,8 x 16 Bit PWM,1 x 12Bit ADC,1 x 6Bit DAC 和 42个 GPIO。开发板的资源还是较丰富的。
   
    1.1、这里使用串口0和CAN通信接口
    01.png
   
    1.2、使用到的端口如下:
    PA2,PA3端口连接测距模组
    PB0,PB1端口默认的仿真器,电脑串口查看数据
    PC6,PC7端口使用CAN通信输出
    02.png

    二、软件部分


    软件部分使用了定时器,串口和CAN通信。

    2.1、定时器
    使用定时器FTM设置定时时间为1MS
  1. void Init_tiMER(void)
  2. {
  3.         ftm_config_t ftmInfo;

  4.   FTM_GetDefaultConfig(&ftmInfo);
  5.   ftmInfo.prescale = kFTM_Prescale_Divide_4;
  6.   FTM_Init(FTM_BASEADDR, &ftmInfo);

  7.   FTM_SetTimerPeriod(FTM_BASEADDR, USEC_TO_COUNT(1000U, FTM_SOURCE_clock));
  8.         FTM_EnableInterrupts(FTM_BASEADDR, kFTM_TimeOveRFlowInterruptEnable);
  9.   EnableIRQ(FTM_IRQ_NUM);
  10.   FTM_StartTimer(FTM_BASEADDR, kFTM_SystemClock);
  11. }

  12. void FTM_HANDLER(void)
  13. {
  14.     /* Clear interrupt flag.*/
  15.         FTM_ClearStatusFlags(FTM_BASEADDR, kFTM_TimeOverflowFlag);
  16.     //ftmIsrFlag = true;
  17.         LED_BLUE_TOG();
  18.         
  19.            
  20.         IF(uart_timeout_flag==1)
  21.         {
  22.                 uart_timeout_cnt++;
  23.                 if(uart_timeout_cnt>20)
  24.                 {
  25.                         uart_timeout_cnt=0;
  26.                         uart_timeout_flag=0;
  27.                         uart0_rxjs=0;
  28.                 }
  29.         }
  30.         else
  31.         {
  32.                 uart_timeout_cnt=0;
  33.         }
  34.         
  35.         
  36.         uart_sendcnt++;
  37.         if(uart_sendcnt>100)
  38.         {
  39.                 uart_sendcnt=0;
  40.                 uart_sendflag=1;
  41.         }
  42. }
复制代码

    2.2、CAN通信

   CAN通信设置代码
  1. static void mscan_callback(MSCAN_Type *base, mscan_handle_t *handle, status_t status, void *userData)
  2. {
  3.     switch (status)
  4.     {
  5.         /* Process MSCAN Rx event. */
  6.         case kStatus_MSCAN_RxIdle:
  7.             rxComplete = true;
  8.             break;

  9.         /* Process MSCAN Tx event. */
  10.         case kStatus_MSCAN_TxIdle:
  11.             txComplete = true;
  12.             break;

  13.         default:
  14.             break;
  15.     }
  16. }


  17. void Init_CAN(void)
  18. {
  19.         mscan_config_t mscanConfig;
  20.         CLOCK_EnableClock(kCLOCK_PortC);
  21.         PORT_SetPinMux(CAN_RX_PORT, CAN_RX_PIN, kPORT_MuxAlt5);
  22.         PORT_SetPinMux(CAN_TX_PORT, CAN_TX_PIN, kPORT_MuxAlt5);
  23.         
  24.         MSCAN_GetDefaultConfig(&mscanConfig);
  25.         mscanConfig.filterConfig.u32IDAR0 = MSCAN_RX_MB_EXT_MASK(CAN_ID1);
  26.         mscanConfig.filterConfig.u32IDAR1 = MSCAN_RX_MB_EXT_MASK(CAN_ID1);
  27.         mscanConfig.filterConfig.u32IDMR0 = CAN_IDMR0;
  28.         mscanConfig.filterConfig.u32IDMR1 = CAN_IDMR1;
  29.         
  30.         mscanConfig.enableTimer = true;
  31.         
  32.         MSCAN_Init(CAN, &mscanConfig, CAN_CLK_FREQ);
  33.         MSCAN_TransferCreateHandle(CAN, &mscanHandle, mscan_callback, NULL);        
  34. }


  35. void CAN_SendDat(uint8_t *txdat)
  36. {
  37.         txFrame.ID_Type.ID = CAN_ID1;
  38.         txFrame.format = kMSCAN_FrameFormatExtend;
  39.         txFrame.type = kMSCAN_FrameTypeData;
  40.         txFrame.DLR = 8;
  41.                
  42.         txFrame.dataByte0=txdat[0];        
  43.         txFrame.dataByte1=txdat[1];
  44.         txFrame.dataByte2=txdat[2];
  45.         txFrame.dataByte3=txdat[3];
  46.         txFrame.dataByte4=txdat[4];
  47.         txFrame.dataByte5=txdat[5];
  48.         txFrame.dataByte6=txdat[6];
  49.         txFrame.dataByte7=txdat[7];
  50.         
  51.         txXfer.frame = &txFrame;
  52.         txXfer.mask = kMSCAN_TxEmptyInterruptEnable;
  53.         MSCAN_TransferSendNonBlocking(CAN, &mscanHandle, &txXfer);
  54.         while (!txComplete);
  55.         txComplete = false;
  56. }
复制代码

   2.3、串口

    串口使用UART0复用为两路串口。
    应用的帖子:https://bbs.elecfans.com/jishu_1983568_1_1.html
    2.3.1、通过下面函数来分时使用串口0,实现串口0复用为两路外接串口。
  1. void Uart0_Chl(uint8_t ch)
  2. {
  3.         switch (ch)
  4.   {
  5.           case debug_UART:
  6.                         CLOCK_EnableClock(kCLOCK_PortB);
  7.                         PORT_SetPinMux(DEBUG_UART_RX_PORT, DEBUG_UART_RX_PIN, kPORT_MuxAlt2);
  8.                         PORT_SetPinMux(DEBUG_UART_TX_PORT, DEBUG_UART_TX_PIN, kPORT_MuxAlt2);  
  9.                         PORT_SetPinMux(ANDUINO_UART_RX_PORT, ANDUINO_UART_RX_PIN, kPORT_MuxAsGpio);
  10.                         PORT_SetPinMux(ANDUINO_UART_TX_PORT, ANDUINO_UART_TX_PIN, kPORT_MuxAsGpio);
  11.                   break;
  12.           case ANDUINO_UART:
  13.                         CLOCK_EnableClock(kCLOCK_PortA);
  14.                         PORT_SetPinMux(ANDUINO_UART_RX_PORT, ANDUINO_UART_RX_PIN, kPORT_MuxAlt6);
  15.                         PORT_SetPinMux(ANDUINO_UART_TX_PORT, ANDUINO_UART_TX_PIN, kPORT_MuxAlt6);
  16.                         PORT_SetPinMux(DEBUG_UART_RX_PORT, DEBUG_UART_RX_PIN, kPORT_MuxAsGpio);
  17.                         PORT_SetPinMux(DEBUG_UART_TX_PORT, DEBUG_UART_TX_PIN, kPORT_MuxAsGpio);
  18.                   break;
  19.           default:
  20.                   break;
  21.   }  
  22. }
复制代码
        2.3.2、串口发送接收

  1. if(uart_sendflag==1)
  2.                 {
  3.                         uart_sendflag=0;
  4.                         Uart0_SendCmd();
  5.                 }
  6.                 uart_rxdat();
复制代码

      2.3.3、数据处理
    数据处理后,通过串口和CAN通信将数据输出。
  1. void uart_rxdat(void)
  2. {
  3.         uint8_t txdat[8];

  4.         if(uart0_rxflag==1)
  5.         {
  6.                 uart0_rxflag=0;
  7.                 Uart0_Chl(DEBUG_UART);
  8.                 Uart0_SendDat(0x2A);
  9.                 Uart0_SendDat(txcnt);
  10.                 Uart0_SendDat(uart0_rxbuf[4]);
  11.                 Uart0_SendDat(uart0_rxbuf[5]);
  12.         
  13.                

  14.                 txdat[0]=txcnt;
  15.                 txdat[1]=uart0_rxbuf[4];
  16.                 txdat[2]=uart0_rxbuf[5];
  17.                 txdat[3]=0X00;
  18.                 txdat[4]=0X00;
  19.                 txdat[5]=0X00;
  20.                 txdat[6]=0X00;
  21.                 txdat[7]=0X00;
  22.                 CAN_SendDat(txdat);        
复制代码


    三、执行结果

    3.1、连接CAN通信和串口,查看最后执行的数据。

    03.png
    串口和CAN通信同时输出测距处理后的数据。

    3.2、执行的视频
    001.gif


只有小组成员才能发言,加入小组>>

72个成员聚集在这个小组

加入小组

创建小组步骤

关闭

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

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