發表文章

組合語言使用SDCC進行組譯

圖片
先前提過SDCC全稱Small Device C Compiler,為一套微處理器或微控制器的編譯工具,支援多種架構,例如MCS-51 (8051)、PIC16、STM8、Z80等。 https://danchouzhou.blogspot.com/2018/06/sdccn76e003-1t-8051.html https://github.com/danchouzhou/N76E003-SDCC https://github.com/danchouzhou/MS51BSP_SDCC 基本上如果我們用C語言撰寫8051的程式,從C語言(source code, .c檔)一直到燒錄進晶片的執行檔(binary)通常要經過以下幾個步驟: 1. 編譯(Compile): 透過編譯器將C語言編譯成 帶有標籤 組合語言 2. 組譯(Assemble): 透過組譯器將 帶有旗標符號 組合語言組譯成 帶有 標籤 機器碼(物件檔) 3. 鏈結(Link): 透過鏈結器將 一份或多份機器碼 合成為一份執行檔 由於一份有點規模且管理良好的微控制器韌體專案,也許會把各功能或者函式庫拆成獨立一份source code,編譯時會把每一份source code透過編譯器編成組合語言,再透過組譯器組譯成機器碼,並且會在各函式的機器碼加上一些標籤或符號。最後在鏈結時,鏈結器會把主程式、函式根據目標微控制器(target)合理的安排在程式記憶體裡面,當主程式呼叫函式時就會讓CPU去執行函式的機器碼,所以組譯完的機器碼要加上標籤或符號的目的就是讓鏈結器知道函式在哪裡。 綜合來說,如果從C語言到機器碼,編譯、組譯、鏈結這三個步驟其實是密不可分的,編譯器必須編譯出組譯器認得的標籤與符號的組合語言,組譯器要組譯出鏈結器認得的標籤與符號的機器碼,鏈結器要能認得這些標籤與符號根據target合成一份執行檔。因此如今的compiler已經會是"一套工具",包含編譯器、組譯器、鏈結器。 如果要徹底了解微控制器運作的方式,最好的方式還是試試一些簡單的組合語言程式。這幾天也因為教學目的開始研究看看怎麼使用SDCC帶有的組譯器。根據SDCC的手冊章節2.9 Components of SDCC, sdas8051與sdld分別是assembler與linker http...

無法被取代的指針型三用電表(二):LED順向偏壓量測篇

圖片
上回有提過,指針電表有許多功能是數位電表不容易做到的,如果您沒跟上可以先從這裡上車。 https://danchouzhou.blogspot.com/2020/05/analogueMultimeter.html 那麼今天先從最簡單的,測量LED的方法來介紹。其實介紹的這些好用的功能,最關鍵的地方在於指針電表上頭的LV與LI刻度和指針電表輸出的電壓夠高。 我們拿到一台指針電表第一件事情是要將指針歸零。可以用合適的工具去調整錶頭中央的旋鈕,讓指針在常態下指在0點。此外我們閱讀指針時要善用上面那排反射鏡,原則上要讓指針本體與反射鏡上反射出的指針影像重疊,才能確保閱讀時沒有視角誤差。 另外有些指針電表在不同方向(地球引力)甚至方位(地磁)會讓指針有些許偏差,都會影響量測的結果,使用時要注意這些問題。我們這台DE-965TRn採用的是日製雙懸吊機心,這些影響都算還好。 指針歸零以後,切到歐姆檔也要記得歸零。指針電表上的電壓、電流檔都是依靠待測物的電源來驅動表頭;歐姆檔則是靠電表裡面的電池,經過一些合適的電阻進行分壓、分流,送到探棒兩端去量測待測物。當探棒兩端接著的負載不同,表頭分到的電流也會不同,進而在刻度上指示待測物的電阻值。隨著使用或者放置的時間,電池的特性或多或少會不太一樣(可能是電壓或者內阻會改變),因此指針電表上都有設計一個歸零的旋鈕可以校正這個誤差。此外也可以順便校正探棒線電阻的誤差。 歸零的方式就是將探棒短路,旋轉歐姆檔歸零可變電阻,直到指針指在零歐姆的位置。這個可變電阻ㄧ般位於檔位旋鈕的右上方,會標示0Ω ADJ。手指盡量不要接觸到探棒探針的部分,因為手上的鹽分會使探針變得容易氧化。 一樣要記得讓指針本體與反射鏡上反射出的指針影像重疊,才能確保閱讀時沒有視角誤差。 接著我們就可以開始來量看看LED的順向偏壓。這台DE-965TRn有LED/電晶體測試的插槽,如果您手上的電表沒有這個插槽也沒關係,直接從探棒接出來意思是一樣的。不過要注意,我們一般拿到的都是日規的指針電表,從電表輸出的電源是與探棒標示的極性相反, 所以LED的陽極(P)要接黑棒、陰極(N)要接在紅棒 。 先拿一顆紅光LED插上去量看看。 我們可以閱讀刻度上的LV與LI得知當下輸出的電壓與電流,分別為1.85V、6.25mA。 再來我們...

