鴻蒙通信開發Wi-Fi IoT套件連PCF8563實現電子鐘功能

https://harmonyos.51cto.com/#zz
首先跟同樣新入手單片機開發的小伙伴分享一點I2C通信的知識。我估計大部分入手開發板的小伙伴都有一定程序開發的能力,但是底層開發可能是新接觸,我看有的小伙伴配置開發環境都有障礙,其實并不是多復雜,只是首次接觸很陌生罷了,大膽試,多搞幾回就輕松應對了。
通信開發是單片機主要開發內容,通信方式和協議有很多種,針對應用場景和模塊的情況選用合適的協議。各種協議大同小異,開始了解通透一種,理解其思想,其他協議也就很容易理解了。

如果是第一次看到這種圖是不是有點懵。
大概過程就是:
1. 發送一段模塊地址信息 + 讀/寫。
等待…
模塊如果收到,會給你個回復 ACK
2. 你看到ACK響應,進行下一步
再發送一段,讀/寫寄存器地址信息。
模塊收到,再給你回復ACK
3. 如果是寫,就再發送寫的內容信息。
如果是讀,就接收模塊發送來的返回信息。
換個現實場景理解一下,假設你喊你室友幫你取快遞:
你:三胖子!(發送模塊地址)
三胖子:干啥。(接聽ACK)
你:給我取份快遞。(發送寄存器地址)
三胖子:好的。(接聽ACK)
你:接收室友給你送來的快遞。(接收信息)
整個通信過程就是一問一答,雙方不能同時問答,一方說話一方只能接聽。當然具體過程還要復雜一些,比如接收信息也要給模塊回復應答,但是主體過程就是這樣的。這個過程大概了解一下就行,所有通信的細節部分都已經被鴻蒙下的函數封裝好了,具體過程交由鴻蒙做就好,你只需要考慮要說什么做什么就行了。這個過程真的好簡單。
看一下鴻蒙真對WifiIoT智能設備提供的I2C相關函數:
將數據寫入I2C設備。
- unsigned int I2cWrite(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData);
在i2c.h文件里有詳細的說明,這里復制過來一一對照看一下每個參數的意義。
將數據寫入I2C設備。
id表示I2C設備id。
deviceAddr表示I2C設備地址。
i2cData表示指向要寫入的數據描述符的指針。
如果操作成功,返回WIFI_IOT_ SUCCESS;
否則返回在wifiiot_errno.h中定義的錯誤代碼。
(百度翻譯還是很準確的哦!哈)
從I2C設備讀取數據。
- unsigned int I2cRead(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData);
讀取的數據將保存到i2cData指定的地址。
id表示I2C設備id。
deviceAddr表示I2C設備地址。
i2cData表示指向要讀取的數據描述符的指針。
如果操作成功,返回WIFI_IOT_ SUCCESS;
否則返回在wifiiot_errno.h中定義的錯誤代碼。
鴻蒙把I2C所使用的數據封裝在一個結構體中。我們只需要把數據寫入到這個結構體中,然后讓函數自己處理就可以了。
- typedef struct {
- /** Pointer to the buffer storing data to send */
- unsigned char *sendBuf;
- /** Length of data to send */
- unsigned int sendLen;
- /** Pointer to the buffer for storing data to receive */
- unsigned char *receiveBuf;
- /** Length of data received */
- unsigned int receiveLen;
- } WifiIotI2cData;
定義I2C數據傳輸屬性。
指向存儲要發送的數據的緩沖區的指針
- unsigned char *sendBuf;
要發送的數據長度
- unsigned int sendLen;
指向用于存儲要接收的數據的緩沖區的指針
- unsigned char *receiveBuf;
接收數據的長度
- unsigned int receiveLen;
具體用的時候,我們可以根據實際情況再封裝一下。這是主要根據使用場景和模塊所提供的功能。我針對我要使用PCF8563模塊把I2C過程做了一點包裝??梢钥纯次覍懙拇a,也許能給你一點啟發。參看我的代碼。
在這次開發過程中還用到了GPIO管腳中斷
很多老師都專門寫了按鍵的中斷觸發,我也是仔細研讀然后做了我這個程序的觸發控制,老師的文章寫的太詳細了,實在沒什么好再說明的,我在使用中也沒有遇到什么問題,最多就是,要關閉看門狗功能,否者會重啟,再就是當暫中斷發的時候用到這個方法。
- GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_8, 0); 正常
- GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_8, 1); 暫停
ADC模數轉換
用到OLED模塊上的按鍵的時候碰到了ADC功能,這里先做個伏筆,主要是還沒把鴻蒙下的ADC方法研究明白,而且數模轉換應用場景非常多,以后用到專門的模塊再仔細寫寫心得吧。暫時看老師們的代碼照貓畫虎也能運行,有時候會不穩定。
PCF8563是個比價常用的模塊。
PCF8563 是PHILIPS 公司推出的一款工業級內含I2C 總線接口功能的具有極低功耗的多功能時鐘/日歷芯片。PCF8563 的多種報警功能、定時器功能、時鐘輸出功能以及中斷輸出功能能完成各種復雜的定時服務,甚至可為單片機提供看門狗功能。是一款性價比極高的時鐘芯片,它已被廣泛用于電表、水表、氣表、電話、傳真機、便攜式儀器以及電池供電的儀器儀表等產品領域。

