2018年9月27日 星期四

STM32 SPL/HAL/LL Driver的差異

相信使用STM32的人都有一些疑問,就是為何有CMSIS/SPL/HAL/LL這麼多種Driver or Library, 其實都是以CMSIS為基礎建構上去,差異就是低階高階之間的分別而已,以下大致對這幾種Libraries做簡單的敘述!

CMSIS
雖然使用ARM Cortex系列的人可能都知道CMSIS, 以下是節錄ARM KEIL官網上的敘述:The Cortex Microcontroller Software Interface Standard (CMSIS) provides a software framework for embedded applications that run on Cortex-M based microcontrollers and Cortex-A5/A7/A9 based processors. CMSIS was started in 2008. It is a close cooperation with various silicon and software vendors.CMSIS enables consistent and simple software interfaces to the processor and the peripherals, simplifying software reuse, reducing the learning curve for microcontroller developers.


SPL
參考成大資工的http://wiki.csie.ncku.edu.tw/embedded/Lab19/stm32-prog.pdf這篇文章中有以下敘述:ST 提供的標準週邊硬體函式庫是完全符合 CMSIS(Cotex Microcontroller Software Interface Standard)的。CMSIS 是 ARM 公司針對 CortexM 系列處理器定義的一個與晶片製造 商無關的,獨立的硬體抽象層,基於符合CMSIS 的韌體函式庫開發程式,程式碼復用的好處是顯而易見的。只要其它晶片供應商的 CortexM 處理器也提供符合 CMSIS 的韌體函式庫,我們基於 STMicroelectronics的韌體函式庫開發的程式就很容易移植過去。

在STM32CubeMX這套軟體另外為STM32提供了HAL Driver(hardware abstraction layer)及LL Driver(low layer)來讓使用者可以更迅速的建立初始化的程式,HAL更提供了更高階的APIs可以呼叫與可攜性,脫離硬體的思維,讓韌體設計者可以更快速的開發應用程式,不必去煩惱如何設定站存器與如何設定硬體工作等繁雜的事情;而LL Driver則提供低階的APIs(register level),讓使用者可以設定硬體最佳化但可攜性較差,而且需要對MCU硬體架構更加了解!

在STM32CubeMX這套軟體當中,可以透過Project Settings選擇是要使用HAL or LL Driver,讓程式更有效率或彈性


2017年11月22日 星期三

FloatToString

/***************************************************************************//**
 * @brief Converts a float value to a character array with 3 digits of accuracy.
 *
 * @param *buf - returns the converterd value
 * @param val - value to be converted
 *
 * @return None.
*******************************************************************************/
void FloatToString(char * buf, double val)
{
    long  intPart  = 0;
    short fracPart = 0;
    short  charPos  = 0;
    char  localBuf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    short  i = sizeof(localBuf) - 1;

    intPart = (long)val;
    fracPart = (short)((val - intPart) * 1000 + 0.5);
    while(i > sizeof(localBuf) - 4)
    {
        localBuf[i] = (fracPart % 10) + 0x30;
        fracPart /= 10;
        i--;
    }
    localBuf[i] = '.';
    if(intPart == 0)
    {
        i --;
        localBuf[i] = '0';
    }
    while(intPart)
    {
        i --;
        localBuf[i] =(intPart % 10)  + 0x30;
        intPart /= 10;
    }
    for(charPos = i; charPos < sizeof(localBuf); charPos ++)
    {
        *buf = localBuf[charPos];
        buf ++;
    }
*buf = 0;
}

2017年9月27日 星期三

IAR Embedded Workbench建立STM32 ARM MCU專案

使用過幾種ARM的IDE開發工具後,覺得其實IAR是不錯的選擇,操作簡潔好用,寫MCU程式的人對於IDE的設定繁雜也是蠻苦惱的,今天要介紹如何設定IAR來完成STM32L1XX專案設定,順便幫自己做一下筆記,以免常常花很多時間在開發硬體上,一段時間之後要寫程式又忘了專案的設定!

1.安裝IAR Embedded Workbench(可以去官網下載)

2.開啟IAR Embedded Workbench


3.下載STM32L1xx standard peripherals library(STSW-STM32077), Libraries裡面有CMSIS及STM32L1xx_StdPeriph_Driver是撰寫STM32L1XX所需要的檔案,下載網址路徑如下:
http://www.st.com/en/embedded-software/stsw-stm32077.html


4.在C:\跟目錄底下建立專案資料夾IAR_STM32L1(資料夾名稱隨你喜歡即可),其實資料夾要放哪隨便你,本文說明為了方便直接放在C槽