新唐NuMaker-IoT-M487 HTTP POST連網實作

圖片
幾年前用過新唐的NuMaker Tomato做過一些專案的雛型,時間與能力有限的情況下用官方編好的Python,自己寫一些Python script做簡單的資料庫與I/O控制,還自己編了一個UVC (USB Video Class)執行檔,操作USB上連接的視訊鏡頭。 NuMaker Tomato是用新唐NCU970 ARM9的微處理器,效能很夠直接跑個Linux。今天要介紹的NuMaker-IoT-M487是ARM Cortex-M4微控制器,上面頂多跑個RTOS、MicroPython。新唐應該也是為了推廣,直接把port好的MicroPython放在官方的GitHub上:  https://github.com/OpenNuvoton/NuMicroPy 開發板上還包含Wi-Fi模組、乙太網路介面、音訊編解碼器、加速度計等,很適合拿來做物聯網相關的應用。 看起來這個專案大概是從2019年2月開始的,可能因為知名度不高用的人不多,目前使用還有很多問題。好比說中斷服務程式裡面放個print很容易會當機,已經發issue上去等他修。歡迎大家一起來用,發現問題發上去讓程式更穩定。 話說甚麼是MicroPython? 顧名思義就是微型Python,他是拿來給微控制器使用的Python。與標準的Python一樣,我們將編好的Python直譯器放入微控制器裡面執行,寫好Python script以後可以讓已經在微控制器裡面執行的Python直譯器直接執行我們要的功能。比較不同的地方是,由於MicroPython是給微控制器用的,因此刪減了很多標準Python有的功能與模組(函式庫),當然語法與邏輯還是與標準Python一致。另外在編MicroPython的時候,可以選擇要把哪些模組(函式庫)一起加入執行檔,由於微控制器的記憶體、效能相對有限,沒辦法把所有的模組都一起編進去,只能選擇一些必要的模組。這個動作有點像我們在Linux上使用Python,可以apt install一些我們需要的函式庫,只不過在這邊都要事先編好存入微控制器的程式記憶體當中。 最近剛好做了個小教案,要求是要用MicroPython配合資策會IDEAS Chain雲端平台。剛才說過以前用過Python寫過簡單的資料庫,當時只用了HTTP GET,但這次要用的IDEAS Chai...

無法被取代的指針型三用電表(一):前言

