111年8月更新

個人

前言

距離上次更新已經過了一個月又多一點了,這段期間除了在處理學校的專題還有研究之外,對於之前開的坑也在這段時間,前進了「一點」。

😿 對,真的是一點…

黑貓框架

minexo79/CatFramework_For_MSP430FR59xx - GitHub

這次的更新,包含了下面幾個改進:

程式架構

架構方面,採用「模組化」的方式,在最上層的Header引入其他功能的Header檔案,在往後也方便維護。
頂層架構

另外,我通常寫MSP430系列的MCU都是會「直接操作暫存器」,所以常常都會使用到C語言的邏輯運算符號 (And, Or, Xor, Not…等等)。
為了簡化並在往後能好理解每個程式碼的運作過程,我將操作暫存器的程式碼使用define形式定義,後續就可以用自己定義的define來撰寫程式。

1
2
3
4
5
6
7
8
9
// SFR Data Type
#define _Reg8 volatile unsigned char
#define _Reg16 volatile unsigned

// Bit Operation
#define AssignBit(x, y) x = y
#define SetBit(x, y) x |= y
#define ResetBit(x, y) x &= ~y
#define ToggleBit(x, y) x ^= y

模組撰寫

對於每個模組,我參考了Arduino Core和其他幾個HAL函式庫的寫法,在Header檔案先定義好需要用到的暫存器陣列,以及會給使用者做的函式。
arduino/ArduinoCore-avr - GitHub
這裡我用到了extern保留字,它的作用是讓編譯器就自動去尋找其他程式嗎是否有該函式/變數,並且連結起來。
讓我能在後續維護中,只需更改其他檔案中,有一樣名稱的函式/暫存器陣列,而不必整個檔案都需要動到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Register
extern _Reg8 * uartSelPort0 [];
extern _Reg8 * uartSelPort1 [];
extern _Reg16 * uartControlReg [];
// ...

/*
* ======================================
*/

// Function
extern void Uart_ParamInit (uartParam *);
extern void Uart_Init (uartParam *);

extern void Uart_Write (uartParam *, char);
extern void Uart_WriteStr (uartParam *, char *, char);
extern void Uart_WriteStrln (uartParam *, char *, char);

UART

目前僅實現了下面的功能:

  • 初始化設定
  • 字元/字串非中斷方式傳輸

其中傳輸的部分,我先寫好UART傳輸一個字元的函式Uart_Write,在之後擴充的時候,就可以事先呼叫寫好的傳輸函式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 傳送一個字元
void Uart_Write (uartParam * ptr, char word)
{
// wait previous buffer was sent.
while((*uartInterFlagReg[ptr->unit] & UCTXIFG) != UCTXIFG);
// send buffer
*uartWriteReg[ptr->unit] = word;
}
// 傳送一組字串
void Uart_WriteStr (uartParam * ptr, char * str, char length)
{
if(ptr->interruptMode == NONIE)
{
char _len = 0;
// String was sent?
while(_len < length)
{
Uart_Write(ptr, str[_len++]); // 在這裡就可以直接呼叫Uart_Write函式,取代掉上面兩行。
}
}
}

結果如下:
Serial Output

其他

其他有實現的程式碼就放在這邊介紹:

看門狗

  • WatchDog_Shutdown():關閉看門狗計時,防止重新開機。

GPIO

  • GPIO_Init():初始化所有GPIO腳位的狀態,並且設定32.768K震盪器的腳位模式。
    1
    2
    3
    AssignBit(PJOUT,   0x00);
    AssignBit(PJSEL0, (BIT4 | BIT5)); // For XT1
    AssignBit(PJDIR, 0xFFFF);

SystemClock

  • SystemClock_Init(MHZ):設定系統時鐘,並且檢查震盪器用作是否正常。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Enable LFXT1
    ResetBit(CSCTL4, LFXTOFF);

    do
    {
    ResetBit(CSCTL5, LFXTOFFG); // Clear XT1 fault flag
    ResetBit(SFRIFG1, OFIFG);
    }
    while (SFRIFG1&OFIFG); // Test oscillator fault flag

