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燈:PB十二、PB1三、PB14:
	GPIO_SetBits(GPIOB,  GPIO_Pin_0 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);	         //關閉3個LED燈:PB十二、PB1三、PB14,輸出高電平
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;	             //選定PB十二、PB1三、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\r\n",angle[0],angle[1],angle[2]);
                  break;
               default:  break;
            }
			printf("X角度:%.2f  Y角度:%.2f  Z角度:%.2f  X速度:%.2f  Y速度:%.2f  Z速度:%.2f\r\n",angle[0],angle[1],angle[2],w[0],w[1],w[2]);
         }
         
      }
      delay_ms(50);
   }
}
相關文章
相關標籤/搜索