PCF8563并不是我們套件里所帶的模塊,只是趕巧我手上剛好有這么個模塊。官方套件提供的模塊有限,但是涵蓋了單片開發的所有應用場景,如果每個模塊都認真走一遍,那么基本解鎖了鴻蒙單片機開發的所有知識了。在實際應用中,我們還是要使用各種功能的電子模塊來實現更有趣的功能的。所以以后還是要更多嘗試新模塊的使用,也能提高鴻蒙系統的應用范圍。
前面已經開發過AHT20溫濕度模塊,SSD1306模塊,所以再開發PCF8563的過程就變的很簡單。有很多內容都是重疊的,整體思路也是相通的,所以過程變得非常輕松。
任何一個模塊上手第一步都是讀它的技術手冊,了解功能寄存器的配置。讀手冊的過程是枯燥的,只有堅持把手冊讀透,那么這個模塊才算真正屬于你。
我想要實現的功能是一個時鐘功能,然后按需求和過程寫一大坨流水賬代碼,測試走通,再把代碼整理一下,最后歸結為2部分,一部分設置時間,一部分讀取時間。完了!
當你擁有了一個寫時鐘的能力,你就擁有了各種計時的能力,比如寫個萬年歷,做個股票投資報時,等等。我通過一部電影獲得靈感,做了一個到計數時鐘,看時間飛快的流逝,會不會讓看鐘的人有壓力感,治治拖延癥呢。但結果除了無聊一點用沒有。
PCF8563模塊可以輸出時鐘信號,我開始設想通過Hi3861的1個端口接收時鐘信模塊發出的周期性低電平,把間隔設定為1秒,觸發中斷,然后讀取模塊的時間信息,發送到OLED上顯示出來。這樣就能每隔1秒顯示一次。
OLED模塊上有2個按鍵,想通過它們實現時間設置功能。這個兩個按鍵很有趣,通過1個端口接收信號,通過測試信號的電壓強度來區分是那個按鍵再工作。這時候需要通過ADC能來實現,(坑王艾希已經上線,哈開玩笑。)數模轉換功能,難道不能通過2個端口來實現嗎?當然不是,這可能是這套開發板設計的初衷,就是讓你充分學習未來可能遇到的所有知識。閑話少敘,又解鎖新姿勢了。
通過2個按鍵實現功能控制:早期機械計算機用齒輪實現功能的切換,比如可編曲發音盒,有一種可編曲的,中間轉子每個音節都可調,實現編曲功能,那種太高級了,沒找到圖片。我借鑒這種工作原理,來實現2個按鍵的復雜控制。

按鍵功能實現的原理就跟那個齒輪是一樣的,S1驅動gear這個大齒輪,他有9齒,按一下,轉1齒,循環往復,每一齒聯動1個功能。S2驅動gears組的7個小齒輪,每個小齒輪針對1個時間的值。當然這不是唯一的控制方法,也可以做個大數組什么的,只是一種方法而已。
- gear = 9 正常時間顯示
- gear = 0 進入設置狀態
- gear = 1 秒設置 gears[0]可以驅動
- gear = 2 分設置 gears[1]可以驅動
- gear = 3 時設置 gears[2]可以驅動
- gear = 4 日設置 gears[3]可以驅動
- gear = 5 周設置 gears[4]可以驅動
- gear = 6 月設置 gears[5]可以驅動
- gear = 7 年設置 gears[6]可以驅動
- gear = 8 將設置好的值輸入到時間模塊
- gear = 9 正常時間顯示
因為不是套件中的模塊,我只簡單說一下主體程序工作結構。
1. 所有功能先初始化,準備好。
2. 做中斷觸發,每按1次驅動gear加1循環往復。
3. 建1個主循環,所有的工作就這個循環里了。
4. 針對gear的值,調用執行不同的功能。
完了! 謝謝。~哈
看代碼吧,代碼寫的像流水賬,我也懶了改了,歡迎糾錯,有問題歡迎問。
隨著代碼越寫越多,也深感C語言知識太少。我會再好好看看C教程,希望以后寫的代碼,能更好些。
©著作權歸作者和HarmonyOS技術社區共同所有,如需轉載,請注明出處,否則將追究法律責任。
https://harmonyos.51cto.com/#zz