<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      白了少年頭,空悲切。
      又有哥們生孩子了。他們有車有房有老婆還有孩子,也不知咋掙來的。搞得我聚會都不想去了。
      郁悶。
      沒辦法,自己只有努力。
      胸藏萬卷憑吞吐,筆有千鈞任翕張。

      前言

      • 之前用ESP32驅動兩路AS5600沒有成功,后面簡單梳理了下IIC的邏輯,才反應過來。下面記錄一下。

      ESP32 IDF環境下雙路IIC的切換讀取

      在官方提供的幾個IIC的demo中,都是不做切換的讀取。按照例程的步驟初始化單路IIC,讀取時沒問題。多路切換時,只需要注意切換 i2c_master_port 這個參數就行了。

      首先,需要在初始化中分別注冊兩路IIC及其對應的引腳:

       esp_err_t i2c_master_init(void)
      {
      
      	 int i2c_master_port = I2C_AS5600_NUM0;  //這個port是切換IIC的關鍵,在i2c_driver_install中要注冊不同的port
      
      	     i2c_config_t conf = {
      	         .mode = I2C_MODE_MASTER,
      	         .sda_io_num = I2C_AS5600_SDA_0,
      	         .sda_pullup_en = GPIO_PULLUP_ENABLE,
      	 		.scl_io_num = I2C_AS5600_SCL_0,
      	         .scl_pullup_en = GPIO_PULLUP_ENABLE,
      	         .master.clk_speed = I2C_AS5600_FREQ_HZ,
      	     };
      
      	     i2c_param_config(i2c_master_port, &conf);
      
      	     i2c_driver_install(i2c_master_port, conf.mode, I2C_AS5600_RX_BUF_DISABLE, I2C_AS5600_TX_BUF_DISABLE, 0);
      
      	     i2c_master_port = I2C_AS5600_NUM1;//另一路IIC
      
      	     i2c_config_t conf1 = {
      	         .mode = I2C_MODE_MASTER,
      	         .sda_io_num = I2C_AS5600_SDA_1,
      	         .sda_pullup_en = GPIO_PULLUP_ENABLE,
      	 		.scl_io_num = I2C_AS5600_SCL_1,
      	         .scl_pullup_en = GPIO_PULLUP_ENABLE,
      	         .master.clk_speed = I2C_AS5600_FREQ_HZ,
      	     };
      
      	     i2c_param_config(i2c_master_port, &conf1);
      
      	     return i2c_driver_install(i2c_master_port, conf1.mode, I2C_AS5600_RX_BUF_DISABLE, I2C_AS5600_TX_BUF_DISABLE, 0);
      
      
      }
      
      

      然后在使用過程中,切換 i2c_master_port 參數就行了:

      
      static  esp_err_t i2c_master_DataGet(uint8_t sensorNum,float *returnAngel){
      
      	uint8_t angle_high = 0;
      	    uint8_t angle_low = 0;
      	    uint16_t result = 0;
      	    float angle=0;
      	    i2c_cmd_handle_t cmd;
      	    int i2c_master_port = I2C_AS5600_NUM0;
      
      	    if(sensorNum == 0){
      	    	 i2c_master_port = I2C_AS5600_NUM0;//這個port是切換IIC的關鍵,讀取時使用不同的port就能切換IIC
      	    }else{
      	    	i2c_master_port = I2C_AS5600_NUM1;
      	    }
      	    //讀取HighAddr
      	    cmd = i2c_cmd_link_create();
      	    i2c_master_start(cmd);
      	    i2c_master_write_byte(cmd, I2C_AS5600_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
      	    i2c_master_write_byte(cmd, I2C_AS5600_ANGLE_ADDRH, ACK_CHECK_EN);
      	    i2c_master_stop(cmd);
      	    i2c_master_cmd_begin(i2c_master_port, cmd, 10 / portTICK_PERIOD_MS);  //可以看到,上面的操作應該是需要這個begin開始啟動,使用port來確認對哪個IIC進行操作
      	    i2c_cmd_link_delete(cmd);
      	    //vTaskDelay(1 / portTICK_PERIOD_MS);
      
      	    cmd = i2c_cmd_link_create();
      	    i2c_master_start(cmd);
      	    i2c_master_write_byte(cmd, I2C_AS5600_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
      	    i2c_master_read_byte(cmd, &angle_high, ACK_VAL); //0x0c是高位
      	    i2c_master_read_byte(cmd, &angle_low, NACK_VAL);
      	    i2c_master_stop(cmd);
      	    i2c_master_cmd_begin(i2c_master_port, cmd, 10 / portTICK_PERIOD_MS);
      	    i2c_cmd_link_delete(cmd);
      
      	    result=(uint16_t)(angle_high<<8|angle_low); //一共就11位 注意
      	    angle=((int) result & 0b0000111111111111)*360.0/4096.0;
      	    *returnAngel = angle;
      	    //printf("angle%d: %.2f \n",sensorNum,angle);
      
      return 0;
      }
      
      

      可以看到,IDF環境對于IIC的處理是將IIC的操作放到了 i2c_master_start()和 i2c_master_stop()之間,進行了類似隊列的保存操作(沒深入探究),然后是用i2c_master_cmd_begin()才開始 進行硬件上的操作,所以在此處切換不同的IIC端口。一開始沒注意到此處,就想著前面怎么沒有端口切換相關的參數呢。

      剝離成中間函數

      后面是用結構體來 模擬C++的類,進行函數封裝。
      首先在 .h文件中定義結構體函數,并定義需要的結構體函數,然后是用 extern 做全局定義:

      
      struct cenAngleGetBasicStruct{
      	uint8_t AngleSenserNum;
      	int8_t	SensorMoveDir[2];		//電機運動方向,+1:正向,-1:負向,0:不動
      	float AngelSingleTurn[2];		//單圈記錄值,浮點數類型
      	float AngelSingleTurnInit[2];	//單圈記錄值,精確到0.01度,放大100倍,
      	long double AngelMultiTurn[2];		//多圈圈記錄角度值,精確到0.01度,放大100倍
      	void (*cenAngleGetInit)(void);
      	void (*cenAngleGet)(uint8_t sensorNum,float *returnAngle);
      
      };
      
      extern struct cenAngleGetBasicStruct cenAngleGetClass;  //全局使用的角度相關的結構體
      void cenAngleGetClassInit(void);
      

      然后在同名 .c 文件中進行賦值和函數綁定:

      struct cenAngleGetBasicStruct cenAngleGetClass;  //全局使用的角度相關的結構體
      /*------------------------------
      *函數:cenAngleGetClassInit
      *
      *說明: 中間層的角度獲取class初始化
      *		需要在主函數之前調用一次本函數,用于仿class類的初始化綁定
      *
      *
      *參數:
      *
      *
      *編寫:ZNZZ wcc 執念執戰 2023-5-20
      *
      *修改:
      ------------------------------*/
      void cenAngleGetClassInit(void){
      	//初始化內部參數,設置默認參數
      	cenAngleGetClass.AngleSenserNum = 2;
      	cenAngleGetClass.AngelMultiTurn[0]=0;
      
      	//綁定對應的函數形成方法
      	cenAngleGetClass.cenAngleGetInit = basAS5600Init;
      	cenAngleGetClass.cenAngleGet = basAS5600AngleGet;  //角度獲取方法,在需要的地方調用即可
      	//調用方法
      	cenAngleGetClass.cenAngleGetInit();//調用Init方法來完成硬件初始化。
      }
      
      
      

      然后就能在其他地方包含 .h 頭文件后使用了。這種方法能夠較為簡單的剝離底層和上層。實際上,將賦值這一步想辦法實現為從bin地址中賦值為指定的函數地址,理論上就能實現更為復雜的類似驅動安裝的效果,實現跨平臺(當然,我沒有深究過別人的跨平臺是如何實現的,但是思路上應該差不多)。我后續的程序會盡可能的使用這種方式,將不同的功能都剝離成各自的仿類Class。這種方式寫起來略顯麻煩,因為都要多加一步中間的結構體層。

      下面是在mian中的測試方法:

      void app_main(void)
      {
      	int count = 0;
      	float angle = 0.0;
      	cenAngleGetClassInit();
      	while(1){
      		cenAngleGetClass.cenAngleGet(count%2,&angle);//實現兩路IIC的快速切換讀取
      		printf("GetAngle %d:%.2f \n",count%2,angle);
      		count++;
      	}
      }
      
      

      總結

      我看到還有很多用C語言模擬C++或是其他語言特性的寫法,不過實現起來比較費時間,用起來也比較雞肋。所以簡單用一些比較好用的特性就夠了,畢竟現在很多單片機的編譯器都支持C++語法特性了,比如現在用的ESP32-IDF的開發環境就是支持C++語法的,只是需要簡單配置。

      最近變得好懶了,FOC好幾周了,只是能讓電機保持不動了,怎么讓電機動起來還是不想搞。

      • 本文水平有限,內容很多詞語由于知識水平問題不嚴謹或很離譜,但主要作為記錄作用,希望以后的自己和路過的大神對必要的錯誤提出批評與指點,對可笑的錯誤請指出來,我會改正的。
      • 另外,轉載使用請注明作者和出處,不要刪除文檔中的關于作者的注釋。

      隨夢,隨心,隨愿,恒執念,為夢執戰,執戰蒼天! ------------------執念執戰

      posted on 2023-06-01 23:15  執念執戰  閱讀(648)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 真人性囗交视频| 欧美成人午夜精品免费福利| av无码精品一区二区乱子 | 精品无码人妻| 午夜成人无码免费看网站| 国产特色一区二区三区视频| 天堂网在线.www天堂在线资源| 丰满巨乳淫巨大爆乳| 伊人狠狠色丁香婷婷综合| 中文字幕av无码不卡| 日韩美女视频一区二区三区| 精品人妻无码一区二区三区| 九九热在线视频精品免费| 成人亚欧欧美激情在线观看 | 临武县| 国产免费又黄又爽又色毛| 国产精品点击进入在线影院高清 | 日本精品不卡一二三区| 丁香五月天综合缴情网| 另类国产精品一区二区| 九九综合va免费看| 久久亚洲精品成人av无| 农村欧美丰满熟妇xxxx| 成人一区二区三区久久精品| 亚洲另类无码一区二区三区| 日韩中文字幕v亚洲中文字幕| 无码精品人妻一区二区三区中| 亚洲精品精华液一区二区| 成人3D动漫一区二区三区| 国产一区二区日韩经典| 国产午夜福利视频合集| 欧美人与动牲交a免费| 亚洲va久久久噜噜噜久久狠狠| 丁香五月婷激情综合第九色 | 国产精品午夜精品福利| 巴林左旗| 少妇人妻综合久久中文字幕| 国产mv在线天堂mv免费观看| 日本亚洲一区二区精品久久| 天天做天天爱夜夜爽导航 | 大陆一级毛片免费播放|