在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32基于onewire單總線的數據抽象實例簡析

STM32嵌入式開發 ? 來源:STM32嵌入式開發 ? 2023-10-27 15:44 ? 次閱讀

1.前言

onewire(單總線) 是DALLAS公司推出的外圍串行擴展總線技術總線,顧名思義,它是采用一根信號線進行通信,既傳輸時鐘信號又傳輸數據,而且能夠進行雙向通信,具有節省I/O口線、資源結構簡單、成本低廉、便于總線擴展和維護等諸多優點。

常用到單總線的器件,一般是溫度傳感器、EEPROM、唯一序列號芯片等,如DS18B20、DS2431。

在使用單總線時,往往很少CPU會提供硬件單總線,幾乎都是根據單總線標準的時序圖,通過普通IO翻轉模擬實現單總線。而在模式實現時序圖的過程中,需要根據CPU時鐘頻率等條件進行時序時間計算,如果更換CPU后,需要重新計算時序時間,如果時序代碼和器件外設控制代碼集成在一起,則代碼改動比較大。

或者同一CPU需要模擬多根單總線時,傳統的“復制”方式使得程序顯得累贅,還增加ROM占用空間。因此,可以利用“函數指針”的方式,將時序部分抽象出來,達到“復用”代碼的效果,減少重復代碼編寫。

2.onewire 抽象

2.1 onewire 結構體

onewire結構體主要是對與CPU底層相關的操作抽象分離,調用時只需將該結構體地址(指針)作為函數入口參數,通過該指針實現對底層函數的回調。該結構體我們命名為“struct ops_onewire_dev”,其原型如下:


struct ops_onewire_dev
{
    void (*set_sdo)(int8_t state);
    uint8_t (*get_sdo)(void);
    void (*delayus)(uint32_t us);
};
其中: 1)set_sdo:IO輸出1bit,包括時鐘和數據。 2)get_sdo:IO輸入1bit,包括時鐘和數據。 3)delayus:時序延時函數,根據CPU頻率進行計算。 回調函數相關文章:C語言技巧之回調函數

2.2 onewire 對外接口



extern uint8_t ops_onewire_reset(struct ops_onewire_dev *onewire);
extern int ops_onewire_read(struct ops_onewire_dev *onewire,void *buff,int size);
externintops_onewire_write(structops_onewire_dev*onewire,void*buff,intsize);
1)分別為復位函數、讀函數、寫函數。

2)入口首參數為“struct ops_onewire_dev”結構體指針,此部分就是硬件層相關,需要后期初始化的.

3)其余入口參數易于理解,讀/寫緩存及數據大小。

2.3 onewire 抽象接口實現

分別實現上述三者函數接口。

2.3.1 復位函數

復位函數,在單總線初始化外設器件時需要用到,用于判斷總線與器件是否通信上,類似“握手”的動作。如圖,為DS18B20的復位時序圖,以下與單總線相關的時序圖,都是以DS18B20為例,因為此芯片為單總線應用的經典。 1643d926-749c-11ee-939d-92fbcf53809c.png 根據時序圖,實現復位函數。


/**
  * @brief  單總線復位時序
  * @param  onewire 總線結構體指針
  * @retval 成功返回0
*/
uint8_t ops_onewire_reset(struct ops_onewire_dev *onewire)
{
 uint8_t ret = 0;
 
 onewire->set_sdo(1);
 onewire->delayus(50);
 onewire->set_sdo(0);
 onewire->delayus(500);
 onewire->set_sdo(1);
 onewire->delayus(40);
 ret = onewire->get_sdo();
 onewire->delayus(500);
 onewire->set_sdo(1);
 return ret;
}

2.3.2 讀函數

讀函數即以該函數,通過單總線從外設上讀取數據,至于代碼的實現,完全是時序圖的實現,無特殊難點。先實現單字節讀函數,再通過調用單字節讀函數實現多字節讀函數。

pYYBAGGSOe-AeFXUAACD9VFIX00147.png


/**
  * @brief  單總線讀取一字節數據
  * @param  onewire 總線結構體指針
  * @retval 返回讀取的數據
*/
static char ops_onewire_read_byte(struct ops_onewire_dev *onewire)
{
 char data = 0;
 uint8_t i;
 
 for(i=8;i>0;i--)
 {
  data >>= 1;
  onewire->set_sdo(0);
  onewire->delayus(5);
  onewire->set_sdo(1);
  onewire->delayus(5);
  if(onewire->get_sdo())
   data |= 0x80;
  else
   data &= 0x7f;
  onewire->delayus(65);
  onewire->set_sdo(1);
 }
 return data;
}


