全网仅此一篇:工业级压力传感器设计及实现(华大半导体HC32L136)
目錄
1、項目概述
2、模組簡介
2.1、NSA2862物聯網專用橋式傳感器調理芯片
2.2、Metallux ME501/ME505陶瓷壓力傳感器
3、驅動原理
4、項目實現
近期基于Metallux ME501/ME505陶瓷壓力傳感器模組和NSA2862物聯網調理芯片設計一款工業級壓力傳感器,并使用華大半導體HC32L136 MCU實現控制,特將項目心得與體會分享給各位朋友,目前全網僅此一篇,請多多支持~
1、項目概述
本項目傳感器基于Metallux ME501/ME505陶瓷壓力傳感器模組和納芯微NSA2862物聯網調理芯片,微控制器基于華大半導體HC32L136,在保證高性能的前提下,支持待機與休眠喚醒,具備超低的功耗,可連續工作10年而無需更換電池,可大規模應用在智慧城市、工業物聯網等領域。
項目的測量、校準、評估和設計這里參照于納芯微電子傳感器解決方案實現,沒辦法,工業級傳感器設計就是燒錢啊。
2、模組簡介
2.1、NSA2862物聯網專用橋式傳感器調理芯片
NSA2862是一顆專門針對物聯網應用推出的用于阻式或者電壓型傳感器,例如阻式壓力傳感器,熱電偶,RTD等傳感器的超低功耗信號調理專用芯片。NSA2862集成了24位主信號測量通道和24位輔助溫度測量通道,傳感器校準邏輯,雙路恒流源等電路,支持I2C、SPI或者OWI輸出。通過內置的MCU,NSA2862支持對傳感器的零點,靈敏度的二階溫度漂移校準以及最高三階的非線性校準,校準精度可以達到0.1%以內,其校準系數存儲于一組EEPROM中,芯片結構如下所示:
參數特性所示所示:
- 超低待機功耗:<100nA
- 低溫漂內置參考電壓
- 高精度 1X~256X增益可變儀表放大器
- 24位 ADC用于主信號測量
- 24位 ADC用于溫度測量
- 支持內置溫度傳感器和外部溫度傳感器
- 雙路恒流源輸出
- 1X~8X ADC數字增益
- 多種 ODR 設置,支持 50/60Hz 工頻抑制
- 基于內置 MCU的通用傳感器校準邏輯
- EEPROM,可多次編程
- 支持 SPI和 I2C及OWI接口
- 封裝:TSSOP20
- 工作溫度范圍:-40℃~105℃
芯片功能框圖如下圖所示:
2.2、Metallux ME501/ME505陶瓷壓力傳感器
?壓力傳感器一般用于對傳感器敏感器件所處氣體或液體氛圍的壓力測量,一般用于反饋給系統主控單元,實現系統精確控制。壓力傳感器作為傳感器中的一大門類,在汽車、工業、家電、消費電子等不同行業均有廣泛的應用。常用壓力傳感器從感測原理來區分,主要包括如下幾大類:
- 硅壓阻技術
- 陶瓷電阻技術
- 玻璃微熔技術
- 陶瓷電容技術
硅壓阻技術由半導體的壓阻特性來實現,半導體材料的壓阻特性取決于材料種類、摻雜濃度和晶體的晶向等因素。該技術可以采用半導體工藝實現,具有尺寸小,產量高、成本低、信號輸出靈敏度高等優勢。不足之處主要體現在介質耐受程度低,溫度特性差和長期穩定性較差等方面。常見于中低壓量程范圍,如5kPa~700kPa。業界也有通過特殊封裝工藝提高硅壓阻技術的介質耐受程度的方案,如充油、背壓等技術,但也會帶來成本大幅增加等問題。
陶瓷電阻技術采用厚膜印刷工藝將惠斯通電橋印刷在陶瓷結構的表面,利用壓敏電阻效應,實現將介質的壓力信號轉換為電壓信號。陶瓷電阻技術具有成本適中,工藝簡單等優勢,目前國內有較多廠家提供陶瓷電阻壓力傳感器芯體。但該技術信號輸出靈敏度低,量程一般限定在500kPa~10MPa,且常規中空結構,僅靠膜片承壓,抗過載能力差,當待測介質壓力過載時,陶瓷電阻傳感器會存在膜片破裂,介質泄露的風險。
玻璃微熔技術采用高溫燒結工藝,將硅應變計與不銹鋼結構結合。硅應變計等效的四個電阻組成惠斯通電橋,當不銹鋼膜片的另一側有介質壓力時,不銹鋼膜片產生微小形變引起電橋變化,形成正比于壓力變化的電壓信號。玻璃微熔工藝實現難度較大,成本高。主要優勢是介質耐受性好,抗過載能力強,一般適用于高壓和超高壓量程,如10MPa~200MPa,應用較為受限。
陶瓷電容技術采用固定式陶瓷基座和可動陶瓷膜片結構,可動膜片通過玻璃漿料等方式與基座密封固定在一起。兩者之間內側印刷電極圖形,從而形成一個可變電容,當膜片上所承受的介質壓力變化時兩者之間的電容量隨之發生變化,通過調理芯片將該信號進行轉換調理后輸出給后級使用。陶瓷電容技術具有成本適中,量程范圍寬,溫度特性好、一致性、長期穩定性好等優勢。國際上來看廣泛應用于汽車與工業過程控制等領域,分別以美國森薩塔和瑞士E+H為代表。由于電容信號不同于電阻信號,對信號處理電路要求較高,傳感器設計時需要將電容和信號調理芯片ASIC協同考慮,國內目前僅蘇州納芯微電子股份有限公司能夠同時提供兩者整合的完整解決方案。
陶瓷電容作為壓力傳感器中一種主要技術路線,主要由瓷環、陶瓷膜片和陶瓷蓋板三部分組成,具有耐腐蝕、抗沖擊、介質兼容性好的優點。Metallux ME501/ME505傳感器工作原理是陶瓷電阻技術,其由激光可調PTC電阻進行熱補償,陶瓷的使用確保了整個測量范圍內的高線性度,將遲滯效應降到最低,傳感器結構如下所示:
?傳感器技術特性如下表所示:
3、驅動原理
本項目中微控制器華大半導體HC32L136驅動NSA2862傳感器調理芯片基于I2C通信協議,I2C 是雙線雙向的同步串行總線,它利用一根時鐘線和一根數據線在連接總線的兩個器件之間進行信息的傳遞,為設備之間數據交換提供了一種簡單高效的方法。每個連接到總線上的器件都有唯一的地址,任何器件既可以作為主機也可以作為從機,但同一時刻只允許有一個主機。I2C 標準是一個具有沖突檢測機制和仲裁機制的真正意義上的多主機總線,它能在多個主機同時請求控制總線時利用仲裁機制避免數據沖突并保護數據。I2C 總線控制器,能滿足 I2C 總線的各種規格并支持所有與 I2C 總線通信的傳輸模式。
通常標準 I2C 傳輸協議包含四個部分:起始(S)或重復起始信號(Sr),從機地址及讀寫位,傳輸數據,停止信號(P)。I2C 傳輸協議圖如下所示:
當總線處于空閑狀態下(SCL 和 SDA 線同時為高),SDA 線上出現由高到低的信號,表明總線上產生了起始信號。當兩個起始信號之間沒有停止信號時,即產生了重復起始信號。主機采用這種方法與另一個從機或相同的從機以不同傳輸方向進行通信(例如:從寫入設備到從設備讀出)而不釋放總線。當 SCL 線為高時,SDA 線上出現由低到高的信號,被定義為停止信號。主機向總線發出停止信號結束數據傳送。?START和STOP 條件圖如下所示:
當起始信號產生后,主機立即傳輸數據的第一字節:7 位從機地址 + 讀寫位,讀寫位控制從機的數據傳輸方向(0:寫;1:讀)。被主機尋址的從機會通過在第 9 個 SCL時鐘周期將 SDA 置為低電平作為應答。
?數據傳輸過程中,一個 SCL 時鐘脈沖傳輸一個數據位,且 SDA 線只有在 SCL 為低時才可以改變。I2C 總線上位傳輸圖如下所示:
華大半導體I2C 組件可實現 8 位的雙向數據傳輸,傳輸速率在標準模式下可達到 100Kbps 而在高速模式下可達 400Kbps,在超高速模式下可達 1Mbps,并且可以在四種模式下工作:主機發送模式、主機接收模式、從機接收模式、從機發送模式。 還有一種特殊模式廣播呼叫模式,其操作方式與從機接收模式類似。
華大半導體HC32L136 I2C 控制器支持以下特性:
- 支持主機發送/接收,從機發送/接收四種工作模式
- 支持標準(100Kbps) / 快速(400Kbps) / 高速(1Mbps) 三種工作速率
- 支持 7 位尋址功能
- 支持噪聲過濾功能
- 支持廣播地址
- 支持中斷狀態查詢功能
I2C功能模塊如下圖所示:
本項目中采用主機模式實現數據收、發通信,主收、發送模式數據同步圖如下圖所示(更詳細說明可參見用戶手冊):
4、項目實現
第1步:明確從機地址(壓力傳感器地址),NSA2862 的 I2C 設備地址如下表所示:
第2步:配置HC32L136 I2C功能模塊,這里需要留意NSA2862 的 I2C通訊引腳的電性特性,如下表所示:
I2C GPIO配置代碼如下所示:?
///< IO端口配置
void App_PortCfg(void)
{stc_gpio_cfg_t stcGpioCfg;DDL_ZERO_STRUCT(stcGpioCfg);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //開啟GPIO時鐘門控 stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->輸出 stcGpioCfg.enOD = GpioOdEnable; ///< 開漏輸出stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止Gpio_Init(GpioPortB,GpioPin8,&stcGpioCfg); ///< 端口初始化Gpio_Init(GpioPortB,GpioPin9,&stcGpioCfg);Gpio_SetAfMode(GpioPortB,GpioPin8,GpioAf1); ///< 配置PB08為SCLGpio_SetAfMode(GpioPortB,GpioPin9,GpioAf1); ///< 配置PB09為SDA
}
I2C配置代碼如下所示:
///< I2C 模塊配置
void App_I2cCfg(void)
{stc_i2c_cfg_t stcI2cCfg;DDL_ZERO_STRUCT(stcI2cCfg); ///< 初始化結構體變量的值為0Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c0,TRUE); ///< 開啟I2C0時鐘門控stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 獲取PCLK時鐘stcI2cCfg.u32Baud = 100000; ///< 100KstcI2cCfg.enMode = I2cMasterMode; ///< 主機模式stcI2cCfg.bGc = FALSE; ///< 廣播地址應答使能關閉I2C_Init(M0P_I2C0,&stcI2cCfg); ///< 模塊初始化
}
?第3步:編寫接收驅動函數,主機接收狀態圖如下所示:
接收驅動代碼如下所示:?
/********************************************************************************** \brief 主機接收函數**** \param u8Addr從機內存地址,pu8Data讀數據存放緩存,u32Len讀數據長度**** \retval 讀數據是否成功********************************************************************************/en_result_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
{en_result_t enRet = Error;uint8_t u8i=0,u8State;I2C_SetFunc(I2CX,I2cStart_En);while(1){while(0 == I2C_GetIrq(I2CX)){}u8State = I2C_GetState(I2CX);switch(u8State){case 0x08: ///< 已發送起始條件,將發送SLA+WI2C_ClearFunc(I2CX,I2cStart_En);I2C_WriteByte(I2CX,I2C_SLAVEADDR);break;case 0x18: ///< 已發送SLA+W,并接收到ACKI2C_WriteByte(I2CX,u8Addr); ///< 發送從機內存地址break;case 0x28: ///< 已發送數據,接收到ACK, 此處是已發送從機內存地址u8Addr并接收到ACKI2C_SetFunc(I2CX,I2cStart_En); ///< 發送重復起始條件break;case 0x10: ///< 已發送重復起始條件I2C_ClearFunc(I2CX,I2cStart_En);I2C_WriteByte(I2CX,I2C_SLAVEADDR|0x01);///< 發送SLA+R,開始從從機讀取數據break;case 0x40: ///< 已發送SLA+R,并接收到ACKif(u32Len>1){I2C_SetFunc(I2CX,I2cAck_En); ///< 使能主機應答功能}break;case 0x50: ///< 已接收數據字節,并已返回ACK信號pu8Data[u8i++] = I2C_ReadByte(I2CX);if(u8i==u32Len-1){I2C_ClearFunc(I2CX,I2cAck_En); ///< 已接收到倒數第二個字節,關閉ACK應答功能}break;case 0x58: ///< 已接收到最后一個數據,NACK已返回pu8Data[u8i++] = I2C_ReadByte(I2CX);I2C_SetFunc(I2CX,I2cStop_En); ///< 發送停止條件break;case 0x38: ///< 在發送地址或數據時,仲裁丟失I2C_SetFunc(I2CX,I2cStart_En); ///< 當總線空閑時發起起始條件break;case 0x48: ///< 發送SLA+R后,收到一個NACKI2C_SetFunc(I2CX,I2cStop_En); ///< 發送停止條件I2C_SetFunc(I2CX,I2cStart_En); ///< 發送起始條件break;default:I2C_SetFunc(I2CX,I2cStart_En); ///< 其他錯誤狀態,重新發送起始條件break;}I2C_ClearIrq(I2CX); ///< 清除中斷狀態標志位if(u8i==u32Len) ///< 數據全部讀取完成,跳出while循環{break;}}enRet = Ok;return enRet;
}
?第4步:編寫發送驅動函數,主機發送狀態圖如下所示:?
發送驅動代碼如下所示:??
/********************************************************************************** \brief 主機發送函數**** \param u8Addr從機內存地址,pu8Data寫數據,u32Len寫數據長度**** \retval 寫數據是否成功********************************************************************************/
en_result_t I2C_MasterWriteData(M0P_I2C_TypeDef* I2CX,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
{en_result_t enRet = Error;uint8_t u8i=0,u8State;I2C_SetFunc(I2CX,I2cStart_En);while(1){while(0 == I2C_GetIrq(I2CX)){;}u8State = I2C_GetState(I2CX);switch(u8State){case 0x08: ///< 已發送起始條件I2C_ClearFunc(I2CX,I2cStart_En);I2C_WriteByte(I2CX,I2C_SLAVEADDR); ///< 從設備地址發送break;case 0x18: ///< 已發送SLA+W,并接收到ACKI2C_WriteByte(I2CX,u8Addr); ///< 從設備內存地址發送break;case 0x28: ///< 上一次發送數據后接收到ACKI2C_WriteByte(I2CX,pu8Data[u8i++]); ///< 繼續發送數據break;case 0x20: ///< 上一次發送SLA+W后,收到NACKcase 0x38: ///< 上一次在SLA+讀或寫時丟失仲裁I2C_SetFunc(I2CX,I2cStart_En); ///< 當I2C總線空閑時發送起始條件break;case 0x30: ///< 已發送I2Cx_DATA中的數據,收到NACK,將傳輸一個STOP條件I2C_SetFunc(I2CX,I2cStop_En); ///< 發送停止條件break;default:break;}if(u8i>u32Len){I2C_SetFunc(I2CX,I2cStop_En); ///< 此順序不能調換,出停止條件I2C_ClearIrq(I2CX);break;}I2C_ClearIrq(I2CX); ///< 清除中斷狀態標志位}enRet = Ok;return enRet;
}
??第5步:為驗證I2C通信是否成功,向NSA2862空閑寄存器0XCF中執行讀數據0X55并讀取出來,空閑寄存器地址如下表所示:
驗證示例代碼如下所示:??
uint8_t u8Senddata[2] = {0x00,0x55};
uint8_t u8Recdata[1]={0x00};///< 向I2C總線發起開始信號
I2C_SetFunc(M0P_I2C1,I2cStart_En);
///< 寫數據
I2C_MasterWriteData(M0P_I2C0,0x30,&u8Senddata[0],1);
I2C_MasterWriteData(M0P_I2C0,0xCF,&u8Senddata[1],1);
delay1ms(100);///< 讀數據
I2C_MasterReadData(M0P_I2C0,0xCF,u8Recdata,1); ///< 串口打印
for(int i=0;i<1;i++)
{Uart_SendDataIt(M0P_UART1,u8Recdata[i]); //啟動UART1發送數據delay1ms(3);
}
使用示波器查看效果,程序運行時鐘信號波形如下所示:
程序運行數據信號波形如下所示:?
串口輸出效果如下所示:?
說明可以實現正常的I2C數據讀寫。
第6步:讀取壓力傳感器數值,寄存器地址如下表所示:
讀取傳感器數值代碼如下所示:
uint8_t u8Senddata[2] = {0x00,0x40};
uint8_t u8Recdata[4]={0x00};///< 向I2C總線發起開始信號
I2C_SetFunc(M0P_I2C1,I2cStart_En);
///< 寫入寄存器啟動使RAW_P=0
I2C_MasterWriteData(M0P_I2C0,0x30,&u8Senddata[0],1);
I2C_MasterWriteData(M0P_I2C0,0xA5,&u8Senddata[1],1);
delay1ms(100);///< 讀取經過校正的傳感器數據
I2C_MasterReadData(M0P_I2C0,0x06,u8Recdata,1);
I2C_MasterReadData(M0P_I2C0,0x07,u8Recdata+1,1);
I2C_MasterReadData(M0P_I2C0,0x08,u8Recdata+2,1); for(int i=0;i<3;i++)
{Uart_SendDataIt(M0P_UART1,u8Recdata[i]); //啟動UART1發送數據delay1ms(3);
}
使用示波器查看效果,程序運行時鐘信號波形如下所示:
程序運行數據信號波形如下所示:?
串口輸出效果如下所示:?
數據0X014ADD就是校準后ME501壓力數值(2的補碼形式)。
總結
以上是生活随笔為你收集整理的全网仅此一篇:工业级压力传感器设计及实现(华大半导体HC32L136)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4行Python代码生成图像验证码
- 下一篇: 力扣(LeetCode)刷题,简单题(第