常用的功能

  • stoi():字串轉整數。
  • sort(array, arraylength):使用插入排序法,由小到大重新排列。

CC1350 與 Ti RTOS

緣起

大二的時候,因為教授的推薦,讓我接觸並嘗試轉寫了Ti的SimpleLink無線射頻系列MCU,並且應用在大專院校計畫身上。
這系列的MCU大部分都使用Arm Cortex-M的核心(M0、M3、M4F),有寫Arm的應該不太陌生。
CC1350 Diagram
但當時我是第一次嘗試這類的開發,所以碰到很多卡關的地方。尤其是在於,Ti官方在Example有分成No-RTOS與Ti-RTOS,所以兩者的範例多寡有很大的不同。
不同的範例就會有用Ti-RTOS與No-RTOS實現的差別

好在Ti官方的Example裡面的程式碼不太難懂,一方面是SDK的功勞,很多功能都可以用HAL方式實現。加上程式碼不難移植,所以減少很多複雜的功夫。
就這樣子邊看前人的經驗,邊參照官方的資源文件,很順利的把我的大專計畫結束掉了。
講真的,光要啃Example的程式碼,就能知道學這些的程式基礎一定要很夠www。

奉勸各位學弟,大一的程式設計一定要學好。

題外話:自從加入實驗室後,因為太常說到Ti的產品,好幾次都被社群朋友說是Ti推廣大使XD

後續

由於我在做大專的時候,由於焊接好的樣品不多,導致留下了很多洗好沒焊接的電路板。
就這樣過了一年,到這個暑假,突然某天不知哪來的動力,隨手抓了一把沒焊好還是全新的電路板,還有當初買的一些料。
加上從壞掉的板子拆下來的晶片,就髓手焊了3塊可以運作的小系統版。
後來我想說,正好之前買了一塊包有藍牙 + Sub GHz私有網路的CC1350開發版,那不如研究一下之前沒研究過的FreeRTOS,並且做點小玩具。
CC1350 開發板

購買到開發板之後,我先去Github翻了一圈,發現到有人放出可以跑FreeRTOS的開源專案。這讓我又激起想讓它動起來的動力了。
cc1310_freertos_radio - GitHub

就正好興高采烈地去下載好FreeRTOS,並且嘗試要放到Project的時候…悲劇發生了。

我照之前的經驗,翻了官方的Example,看看有沒有關於FreeRTOS的範例可以參考,不出意外的是:「沒有」。
而後我去翻了官方的文件,想說文件內有講到如何安裝FreeRTOS,那應該是可以完整被官方支援才對。直到我看到了這段話:

Note: FreeRTOS is not supported for the CC13xx or CC26xx device families, since these devices use TI-RTOS in ROM.

看到了這段話之後,這是我當下的心情:
恩恩恩阿阿阿阿阿~~~

後來想想,可能是因為:這系列的晶片是有包含M3/M4F與M0的核心,其中M0已經被Ti官方固化成只能操作RF單元,導致FreeRTOS無法完美相容。,導致CC13xx與CC26xx沒有被官方正式支援FreeRTOS。

那既然不正式支援FreeRTOS,那倒是可以先學Ti官方的RTOS。

在這之前,大專的時候有簡單看過Ti RTOS的Example,但是當時我是使用No RTOS,也就是Bare-Metal的方式做開發,所以並未針對這方面下去研究。
於是為了讓自己能快速深入Ti的RTOS到底在幹嘛,我參考了兩份網路資源,並做成筆記供未來複習。
而其中一份也順便讓我知道原來SimpleLink系列的MCU可以讓主單元與RF單元進入休眠模式,讓這U可以到如此低的功耗:

  1. Ti SimpleLink Academy (筆記大部分的Code都是來自於這份)
  2. CC1310 軟體速成 (與其說這是教學,不如說這叫做產品發布會)

就這樣看了這兩個教學,我也拿了之前買的SHT40感測器,接上開發板,嘗試做了一個簡單的Demo,之後做完整一點再來寫一篇好了。