圖片
隨著電子電路、積體電路製造技術提升,數位電表已經廣泛在市場中出現,同時一機也不再是三種用途了。現今的數位電表可能還有真實有效值量測、電容、頻率、工作周期,甚至電感、資料紀錄等,儘管數位電表擁有這麼多先進的功能,我認為指針電表仍有他無法取代的特性。 先在這邊告訴大家哪些是指針電表能做到、數位電表做不到的事情,稍待解釋為甚麼。 1. 判斷MOSFET、BJT的極性(N channel, P channel或NPN, PNP)與腳位(G, D, S或E, C, B) 2. 測量稽納二極體的電壓 3. 測量發光二極體的順向導通電壓及電流 4. 判斷變壓器的好壞 前三項其實都歸功於指針電表歐姆檔輸出電壓與電流夠高, X1~X1000的檔位使用的是兩顆三號電池串聯成3V的電源,X10K的檔位則是由9V方形電池與兩顆串聯的三號電池所構成的12V電源,如此高的電壓足夠讓半導體高參雜的接面崩潰,因此能夠判斷BJT的腳位或者測量稽納二極體與發光二極體的電壓。另外,MOSFET 閘極的臨界電壓(Vth)也差不多要3至10伏特才能讓洩極與源極導通。然而數位電表歐姆檔開路電壓約只有2伏特。 第四項,由於數位電表歐姆檔不具備歸零功能,探棒線材本身的內阻、探針的氧化在測量線圈電阻極低的變壓器都是一種誤差,使用數位電表將難以判斷是變壓器線圈的內阻還是線材與探針的電阻。使用指針電表就可以透過歸零的功能補償誤差,而且指針些微的變化人眼都能夠分辨出來。 我很推薦得益DE-965TRn這一款指針電表,得益是一間台灣專門製造各種儀表的公司,產品包含數位電表、指針電表、溫溼度計、表頭、分流器、比流器等,並且有幫國際知名廠牌代工(如HIOKI, KING TONY等) 。DE-965TRn則是採用日本原裝進口TAUT BAND雙懸吊機心,阻尼、抗震能力、精準度、誤差均會比一般的產品來得好,值得一提的是它內建比流器,與其他的指針電表不同,他能夠測量AC電流。 我人生第一台指針電表是HA-380功能與這台電表相似,約莫用了七年因為電池槽、探棒插孔接觸不良等問題又再買一台新的HA-380,沒想到品質沒有上一台好兩三年後又換了一台。到了第三台更慘,不到一年就不想用了。最後發現得益這家電表廠商很可靠,於是多花了一點買DE-965TRn,果然是一分錢一分貨。探棒跟插座均有電鍍處理可以避免氧化,電...

[原創] 使用SDCC開發新唐N76E003 1T 8051

圖片
新唐科技2017年推出了一顆新的1T 8051 MCU,在一個TSSOP-20的封裝裡提供高達18PIN的I/O接腳,並且與STM8S003 pin to pin相容。內建1T 8051核心,具18KB Flash程式記憶體、1KB SRAM(256Byte + 768Byte XRAM),周邊包含6通道16-bit PWM、8通道12-bit ADC、SPI介面、I2C介面及兩組UART,小小一顆功能卻非常強大,可說是麻雀雖小,五臟俱全。 N76E003開發板 : http://goods.ruten.com.tw/item/show?21819007454427 另外傳統的8051指令週期為12T,也就是一條指令至少要12個時脈來完成。大部分的指令都可以在1到2個指令週期完成,而除法這種較複雜的指令則要4個指令週期來完成。所以傳統的8051每條指令所需的時脈會是12的倍數。 然後新唐的1T 8051意思就是指令週期為1T,一條指令至少要1個時脈來完成,而每個指令所需的時脈都會是1的倍數,好處是程式的執行速度可能比較快,缺點是如果在優化timming較不容易計算每條指令所花費的時間。 http://www.keil.com/dd/docs/datashts/intel/ism51.pdf 不過一點較可惜的部分新唐官方提供的BSP僅支援keil c51和IAR,以大家拿手的keil來說免費評估版本code size具2KB限制,除非花錢去買正版軟體不然18KB的flash也只能看著流口水,且礙於code size限制這麼多功能可能也發揮不起來,於是著手研究看看如何使用sdcc進行開發。 一、SDCC SDCC: Small Device C Compiler,一套開源的微控制器C語言編譯器,起初僅針對MCS-51系列的微控制器所開發,現在除了MCS-51以外已經支援Z80、STM8、PIC14、PIC16等常見的微控制器。 我們可以從官網下載並安裝最新版本的SDCC: http://sdcc.sourceforge.net/snap.php#Windows 安裝結束後可以勾選add to system path以便我們能夠直接在cmd或ps中直接使用sdcc。完畢後要重新開機才會套用環境變數。 二、使用SDCC別於Keil C51的部...

NUC200 NUC220接收&處理GPS之資料

