基于FPGA控制PCF8591開展ADC采樣,以采樣煙霧模塊輸出模擬電壓為例(IIC通信)

基于FPGA控制PCF8591開展ADC采樣

  • 前言
  • 一、芯片手冊閱讀
    • 1.設備地址
    • 2.字節地址
    • 3.IIC通信協議
  • 二、仿真分析
  • 三、代碼分析
  • 總結
    • 視頻演示

前言

這段時間做設計總是遇到一些傳感器模塊輸出模擬電壓,采集模擬電壓進而了解傳感器輸出的濃度占比,在淘寶上找到了一個4通道的ADC采集模塊,用這個來獲取不同傳感器的模擬電壓輸出正好,其實物如圖所示:
該模塊具有ADC采樣以及DAC輸出的功能,其中4路為ADC采樣輸入AIN0-4,一路DAC輸出AOUT。
與FPGA相連接的端口為VCC、GND、SCL、SDA,主要就是通信協議的實現,實現之前需要閱讀芯片手冊,獲取一下有用的關鍵信息,通信速率,從機設備地址、控制指令信息等等
產品參數:
在這里插入圖片描述

在這里插入圖片描述

使用注意事項:
供電:5V,你的adc輸入范圍就是0-5V,如果用3.3V供電,你的輸入范圍就是0-3.3V。不同的供電可能效果不同,我目前遇到過好多供電問題,然后換一種供電就工作正常,所以大家遇到問題時要不斷排除問題。
跳帽:你如果需要用adc通道采集外部的模擬電壓,你就需要對應通道的跳帽拔下來。否則數據一直是模塊本身自帶的數據。

一、芯片手冊閱讀

1.設備地址

結合兩個圖,發現還有A0-A2三個未知的比特,通過查看模塊原理圖,發現這三個引腳接地。所以設備地址確定為:0x1001000
寫數據就是0x90 讀數據就是0x91
在這里插入圖片描述在這里插入圖片描述

2.字節地址

一堆英文不想看,看圖就行了,如下圖所示,每個比特干啥的都說的比較清楚。
從低位這邊看,[0:1]是負責說明對哪個通道進行操作的,前面也提到了總共4個通道。
然后[2]這個比特默認為1
然后[3]默認為0
然后[4:5]說明這四個通道的輸入模式,有差分輸入啥的,不選擇,我只需要最普通的那種輸入即可,所以默認00
然后[6]在ADC時為0,在DAC時為1
然后最高位默認為0

比如現在要對通道1進行ADC采樣轉化的功能實現,就要發送0x00000000
比如現在要對通道2進行ADC采樣轉化的功能實現,就要發送0x00000001
比如現在要對通道3進行ADC采樣轉化的功能實現,就要發送0x00000010
比如現在要對通道4進行ADC采樣轉化的功能實現,就要發送0x00000011

比如現在要對通道1進行DAC采樣轉化的功能實現,就要發送0x01000000
在這里插入圖片描述

3.IIC通信協議

了解一下基本的信息,對后面實現通信流程有所參考。
在這里插入圖片描述
如果發送完設備地址了,后面采樣轉化可以進行連續操作。

在這里插入圖片描述
數字量跟模擬量的關系
在這里插入圖片描述

完整的通信流程應該就是如下圖所示。
在這里插入圖片描述

二、仿真分析

仿真測試文件忘了放哪里了。就是簡單的iic驅動,設備地址,字節地址,讀取數據的命令都知道了,就是按照時序進行發送就可以了。
在這里插入圖片描述

三、代碼分析

