2017年9月4日 星期一

簡單的中值平均濾波器

有時寫ADC做平均時,可能因為訊號本身雜訊的影響,導致平均演算後出來的訊號不太滿意,因此會想一些其他平均的方式來試試看,效果也還可以,這邊就分享一下方式給大家中值!

假設ADC快速取樣16筆,當然取樣的頻率必須符合取樣定理如下連結http://www.ni.com/white-paper/2709/zht/,如這部分沒問題了就繼續了解中值平均濾波器,所謂中值,就是數值大小介於大跟小之間的數值,如何取得中值?要取得中值就必須要先將取樣的訊號做排序,排序之後再將比較大的跟比較小的數值踢掉,其餘的數值再進行加總做平均,排序的方式有很多種,可以是氣泡排序或者選擇排序亦或插入排序法等方式,不同排序的方式跟時間複雜度有關,資料結構或演算法課程當中會提到這些內容,需要的人自己可以去了解!

這邊將取樣後的數值存在buffer裡面,等存滿之後,用Selection sort的方式做排序,程式如下:

#define SWAP(x, y, t) ((t) = (x), (x) = (y), (y) = (t))

unsigned int ADC_Result[8] = {512, 510, 520, 513, 509, 505, 511, 512};

void main(void)
{
        unsigned char i = 0;
        unsigned int Sum = 0
        unsigned int ADC_Avg = 0;

        SelectionSort(ADC_Result, 8);

        for(i = 2; i < 6; i++)    // 去除最高最低的數值共四筆數值
       {
                Sum += ADC_Result[i];
       }
       ADC_Avg = Sum >> 2;   // 總和值/4做平均
        return;
}

void SelectionSort(unsigned int list[], unsigned char length)
{
        unsigned char i, j, min;
unsigned int temp;

for(i = 0; i < (length - 1); i++)
{
min = i;
for(j = i + 1; j < length; j++)
{
if(list[j] < list[min])
min = j;
}
SWAP(list[i], list[min], temp);
}
return;
}

上述方式建議適用在偏向直流訊號的ADC採樣,當中含有一些數位雜訊,可以透過這樣的方式做一些基礎的濾波,若用在交流訊號的取樣,會因為要增加取樣數,且取樣速度要夠快,否則會導致不符合取樣定理,有時會反效果,造成訊號混疊的情況發生!

STM32於IAR 9.3以後的版本將uart導向至printf

首先,請先參考如以下IAR提供的"在IAR Embedded Workbench中实现打印输出技術資料" https://www.iar.com/cn/knowledge/support/technical-notes/general/implementing-printf-ou...