圖片
透過MCU的UART接收GPS的資料,然後透過字串處理解讀NMEA GPRMC #include "stdlib.h" #include "stdio.h" #include "string.h" #include "NUC200Series.h" #define PLL_CLOCK 48000000 char gps_data[512] = { 0 }; int flag = 0; struct { char _gprmc[10]; char utc_time[10]; char status[10]; char latitude_value[10]; char latitude[10]; char longtitude_value[10]; char longtitude[10]; char speed[10]; char azimuth_angle[10]; char utc_date[10]; char declination_value[10]; char declination[10]; char check_sum[10]; } gprmc = { 0 }; void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable Internal RC 22.1184MHz clock */ CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);...

Nuvoton NUC200 NUC220使用FIFO觸發中斷及接收超時中斷處理UART接收的資料

圖片
NUC200NUC220_BSP當中所提供之UART_Read(uart, pu8RxBuf, u32ReadBytes)函式屬於輪詢方式,接收緩衝器為空時這個函式就會在原地等待,屆時CPU沒辦法做其他事情。本篇介紹使用中斷的方式處理UART接收到的資料。 在這邊我們使用到UART兩個中斷源,分別是"接收資料可用中斷"及"接收超時中斷"。 接收資料可用中斷的發生條件為,當接收到的位元組大於等於所設定之閥值發生,而閥值可由UART->FCR[7:4] RFITL設定1Byte、4Bytes、8Bytes、14Bytes、30Bytes、46Bytes及62Bytes。在這邊要注意,NUC220的UART0才有提供到64Bytes的接收緩衝區,UART1及UART2只提供了16Bytes的接收緩衝區,當閥值設定超過14Bytes則以14Bytes為準。清除接收資料可用中斷的中斷旗標只要讀取RBR即可。 接收超時中斷的發生條件為,當超時計數器的值大於等於超時比較器(UART->TOR[7:0] TOIC)的值發生接收超時中斷。超時計數器在每一個Byte進來時會歸零並且開始計時,而計數器的時脈等於Baudrate,所以建議將TOIC設定在40~255之間,以避免在下一個Byte進來以前就發生了超時中斷。若要清除接收超時中斷的中斷旗標同樣讀取RBR即可。 那麼為甚麼我們要使用這兩種中斷? 首先我們將緩衝區設定在30Bytes會發生中斷,若進來資料是一長串的話可以每30Bytes收一次以降低CPU的負擔。問題是如果進來的資料不剛好整除30個Byte怎麼辦? 這些不到30Bytes的資料就透過超時中斷來處理。假設進來的資料剛好是30個Byte,那很好就剛好把30個Byte收完以後就結束了,如果大於30個Byte則會在超時中斷發生時將剩下的幾個Byte讀取完畢。 下面的程式透過接收中斷的方式將RX接收到的資料傳回TX,所以TX應傳出RX所接收到的資料。由Arduino IDE的Serial Monitor來輸入資料及監測程式運作的狀況。記得UART0的中斷服務程式要叫做"UART02_IRQHandler"。 1. 首先輸入一個不到30Bytes的字串會發生超時中斷,並將這些字元存入軟體b...

煤油暖爐怎麼挑選?