`timescale  1ns/1ns

// Author        : EmbedFire
// Create Date   : 2019/04/01
// Module Name   : pcf8591_adda
// Project Name  : ad
// Target Devices: Altera EP4CE10F17C8N
// Tool Versions : Quartus 13.0
// Description   : AD電壓測量模塊
// 
// Revision      : V1.0
// Additional Comments:
// module  pcf8591_ad
(input   wire            sys_clk     ,   //輸入系統時鐘,50MHzinput   wire            sys_rst_n   ,   //輸入復位信號,低電平有效input   wire            i2c_end     ,   //i2c設備一次讀/寫操作完成input   wire    [7:0]   rd_data     ,   //輸出i2c設備讀取數據output  reg             rd_en       ,   //輸入i2c設備讀使能信號output  reg             i2c_start   ,   //輸入i2c設備觸發信號output  reg     [15:0]  byte_addr   ,   //輸入i2c設備字節地址output  wire    [15:0]  adc_data1    ,     //adc1數據 output  wire    [15:0]  adc_data2          //adc2數據
);//************************************************************************//
//******************** Parameter and Internal Signal *********************//
//************************************************************************//
//parameter     define
parameter   CTRL_DATA1   =   8'b0100_0001;   //AD/DA控制字
parameter   CTRL_DATA2   =   8'b0100_0010;   //AD/DA控制字
parameter   CNT_WAIT_MAX=   18'd6_9999  ;   //采樣間隔計數最大值
parameter   IDLE        =   3'b001,AD_START1    =   3'b010,AD_CMD1      =   3'b100,WAIT         =   3'b101,AD_START2    =   3'b110,AD_CMD2      =   3'b111;//wire  define
wire    [31:0]  data_reg1/* synthesis keep */;   //數碼管待顯示數據緩存
wire    [31:0]  data_reg2/* synthesis keep */;   //數碼管待顯示數據緩存
//reg   define
reg     [17:0]  cnt_wait;   //采樣間隔計數器
reg     [4:0]   state   ;   //狀態機狀態變量
reg     [7:0]   ad_data1 ;   //AD數據
reg     [7:0]   ad_data2 ;   //AD數據wire [23:0] data_temp;
wire [23:0] data_temp1;wire [23:0] data_temp2;
wire [23:0] data_temp3;wire    [23:0]  po_data1    ; 
wire    [23:0]  po_data2    ; 
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//cnt_wait:采樣間隔計數器
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_wait    <=  18'd0;else    if(state == IDLE || state == WAIT )if(cnt_wait == CNT_WAIT_MAX)cnt_wait    <=  18'd0;elsecnt_wait    <=  cnt_wait + 18'd1;elsecnt_wait    <=  18'd0;//state:狀態機狀態變量
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)beginstate   <=  IDLE;byte_addr   <=  16'b0;endelsecase(state)IDLE:beginbyte_addr   <=  16'b0;if(cnt_wait == CNT_WAIT_MAX)state   <=  AD_START1;elsestate   <=  IDLE;endAD_START1:beginstate   <=  AD_CMD1;byte_addr   <=  CTRL_DATA1;endAD_CMD1:if(i2c_end == 1'b1)state   <=  WAIT;elsestate   <=  AD_CMD1;WAIT:beginif(cnt_wait == CNT_WAIT_MAX)beginstate   <=  AD_START2;endelsestate   <=  WAIT;endAD_START2:beginstate   <=  AD_CMD2;byte_addr   <=  CTRL_DATA2;endAD_CMD2:beginif(i2c_end == 1'b1)state   <=  IDLE;elsestate   <=  AD_CMD2;enddefault:state   <=  IDLE;endcase//i2c_start:輸入i2c設備觸發信號
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)i2c_start   <=  1'b0;else    if(state == AD_START1 || state == AD_START2)i2c_start   <=  1'b1;elsei2c_start   <=  1'b0;//rd_en:輸入i2c設備讀使能信號
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rd_en   <=  1'b0;else    if(state == AD_CMD1 || state == AD_CMD2)rd_en   <=  1'b1;elserd_en   <=  1'b0;byte_addr:輸入i2c設備字節地址
//always@(posedge sys_clk or negedge sys_rst_n)
//    if(sys_rst_n == 1'b0)
//        byte_addr   <=  16'b0;
//    else
//        byte_addr   <=  CTRL_DATA;//ad_data:AD數據
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ad_data1 <=  8'b0;else    if((state == AD_CMD1) && (i2c_end == 1'b1)) //(state == AD_CMD) && (i2c_end == 1'b1))ad_data1 <=  rd_data;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ad_data2 <=  8'b0;else    if((state == AD_CMD2) && (i2c_end == 1'b1)) //(state == AD_CMD) && (i2c_end == 1'b1))ad_data2 <=  rd_data;//MQ-2:ppm = pow(11.5428 * 35.904 * Vrl/(25.5-5.1* Vrl),(1/0.6549));	
//(1/0.6549)=1.53  
// 11.5428 * 35.904 * Vrl/(25.5-5.1* Vrl)=(414*vrl)/(25.5-5.1* Vrl)
// 
//data_reg:數碼管待顯示數據緩存assign  data_reg1 = ((ad_data1 * 3300) >> 4'd8);
assign  data_reg2 = ((ad_data2 * 3300) >> 4'd8);assign  data_temp= (414*data_reg1);
assign  data_temp1= 25500-(5*data_reg1);
assign  data_temp2= (414*data_reg2);
assign  data_temp3= 25500-(5*data_reg2);
//po_data:數碼管待顯示數據
assign  po_data1 = data_temp2/data_temp3;
//轉換后的煙霧濃度0-150
assign  po_data2 = data_temp/data_temp1;assign  adc_data1 = po_data1[15:0];
assign  adc_data2 = po_data2[15:0];
endmodule

我這是采集兩個通道的adc,對控制字節進行了切換,使用狀態機。

在這里插入圖片描述
邏輯分析儀讀取的正常時序。
該說不說Quartus的邏輯分析儀使用感差于vivado。代碼兩個平臺是通用的

總結

視頻演示

FPGA環境監測火災監測家居監測(溫濕度模塊、煙霧模塊、PM2.5模塊等等)藍牙通信

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904678.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904678.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904678.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Python和C/C++之間共享std::vector<std::vector<int>>數據

在Python和C/C之間共享std::vector<std::vector>數據 在Python和C/C之間共享嵌套向量數據(std::vector<std::vector<int>>)可以通過幾種方法實現。以下是幾種常見的方法&#xff1a; 方法1: 使用Cython Cython是連接Python和C的很好選擇&#xff0c;它可以…

Linux NVIDIA 顯卡驅動安裝指南(適用于 RHEL/CentOS)

&#x1f4cc; 一、禁用 Nouveau 開源驅動 NVIDIA 閉源驅動與開源的 nouveau 驅動沖突&#xff0c;需先禁用&#xff1a; if [ ! -f /etc/modprobe.d/blacklist-nouveau.conf ]; thenecho -e "blacklist nouveau\noptions nouveau modeset0" | sudo tee /etc/modpr…

Python爬蟲實戰:獲取千庫網各類素材圖片,為設計師提供參考

一、引言 在當今設計領域,豐富的素材積累對設計師而言至關重要。千庫網作為一個素材資源豐富的平臺,擁有海量的各類素材圖片。然而,手動從該網站收集素材不僅耗時,而且效率低下。Python 作為一種功能強大的編程語言,具備豐富的庫和工具,可用于開發高效的爬蟲程序。通過 …

vue截圖-html2canvas

使用html2canvas進行截圖操作 在 Vue 中使用 ??html2canvas?? 將 HTML 元素&#xff08;如包含貝塞爾曲線的 Canvas/SVG&#xff09;轉換為圖片 下載html2canvas npm install html2canvas在頁面中使用&#xff0c;要截取哪個div的內容&#xff0c;先給這個div加一個ref標…

介紹Unity中的Dictionary

在 Unity&#xff08;C#&#xff09;中&#xff0c;Dictionary 是一個非常常用的數據結構&#xff0c;它提供 鍵值對&#xff08;Key-Value Pair&#xff09; 的存儲方式。類似于 Python 的 dict 或 JavaScript 的對象&#xff08;Object&#xff09;&#xff0c;但它是強類型的…

MySQL 常用函數(詳解)

目錄 一、數學函數1.1 四舍五入函數1.2 求絕對值函數二、日期時間函數2.1 獲取當前日期和時間三、字符串函數3.1 字符串拼接函數3.2 提取子字符串函數四、聚合函數4.1 計算平均值函數4.2 計算最大值函數五、轉換函數5.1 類型轉換函數六、總結MySQL 提供了豐富的內置函數,涵蓋了…

SOFA編譯-Ubuntu20.04-SOFA22.12

一、事前說明 單純的編譯sofa是很簡單的&#xff0c;但是想要同時編譯SofaPython3則比較難了&#xff0c;我編譯了v22.12分支&#xff0c;其他版本sofa的編譯也可以參考此篇教程&#xff0c;需注意的是&#xff1a; 1、確定SOFA需要的Python版本&#xff0c;sofa22.12需要的是…

靜態BFD配置

AR2配置 int g0/0/0 ip add 10.10.10.2 quit bfd quit bfd 1 bind peer-ip 10.10.10.1 source-ip 10.10.10.2 auto commit AR1配置 int g0/0/0 ip add 10.10.10.1 int g0/0/1 ip add 10.10.11.1 quit bfd quit bfd 1 bind peer-ip 10.0.12.2 source-ip 10.0.12.1 auto co…

關鍵字where

C# 中的 where 關鍵字主要用在泛型約束&#xff08;Generic Constraints&#xff09;中&#xff0c;目的是對泛型類型參數限制其必須滿足的條件&#xff0c;從而保證類型參數具備特定的能力或特性&#xff0c;增強類型安全和代碼可讀性。 約束寫法說明適用場景舉例C#版本要求w…

Arm核的Ubuntu系統上安裝Wireshark

Arm核的Ubuntu系統上安裝Wireshark 一、安裝wireshark 安裝命令&#xff1a; sudo apt-get install wireshark-qt 如下圖所示&#xff1a; 安裝過程彈出如下界面&#xff1a; 鼠標選擇Yes&#xff0c;點回車鍵確認 安裝完成。 二、打開wireshark 輸入命令行打開wireshark …

編專利或委托他人編專利屬于學術不端行為嗎?

原文鏈接&#xff1a;編專利或委托他人編專利屬于學術不端行為嗎&#xff1f; 自己編專利或委托他人編專利屬于學術不端嗎&#xff1f; 5月4日&#xff0c;一篇題為《針對性護理干預在子宮肌瘤圍手術期的情緒和生活質量臨床應用效果》的論文&#xff0c;受到網友的廣泛議論。…

Music AI Sandbox:打開你的創作新世界

AI 和音樂人的碰撞 其實&#xff0c;Google 早在 2016 年就啟動了一個叫 Magenta 的項目&#xff0c;目標是探索 AI 在音樂和藝術創作上的可能性。一路走來&#xff0c;他們和各種音樂人合作&#xff0c;終于在 2023 年整出了這個 Music AI Sandbox&#xff0c;并且通過 YouTub…

Java游戲服務器開發流水賬(2)開發中Maven的管理

Maven 是一款流行的 Java 項目管理工具&#xff0c;它基于項目對象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;的概念來管理項目的構建、依賴和文檔等。游戲服務器開發中也會使用. 項目構建 生命周期管理&#xff1a;Maven 定義了一套清晰的項目構建生…

枚舉 · 例8擴展-校門外的樹:hard

登錄—專業IT筆試面試備考平臺_牛客網 代碼區&#xff1a; #include<algorithm> #include<iostream> #include<vector>using namespace std; struct TREE{int left,right; }; bool compare(const TREE&a,const TREE& b ){if(a.left!b.left){return…

Windows Server 2025 安裝AMD顯卡驅動

運行顯卡驅動安裝程序&#xff0c;會提示出問題。但是此時資源已經解壓 來到驅動路徑 C:\AMD\AMD-Software-Installer\Packages\Drivers\Display\WT6A_INF 打開配置文件&#xff0c;把這兩行替換掉 %ATI% ATI.Mfg, NTamd64.10.0...16299, NTamd64.10.0, NTamd64.6.0, NTamd64.…

為什么 MySQL 用 B+ 樹作為數據的索引,以及在 InnoDB 中數據庫如何通過 B+ 樹索引來存儲數據以及查找數據

http://www.liuzk.com/410.html 索引是一種數據結構&#xff0c;用于幫助我們在大量數據中快速定位到我們想要查找的數據。 索引最形象的比喻就是圖書的目錄了。注意這里的大量&#xff0c;數據量大了索引才顯得有意義&#xff0c;如果我想要在 [1,2,3,4] 中找到 4 這個數據&am…

AWS VPC架構師指南:從零設計企業級云網絡隔離方案

一、VPC核心概念解析 1.1 核心組件 VPC&#xff1a;邏輯隔離的虛擬網絡&#xff0c;可自定義IPv4/IPv6地址范圍&#xff08;CIDR塊&#xff09; 子網&#xff08;Subnet&#xff09;&#xff1a; 公有子網&#xff1a;綁定Internet Gateway&#xff08;IGW&#xff09;&#…

HuggingFace與自然語言處理(從框架學習到經典項目實踐)[ 01 API操作 ]

本教程適用與第一次接觸huggingface與相應框架和對nlp任務感興趣的朋友&#xff0c;該欄目目前更新總結如下&#xff1a; ??Tokenizer??&#xff1a; 支持單句/雙句編碼&#xff0c;自動處理特殊符號和填充。 批量編碼提升效率&#xff0c;適合訓練數據預處理。Datasets?…

【LeetCode 42】接雨水(單調棧、DP、雙指針)

題面&#xff1a; 思路&#xff1a; 能接雨水的點&#xff0c;必然是比兩邊都低&#xff08;小&#xff09;的點。有兩種思路&#xff0c;一種是直接計算每個點的最大貢獻&#xff08;也就是每個點在縱向上最多能接多少水&#xff09;&#xff0c;另一種就是計算每個點在橫向上…

【嵌入式開發-USB】

嵌入式開發-USB ■ USB簡介 ■ USB簡介