<tbody id="jeav1"></tbody>

<progress id="jeav1"></progress>

    <tbody id="jeav1"><noscript id="jeav1"><video id="jeav1"></video></noscript></tbody>

      電子發燒友App

      硬聲App

      創作
      電子發燒友網>電子資料下載>單片機>基于STM32單片機模塊練習——在使用MPU6050時遇到的令人頭疼的問題

      基于STM32單片機模塊練習——在使用MPU6050時遇到的令人頭疼的問題

      2021-11-23 | pdf | 166.44KB | 次下載 | 免費

      資料介紹

      在使用MPU6050時遇到的令人頭疼的問題

      1.整個程序在一開始運行就卡死在啟動文件


      首先看一下,Target設置選項下的Use MicroLIB選項是不是選上勾了。
      如果這個設置也解決不了問題,那么你需要檢查一下程序里,是否寫了printf函數的接口函數。因為MPU6050里面有
      用到了這個函數,如果你沒寫這個函數的接口函數,就會導致系統卡死在系統文件里。
      printf函數的接口函數

      ///重定向c庫函數printf到串口,重定向后可使用printf函數
      int fputc(int ch, FILE *f)
      {
      		/* 發送一個字節數據到串口 */
      		USART_SendData(DEBUG_USARTx, (uint8_t) ch);
      		
      		/* 等待發送完畢 */
      		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);		
      	
      		return (ch);
      }
      

      2.while循環里的條件明明不滿足了,程序卻一致卡死在此循環里

      檢查一下,判斷條件里的變量的類型是否正確。另外,如果這個變量在中斷服務函數里面需要改變值,那么在定義這個變量的語句前應該加上關鍵字
      volaTIle
      volatile的具體描述參考

      3.MPU6050在執行mpu_dmp_init()函數時,一直出現錯誤,且錯誤在run_self_test()

      1)首先,看一下是不是因為你在程序初始化的時候,沒有把MPU6050水平放置,至于為什么要水平放置呢?
      因為在run_self_test()函數里面有一個mpu_run_self_test(gyro, accel)函數,這個函數上面有一個注釋特別重要:

      This funcTIon must be called with the device either face-up or face-down
       *  (z-axis is parallel to gravity).此函數必須在設備面朝上或面朝下時調用(z軸與重力平行)
      

      2)如果照著1)的方法還是解決不了這個問題,那么請你檢查一下run_self_test函數里面的具體內容是否和下面的一模一樣:

      //MPU6050自測試
      //返回值:0,正常
      //    其他,失敗
      u8 run_self_test(void)
      {
      	int result;
      	//char test_packet[4] = {0};
      	long gyro[3], accel[3]; 
      	result = mpu_run_self_test(gyro, accel);
      	if (result == 0x3) //這個地方要的別注意,有的例程會把0X3錯誤的寫為0X7
      	{
      		/* Test passed. We can trust the gyro data here, so let's push it down
      		* to the DMP.
      		*/
      		float sens;
      		unsigned short accel_sens;
      		mpu_get_gyro_sens(&sens);
      		gyro[0] = (long)(gyro[0] * sens);
      		gyro[1] = (long)(gyro[1] * sens);
      		gyro[2] = (long)(gyro[2] * sens);
      		dmp_set_gyro_bias(gyro);
      		mpu_get_accel_sens(&accel_sens);
      		accel[0] *= accel_sens;
      		accel[1] *= accel_sens;
      		accel[2] *= accel_sens;
      		dmp_set_accel_bias(accel);
      		return 0;
      	}else return 1;
      }
      

      4.mpu_dmp_get_data(&pitch,&roll,&yaw)函數的返回值不正確(一直不是0)

      MPU6050讀不出來數據
      如果參考以上這篇文章還是無法幫助解決問題,那么不妨試一下,把模擬iic的這部分代碼換一下,也許可能就是因為iic這部分程序不正確。
      模擬IIC的代碼:

      #include "mpuiic.h"
      #include "./sysTIck/bsp_SysTIck.h"
      #define Soft_I2C_SDA 		  GPIO_Pin_3
      #define Soft_I2C_SCL 		  GPIO_Pin_4
      #define Soft_I2C_PORT     GPIOB
      #define MPU6050_GPIO_CLK  RCC_APB2Periph_GPIOB
      //IO方向設置  ---PB11
      #define MPU_SDA_IN()  {Soft_I2C_PORT ->CRL &= 0XFFFF0FFF;Soft_I2C_PORT ->CRL |= 8<<12;}       //上拉/下拉 輸入模式
      #define MPU_SDA_OUT() {Soft_I2C_PORT ->CRL &= 0XFFFF0FFF;Soft_I2C_PORT ->CRL |= 7<<12;}		//開漏輸出  輸出模式
      
      /* 定義讀寫SCL和SDA的宏,已增加代碼的可移植性和可閱讀性 */
      #if 1	/* 條件編譯: 1 選擇GPIO的庫函數實現IO讀寫 */
      	#define MPU6050_I2C_SCL_1()  GPIO_SetBits(Soft_I2C_PORT, Soft_I2C_SCL)		/* SCL = 1 */
      	#define MPU6050_I2C_SCL_0()  GPIO_ResetBits(Soft_I2C_PORT, Soft_I2C_SCL)		/* SCL = 0 */
      	
      	#define MPU6050_I2C_SDA_1()  GPIO_SetBits(Soft_I2C_PORT, Soft_I2C_SDA)		/* SDA = 1 */
      	#define MPU6050_I2C_SDA_0()  GPIO_ResetBits(Soft_I2C_PORT, Soft_I2C_SDA)		/* SDA = 0 */
      	
      	#define MPU6050_I2C_SDA_READ()  GPIO_ReadInputDataBit(Soft_I2C_PORT, Soft_I2C_SDA)	/* 讀SDA口線狀態 */
      #else	/* 這個分支選擇直接寄存器操作實現IO讀寫 */
          /* 注意:如下寫法,在IAR最高級別優化時,會被編譯器錯誤優化 */
      	#define MPU6050_I2C_SCL_1()  Soft_I2C_PORT->BSRR = Soft_I2C_SCL				/* SCL = 1 */
      	#define MPU6050_I2C_SCL_0()  Soft_I2C_PORT->BRR = Soft_I2C_SCL				/* SCL = 0 */
      	
      	#define MPU6050_I2C_SDA_1()  Soft_I2C_PORT->BSRR = Soft_I2C_SDA				/* SDA = 1 */
      	#define MPU6050_I2C_SDA_0()  Soft_I2C_PORT->BRR = Soft_I2C_SDA				/* SDA = 0 */
      	
      	#define MPU6050_I2C_SDA_READ()  ((Soft_I2C_PORT->IDR & Soft_I2C_SDA) != 0)	/* 讀SDA口線狀態 */
      #endif
      
      /**********************************************
      函數名稱:MPU_IIC_Delay
      函數功能:MPU IIC延時函數,延時2ms
      函數參數:無
      函數返回值:無
      **********************************************/
      void MPU_IIC_Delay(void)
      {
      	uint8_t i;
      
      	/* 
      	 	下面的時間是通過邏輯分析儀測試得到的。
          工作條件:CPU主頻72MHz ,MDK編譯環境,1級優化
        
      		循環次數為10時,SCL頻率 = 205KHz 
      		循環次數為7時,SCL頻率 = 347KHz, SCL高電平時間1.5us,SCL低電平時間2.87us 
      	 	循環次數為5時,SCL頻率 = 421KHz, SCL高電平時間1.25us,SCL低電平時間2.375us 
      	*/
      	for (i = 0; i < 100; i++);
      }
      
      
      /**********************************************
      函數名稱:MPU_IIC_Init
      函數功能:MPU IIC初始化
      函數參數:無
      函數返回值:無
      **********************************************/
      void MPU_IIC_Init(void)
      {					     
        GPIO_InitTypeDef  GPIO_InitStructure;
      	
        RCC_APB2PeriphClockCmd(MPU6050_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);			//先使能外設IO PORTB時鐘 
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); 	
        GPIO_InitStructure.GPIO_Pin = Soft_I2C_SCL|Soft_I2C_SDA;	  //端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 				  //推挽輸出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;				  //IO口速度為50MHz
        GPIO_Init(Soft_I2C_PORT , &GPIO_InitStructure);					 					//根據設定參數初始化GPIO 
      	
        GPIO_SetBits(Soft_I2C_PORT,Soft_I2C_SCL|Soft_I2C_SDA);						  //PB10,PB11 輸出高	
       
      }
      
      //產生IIC起始信號
      void MPU_IIC_Start(void)
      {
      	MPU_SDA_OUT();      //sda線輸出
      	MPU6050_I2C_SDA_1();	  	  
      	MPU6050_I2C_SCL_1();
      	MPU_IIC_Delay();
       	MPU6050_I2C_SDA_0();//START:when CLK is high,DATA change form high to low 
      	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_0();//鉗住I2C總線,準備發送或接收數據 
      }	  
      //產生IIC停止信號
      void MPU_IIC_Stop(void)
      {
      	MPU_SDA_OUT();//sda線輸出
      	MPU6050_I2C_SCL_0();
      	MPU6050_I2C_SDA_0();//STOP:when CLK is high DATA change form low to high
       	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_1();  
      	MPU6050_I2C_SDA_1();//發送I2C總線結束信號
      	MPU_IIC_Delay();							   	
      }
      //等待應答信號到來
      //返回值:1,接收應答失敗
      //        0,接收應答成功
      u8 MPU_IIC_Wait_Ack(void)
      {
      	u8 ucErrTime=0;
      	MPU_SDA_IN();      //SDA設置為輸入  
      	MPU6050_I2C_SDA_1();MPU_IIC_Delay();	   
      	MPU6050_I2C_SCL_1();MPU_IIC_Delay();	 
      	while(MPU6050_I2C_SDA_READ())
      	{
      		ucErrTime++;
      		if(ucErrTime>250)
      		{
      			MPU_IIC_Stop();
      			return 1;
      		}
      	}
      	MPU6050_I2C_SCL_0();//時鐘輸出0 	   
      	return 0;  
      } 
      //產生ACK應答
      void MPU_IIC_Ack(void)
      {
      	MPU6050_I2C_SCL_0();
      	MPU_SDA_OUT();
      	MPU6050_I2C_SDA_0();
      	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_1();
      	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_0();
      }
      //不產生ACK應答		    
      void MPU_IIC_NAck(void)
      {
      	MPU6050_I2C_SCL_0();
      	MPU_SDA_OUT();
      	MPU6050_I2C_SDA_1();
      	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_1();
      	MPU_IIC_Delay();
      	MPU6050_I2C_SCL_0();
      }					 				     
      //IIC發送一個字節
      //返回從機有無應答
      //1,有應答
      //0,無應答			  
      void MPU_IIC_Send_Byte(u8 _ucByte)
      {                        
      
      		uint8_t i;
              MPU_SDA_OUT(); 
      	MPU6050_I2C_SCL_0();//拉低時鐘開始數據傳輸
      	/* 先發送字節的高位bit7 */
      	for (i = 0; i < 8; i++)
      	{		
      		if (_ucByte & 0x80)
      		{
      			MPU6050_I2C_SDA_1();
      		}
      		else
      		{
      			MPU6050_I2C_SDA_0();
      		}
      		_ucByte <<= 1;	/* 左移一個bit */
      		
      		MPU6050_I2C_SCL_1();
      		MPU_IIC_Delay();	
      		MPU6050_I2C_SCL_0();
      		MPU_IIC_Delay();
      	
      		
      	
      	}
      } 	    
      //讀1個字節,ack=1時,發送ACK,ack=0,發送nACK   
      u8 MPU_IIC_Read_Byte(unsigned char ack)
      {
      	unsigned char i,receive=0;
      	MPU_SDA_IN();//SDA設置為輸入
          for(i=0;i<8;i++ )
      	{
              MPU6050_I2C_SCL_0(); 
              MPU_IIC_Delay();
      		MPU6050_I2C_SCL_1();
              receive<<=1;
              if(MPU6050_I2C_SDA_READ())receive++;   
      		MPU_IIC_Delay(); 
          }					 
          if (!ack)
              MPU_IIC_NAck();//發送nACK
          else
              MPU_IIC_Ack(); //發送ACK   
          return receive;
      }
      
      
      
      

      5.讀取的數據成功率低(也就是說讀取10次,mpu_dmp_get_data有5次都返回1,而不是0)

      1.可能是 MPU_IIC_Delay()這個函數取值不恰當,可以調整一下看看效果。
      2.讀取MPU6050數據卡死的總結

      6.容易忽視的小問題,卻恰恰最致命

      例如:

      STM32的PB3、PB4,分別是JTAG的JTDO和NJTRST引腳,在沒關閉JTAG功能之前,在程序中是配置不了這些引腳的功能的。要配置這些引腳,首先要開啟AFIO時鐘,然后在AFIO的設置中,釋放這些引腳。具體看STM32的參考手冊中有關AFIO的部分。

      RCC_APB2PeriphClockCmd(MPU6050_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);			//先使能外設IO PORTB時鐘 
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); 	
      /******************************************************************
       #define GPIO_Remap_SWJ_NoJTRST      ((uint32_t)0x00300100)  < Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST 
      #define GPIO_Remap_SWJ_JTAGDisable  ((uint32_t)0x00300200) < JTAG-DP Disabled and SW-DP Enabled 
      #define GPIO_Remap_SWJ_Disable      ((uint32_t)0x00300400) !< Full SWJ Disabled (JTAG-DP + SW-DP) 
      ******************************************************************/
      

      STM32——GPIO重映射(GPIO_PinRemapConfig)

      下載該資料的人也在下載 下載該資料的人還在閱讀
      更多 >

      評論

      查看更多

      下載排行

      本周

      1. 1STM32F407+ESP8266+SD卡進行遠程固件升級
      2.   |  19次下載  |  免費
      3. 2五、觸摸屏基本概念?
      4.   |  6次下載  |  免費
      5. 3STM32--STM32F051 IAP的實現
      6.   |  5次下載  |  免費
      7. 4硬核創客DIY遙控氦氣球飛行器——會飛的鯊魚的誕生的全過程
      8.   |  5次下載  |  免費
      9. 5第一次使用國產芯片--芯旺微--KungFu--ChipOn
      10.   |  5次下載  |  免費
      11. 6畢業設計 - 題目:基于單片機的指紋識別門禁系統設計
      12.   |  5次下載  |  免費
      13. 7peakcoo分享:soc芯片
      14.   |  5次下載  |  免費
      15. 8ESP32時鐘筆記
      16.   |  4次下載  |  免費

      本月

      1. 1MOS管及其外圍電路設計
      2. 1.27MB  |  239次下載  |  免費
      3. 2348常用實用電路圖大全
      4. 7.95 MB  |  150次下載  |  免費
      5. 351單片機之邏輯運算指令ANL、ORL、XRL等
      6. 93.18KB  |  65次下載  |  免費
      7. 4計算機主板電源接口8pin,菜鳥老鳥都要知道 電源接口圖文全教程
      8. 538.52KB  |  42次下載  |  免費
      9. 5磁環介紹與應用(轉)
      10. 214.96KB  |  39次下載  |  免費
      11. 6霍爾編碼器原理及測速--PID—arduino
      12.   |  35次下載  |  免費
      13. 7macOS搭建51單片機開發環境
      14. 593.4KB  |  29次下載  |  免費
      15. 8LED開關電源與普通開關電源有什么區別
      16. 84.11KB  |  26次下載  |  免費

      總榜

      1. 1matlab 7.0軟件下載(免費破解版)
      2. 1228800  |  934816次下載  |  免費
      3. 2protel99se軟件下載(可英文版轉中文版)
      4. 78.1 MB  |  537325次下載  |  免費
      5. 3MATLAB 7.1 下載 (含軟件介紹)
      6. 1331200  |  419801次下載  |  免費
      7. 4OrCAD10.5下載,OrCAD10.5中文版軟件
      8. 817182  |  233659次下載  |  免費
      9. 5Protel DXP2004破解版下載
      10. 未知  |  232856次下載  |  免費
      11. 6電路仿真軟件multisim 10.0免費下載
      12. 340992  |  190854次下載  |  免費
      13. 7十天學會AVR單片機與C語言視頻教程 下載
      14. 158M  |  183042次下載  |  免費
      15. 8proe5.0野火版下載(中文版免費下載)
      16. 818176  |  137846次下載  |  免費
      版權所有 © 深圳華秋電子有限公司 電子發燒友電路圖粵公網安備 44030402000349號 電信與信息服務業務經營許可證:粵B2-20160233 工商網監認證工商網監 粵ICP備14022951號
      り卐☆熟女の色香:真实处破女刚成年AⅤ是基于地理位置的互联网生活服务平台,国产免费破外女真实出血视频用户可以通过到位找寻身边可上门的被男人吃奶跟添下面特舒服服务,可选择的服务包括按摩、特殊、出台、全套、三陪、等真实处破女刚成年AⅤ服务。
      <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>