圖片
寒冬將至,一直很嚮往放一台煤油暖爐在家。早在去年冬天逛網拍的時候就發現煤油暖爐這種東西,起初還以為是近幾年出來的新產品,去查才發現在日本和一些高緯度地區早在幾十年前就開始使用。由於煤油暖爐是透過燃燒產生熱能,其熱量非常大少說是2.5kW以上,這是一般電暖爐沒辦法達到的。近來看蠟筆小新的時候無意間在裡面看到煤油暖爐,又勾起我對煤油暖爐的那份感覺(燃燒的快感?),於是下定決心要買一台放在家裏。露天拍賣查了一下,大部分煤油暖爐都是日本平行輸入的,畢竟台灣對煤油暖爐的需求也不是很高,重點來了,品牌、型式、型號少說20種,到底該怎麼挑選? 花了兩天做了一點功課供大家參考。 煤油暖爐相較於電暖爐的優點與缺點 1. 煤油暖爐燃燒煤油是最直接產生熱的方法,不像電暖爐從發電廠先將燃料燃燒之後再燒水推動渦輪發電機。缺點就是由於是燃燒煤油,使用時必須注意空氣對流避免燃燒不完全造成一氧化碳中毒。 2. 即使是需要插電的款式耗電量也遠比電暖爐低,增加了用電安全。缺點是原廠不建議在睡眠期間開著,由於輸出的熱量相當高,如果在出風口有易燃物(如紙張、塑膠袋)有可能造成危險。 3. 發熱量夠,可以且須要開窗使用,不會讓室內悶悶的 但以上兩個缺點不必太過擔心,使用的時候只要窗戶留些空隙或定時打開窗戶讓新鮮的空氣進入室內,基本上不用擔心燃燒不完全的問題。建議的使用方式是在睡前將煤油暖爐開著暖房,到了舒適的溫度以後即可關閉。另外有些人會擔心味道的問題,以我挑選的Dainichi FW-3216NE使用經驗,只會在點火和熄火的時候會有煤油味,正常燃燒的情況下吹出來的風就跟一般電暖爐一樣乾淨舒爽。 一、型式 1. 傳統對流型煤油暖爐 基本上就是一個圓筒狀的燃燒室,並在周遭配有防燙網,部分機種頂部可以放茶壺順便燒水、加濕空氣。這種的好處是不用插電可以到處放不受電源牽制,部分機種安裝電池是為了在啟動時電子點火用,不用裝電池的則是要自己用點火槍點燃燈芯。缺點就是煤油的味道可能比較重、燈芯損壞了要更換。這種體積較大、熱量也較高,比較適合在大坪數的空間中使用。 TOYOTOMI KS-67H 2. 紅外線反射式煤油暖爐 紅外線反射式煤油暖爐是讓煤油在下方燃燒並加熱上面的金屬產生紅外線,透過鏡面將紅外線反射出來,同時會有對流的效果,也會有台灣常見的鹵素電暖器輻射熱的效果但暖房能力恐...

關於新唐科技NuMicro ISP的介紹和使用方式

圖片
2025.03.07 更新 新貼出了一篇文章,內容、操作步驟比較完整,敬請參考。 不用燒錄器也能更新韌體 - In-System Programming (ISP) 、 NuMicro ISP Programming Tool 目前新唐科技主流的幾款微控制器均支援ICP、ISP及IAP三種燒錄方式,本文主要介紹NuMicro ISP的使用方式並實作。在這之前讓我們先來了解以上三種燒錄方式的差異,但不同的微控制器設計製造商可能對這些名詞有不同的定義。 ICP全稱為"In circuit programming"中文為"在電路上燒錄程式",意思上就是該單晶片可以在工作電壓之下直接進行燒錄。早期的單晶片的程式記憶體為EPROM,更新程式前必須從電路中拔下來以紫外線清洗機將舊有的程式給清除乾淨,再插上燒錄器燒上新的程式。新一點的單晶片(如89C51)內部的程式記憶體為EEPROM,抹除及燒錄需使用12V高壓來進行,雖然可透過電氣的方式抹除舊有的程式並燒錄,但工作電壓5V依然需將其從電路中拔下來。這兩種燒錄方式在開發上都會造成不方便。而近期所出的單晶片則使用Flash Memory作為程式記憶體,能夠在工作電壓下直接進行讀寫、抹除故稱為"In circuit programming"。 ISP全稱為"In system programming"中文為"在系統上燒錄程式",此種燒錄方式是透過微控制器內部的程式對該程式以外的記憶體進行更新,通常會將一段更新用的程式碼放在程式記憶體的開頭或者特定的區塊,我們稱作為Bootloader。以新唐的微控制器舉例,記憶體主要分為LDROM和APROM,LDROM容量不大通常只有4KB,只擺一支小程式讀取UART、USB或其他通訊界面傳進來的的資料,並將這些資料存入APROM以達到更新的目的。所以這種燒錄方式只要在第一次透過燒錄器將Bootloader存入LDROM,往後使用者若要更新程式只要透過UART或者USB即可,無須再使用燒錄器。這個做法就跟Arduino UNO一樣透過Bootloader從UART進行軟體的更新。 #題外話 講到在這邊跟大家分享,我一位教微控制器實習的大學老師,自己設計了一塊課堂要使用的8051開發...