zoukankan      html  css  js  c++  java
  • STM32 MPU6050 源码

    MPU6050型号

    商家描述:此六轴模块采用先进的数字滤波技术,能有效降低测量噪声,提高测量精度。模块内部集成了运动引擎DMP,获取四元数得到当前姿态。姿态测量精度0.01度,稳定性极高,性能甚至优于某些专业的倾角仪!此六轴模块采用高精度的陀螺加速度计 MPU6050,通过处理器读取 MPU6050 的测量数据然后通过串口输出,免去了用户自己去开发MPU6050 复杂的 I2C 协议,同时精心的 PCB 布局和工艺保证了 MPU6050 收到外接的干扰最小,测量的精度最高。

    模块发送至上位机每帧数据分为 3 个数据包,分别为加速度包,角速度包和角度包,3个数据包顺序输出。波特率 115200 时每隔 10ms 输出 1 帧数据,波特率 9600 时每隔 50ms 输出一帧数据。

    通信协议:电平:TTL 电平,波特率:115200/9600,停止位 1,校验位 0。

    源码分析

    整体流程是:初始化,然后反复通过串口接收数据,取走数据。(因为不改写模块的配置,所以不考虑向模块发送数据部分)

    初始化:配置系统时钟、初始化IO口、中断优先级初始化、初始化串口、初始化延时函数

    配置系统时钟

    //配置系统时钟
    void RCC_Configuration(void)
    {
    	ErrorStatus HSEStartUpStatus;                    //定义外部高速晶体启动状态枚举变量
    
    	RCC_DeInit();                                    //复位RCC外部设备寄存器到默认值
    	RCC_HSEConfig(RCC_HSE_ON);                       //打开外部高速晶振
    	HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速时钟准备好
    	if(HSEStartUpStatus == SUCCESS)                  //外部高速时钟已经准别好
    	{
    		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
    		FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延时
    			
    		RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)时钟等于==SYSCLK
    		RCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)钟==AHB时钟
    		RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)钟==AHB1/2时钟
    			 
    		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
    		RCC_PLLCmd(ENABLE);                                   //使能PLL时钟
       
    		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)    //等待PLL时钟就绪
    		{
    		}
    		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系统时钟 = PLL时钟
    		while(RCC_GetSYSCLKSource() != 0x08)                  //检查PLL时钟是否作为系统时钟
    		{
    		}
    	}
    }
    
    

    初始化IO口

    
    //IO口配置
    //用法:用哪个打开那个
    void GPIO_Configuration(void)
    {
    	GPIO_InitTypeDef   GPIO_InitStructure;   //定义名为GPIO_InitStructure的结构体类型变量
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //打开GPIOB的时钟,并使能。
    	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  //打开GPIOC的时钟,并使能。
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);  //打开GPIOD的时钟,并使能。
    	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //打开GPIOA的时钟,并使能。
    	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);  //打开GPIOB和GPIOD的时钟,并使能。
    	//配置PD10口:
    //	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_9;              //选定哪个IO口 现选定PD9口和PD10口
    //	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;                       //设定IO口的模式为上拉输入�
    //	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	                 //如果IO口的模式是输入,GPIO_Speed可以不赋值
    //	GPIO_Init(GPIOD, &GPIO_InitStructure);	/* PC6 */                    //初始化GPIOD
    
    	//配置PA口:
    //	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;              //选定哪个IO口 现选定PA0口和PA1口
    //	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		             //设定IO口的模式为推挽输出�
    //	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;	                 //设定IO口的输出速度为2MHz
    //	GPIO_Init(GPIOA, &GPIO_InitStructure);	/* PC6 */                    //初始化GPIOD
    	
    	//配置PD口:
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;              //选定哪个IO口 现选定PD0123口
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		             //设定IO口的模式为推挽输出�
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	                 //设定IO口的输出速度为50MHz
    	GPIO_Init(GPIOD, &GPIO_InitStructure);	                             //初始化GPIOD
    
    	//配置PD口:
    //	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;              //选定哪个IO口 现选定PD2口
    //	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		             //设定IO口的模式为推挽输出�
    //	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;	                 //设定IO口的输出速度为2MHz
    //	GPIO_Init(GPIOD, &GPIO_InitStructure);	/* PC6 */                    //初始化GPIOD
    
    	//配置3个LED灯:PB12、PB13、PB14:
    	GPIO_SetBits(GPIOB,  GPIO_Pin_0 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);	         //关闭3个LED灯:PB12、PB13、PB14,输出高电平
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;	             //选定PB12、PB13、PB14
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		             //设定IO口的模式为推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;		             //设定IO口的输出速度为2MHz
    	GPIO_Init(GPIOB, &GPIO_InitStructure);					             //初始化GPIOB
    }
    
    

    中断优先级初始化

    //中断IO口配置
    //用法:用哪个打开那个
    void EXTI_Configuration(void)
    {
    	EXTI_InitTypeDef EXTI_InitStructure;						   //定义一个结构体变量
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 		   //打开APB2总线复用时钟
    	
    	//外部中断线10配置:
    	EXTI_ClearITPendingBit(EXTI_Line10);						   //清除中断挂起位 外部中断线10
    	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		       //选择是中断触发还是事件触发,现在选择的是中断触发
    	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	       //触发方式:现在选择的是下降沿触发
    	EXTI_InitStructure.EXTI_Line = EXTI_Line10;				       //选择哪个IO口作为中断输入,现在选择的是PD10口
    	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					   //使能中断
    	EXTI_Init(&EXTI_InitStructure);							       //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource10);   //选择GPIO管脚作为外部中断线路
    	//外部中断线9配置:
    	EXTI_ClearITPendingBit(EXTI_Line9);						       //清除中断挂起位 外部中断线9
    	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		       //选择是中断触发还是事件触发,现在选择的是中断触发
    	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	       //触发方式:现在选择的是下降沿触发
    	EXTI_InitStructure.EXTI_Line = EXTI_Line9;				       //选择哪个IO口作为中断输入,现在选择的是PD9口
    	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					   //使能中断
    	EXTI_Init(&EXTI_InitStructure);							       //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource9);    //选择GPIO管脚作为外部中断线路
    }
    
    

    中断优先级管理

    //中断优先级配置
    //用法:用哪个打开那个
    void NVIC_Configuration(void)
    {
    	NVIC_InitTypeDef    NVIC_InitStructure; 					   //定义用于配置中断的结构体变量
    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                //中断优先级分组  抢占式优先级别设置为2位;响应优先级占2位
    	
    	//外部中断线10优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;           //指定中断源
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //使能外部中断通道
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    	//外部中断线9优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;             //指定中断源  
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	   //抢占优先级 暂时没有
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;             //指定响应优先级别2
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //使能外部中断通道
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    	//串口1中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;              //通道设置为串口1中断  
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    	//串口1用DMA接收中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;       //通道设置为串口DMA通道4中断  
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    	//串口2中断优先级设置(RS485)
    	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;			   //指定中断源
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;             //指定响应优先级别1
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    	//串口3中断优先级设置(RS485)
    //	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;			   //指定中断源
    //  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    //	//串口1用DMA接收优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;       //DMA1通道5中断 
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    //	//串口4中断优先级设置(RS485)
    //	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;			   //指定中断源
    //  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    //	//串口5中断优先级设置(RS485)
    //	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;			   //指定中断源
    //  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	   //抢占优先级1
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //指定响应优先级别1
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	               //打开中断
    //	NVIC_Init(&NVIC_InitStructure);							       //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    	
    	//通用定时器2中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器	
    	
    	//通用定时器3中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
    	
    	//通用定时器4中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器	
    	
    	//通用定时器5中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM5中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器	
    	
    	//通用定时器6中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;  //TIM6中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器	
    	
    	//通用定时器7中断优先级设置
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;  //TIM7中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级1级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器					 
    }
    

    串口初始化

    //串口1初始化
    void USART1_Config(void)		//初始化 配置USART1
    {
    	GPIO_InitTypeDef     GPIO_InitStructure;   //串口端口配置结构体变量
    	USART_InitTypeDef    USART_InitStructure;  //串口参数配置结构体变量
    
    	//第1步:打开GPIO和USART部件的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);	 //打开GPIOA时钟和GPIOA复用时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//打开串口复用时钟
    	USART_DeInit(USART1);  //复位串口1
    
    	//第2步:将USART1 Tx(发送脚)的GPIO配置为推挽复用模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;			   //串口1发送脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		   //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	   //输出速度50MHz
    	GPIO_Init(GPIOA, &GPIO_InitStructure);				   //初始化GPIOA
    														  
    	//第3步:将USART Rx(接收脚)的GPIO配置为浮空输入模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;			   //串口1接收脚
    	//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
    	GPIO_Init(GPIOA, &GPIO_InitStructure);				   //初始化GPIOA
    
    	//第4步:配置USART1参数
    	USART_InitStructure.USART_BaudRate             = 115200;							 //波特率设置:115200
    	USART_InitStructure.USART_WordLength           = USART_WordLength_8b;			 //数据位数设置:8位
    	USART_InitStructure.USART_StopBits             = USART_StopBits_1;				 //停止位设置:1位
    	USART_InitStructure.USART_Parity               = USART_Parity_No;				 //是否奇偶校验:无
    	USART_InitStructure.USART_HardwareFlowControl  = USART_HardwareFlowControl_None; //硬件流控制模式设置:没有使能
    	USART_InitStructure.USART_Mode                 = USART_Mode_Rx | USART_Mode_Tx;	 //接收与发送都使能
    	USART_Init(USART1, &USART_InitStructure);										 //初始化USART1
    
        //打开发送中断和接收中断(如果需要中断)
    	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  // 使能指定的USART1发送中断 ;
      	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能指定的USART1接收中断 ;
    
    	//第5步:使能 USART1, 配置完毕
    	USART_Cmd(USART1, ENABLE);							   //使能 USART1
    
        //如下语句解决第1个字节无法正确发送出去的问题
        USART_ClearFlag(USART1, USART_FLAG_TC);                //清串口1发送标志	
    }
    
    
    //串口2初始化
    void USART2_Config(void)   //初始化 配置USART2
    {
    	GPIO_InitTypeDef    GPIO_InitStructure;	   //串口端口配置结构体变量
    	USART_InitTypeDef   USART_InitStructure;   //串口参数配置结构体变量
    
    	//使能 USART2 时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	//打开串口复用时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);   //打开PA端口时钟
    
    	//将USART2 Tx(发送脚)的GPIO配置为推挽复用模式   
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;				  //选定哪个IO口 现选定PA2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		  //设定IO口的输出速度为50MHz
    	GPIO_Init(GPIOA, &GPIO_InitStructure);    				  //初始化GPIOA
    
    	//将USART2 Rx(接收脚)的GPIO配置为浮空输入模式														  
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;				  //选定哪个IO口 现选定PA3
    	//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //浮空输入
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
    	GPIO_Init(GPIOA, &GPIO_InitStructure);                    //初始化GPIOA
    	  
    	//配置USART2参数
    	USART_InitStructure.USART_BaudRate = 115200;	                    //波特率设置:115200
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	    //数据位数设置:8位
    	USART_InitStructure.USART_StopBits = USART_StopBits_1; 	        //停止位设置:1位
    	USART_InitStructure.USART_Parity = USART_Parity_No ;            //是否奇偶校验:无
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制模式设置:没有使能
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收与发送都使能
    	USART_Init(USART2, &USART_InitStructure);                       //初始化USART2
    	
    	//打开发送中断和接收中断(如果需要中断)
    	//USART_ITConfig(USART2, USART_IT_TXE, ENABLE);  // 使能指定的USART2发送中断
      	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 使能指定的USART2接收中断
    
    	//使能 USART2, 配置完毕
    	USART_Cmd(USART2, ENABLE);                             // USART2使能
    
    	//如下语句解决第1个字节无法正确发送出去的问题
        USART_ClearFlag(USART2, USART_FLAG_TC);                //清串口2发送标志
    }
    
    //串口3初始化
    void USART3_Config(void)   //初始化 配置USART3
    {
    	GPIO_InitTypeDef GPIO_InitStructure;	  //串口端口配置结构体变量
    	USART_InitTypeDef USART_InitStructure;	  //串口参数配置结构体变量
    
    	//使能 USART3 时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);	//打开串口复用时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //打开PB端口时钟
      	
    	//将USART3 Tx(发送脚)的GPIO配置为推挽复用模式   
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;				  //选定哪个IO口 现选定PB10
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		  //设定IO口的输出速度为50MHz
    	GPIO_Init(GPIOB, &GPIO_InitStructure);    				  //初始化GPIOB
    	
    	//将USART3 Rx(接收脚)的GPIO配置为浮空输入模式														  
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;				  //选定哪个IO口 现选定PB11
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //浮空输入
    	GPIO_Init(GPIOB, &GPIO_InitStructure);                    //初始化GPIOA
    	  
    	//配置USART3参数
    	USART_InitStructure.USART_BaudRate = 2400;	                    //波特率设置:2400
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	    //数据位数设置:8位
    	USART_InitStructure.USART_StopBits = USART_StopBits_1; 	        //停止位设置:1位
    	USART_InitStructure.USART_Parity = USART_Parity_No ;            //是否奇偶校验:无
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制模式设置:没有使能
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收与发送都使能
    	USART_Init(USART3, &USART_InitStructure);                       //初始化USART3
    	
        //打开发送中断和接收中断(如果需要中断)
    	//USART_ITConfig(USART3, USART_IT_TXE, ENABLE);  // 使能指定的USART3发送中断
      	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 使能指定的USART3接收中断
    
    	//使能 USART3, 配置完毕
    	USART_Cmd(USART3, ENABLE);                             // USART3使能
    
    	//如下语句解决第1个字节无法正确发送出去的问题
        USART_ClearFlag(USART3, USART_FLAG_TC);                //清串口3发送标志
    }
    
    //串口4初始化
    void UART4_Config(void)   //初始化 配置USART4
    {
    	GPIO_InitTypeDef GPIO_InitStructure;	   //串口端口配置结构体变量
    	USART_InitTypeDef USART_InitStructure;	   //串口参数配置结构体变量
    
    	//使能 UART4 时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);	//打开串口复用时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   //打开PC端口时钟
    	
    	//将USART4 Tx(发送脚)的GPIO配置为推挽复用模式   
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;				  //选定哪个IO口 现选定PC10
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		  //设定IO口的输出速度为50MHz
    	GPIO_Init(GPIOC, &GPIO_InitStructure);    				  //初始化GPIOC
    
    	//将UART4 Rx(接收脚)的GPIO配置为浮空输入模式														  
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;				  //选定哪个IO口 现选定PC11
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //浮空输入
    	GPIO_Init(GPIOC, &GPIO_InitStructure);                    //初始化GPIOC
    	  
    	//配置UART4参数
    	USART_InitStructure.USART_BaudRate = 2400;	                    //波特率设置:2400
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	    //数据位数设置:8位
    	USART_InitStructure.USART_StopBits = USART_StopBits_1; 	        //停止位设置:1位
    	USART_InitStructure.USART_Parity = USART_Parity_No ;            //是否奇偶校验:无
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制模式设置:没有使能
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收与发送都使能
    	USART_Init(UART4, &USART_InitStructure);                       //初始化UART4
    	
    	//打开发送中断和接收中断(如果需要中断)
    	//USART_ITConfig(UART4, USART_IT_TXE, ENABLE);  // 使能指定的UART4发送中断
      	USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); // 使能指定的UART4接收中断
    
    	//使能 UART4, 配置完毕
    	USART_Cmd(UART4, ENABLE);                             // UART4使能
    
    	//如下语句解决第1个字节无法正确发送出去的问题
        USART_ClearFlag(UART4, USART_FLAG_TC);                //清串口4发送标志
    }
    
    //串口5初始化
    void UART5_Config(void)   //初始化 配置UART5
    {
    	GPIO_InitTypeDef GPIO_InitStructure;		//串口端口配置结构体变量
    	USART_InitTypeDef USART_InitStructure;		//串口参数配置结构体变量
    
    	//使能 UART5 时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);	//打开串口复用时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   //打开PC端口时钟
    	
    	//将UART5 Tx(发送脚)的GPIO配置为推挽复用模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				  //选定哪个IO口 现选定PC12
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		  //设定IO口的输出速度为50MHz
    	GPIO_Init(GPIOC, &GPIO_InitStructure);    				  //初始化GPIOC
    
    	//将UART5 Rx(接收脚)的GPIO配置为浮空输入模式															  
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;				  //选定哪个IO口 现选定PD2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //浮空输入
    	GPIO_Init(GPIOD, &GPIO_InitStructure);                    //初始化GPIOC
    	  
    	//配置UART5参数
    	USART_InitStructure.USART_BaudRate = 2400;	                    //波特率设置:2400
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	    //数据位数设置:8位
    	USART_InitStructure.USART_StopBits = USART_StopBits_1; 	        //停止位设置:1位
    	USART_InitStructure.USART_Parity = USART_Parity_No ;            //是否奇偶校验:无
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制模式设置:没有使能
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收与发送都使能
    	USART_Init(UART5, &USART_InitStructure);                       //初始化UART5
    
    	//打开发送中断和接收中断(如果需要中断)
    	//USART_ITConfig(UART5, USART_IT_TXE, ENABLE);  // 使能指定的UART4发送中断
      	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); // 使能指定的UART4接收中断
    
    	//使能 UART5, 配置完毕
    	USART_Cmd(UART5, ENABLE);                             // UART5使能
    
    	//如下语句解决第1个字节无法正确发送出去的问题 */
        USART_ClearFlag(UART5, USART_FLAG_TC);                //清串口5发送标志
    }
    

    反复接收串口2数据

    void USART2_IRQHandler(void){
       if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断有效,若接收数据寄存器满
         {
          Temp[counter] = USART_ReceiveData(USART2);   //接收数据
          //网购给的程序
          //if(counter == 0 && Re_buf[0] != 0x55) return;      //第 0 号数据不是帧头,跳过
    	  if(counter == 0 && Temp[0] != 0x55) return;      //第 0 号数据不是帧头,跳过
          counter++; 
          if(counter==11) //接收到 11 个数据
          { 
             memcpy(Re_buf,Temp,11);
             counter=0; //重新赋值,准备下一帧数据的接收
             sign=1;//缓冲区Re_buf是否有数据标志
          }    
       }
    }
    

    反复查询缓冲区是否存在数据,存在并取走

       while (1)
       {
          if(sign)
          {  
             memcpy(Temp,Re_buf,11);
             sign=0;
             if(Re_buf[0]==0x55)       //检查帧头
             {  
                switch(Re_buf[1])
                {
                   case 0x51: //标识这个包是加速度包
                      a[0] = ((short)(Temp[3]<<8 | Temp[2]))/32768.0*16;      //X轴加速度
                      a[1] = ((short)(Temp[5]<<8 | Temp[4]))/32768.0*16;      //Y轴加速度
                      a[2] = ((short)(Temp[7]<<8 | Temp[6]))/32768.0*16;      //Z轴加速度
                      T    = ((short)(Temp[9]<<8 | Temp[8]))/340.0+36.25;      //温度
                      break;
                   case 0x52: //标识这个包是角速度包
                      w[0] = ((short)(Temp[3]<<8| Temp[2]))/32768.0*2000;      //X轴角速度
                      w[1] = ((short)(Temp[5]<<8| Temp[4]))/32768.0*2000;      //Y轴角速度
                      w[2] = ((short)(Temp[7]<<8| Temp[6]))/32768.0*2000;      //Z轴角速度
                      T    = ((short)(Temp[9]<<8| Temp[8]))/340.0+36.25;      //温度
                      break;
                   case 0x53: //标识这个包是角度包
                      angle[0] = ((short)(Temp[3]<<8| Temp[2]))/32768.0*180;   //X轴滚转角(x 轴)
                      angle[1] = ((short)(Temp[5]<<8| Temp[4]))/32768.0*180;   //Y轴俯仰角(y 轴)
                      angle[2] = ((short)(Temp[7]<<8| Temp[6]))/32768.0*180;   //Z轴偏航角(z 轴)
                      T        = ((short)(Temp[9]<<8| Temp[8]))/340.0+36.25;   //温度
    
                      //printf("X轴角度:%.2f   Y轴角度:%.2f   Z轴角度:%.2f
    ",angle[0],angle[1],angle[2]);
                      break;
                   default:  break;
                }
    			printf("X角度:%.2f  Y角度:%.2f  Z角度:%.2f  X速度:%.2f  Y速度:%.2f  Z速度:%.2f
    ",angle[0],angle[1],angle[2],w[0],w[1],w[2]);
             }
             
          }
          delay_ms(50);
       }
    }
    
    
    
  • 相关阅读:
    .Net/C#: 实现支持断点续传多线程下载
    软件设计过程中常用的几种图(二)
    走马灯 代码appendChild实现的无缝滚动
    调用web service时的SOAPHEADER验证
    Excel VBA 学习总结 数据验证与正则表达式
    C#者重建C++之路 运行机制的差异
    Excel VBA 学习总结 代码优化之道
    Excel VBA 学习总结 文件系统
    软件设计:“度”、“裁剪”与“变通”
    Excel VBA 学习总结 开发模式
  • 原文地址:https://www.cnblogs.com/uestcman/p/9054623.html
Copyright © 2011-2022 走看看