5.在IAR_IAR_STM32L1資料夾中貼上STSW-STM32077 Libraries裡面的CMSIS及STM32L1xx_StdPeriph_Driver,並新增資料夾Inc及Src, Inc及Src分別用來放置使用者自行撰寫的*.c及*.h檔案

6.建立IAR專案及設定IAR-->Project-->Create New Project, 如以下選擇案OK後會跳出儲存專案*.ewp的視窗,將專案命名並存在IAR_STM32L1資料夾內


7.儲存STM32L1.ewp專案後如下圖,在左邊的STM32L1-Debug欄位案右鍵選擇Add Group...,
新增一些Group : (1)CMSIS (2)STM32L1xx_StdPeriph_Driver (3)User, 用來放置要撰寫的程式及要引入的Libraries,



8.到STSW-STM32077裡面的Project資料夾內的STM32L1xx_StdPeriph_Templates資料夾中,
複製以下(1)stm32l1xx_it.c (2)stm32l1xx_conf.h (3)system_stm32l1xx.c (4)stm32l1_it.h檔案到所建立的專案資料夾中


9.將一些需要用到的Libraries及相關STM32L1需要用到的檔案加入到對應的Group裡面

9.新增Group,命名為EWARM用來放置startup_stm32l1xx_md.s, startup_stm32l1xx_md.s可於所下載的STSW-STM32077檔案中搜尋startup_stm32l1xx_md.s並複製貼到EWARM,STM32L1資料夾,startup有分(1)startup_stm32l1xx_hd.s (2)startup_stm32l1xx_md.s (3)startup_stm32l1xx_mdp.s (4)startup_stm32l1xx_xl.s由於選擇的MCU是STM32L100R8T6A, 因此可以找一下stm32l1xx.h裡面有以下關於density的資訊:
/* #define STM32L1XX_MD  */   /*!< - Ultra Low Power Medium-density devices: STM32L151x6xx, STM32L151x8xx,
                                     STM32L151xBxx, STM32L152x6xx, STM32L152x8xx, STM32L152xBxx,
                                     STM32L151x6xxA, STM32L151x8xxA, STM32L151xBxxA, STM32L152x6xxA,
                                     STM32L152x8xxA and STM32L152xBxxA.
                                   - Ultra Low Power Medium-density Value Line devices: STM32L100x6xx,
                                     STM32L100x8xx and STM32L100xBxx.  */

/* #define STM32L1XX_MDP */   /*!< - Ultra Low Power Medium-density Plus devices: STM32L151xCxx, STM32L152xCxx and STM32L162xCxx 
                                   - Ultra Low Power Medium-density Plus Value Line devices: STM32L100xCxx  */

/* #define STM32L1XX_HD */     /*!< Ultra Low Power High-density devices: STM32L151xDxx, STM32L152xDxx and STM32L162xDxx */

/* #define STM32L1XX_XL */     /*!< Ultra Low Power XL-density devices: STM32L151xExx, STM32L152xExx and STM32L162xExx */



10.設定Options,在Workspace專案名稱案右鍵選擇Options,設定如下



11.按存檔會跳出視窗要你存*.eww

12.編譯看看是否有錯,通常有錯都是其中的步驟有設錯,尤其是步驟10的Additional include directories有缺路徑沒有選擇,無法找到邊譯器無法找到某個.h檔







2017年9月26日 星期二

STM32初始化程式流程(initialization code)

很多人在做設計MCU程式時,都會遇到一些需要寫底層Driver的問題,偏偏產品開發時程可能無法讓自己做許多的study來了解底層如何撰寫,本篇文章將簡單的介紹STM32如何利用STM32CubeMX軟體來開發底層的程式,讓STM32快速地動起來,加速開發時間!
步驟如下:
1.下載STM32CubeMX軟體
http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html

2.安裝STM32CubeMX軟體

3.安裝對應之STM32 MCU所需的Firmware package
Help --> Install New Libraries

4.在STM32CubeMX開啟畫面選擇New Project後,會跳出一個New Project視窗,接著在Part Number Search搜尋所使用的STM32 MCU,右下角會出現選擇的型號,連點兩下左鍵會進入所選取之MCU的畫面


5.利用左邊tab中的選項設定你的MCU,此時的設定必須依據你的板子電路來規劃,也可以直接點選MCU pin來設定

6.記得所有tab如Pinout/Clock Configurations/ Configurations都要設定



6.選擇Project-->Project Settings, 設定Project Name/Project Location/Toolchain Folder Location/Toolchain IDE等資訊



7.設定完後按存檔*.ioc

8.選擇Project-->Generate Code,程式就會產生在步驟6指定的Location,並會自動詢問是否要開啟專案如EWARM or MDK-ARM V5等專案來開啟程式

9.開始撰寫自己的應用程式



