有谁做过单片机音乐编程,是用C语言
最佳答案 - 由投票者8个月前选出
EM78XXX單晶片自從問世以來已經陸續推出十餘種不同等級的單晶片,小到8Pin的78P152,大到100Pin OTP的78P860,其組合語言指令都是一樣的,僅有57個,所以反覆練習幾次就能熟悉指令的用法。組合語言用在I/O控制非常容易,也有很高的效率,所以坊間的書籍大部份以討論控制為主顯,顯少專門探討軟體技巧的篇幅,其實老手都知道,關於晶片之控制往往用到時再去翻一翻DATA BOOK,注意一下TIMING,然後準備一部示波器,三兩下就可以搞定。反倒是演算法用的好不好會大大影響產品的穩定度,所以有經驗的程式設計師通常都有自己的一套葵花祕笈,所以要提昇自己的功力最好的方式除了多練習之外,看看別人的程式也會使你進步很快。
BCD轉換成Binary
由於EM78XXX是8位元的微控器,因此為了節省記憶體,我們的範例僅以一個BYTE存放兩位BCD數為例,數字的範圍在0~99之間,轉換後的結果放在ACC,如果您需要更多的位數,相信您在看完之後應該不難自行修改才是。
程式一
這個範例程式共花費13個指令CYCLE,需要兩個變數空間,執行後會影響到原BCD的內容。
MOV A,BCD
MOV TMP,A
MOV A,@0x0F
AND TMP,A
SWAP BCD
AND BCD,A
BC PSW,0
RLC BCD ; *2
MOV A,BCD
ADD TMP,A
RLC BCD
RLCA BCD ; *8
ADD A,TMP
說明
在程式一中所採用的方式應該算是最多人知道的方式,也是一種最直覺的方法,先將BCD個位數保存起來,因為十位數必須要乘以10,所以利用移位的技巧乘以10再加上個位數,所得的答案放入ACC。
程式二
在程式一的缺點,就是在執行程式以後,原本BCD的內容已經在移位的過程中被破壞掉了,為了改善這項缺失,我們換一種方式看看。下面這個程式,我們企圖改善前面的缺失,共花費11個指令CYCLE,仍需要兩個變數空間,但是執行後不會破壞原來BCD的內容。
SWAPA BCD
MOV TMP,A
MOV A,@0x0F
AND BCD,A
AND TMP,A
BC PSW,0
RLCA TMP
SWAP TMP
RRC TMP
ADD A,TMP
ADD A,BCD
程式三
對於程式二的結果我們仍然不滿意,似乎稍嫌複雜,雖然速度有所改善,但在記憶體的分配上仍有餘地,所以我們再改善成程式三的型態。轉換過程只花費10個指令CYCLE,而且只需要一個變數空間,執行之後也不會改變原來BCD的內容。
MOV A,@0x0f
AND A,BCD
JBC BCD,4
ADD A,@10
JBC BCD,5
ADD A,@20
JBC BCD,6
ADD A,@40
JBC BCD,7
ADD A,@80
說明
看過以上三個範例,您是否覺得程式三最簡潔而且容易瞭解?寫程式的確是一項極具挑戰性的工作,而且還可以找到很多靈感及樂趣,想不到吧!
Binary轉換成BCD碼
下面的範例程式會將存放在ACC內的二進位數轉換成兩位BCD碼(Compacted BCD Code),可轉換最大的BCD碼是99。
CLR BCD
DIGIT_HI:
ADD A,@256-10
JBS PSW,FC
JMP DIGIT_LO
INC BCD
JMP DIGIT_HI
DIGIT_LO:
ADD A,@10
SWAP BCD
OR BCD,A
減法的陷阱
EM78系列組合語言的減法指令是SUB,使用這個指令時您得特別注意,因為ACC永遠都是減數,不可為被減數。SUB指令的語法有以下三種:
SUB A,R (R-A→A)
SUB R,A (R-A→R)
SUB A,K (K-A→A)
也就是說如果我們想計算A-2的值,如果寫成:
SUB A,@2
其實是執行2-A,解決方法如下:
ADD A,@256-2 或
ADD A,@254
交換兩組暫存器的內容
http://www.szicmusic.com/emc.htm
参考资料
http://www.hnwei.com/bbs/index.asp?boardid=82