TA的每日心情 | 奋斗 2017-12-1 19:29 |
---|
签到天数: 114 天 连续签到: 1 天 [LV.6]常住居民II
|
说明:本实验是通过串口调试助手模拟上位机或者其他MCU发送控制指令,使用RT1052作为从机,通过解析数据包,提取出所需数据。
数据包格式为:(包头)(数据位数)(数据...)(数据位数反码)(包尾)
对于包头和包尾可以自行修改,也可以使用2位数据作为包头,需要简单修改一下代码即可。
2.1 串口设置步骤
1、常规串口配置步骤
开启串口时钟,并设置相应 IO 口的模式,然后配置波特率,数据位长度,奇偶校验位等。
2、RT1052配置步骤
1)开启串口时钟
- CLOCK_EnableClock(kCLOCK_Lpuart1); //使能LPUART1时钟
- CLOCK_SetMux(kCLOCK_UartMux,0); //设置UART时钟源为PLL3 80Mhz,PLL3/6=480/6=80MHz
- CLOCK_SetDiv(kCLOCK_UartDiv,0); //设置UART时钟1分频,即UART时钟为80Mhz
复制代码
2)配置IO为LPUART功能
- //LPUART1所使用的IO功能配置,即:从ALT0~ALT7选择合适的功能。
- IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX,0U); //GPIO_AD_B0_12设置为LPUART1_TX
- IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,0U); //GPIO_AD_B0_13设置为LPUART1_RX
- //配置IO引脚GPIO_AD_B0_12和GPIO_AD_B0_13的功能
- //低转换速度,驱动能力为R0/6,速度为100Mhz,关闭开路功能,使能pull/keepr
- //选择keeper功能,下拉100K Ohm,关闭Hyst
- IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX,0x10B0u);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,0x10B0u);
复制代码 3)配置串口
- lpuart1_config.baudRate_Bps=bound; //波特率
- lpuart1_config.dataBitsCount=kLPUART_EightDataBits; //8位
- lpuart1_config.stopBitCount=kLPUART_OneStopBit; //1位停止位
- lpuart1_config.parityMode=kLPUART_ParityDisabled; //无奇偶校验
- lpuart1_config.enableRx=true; //使能接收
- lpuart1_config.enableTx=true; //使能发送
- LPUART_Init(LPUART1,&lpuart1_config,freq); //初始化LPUART1
复制代码 4)串口中断使能
- LPUART_EnableInterrupts(LPUART1,kLPUART_RxDataRegFullInterruptEnable); //使能接收中断
- RT1052_NVIC_SetPriority(LPUART1_IRQn,5,0); //抢占优先级5,子优先级0
- EnableIRQ(LPUART1_IRQn); //使能LPUART1中断
复制代码 2.2 自行添加串口中断函数代码
1、LPUART.h的设置
添加如下红色部分代码
- #ifndef _USART_H
- #define _USART_H
- #include "sys.h"
- #include "stdio.h"
- #include "fsl_common.h"
- #include "fsl_iomuxc.h"
- //#include "pin_mux.h"
- #include "fsl_debug_console.h"
- //////////////////////////////////////////////////////////////////////////////////
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途
- //ALIENTEK I.MX RT1052开发板
- //串口1初始化
- //正点原子@ALIENTEK
- //技术论坛:www.openedv.csom
- //修改日期:2017/12/10
- //版本:V1.0
- //版权所有,盗版必究。
- //Copyright(C) 正点原子 2009-2019
- //All rights reserved
- //********************************************************************************
- //V1.0修改说明
- //////////////////////////////////////////////////////////////////////////////////
- //跟NXP官方例程里提供的跟debug console有关的宏定义
- #define BOARD_DEBUG_UART_TYPE DEBUG_CONSOLE_DEVICE_TYPE_LPUART
- #define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1
- #define LPUART_REC_LEN 200 //定义最大接收字节数 200
- #define EN_LPUART1_RX 1 //使能(1)/禁止(0)串口1接收
- extern u8 LPUART_RX_BUF[LPUART_REC_LEN]; //接收缓冲,最大LPUART_REC_LEN个字节.末字节为换行符
- extern u16 LPUART_RX_STA; //接收状态标记
- <font color="#ff0000">extern u8 usart_rx_buf[40];
- extern u8 usart_rd_len;
- extern u8 usart_rx_successflag;
- extern u8 len_store;</font>
- void LPUART1_Init(u32 bound);
- #endif
复制代码 2、更改串口中断函数
本实验示例的数据包为:0xee 0x02 0x05/0x06 0x07/0x08 0xfd 0xef
1)设置0x05数据为LED0亮,0x06数据为LED0灭
2)设置0x07数据为LED1亮,0x08数据为LED1灭
程序思路:
1)当发生串口中断时,首先判断LPUART1->STAT和接收数据寄存器满标志是否置位,然后读取寄存器数据LPUART1->DATA
2)判断第一帧数据是否为0xee,如果是,则usart_rx_enableflag=1,接收标志置1
3)如果usart_rx_enableflag=1,那么再读下一帧数据作为数据长度
4)继续读取数据,直到数据校验位和包尾验证正确,将usart_rx_successflag=1
5)如果usart_rx_successflag=1,将存在数组usart_rx_temporary[]中的数据赋给usart_rx_buf[]- uint8_t usart_rx_buf[40]; //接收缓冲,最大40个字节
- uint8_t usart_rx_temporary[40]; //数据保存暂存器,最多能够缓存40个字节
- uint8_t usart_rd_len=0; //有用信息的数据长度
- uint8_t usart_rd_lentemp=0; //用来记录已读取的数据长度
- uint8_t usart_rx_enableflag=0; //接收状态标记
- uint8_t usart_rx_lenrightflag=0;//数据长度校验位正确标志
- uint8_t usart_rx_successflag=0; //成功接收到数据信息
- uint8_t len_store=0;
- void LPUART1_IRQHandler(void) //串口1中断服务程序
- {
- u8 i,res,check_temp;
- if((LPUART1->STAT)&kLPUART_RxDataRegFullFlag) //接收中断
- {
- res=LPUART1->DATA; //读取数据 //读取接收到的数据
- if(usart_rx_enableflag==1) //到接受数据标志置位时,接受数据
- {
- printf("\r\n 接收了数据\r\n\r\n");
- if(usart_rd_lentemp==0) //包头后第一个数据为需要传输的数据的长度
- {
- usart_rd_len=res; //读取数据的长度
- if(usart_rd_len>=40)
- {
- usart_rx_lenrightflag=0; //数据长度校验清零
- usart_rx_successflag=0; //数据接收成功标志清零
- usart_rx_enableflag=0; //数据接收完成,数据接收启动标志清零
- usart_rd_len=0; //数据长度清零
- usart_rd_lentemp=0; //数据长度暂存器清零
- }
- }
- else if(usart_rd_lentemp==usart_rd_len+1) //当读取到第usart_rd_lentemp+1个数据时,校验是否是长度信息的反码
- {
- check_temp=~usart_rd_len; //取数据长度校验位的反码
- if(res==check_temp) //当数据长度校验正确时
- usart_rx_lenrightflag=1; //数据长度校验标志置一
- else
- { //当数据长度校验错误时
- usart_rx_lenrightflag=0; //数据长度校验清零
- usart_rx_successflag=0; //数据接收成功标志清零
- usart_rx_enableflag=0; //当数据长度校验错误时,数据接收启动标志清零
- usart_rd_len=0; //数据长度清零
- usart_rd_lentemp=0; //数据长度暂存器清零
- }
- }
- else if(usart_rd_lentemp==usart_rd_len+2) //当读取到第usart_rd_lentemp+2个数据时,校验包尾是否正确
- {
- if((res==0xef)&&(usart_rx_lenrightflag==1)) //如果包尾数据与长度校验都正确
- {
- usart_rx_lenrightflag=0; //数据长度校验清零
- usart_rx_successflag=1; //数据接收成功标志置一
- usart_rx_enableflag=0; //数据接收完成,数据接收启动标志清零
- //usart_rd_len=0; //数据长度清零
- usart_rd_lentemp=0; //数据长度暂存器清零
- }
- else
- { //当包尾数据校验错误时
- usart_rx_lenrightflag=0; //数据长度校验清零
- usart_rx_successflag=0; //数据接收成功标志清零
- usart_rx_enableflag=0; //数据接收完成,数据接收启动标志清零
- usart_rd_len=0; //数据长度清零
- usart_rd_lentemp=0; //数据长度暂存器清零
- }
- }
- else usart_rx_temporary[usart_rd_lentemp-1]=res; //当usart_rd_lentemp为数据段时,将数据存到串口数据接收寄存器中
- usart_rd_lentemp++; //每次记录数据,数据长度暂存器自加
- if(usart_rx_successflag==1) //如果成功接收到信息数据,将缓存usart_rx_temporary[]内的数据传递给usart_rx_buf[][]
- {
- len_store=usart_rd_len;
- for(i=0;i<usart_rd_len;i++)
- usart_rx_buf[i]=usart_rx_temporary[i];
- usart_rx_lenrightflag=0;
- //数据长度校验清零
- //usart_rx_successflag=0;
- //数据接收成功标志清零
- usart_rx_enableflag=0;
- //数据接收完成,数据接收启动标志清零
- usart_rd_len=0; //数据长度清零
- usart_rd_lentemp=0;
- printf("\r\n 接收成功\r\n\r\n");//Usart_SendString( USART1,"successed rx!\r\n");
- }
- }
- if((res==0xee)&&(usart_rx_enableflag==0)) //当接受到包头(0xee)数据并且还没有成功接收完数据信息
- usart_rx_enableflag=1; //说明这是包头,启动接收数据标志,进入数据接收阶段
- }
- // __DSB(); //数据同步屏蔽指令
- }
复制代码 3、在主函数加入以下代码
- if(usart_rx_successflag==1)
- {
- if(usart_rx_buf[0]==0x05)
- {
- LED0(0);
- }
- if(usart_rx_buf[0]==0x06)
- {
- LED0(1);
- }
- if(usart_rx_buf[1]==0x07)
- {
- LED1(0);
- }
- if(usart_rx_buf[1]==0x08)
- {
- LED1(1);
- }
- usart_rx_successflag=0;
- if(usart_rx_successflag==0)
- {
- printf("\r\n 复位\r\n\r\n");
- }
-
- }
复制代码
2.3 下载程序,设置串口助手发送数据包
从图中可以看出,我们发送数据包一共6位,通过我们添加的printf语句的位置,可以验证数据接收次数为5次,正确,因为不包含帧头。
2.4 实验结果
|
|