最新免费av在线观看,亚洲综合一区成人在线,中文字幕精品无码一区二区三区,中文人妻av高清一区二区,中文字幕乱偷无码av先锋

非線性數(shù)字濾波器:用例和示例代碼

出處:維庫電子市場網(wǎng) 發(fā)布于:2024-03-14 16:34:20

  大多數(shù)編寫固件的嵌入式工程師都使用某種數(shù)字濾波器來清理來自各種輸入的數(shù)據(jù),例如 ADC、具有數(shù)字輸出的傳感器、其他處理器等。很多時候,使用的濾波器是移動平均值 (boxcar)、有限脈沖響應(yīng)(FIR) 或無限脈沖響應(yīng) (IIR) 濾波器架構(gòu)。這些濾波器是線性的,即輸出與輸入的幅度成線性比例。也就是說,如果將輸入流的幅度加倍,濾波器的輸出也會加倍(忽略任何偏移)。但有許多非線性濾波器 (NLF) 在嵌入式系統(tǒng)中非常有用,我敢打賭,你們中的許多人以前都使用過其中的一些。NLF 不一定以數(shù)學(xué)線性方式響應(yīng)其輸入。
  在某些情況下,F(xiàn)IR 和 IIR 可能會遇到脈沖噪聲和突發(fā)噪聲等問題,這些噪聲可能導(dǎo)致輸出以不可接受的方式做出反應(yīng)。非線性濾波器可以為數(shù)據(jù)流提供保護(hù)。根據(jù)您的應(yīng)用,它們可以用作獨(dú)立濾波器或用作 FIR、IIR 或 Boxcar 濾波器之前的預(yù)濾波器。
  本文中的示例假設(shè)是一維流式、有符號或無符號整數(shù)(包括 long 和 long long)。一些示例可能適用于浮動,但其他示例則不然。提到流式傳輸是因?yàn)榧僭O(shè)數(shù)據(jù)將連續(xù)來自源,并且這些過濾器將處理數(shù)據(jù)并將其實(shí)時一對一地發(fā)送出去。換句話說,我們不能只是扔掉壞數(shù)據(jù),我們需要發(fā)送一些值來替換輸入。不過,某些示例可能允許過采樣,在這種情況下,它可能會抽取數(shù)據(jù)。例如,傳感器可以以比所需速度快 10 倍的速率發(fā)送數(shù)據(jù),然后在將 1 個樣本發(fā)送到下一階段之前處理 10 個樣本。
  本討論的另一個假設(shè)是,我們正在設(shè)計需要實(shí)時處理傳入樣本的小型嵌入式系統(tǒng)。小是指我們不會有大量內(nèi)存或高 MIPS 等級。因此,我們將避免使用浮動。
  那么,讓我們看一下一些非線性濾波器,看看它們在哪里有用。
  邊界檢查過濾器
  您以前可能使用過此過濾器,但可能不認(rèn)為它是過濾器。這些過濾器通常也稱為邊界檢查、裁剪、范圍檢查、限制,甚至健全性檢查。我們指的不是指針檢查,而是對傳入數(shù)據(jù)或已被先前代碼修改的數(shù)據(jù)的數(shù)據(jù)檢查。
  這是一段簡單的示例代碼:
  #define Upper_Limit 1000
  #define Lower_Limit -1000
  int limit_check(int n)
  {
  if (n < Lower_Limit) n = Lower_Limit;
  else if (n > Upper_Limit) n = Upper_Limit;
  return n;
  }
  清單 1
  您可以看到,如果整數(shù) n 大于 1000,則返回 1000。如果小于 -1000,則返回 -1000。如果介于 1000 和 -1000(含)之間,則返回 n 的原始值。這將限制大的脈沖噪聲值通過您的系統(tǒng),即它會過濾數(shù)據(jù)。
  當(dāng)與 FIR、IIR 或時間濾波器(如下所述)等其他濾波器結(jié)合使用時,可以根據(jù)運(yùn)行的濾波器值縮放限制值。如果檢測到超出范圍的樣本,則基于此移動限制,邊界檢查器可以返回的過濾器輸出,而不是固定限制或可疑樣本。
  某些系統(tǒng)可能會提供邊界檢查的某些變體作為預(yù)定義的函數(shù)調(diào)用或宏。
  軟削波濾波器
  這與邊界檢查有關(guān),但它不僅僅是在達(dá)到一定水平后限制值,而是隨著輸入接近值或值而慢慢開始回退輸出值。這種類型的軟削波通常用于音頻信號處理應(yīng)用中。
  軟裁剪可以通過 sigmoid 函數(shù)或雙曲正切函數(shù)等函數(shù)來完成。這里的問題是這些方法需要強(qiáng)大的處理能力并且需要快速逼近方法。
  軟削波通常會扭曲輸入與輸出關(guān)系的很大一部分,因此它不適合用于大多數(shù)測量溫度、電路電壓、電流、光照水平或其他計量輸入等的傳感器輸入。因此,我們不會進(jìn)一步討論它,只是說如果你搜索“軟剪輯”,網(wǎng)上有很多信息。
  截斷均值濾波器
  截斷平均值或截尾平均值是一種方法,您獲取一組(至少 3 個)讀數(shù),丟棄和讀數(shù),然后對其余讀數(shù)進(jìn)行平均。這與您在某些奧運(yùn)會評審中看到的方法類似。對于嵌入式項目,它擅長消除脈沖噪聲。實(shí)現(xiàn)此過濾器的一種方法是排序,但在小型處理器的大多數(shù)應(yīng)用中,這可能在計算上很昂貴,因此對于大于 5 個樣本的任何樣本,我建議掃描列表以查找值和值。運(yùn)行掃描時,還計算所有條目的總數(shù)。,從總數(shù)中減去值和值,然后將該值除以條目數(shù)減 2。下面是在輸入值數(shù)組上執(zhí)行此類函數(shù)的示例。在代碼末尾有一個可選行,可以根據(jù)需要進(jìn)行舍入。
  #include
  int TruncatedMean(int inputArray[], unsigned int arraySize) {
  int i = 0;
  int min = INT_MAX;
  int max = 0;
  int total = 0;
  int mean = 0;
  for (i = 0; I < arraySize; i++) {
  if (inputArray[i] < min) min = inputArray[i];
  if (inputArray[i] > max) max = inputArray[i];
  total = total + inputArray[i];
  }
  //mean = (total - min - max) / (arraySize - 2);
  // The previous truncates down. To assist in rounding use the following line
  mean = (total - min - max + ((arraySize - 2)/2)) / (arraySize - 2);
  return mean ;
  }
  清單 2
  如果只有 3 個值,則在計算時間上重寫 C 代碼以消除循環(huán)可能會更有利,如本代碼示例中針對 3 個值的情況所示。
  int TruncatedMean_3(int a, int b, int c) {
  int mean = 0;
  if ((a<=b) && (a>=c) || ((a<=c) && (a>=b)) ) mean = a;
  else if ((b<=c) && (b>=a) || ((b<=a) && (b>=c)) ) mean = b;
  else mean = c;
  return mean;
  }
  清單 3
  請注意,如果需要,還可以使用至少 5 個樣本來實(shí)現(xiàn)截斷平均值,以去除多個值和一個值,這對于突發(fā)噪聲很有好處。另請注意,您可以將其實(shí)現(xiàn)為滑動函數(shù)或過采樣函數(shù)?;瑒雍瘮?shù)(如移動平均值)會滑出舊的輸入并插入新的輸入,然后再次執(zhí)行該函數(shù)。因此,每個輸入都會得到一個輸出?;蛘撸^采樣函數(shù)接受一個值數(shù)組,找到平均值,然后獲取一個新的新值數(shù)組來處理。因此,每個輸入樣本數(shù)組僅生成一個輸出,然后您需要在計算新平均值之前獲取一組新的輸入值。
  中值過濾
  中值濾波器查找一組樣本中的中間值。這對于各種類型的噪聲源可能有用。在大量樣本中,將對樣本數(shù)組進(jìn)行排序,然后讀取中間索引變量。例如,假設(shè)我們有一個包含 7 個樣本的數(shù)組(樣本[0 到 6]),我們對它們進(jìn)行排序,然后中位數(shù)是樣本[3]。請注意,由于執(zhí)行速度的原因,在小型嵌入式系統(tǒng)中排序可能會出現(xiàn)問題,因此應(yīng)明智地使用中值過濾。對于 3 個樣本,代碼與上面的代碼示例函數(shù)“TruncatedMean_3”(清單 3)相同。對于較大的組,清單 4 顯示了一段用于查找中位數(shù)的 C 代碼示例。在代碼底部,您將看到基于樣本數(shù)量奇數(shù)或偶數(shù)的中位數(shù)設(shè)置。這是必需的,因?yàn)榕紨?shù)個樣本的中位數(shù)被定義為中間兩個值的平均值。根據(jù)您的需要,您可能需要對此平均值進(jìn)行四舍五入。
  #define numSamples 6
  int sample[numSamples] = {5,4,3,3,1,0};
  int Median( int sample[], int n) {
  int i = 0;
  int j = 0;
  int temp = 0;
  int median = 0;
  // First sort the array of samples
  for (i = 0; i < n; ++i){
  for (j = i + 1; j < n; ++j){
  if (sample[i] > sample[j]){
  temp = sample[i];
  sample[i] = sample[j];
  sample[j] = temp;
  }
  }
  }
  // If numSamples is odd, take the middle number
  // If numSamples is even, average the middle two
  if ( (n & 1) == 0) {
  median = (sample[(n / 2) - 1] + sample[n / 2]) / 2; // Even
  }
  else median = sample[n / 2]; // Odd
  return(median);
  }
  清單 4
  正如截斷均值濾波器一樣,您可以將其實(shí)現(xiàn)為滑動函數(shù)或過采樣函數(shù)。
  多數(shù)過濾
  多數(shù)過濾器,也稱為模式過濾器,從一組出現(xiàn)次數(shù)多的樣本中提取值——多數(shù)投票。(這不應(yīng)與“多數(shù)元素”混淆,“多數(shù)元素”是出現(xiàn)次數(shù)超過樣本數(shù)/2 的值。)清單 5 顯示了 5 個樣本的多數(shù)過濾器。
  #define numSamples 5
  int Majority( int sample[], int n) {
  unsigned int count = 0;
  unsigned int oldcount = 0;
  int majoritysample = sample[0];
  int i = 0;
  int j = 0;
  for (i = 0; i < numSamples; i++) {
  count = 0;
  for (j = i; j < numSamples; j++) {
  if (sample[i] == sample[j]) count++;
  }
  if (count > oldcount) {
  majoritysample = sample[i];
  oldcount = count;
  }
  }
  return majoritysample;
  }
  清單 5
  該代碼使用兩個循環(huán),個循環(huán)抓取一個元素,第二個循環(huán)然后單步遍歷列表并計算有多少樣本與個循環(huán)索引的值匹配。第二個循環(huán)保留沿途找到的匹配計數(shù)及其樣本值,直到個循環(huán)遍歷整個數(shù)組。如果有多于一組具有相同計數(shù)的樣本值(即,{1, 2, 2, 0, 1},兩個 2 和兩個 1),則個找到的樣本值將作為多數(shù)返回。
  請注意,多數(shù)過濾器可能不適用于典型的嵌入數(shù)據(jù),因?yàn)閿?shù)字的動態(tài)范圍(來自傳感器)通常為 8、10、12 位或更大。如果接收到的樣本使用動態(tài)范圍的大部分,則來自一小組的樣本匹配的機(jī)會很小,除非所測量的信號非常穩(wěn)定。由于這種動態(tài)范圍問題,對多數(shù)濾波器進(jìn)行修改可能會有用。通過對二進(jìn)制符號進(jìn)行右移,過濾器可以匹配彼此接近的符號。例如,假設(shè)我們有數(shù)字(二進(jìn)制??)00100000、00100011、01000011、00100001。這些數(shù)字都不匹配,它們都是不同的。但是,如果我們將它們?nèi)坑乙?2 位,我們會得到 00001000、00100011、00010000、00001000。現(xiàn)在其中三個匹配。
  同樣,與截斷均值濾波器一樣,您可以將其實(shí)現(xiàn)為滑動函數(shù)或過采樣函數(shù)。
  時間過濾
  這是一組濾波器,它們對信號的反應(yīng)更多地基于時間而不是幅度。一分鐘后這一點(diǎn)就會變得更清楚。我們將這些不同的時間濾波器稱為模式 1 到模式 4,我們從模式 1 開始:
  模式 1的工作原理是將輸入樣本與起始過濾值(“filterout”)進(jìn)行比較,然后,如果樣本大于當(dāng)前過濾值,則當(dāng)前過濾值增加 1。同樣,如果樣本小于當(dāng)前過濾值,則當(dāng)前過濾值增加 1。過濾后的值,當(dāng)前過濾后的值減1。(增減數(shù)也可以是任意合理的固定值(如2、5、10……)。該過濾器的輸出為“filterout”??梢钥吹捷敵鰧⒙蛐盘栯娖揭苿?,因此變化與時間(樣本數(shù)量)比與樣本值更相關(guān)。
  現(xiàn)在,如果我們得到不需要的脈沖,無論樣本的幅度是多少,它都只能將輸出移動 1。這意味著突發(fā)噪聲和脈沖噪聲大大減輕。這種類型的濾波器非常適合相對于采樣率緩慢移動的信號。它可以很好地過濾 ADC 的溫度讀數(shù)等數(shù)據(jù),尤其是在電噪聲環(huán)境中。它在我從事的一個項目中表現(xiàn)非常好,該項目提取了在電力線上發(fā)送的非常緩慢的移動信號(非常嘈雜的環(huán)境,信號比線路電壓低約 -120 dB)。此外,它非常適合創(chuàng)建動態(tài)數(shù)字參考電平,例如交流信號的直流偏置電平或控制 PLL 的信號。清單 6 說明了使用模式 1 時間濾波器來平滑值“filterout”。
  #define IncDecValue 1
  int sample = 0;
  int filterout = 512; // Starting value
  call your “getsample” function here…
  if (sample > filterout) filterout = filterout + IncDecValue;
  else if (sample < filterout) filterout = filterout - IncDecValue;
  清單 6
  如果您要過濾的樣本是 int,您可能需要進(jìn)行檢查以確保過濾后的值不會上溢/下溢和回繞。如果您的樣本來自 10 或 12 位的傳感器或 ADC,則這不是問題,無需檢查。
  模式2與模式1相同,但是增加/減少數(shù)不是使用單個值,而是使用兩個或更多個值。一個示例是根據(jù)樣本與當(dāng)前過濾值(“過濾”)之間的差異使用不同的增加/減少值。如果它們很接近,我們使用±1,如果它們相距較遠(yuǎn),我們使用±10。這已成功用于加速 VCO 的時間濾波控制的啟動,該 VCO 用于匹配 GPS 信號的頻率。
  #define IncDecValueSmall 1
  #define IncDecValueBig 10
  #define BigDiff 100
  int sample = 0;
  int filterout = 100; // Starting value
  call your “getsample” function here…
  if (sample > filterout) {
  if ((sample - filterout) > BigDiff) filterout = filterout + IncDecValueBig;
  else filterout = filterout + IncDecValueSmall;
  }
  else if (sample < filterout) {
  if ((filterout - sample) > BigDiff) filterout = filterout - IncDecValueBig;
  else filterout = filterout - IncDecValueSmall;
  }
  清單 7
  增量/減量值還可以是由固件根據(jù)各種內(nèi)部因素或直接由用戶調(diào)整的變量。
  模式 3也與模式 1 非常相似,但如果樣本大于當(dāng)前濾波信號,則當(dāng)前濾波信號將增加當(dāng)前濾波信號與樣本之間差異的固定百分比,而不是增加 ±1。如果樣本小于當(dāng)前濾波信號,則當(dāng)前濾波信號減少一定百分比。讓我們看一個例子。假設(shè)我們從當(dāng)前過濾值(“filterout”)1000 開始,并使用 10% 的變化值。然后我們得到一個新的樣本 1500。這將導(dǎo)致 1500-100 或 50 增加 10%。所以當(dāng)前的過濾值現(xiàn)在是 1050。如果下一個樣本是 500,并且我們使用 -10%,我們會得到過濾后的新電流為 995(1050 減去 1050-500 的 10%)。
  #define IncPercent  10 // 10%
  #define DecPercent  10 // 10%
  int sample = 0;
  int filterout = 1000; // Starting value
  call your “getsample” function here…
  if (sample > filterout) {
  filterout = filterout + (((sample - filterout) * IncPercent) / 100);
  }
  else if (sample < filterout) {
  filterout = filterout - (((filterout - sample) * DecPercent) / 100);
  }
  清單 8
  需要注意的一件事是乘法中的溢出。進(jìn)行這些計算時您可能需要使用長整型。另請注意,將“IncPercent”和“DecPercent”設(shè)置為可通過內(nèi)??部算法或用戶干預(yù)進(jìn)行調(diào)整的變量可能很有用。
  要在缺乏 1 或 2 個周期劃分的系統(tǒng)上加速此代碼:不要將 IncPercent 和 DecPercent 縮放 100,而是將其縮放 128(10 % 約為 13)然后代碼中的“/100”將是“/128” ” 編譯器會將其優(yōu)化為移位操作。
  模式 4與模式 3 類似,只不過與模式 2 一樣,根據(jù)樣本和當(dāng)前輸出值(“過濾器”)之間的差異,可以發(fā)揮兩個或多個級別的作用。在清單 9 的代碼中,有兩個級別。
  #define IncPctBig  25 // 25%
  #define DecPctBig  25 // 25%
  #define IncPctSmall 10 // 10%
  #define DecPctSmall 10 // 10%
  int sample = 0;
  int filterout = 1000; // Stating value
  call your “getsample” function here…
  if (sample > filterout) {
  if ((sample - filterout) > BigDiff) {
  filterout = filterout + (((sample - filterout) * IncPctBig) / 100);
  }
  else filterout = filterout + (((sample - filterout) * IncPctSmall) / 100);
  }
  else if (sample < filterout) {
  if ((filterout - sample) > BigDiff){
  filterout = filterout - (((filterout - sample) * DecPctBig) / 100);
  }
  else filterout = filterout - (((filterout - sample) * DecPctSmall) / 100);
  }
  清單 9
  一個有趣的想法是,時間濾波器也可用于生成脈沖噪聲和突發(fā)噪聲等統(tǒng)計數(shù)據(jù)。他們可以計算一段時間內(nèi)發(fā)生的次數(shù)并計算脈沖/秒等統(tǒng)計數(shù)據(jù)。這可以通過添加另一個比“過濾”值大得多或小得多的樣本進(jìn)行比較來完成。
關(guān)鍵詞:數(shù)字濾波器

版權(quán)與免責(zé)聲明

凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://udpf.com.cn,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實(shí)其內(nèi)容的真實(shí)性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。

如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機(jī)號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務(wù):
賣家服務(wù):
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時間周一至周五
9:00-17:30

關(guān)注官方微信號,
第一時間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務(wù)的動力!意見一經(jīng)采納,將有感恩紅包奉上哦!