/**
  * @brief  讀取多字節
  * @param  onewire 總線結構體指針
  * @param  buff 存放數據緩存
  * @param  size 數據大小
  * @retval 返回讀取到的數據大小
*/
int ops_onewire_read(struct ops_onewire_dev *onewire,void *buff,int size)
{
 int i;
 char *p = (char*)buff; 
 for(i=0;i

2.3.3 寫函數

寫函數與讀函數同理,即以該函數,通過單總線往外設寫入數據,至于代碼的實現,完全是時序圖的實現,無特殊難點。先實現單字節寫函數,再通過調用單字節寫函數實現多字節寫函數。

poYBAGGSOfGAUeEhAADKD-j20k4098.png


/**
  * @brief  單總線寫一字節
  * @param  onewire 總線結構體指針
  * @param  data 待寫數據
  * @retval 返回讀取的數據
*/
static int ops_onewire_write_byte(struct ops_onewire_dev *onewire,char data)
{
 uint8_t i;
 
 for(i=8;i>0;i--)
 {
  onewire->set_sdo(0);
  onewire->delayus(5);
  if(data&0x01)
   onewire->set_sdo(1);
  else
   onewire->set_sdo(0);
  onewire->delayus(65);
  onewire->set_sdo(1);
  onewire->delayus(2);
  data >>= 1;
 }
 return 0;
}


/**
  * @brief  寫多字節
  * @param  onewire 總線結構體指針
  * @param  buff 代寫數據地址
  * @param  size 數據大小
  * @retval 寫入數據大小
*/
int ops_onewire_write(struct ops_onewire_dev *onewire,void *buff,int size)
{
 int i;
 char *p = (char*)buff;
 for(i=0;i
 至此,onewire(單總線)抽象化完成,此部分代碼與硬件層分離,亦可單獨作為一個模塊,移植到不同平臺CPU時,也幾乎無需改動。剩下部分工作則是實現“struct ops_onewire_dev”中的函數指針原型,即可使用一根單總線。

3.onewire 抽象應用

STM32F1為例,實現上述抽象接口。

3.1 “struct ops_onewire_dev” 實現

此部分即是與硬件相關部分,不同CPU平臺改動該部分即可,如從51單片機移植到STM32上。下面涉及到的IO宏,是對應IO的宏定義,如“ONEWIRE1_PORT”、“ONEWIRE1_PIN”,實際使用的是PC13 IO口。

3.1.1 IO輸出


static void gpio_set_sdo(int8_t state)
{
    if (state)
  GPIO_SetBits(ONEWIRE1_PORT,ONEWIRE1_PIN); 
    else
  GPIO_ResetBits(ONEWIRE1_PORT,ONEWIRE1_PIN); 
}

3.1.2 IO輸入


static uint8_t gpio_get_sdo(void)
{
    return (GPIO_ReadInputDataBit(ONEWIRE1_PORT,ONEWIRE1_PIN));
}

3.1.3 延時函數


static void gpio_delayus(uint32_t us)
{
#if 1  /* 不用系統延時時,開啟 */
    volatile int32_t i;
 
    for (; us > 0; us--)
    {
     i = 30;  //mini 17
        while(i--);
    }
#else
  delayus(us);
#endif
}

3.2onewire 總線初始化

3.2.1 onewire 抽象相關

第一步:定義一個“struct ops_onewire_dev”結構體類型變量(全局)——onewire1_dev。


struct ops_onewire_dev onewire1_dev;
第二步:實例化“onewire1_dev”中的函數指針。

onewire1_dev.get_sdo=gpio_get_sdo; onewire1_dev.set_sdo=gpio_set_sdo; onewire1_dev.delayus=gpio_delayus; 第三步:使用時,通過傳入“onewire1_dev”地址(指針)即可。

3.2.2 onewire 基礎相關

初始基礎部分,與使用的CPU硬件相關,如時鐘、IO方向等。


/**
  * @brief  初始化單總線
  * @param  none
  * @retval none
*/
void stm32f1xx_onewire1_init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;          
 RCC_APB2PeriphClockCmd(ONEWIRE1_RCC,ENABLE);  


 GPIO_InitStructure.GPIO_Pin = ONEWIRE1_PIN;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      
   GPIO_Init(ONEWIRE1_PORT, &GPIO_InitStructure);             
 ONEWIRE1_PORT->BSRR = ONEWIRE1_PIN;      
 
 /* device init */
 onewire1_dev.get_sdo = gpio_get_sdo;
 onewire1_dev.set_sdo = gpio_set_sdo;
 onewire1_dev.delayus = gpio_delayus;
}

4.onewire 使用

經過前面的步驟后,我們已經通過IO口翻轉,模擬實現了一根單總線——“onewire1_dev”,以DS18B20為例,調用第一部分中三者接口,實現對DS18B20的操作。

4.1 DS18B20操作

對于DS18B20,不陌生,即是溫度傳感器,不多贅述,使用的功能主要是作為溫度檢測,另外還有其內部的唯一序列號會作為同一總線上掛多個DS18B20時的“地址”識別。 亦可把DS18B20的唯一序列號作為模塊、產品、通信總線等的唯一標識使用。因此,代碼也是主要實現這兩個功能。


#include "onewire_hw.h"
#include "ds18b20.h"


static uint8_t ds18b20_start(void)
{    
 char reg;
    ops_onewire_reset(&onewire1_dev);     
      
 reg = 0xcc; /* 跳過ROM */
 ops_onewire_write(&onewire1_dev,®,1);
 reg = 0x44; /* 溫度轉換指令 */
 ops_onewire_write(&onewire1_dev,®,1);        
 return 0;
}


/**
  * @brief  讀取溫度
  * @param  none
  * @retval 溫度值,浮點型
*/
float ds18b20_readtemp(void)
{
    uint8_t  tl,th,sign;
 uint16_t reg_temp; 
 char reg;
 float temp;
 
 ds18b20_start();
 ops_onewire_reset(&onewire1_dev); 
 reg = 0xcc;
 ops_onewire_write(&onewire1_dev,®,1); /* 跳過ROM */
 reg = 0xbe;
 ops_onewire_write(&onewire1_dev,®,1); /* 讀取RAM */
 ops_onewire_read(&onewire1_dev,&tl,1);  /* 低8位數據 */
 ops_onewire_read(&onewire1_dev,&th,1);   /* 高8位數據 */
 if(th > 7)
 {/* - */
  th = ~th;
  tl = ~tl + 1; 
  sign = 0;             
 }
 else 
 {/* + */
  sign = 1;   
 }  
 reg_temp = (th<<8) | tl;
 temp = reg_temp * 0.0625f; 
 if(sign)
 {
  return temp;       
 }
 else 
 {
  return -temp;   
 }
}
 
/**
  * @brief  讀唯一序列號
  * @param  rom 返回序列號緩存
  * @retval none
*/
void ds18b20_readrom(char *rom)
{
 uint8_t i;
 char reg;
 
 ops_onewire_reset(&onewire1_dev);
 reg = 0x33;
 ops_onewire_write(&onewire1_dev,®,1);
 for (i = 0;i < 8;i++)
 {
  ops_onewire_read(&onewire1_dev,&rom[i],1);  
 } 
}
至此,完成單總線的抽象分層使用。








審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 溫度傳感器
    +關注

    關注

    48

    文章

    2966

    瀏覽量

    156263
  • STM32
    +關注

    關注

    2270

    文章

    10918

    瀏覽量

    356893
  • EEPROM
    +關注

    關注

    9

    文章

    1028

    瀏覽量

    81804
  • DS2431
    +關注

    關注

    0

    文章

    3

    瀏覽量

    8409
  • OneWire
    +關注

    關注

    0

    文章

    2

    瀏覽量

    846

原文標題:STM32基于onewire單總線的數據抽象實例

文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    單總線技術的原理是什么?

    顧名思義,單總線只有一根數據線系統中的數據交換、控制都在這根線上完成。設備(主機或從機)通過一個漏極開路或三態端口連至該數據線,這樣允許設備不發送
    發表于 09-17 09:11

    單總線協議時序對應代碼

    一.單總線協議時序對應代碼1.延時函數//單總線延時函數,約1~2usvoid Delay_OneWire(unsigned int t){static unsigned char i;while(t--){ for(i=0;i
    發表于 01-17 08:05

    DS18B20芯片用法及代碼解析

    :主機和從機通過1根線進行通信,在一條總線上可掛接的從器件數量幾乎不受限制。2.特點:這是由達拉斯半導體公司推出的一項通信技術。它采用單根信號線,既可傳輸時鐘,又能傳輸數據,而且數據傳輸是雙向的。3.優點:
    發表于 01-17 07:37

    總線的基本概念及其分類

    文章目錄1.總線的基本概念2.總線的分類2.1 片內總線2.2 系統總線2.2.1 數據總線2.
    發表于 02-16 06:54

    單總線測溫系統

    單總線測溫系統 1 -Wire Sy tem for Temperature Mea urement 摘要介紹了單總線系統的結構、原理和技術特點,闡述了單總線協議、操作流程以及DS18B20 數字式溫度傳感器的功能結構,
    發表于 01-12 16:58 ?9次下載

    利用單總線傳輸數據與電源

    利用單總線傳輸數據與電源
    發表于 05-04 13:33 ?28次下載

    單總線溫度監測網絡的設計與實現

             以單總線技術為基礎,采用計算機串口、單總線和串口的協議轉換芯片DS2480B、單總線數字化溫度傳感器DS18B20,設計了
    發表于 09-09 09:47 ?15次下載

    1-wire單總線的基本原理

    1-wire單總線的基本原理 1-wire 單總線是Maxim 全資子公司Dallas 的一項專有技術與目前多數標準串行數據通信方式如SPI/I2C/MICROWIRE
    發表于 02-05 17:58 ?79次下載

    基于單總線的冷庫溫度監控系統設計

    本文以單總線技術為基礎,采用計算機串口、單總線和串口的協議轉換芯片DS2480B、單總線數字化溫度傳感器DS18B20,設計了單總線溫度檢測網絡。該系統能滿足各類冷藏、冷凍食品的實際
    發表于 08-22 11:47 ?2442次閱讀
    基于<b class='flag-5'>單總線</b>的冷庫溫度監控系統設計

    鼠標HID例程(中)

    鼠標 HID 例程 緊接《鼠標 HID 例程(上)》一文,繼續向大家介紹鼠 標 HID 例程的未完的內容。
    發表于 07-26 15:18 ?0次下載

    單總線協議詳解

    、資源結構簡單、成本低廉、便于總線擴展和維護等諸多優點。 單總線是DALLAS公司研制開發的種協議由一個總線主節點、或多個從節點組成系統,通過根信號線對從芯片進行數據的讀取。每一個符合
    發表于 10-24 17:50 ?3.8w次閱讀
    <b class='flag-5'>單總線</b>協議詳解

    單總線結構

    使用總線時,能迅速放棄總線控制權。 單總線結構 單總線主機或從機設備通過一個漏極開路或三態端口連接至該數據線,這樣允許設備在不發送
    發表于 10-25 09:28 ?9514次閱讀
    <b class='flag-5'>單總線</b>結構

    單總線優缺點

    總線系統是指微型計算機各部件之間傳送信息的通道。簡單地說就是在總線控制器的作用下,通過總線設備接口控制、管理連接在總線上的設備使用總線
    發表于 10-25 10:03 ?1.7w次閱讀
    <b class='flag-5'>單總線</b>優缺點

    "藍橋杯單片機設計與開發-底層驅動代碼編寫(iic,onewire,ds1302)"

    ;stc15f2k60s2.h>sbit DQ = P1^4; //單總線接口//單總線延時函數void Delay_OneWire(unsigned int t) //STC89C52RC{ while(t--);}//通
    發表于 11-21 13:21 ?0次下載
    "藍橋杯單片機設計與開發-底層驅動代碼編寫(iic,<b class='flag-5'>onewire</b>,ds1302)"

    Onewire單總線驅動DS18B20讀取溫度

    :主機和從機通過1根線進行通信,在一條總線上可掛接的從器件數量幾乎不受限制。2.特點:這是由達拉斯半導體公司推出的一項通信技術。它采用單根信號線,既可傳輸時鐘,又能傳輸數據,而且數據傳輸是雙向的。3.優點:
    發表于 01-18 10:09 ?5次下載
    <b class='flag-5'>Onewire</b><b class='flag-5'>單總線</b>驅動DS18B20讀取溫度
    主站蜘蛛池模板: 夜夜爽夜夜爽| aa黄色大片| 日本污视频网站| 拍拍拍拍拍拍拍无挡大全免费| 日韩在线三级| 噜噜噜久久| 夜色321看片资源站| 国产精品免费看久久久久| 日本xxx69hd| 亚洲欧洲一二三区| a亚洲| 亚州一级| 日本电影在线观看黄| 激情婷婷综合| 在线观看免费视频| 欧美一级片免费观看| 完全免费在线视频| 久久久久久毛片免费播放| 曰本在线| 日韩视频高清| 黄色香蕉网| 亚洲天天在线| 福利在线看片| 美女被异性狂揉下部羞羞视频| 在线观看精品视频看看播放| 四虎影院永久| 激情六月天| 天天久| 日木69xxxhd| 伊人久久大香线蕉综合bd高清| 色综合久久九月婷婷色综合| 毛片免费看网站| 在线观看午夜| 97精品久久天干天天蜜| 激情婷婷综合久久久久| 色多多视频网站| 成人看片在线观看| 国产午夜精品理论片免费观看| 日日操夜夜操狠狠操| 色偷偷成人网免费视频男人的天堂| 精品国模|