2017年9月11日 星期一

Frequency Domain Using Excel

通常硬體工程師在量測雜訊或者電壓漣波時,習慣性使用Time Domain來分析,卻忽略的一點,就是Time Domain看不到頻率的成分存在,這樣會很容易忽略掉一些訊號成分,導致找不出雜訊到底如何來的,由於之前在待在觸控IC設計廠的經驗多少有養成這些觀念,因此將此經驗分享出來!

FFT是一種可以將時域信號轉頻域分析的方法,快速傅立葉轉換(英語:Fast Fourier Transform, FFT),是計算序列的離散傅立葉轉換(DFT)或其逆轉換的一種演算法。傅立葉分析將訊號從原始域(通常是時間或空間)轉換到頻域的表示或者逆過來轉換。

至於太理論的東西我也不熟,這邊是要告訴你除了可以用示波器直接開啟Math做FFT量測訊號,並可以透過Frequency Domain Using Excel這份文件將Time Domain的資料成Frequency Domain,
在這之前我們要了解如下圖所示時域與頻域訊號的關係,Time Domain很重要的兩個資訊是Time及Amplitude(Magnitude),可以透過FFT轉成Frequency Domain,而Frequency Domain則可以看出頻帶及能量大小(dB)!

再來就需要參考San Francisco State University School of Engineering的Frequency Domain Using Excel by Larry Klingenberg April 2005,這份文件說明了如何將示波器的Timer Domain資料轉成Frequency Domain,如下圖可以看出FFT轉換過程,要注意的是假設你是波器可以直接printf,就可以直接將FFT的結果直接Printf成圖片存到隨身碟,就不太需要做以下的動作;若否,則需要先儲存Time Domain訊號成*.dat或者*.txt然後再透過以下方式轉換,整個動作對學習的人有個優點,會對FFT大概怎麼轉換的會比較有概念,縱使不懂數學原理,但對整體觀念會比較能建立!




通常一次轉換FFT後的結果會比較缺乏可靠度,建議是在EXCEL內將好幾次的結果利用作圖疊起來,這樣就會有比較準確的判定,假設一個工程師在分析雜訊的同時可以將Time Domain及Frequency Domain同時放在分析報告,這樣會對整個報告的內容更加有說服力!


2017年9月7日 星期四

如何簡單的分析MCU I/O是否損壞

曾經在一個產品的試產階段,發現IC Chip die(裸晶)做bonding(打線)完後回來的產品有一堆故障,因為當時是冬天,也不確定IC打線製程定沒問題,這時候想到IC的I/O port都有設計ESD protection diode,這時候電表的功用來了,直接用電表二極體檔位量測一下ESD Diode是否電壓約為0.65V左右,發現產品故障的,大部分diode量測電壓都有問題,架構圖如下:

後來詢問打線廠時,將IC封膠去除用顯微鏡觀察I/OPAD狀況發現有破裂,是因為IC的PAD鋁墊層過薄,導致超音波熔接Wire時把鋁墊層打裂,導致IC有故障的狀況,可能是打線的克數過重,導致破裂也有可能,這時觀察號電流也會增加,都可以當作參考數據!

如要正確性高一點的話,可以用半導體分析儀直接量測二極體的IV Curve,Diode從負電壓掃描到正電壓,自動會跑出來Current Curve,教科書上有很多類似的如圖,曾經用來分析I2C的CLK/DATA pin故障情況,由於單純用電表量沒辦法百分之百正確,畢竟有些I/O要死不死的就比較難用二極體電壓判定,用分析儀來跑IV Curve判定會比較正確,只不過一台很昂貴,並非一般廠商會購買的!

補充: 有網友表示這要看 ESD的設計了,很多IC會用更複雜的MOSFET 開關來做ESD保護電路,這時特性可能就不會完全與diode相同,雖然MOSFET到S/D和sub還是存在巨大的PN junction,但又多了控制!
在我的經驗來說之前用半導體分析儀時有時會分析不出來,去跟IC設計人員詢問,因為保護電路是用MOSFET設計的,如果遇到這種情況就會比較棘手,不過基本上若是一般MCU的I/O應該都是判定得出來的!

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採樣,當中含有一些數位雜訊,可以透過這樣的方式做一些基礎的濾波,若用在交流訊號的取樣,會因為要增加取樣數,且取樣速度要夠快,否則會導致不符合取樣定理,有時會反效果,造成訊號混疊的情況發生!

PADS CAM Directory過多路徑刪除方法

 可以在C:\MentorGraphics\9.5PADS\SDD_HOME\Programs底下的powerpcb.ini以文字編輯器開啟,搜尋[CAMDirExt],將底下的路徑刪除即可