` 本帖最后由 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通信接口
1.2、使用到的端口如下:
PA2,PA3端口连接测距模组
PB0,PB1端口默认的 仿真器,电脑串口查看数据
PC6,PC7端口使用CAN通信输出
二、软件部分
软件部分使用了定时器,串口和CAN通信。
2.1、定时器
使用定时器FTM设置定时时间为1MS
- void Init_tiMER(void)
- {
- ftm_config_t ftmInfo;
- FTM_GetDefaultConfig(&ftmInfo);
- ftmInfo.prescale = kFTM_Prescale_Divide_4;
- FTM_Init(FTM_BASEADDR, &ftmInfo);
- FTM_SetTimerPeriod(FTM_BASEADDR, USEC_TO_COUNT(1000U, FTM_SOURCE_CLOCK));
- FTM_EnableInterrupts(FTM_BASEADDR, kFTM_TimeOverflowInterruptEnable);
- EnableIRQ(FTM_IRQ_NUM);
- FTM_StartTimer(FTM_BASEADDR, kFTM_SystemClock);
- }
- void FTM_HANDLER(void)
- {
- /* Clear interrupt flag.*/
- FTM_ClearStatusFlags(FTM_BASEADDR, kFTM_TimeOverflowFlag);
- //ftmIsrFlag = true;
- LED_BLUE_TOG();
-
-
- if(uart_timeout_flag==1)
- {
- uart_timeout_cnt++;
- if(uart_timeout_cnt>20)
- {
- uart_timeout_cnt=0;
- uart_timeout_flag=0;
- uart0_rxjs=0;
- }
- }
- else
- {
- uart_timeout_cnt=0;
- }
-
-
- uart_sendcnt++;
- if(uart_sendcnt>100)
- {
- uart_sendcnt=0;
- uart_sendflag=1;
- }
- }
复制代码
2.2、CAN通信
CAN通信设置代码
- static void mscan_callback(MSCAN_Type *base, mscan_handle_t *handle, status_t status, void *userData)
- {
- switch (status)
- {
- /* Process MSCAN Rx event. */
- case kStatus_MSCAN_RxIdle:
- rxComplete = true;
- break;
- /* Process MSCAN Tx event. */
- case kStatus_MSCAN_TxIdle:
- txComplete = true;
- break;
- default:
- break;
- }
- }
- void Init_CAN(void)
- {
- mscan_config_t mscanConfig;
- CLOCK_EnableClock(kCLOCK_PortC);
- PORT_SetPinMux(CAN_RX_PORT, CAN_RX_PIN, kPORT_MuxAlt5);
- PORT_SetPinMux(CAN_TX_PORT, CAN_TX_PIN, kPORT_MuxAlt5);
-
- MSCAN_GetDefaultConfig(&mscanConfig);
- mscanConfig.filterConfig.u32IDAR0 = MSCAN_RX_MB_EXT_MASK(CAN_ID1);
- mscanConfig.filterConfig.u32IDAR1 = MSCAN_RX_MB_EXT_MASK(CAN_ID1);
- mscanConfig.filterConfig.u32IDMR0 = CAN_IDMR0;
- mscanConfig.filterConfig.u32IDMR1 = CAN_IDMR1;
-
- mscanConfig.enableTimer = true;
-
- MSCAN_Init(CAN, &mscanConfig, CAN_CLK_FREQ);
- MSCAN_TransferCreateHandle(CAN, &mscanHandle, mscan_callback, NULL);
- }
- void CAN_SendDat(uint8_t *txdat)
- {
- txFrame.ID_Type.ID = CAN_ID1;
- txFrame.format = kMSCAN_FrameFormatExtend;
- txFrame.type = kMSCAN_FrameTypeData;
- txFrame.DLR = 8;
-
- txFrame.dataByte0=txdat[0];
- txFrame.dataByte1=txdat[1];
- txFrame.dataByte2=txdat[2];
- txFrame.dataByte3=txdat[3];
- txFrame.dataByte4=txdat[4];
- txFrame.dataByte5=txdat[5];
- txFrame.dataByte6=txdat[6];
- txFrame.dataByte7=txdat[7];
-
- txXfer.frame = &txFrame;
- txXfer.mask = kMSCAN_TxEmptyInterruptEnable;
- MSCAN_TransferSendNonBlocking(CAN, &mscanHandle, &txXfer);
- while (!txComplete);
- txComplete = false;
- }
复制代码
2.3、串口
串口使用UART0复用为两路串口。
应用的帖子:https://bbs.elecfans.com/jishu_1983568_1_1.html
2.3.1、通过下面函数来分时使用串口0,实现串口0复用为两路外接串口。
- void Uart0_Chl(uint8_t ch)
- {
- switch (ch)
- {
- case DEBUG_UART:
- CLOCK_EnableClock(kCLOCK_PortB);
- PORT_SetPinMux(DEBUG_UART_RX_PORT, DEBUG_UART_RX_PIN, kPORT_MuxAlt2);
- PORT_SetPinMux(DEBUG_UART_TX_PORT, DEBUG_UART_TX_PIN, kPORT_MuxAlt2);
- PORT_SetPinMux(ANDUINO_UART_RX_PORT, ANDUINO_UART_RX_PIN, kPORT_MuxAsGpio);
- PORT_SetPinMux(ANDUINO_UART_TX_PORT, ANDUINO_UART_TX_PIN, kPORT_MuxAsGpio);
- break;
- case ANDUINO_UART:
- CLOCK_EnableClock(kCLOCK_PortA);
- PORT_SetPinMux(ANDUINO_UART_RX_PORT, ANDUINO_UART_RX_PIN, kPORT_MuxAlt6);
- PORT_SetPinMux(ANDUINO_UART_TX_PORT, ANDUINO_UART_TX_PIN, kPORT_MuxAlt6);
- PORT_SetPinMux(DEBUG_UART_RX_PORT, DEBUG_UART_RX_PIN, kPORT_MuxAsGpio);
- PORT_SetPinMux(DEBUG_UART_TX_PORT, DEBUG_UART_TX_PIN, kPORT_MuxAsGpio);
- break;
- default:
- break;
- }
- }
复制代码
2.3.2、串口发送接收
- if(uart_sendflag==1)
- {
- uart_sendflag=0;
- Uart0_SendCmd();
- }
- uart_rxdat();
复制代码
2.3.3、数据处理
数据处理后,通过串口和CAN通信将数据输出。
- void uart_rxdat(void)
- {
- uint8_t txdat[8];
- if(uart0_rxflag==1)
- {
- uart0_rxflag=0;
- Uart0_Chl(DEBUG_UART);
- Uart0_SendDat(0x2A);
- Uart0_SendDat(txcnt);
- Uart0_SendDat(uart0_rxbuf[4]);
- Uart0_SendDat(uart0_rxbuf[5]);
-
-
- txdat[0]=txcnt;
- txdat[1]=uart0_rxbuf[4];
- txdat[2]=uart0_rxbuf[5];
- txdat[3]=0X00;
- txdat[4]=0X00;
- txdat[5]=0X00;
- txdat[6]=0X00;
- txdat[7]=0X00;
- CAN_SendDat(txdat);
复制代码
三、执行结果
3.1、连接CAN通信和串口,查看最后执行的数据。
串口和CAN通信同时输出测距处理后的数据。
3.2、执行的视频
`
|