首先,不要誤解,我這裡的計算器是指硬體的計算器,至於純軟體的計算程式,乃至有高級功能的,比如可以求解方程甚至可編程之類,我以後找個時間來說說。這兩天看到有人在博問里問類似的問題,原問是想設計一個有著數位管、有著4x4鍵盤的硬體里的程式,不知道他具體想做什麼,只是給了一些建議。聯想到還有計算器這個東西 ...
版權申明:本文為博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須註明原文網址 http://www.cnblogs.com/Colin-Cai/p/8185972.html 作者:窗戶 QQ:6679072 E-mail:[email protected]
首先,不要誤解,我這裡的計算器是指硬體的計算器,至於純軟體的計算程式,乃至有高級功能的,比如可以求解方程甚至可編程之類,我以後找個時間來說說。這兩天看到有人在博問里問類似的問題,原問是想設計一個有著數位管、有著4x4鍵盤的硬體里的程式,不知道他具體想做什麼,只是給了一些建議。聯想到還有計算器這個東西,這應該很容易作為電子工程或者微電子專業的一個作業的形式出現。以前我招實習生的時候,似乎也曾經叫其實現過計算器。這裡給出一點方案,以供參考。
硬體
框圖如上,主要有4大模塊,電源、控制、按鍵矩陣、數位管。
電源有多種方案,簡單點可以用電池或者usb,這裡不作詳細討論。
數位管採用共陰或共陽,每一位一個片選,選個6位的,一共14個引腳,都接在控制模塊IO引腳上,註意控制信號電平,必要的時候陽級接上拉電阻。
鍵盤矩陣則是以下電路這樣的東西,由一堆按鍵組成,鍵盤矩陣對外8個信號都接在控制模塊的引腳上。另外,如果控制模塊的引腳無法配置上拉或下拉電阻,那麼PD0/PD1/PD2/PD3或者PD4/PD4/PD6/PD7/PD8就要接上拉電阻,這涉及到鍵盤矩陣的檢測原理。
控制模塊,就看想用什麼編程了,如果想用單片機,可以選擇經典的51單片機、AVR單片機、PIC單片機都可以,STM32當然可以,只是ARM可以做遠比這個複雜的事情,沒必要殺雞用牛刀。當然,想學學ARM特別是STM32的編程,可以用STM32。PIC單片機和51單片機我只玩過彙編,不過現在單片機支持C語言都支持的蠻不錯,建議還是C語言編程。
當然,也有想玩玩數字設計的,那麼cpld對於這個需求是合適的,沒必要上FPGA,可以用很早以前的,價格也便宜。對於資源多少沒有把握的話,你也可以先做數字設計,再來選器件。
固件
硬體設計好了之後,需要設計固件。
如果控制模塊選用的是單片機,那麼我們一般是在裸機下編程,對於這幾款單片機我似乎只玩過彙編,但現在都21世紀了,我想至少也應該用C語言來玩玩。
我們首先要明白數位管和鍵盤矩陣的原理:
數位管相對簡單一些,一般來說,數位管每一位顯示的數字都不一樣。如我圖中的共陰6位數位管,當要顯示某位的時候,片選信號選擇是拉低,其他片選拉高,然後再把要顯示的數字所要點亮的管的引腳拉高,這樣,要顯示的這一位就顯示出了數字,而其他的幾位沒有任何顯示。然後快速切換,每一位都顯示該顯示的數字,那麼根據視覺暫留,我們就看到了完整的顯示。
鍵盤矩陣可能要複雜那麼一些。首先,我們假設我們這裡PD5、PD6、PD7、PD8都被我們接了上拉電阻,並且IO都為高阻接收狀態,而不輸出。我們這裡只考慮一個鍵的識別,其實鍵盤矩陣也可以識別多個鍵。我們想一想,如果某個鍵按下去,比如左上角的S3按下之後,會發生什麼。在按下去之前,PD1、PD2、PD3、PD4和PD5、PD6、PD7、PD8之間並不聯通。但當S3按下去,PD1和PD4連在了一起。如果控制模塊把PD4的輸出射為高阻狀態,那麼如果PD0輸入低電平,那麼PD4讀取出來的應該為低電平,否則為高電平。於是我們把PD1、PD2、PD3、PD4這4個引腳每次只其中一個輸出低電平,其他三個輸出高阻狀態,每次都去讀取PD5、PD6、PD7、PD8,那麼就可以根據數值來判斷到底是哪個按鍵被按下。註意,此處PD1、PD2、PD3、PD4這4個引腳每次只其中一個輸出低電平的時候,其他三個不能輸出高電平,而應該是高阻,否則,如果有兩個按鍵被按下,則為短路狀態!
另外要考慮按鍵的抖動問題,有多種解決方法,比如可以在判斷到一次按鍵按下之後0.3秒內不重覆判斷按鍵被按下。
既然數位管的顯示需要定時去切換顯示位,而鍵盤矩陣也需要定時去切換輸入,那麼我們就可以設置一個定時器,把這兩個硬體的處理都掛在同一個定時中斷常式上作為驅動層,其邏輯使用上述的原理來實現,可以每次中斷給一個迴圈計數作為狀態,做一個moore機簡單明瞭,至於0.3秒內不重覆在交互里體現即可。程式中實現驅動層和應用層的層次分離,無論從調試硬體還是設計固件來說都是必要的,當然你也可以分的更細,比如HAL層。當然,非要在這裡把所有的一切糅合在一起也是能夠最終搞定的,但層次感差很多,並且一個初學者真的設計不好一個大的狀態機。
設計一些全局變數用來應用層和驅動層交互顯示數據和所按按鍵。
unsigned char num[6] ;//應用層寫,驅動層讀,用於6位數據的顯示
unsigned char flag;//flag=0的時候,驅動層可以設置key,並把flag設為1;flag=1的時候,應用層可以讀取key,並把flag設置為0
unsigned char key;//以代表是哪個鍵按下,分別給0、1、2、3、4、5、6、7、8、9、+、-、*、/、=、退格編碼為0~15
以上數據有冗餘,在RAM極端受限的情況下,可以裁剪數據。
而至於計算器所要實現的最高6位加減乘除,很容易實現,根本不需要大數計算,結合顯示和按鍵,構成應用層程式,想想一個計算器的功能,你應該很容易的畫出流程圖,不是嗎?
如果作為學生,你選擇的是cpld/fpga,我也支持你,我覺得一個可以自己獨立做出來的學生應該還是不錯的,但也和之前處理器的程式實現類似:分別設計鍵盤驅動模塊、數位管驅動模塊、計算模塊,最後中間有一個核心模塊以一個狀態機形式存在,與其他三個模塊都相連。當然,每個模塊內部也可以分小模塊,比如數位管模塊裡面最好把解碼器單獨實現一個小模塊,而計算模塊裡加減乘除都是單獨的小模塊。