C# MAUI

這個暑假,也因為學校的研究關係,學了一個新的跨平台軟體框架 - MAUI。
這個框架是由微軟開發的,在此之前微軟有推出過叫做Xamarin的跨平台軟體框架。
據微軟前段時間開的發布會兼佈道大會所述:MAUI會成為Xamarin的進化版,與此同時也實現了「一種Code」即在不同的平台上執行的夢想。

抱著這樣的疑慮還有好奇,我跟著看了這位國外Youtuber的4HR教學,一步步地做起了第一個APP。
說真的,也只是照著這份教學來去小改一點東西:包括把資料的來源改成自己寫的,還有針對某些部分去做了點UI上的美化。
MAUI APP

抱怨一下,原本我在看4HR的教學的時候,影片上示範的Code是這樣:

1
2
3
4
5
[ICommand]
public async Task foo()
{
// do smth...
}

但當我在我的電腦運行的時候,我發現Compiler不知道什麼是ICommand,導致一直出錯。
找過相關資料後,才發現到是我的MVVM Toolkit是比較新的版本,所以一些Genreator的名字有被改掉得情況,比如下面的Code:

1
2
3
4
5
// Before:
[ICommand]

// Now:
[RelayCommand]

所以我說,微軟你到底在衝三小。

RISV伴學松

伴學松
暑假快完了,這個活動也快結束了。

坦白說,經過這次的活動,比其學到什麼是CPU,怎麼做CPU之外,比較重要的是如何一起陪伴,一起學習,還有如何享受這個過程。
過程中,我發現到有些人會開著遊戲邊參加活動,想說這樣就算了,比較誇張的是有人連需要使用的軟體都沒有安裝。
原本想著怎麼讓他們能更有參與感,就這樣到了8月底,在某次跟其他學友聊天的時候有談到這件事。他們安慰我,但也跟我說了一句話:

你要做的不應該是這些,你要享受的是活動的過程,再這樣只會搞得更累。

坦白說我還是不懂這句話的含意,雖然挑戰者一次比一次少,還發生了上述的狀況,讓我漸漸不去專注於原本想學的東西。
後來想著,其實我該做的事情已經做到了,就是找一群對這主題有興趣的人共同學習。也許我作為組織者,該做的應該就是這些,剩下的就給他們各自飛,才是對的做法。

題外話:對RISCV有興趣的可以參照這一份共筆開始從頭學起,希望可以幫到想學得人。

實習

這個暑假過後,我就不再是大三,而是該要面對殘酷社會的大四。
關於實習,我前後找了5~6間公司,好幾間都是回我只收正職。其中一間願意讓我過去與他們面談。
但面談時我出了差錯,以及太過於緊張,導致主管的問題我很多都是回答錯誤的。就這樣子失去了這個機會。
恩恩恩阿阿阿阿阿~~~

之後我也在嘗試尋找公司,但時間就這樣過去,來到了我之前所設好的底線。
無奈之下,就轉回學校有簽約的公司,大多數都是沒錢的,雖然失望但也只能挑這些了。
因為我的習慣會先去問,所以就這樣問了其中一間公司,還有沒有實習的機會。
而也就是這個機會,讓我要在下半年,開了不同的學習主線:無刷直流馬達。

一樣的,我去找了幾個教學資源,另外也買了之後會用到的開發板,希望能在實習階段可以快速步上正軌:

  1. 亲手教你转起一台无刷电机 - 煲仔滷煮
  2. 直流無刷馬達原理與驅動控制 - 張雯翔、張家榮、許凱翔、常文峻
  3. 無刷馬達大小事 5分鐘就上手 - 東方馬達

結語

這個暑假真的過得滿充實的,其實還有發生一件事情,讓我成長很多,但基於某些原因我不能公布。
大概就這樣吧,要開學了,也該收心,準備最後專題的衝刺與迎接未來的準備。

喔對,校長你甚麼時候會出來探探頭。

參考資料

Comments

Unable to load Disqus, please make sure your network can access.