基於S3C2451裸機開發的電子相簿
學習S3C2451也有一段時間了,對於ARM9裸機開發也有了一點了解,這次做了一個基於ARM9裸機開發的電子相簿,其中也遇到了一些問題,最終都通過各種方法解決了,現也將之記錄,給後人一個借鑑。
這次電子相簿開發使用的是廣州友善之臂的Mini2451開發板,內建三星公司的S3C2451晶片,對於該晶片的用法在前幾篇博文中已介紹過了,有興趣的朋友可以翻閱前幾篇部落格,本人將所有的函式封裝都已經發布了。
介紹一下此次電子相簿的功能和使用到的晶片功能:
ARM9端:
四個按鍵,key1鍵返回主介面,key2鍵開啟自動切換功能,key3鍵切換上一張圖片,key4鍵切換下一張圖片。這四個按鍵是相簿的基本功能,除此之外,主介面可以顯示時鐘(通過上位機校準時間),主介面10秒鐘未操作將進入屏保模式,兩個LED燈每隔1秒閃爍,這三個功能都是通過RTC時鐘實現的,使用了TICK中斷。
這裡遇到的主要問題是怎麼實現上一張和下一張的切換,將圖片通過取模軟體取模後,生成了10個數組,然後定義一個指標陣列,將這10個圖片陣列的指標存放進來,通過遍歷實現了自動切換相簿功能。在實現上一張和下一張的時候,想了一會,最後我定義了一個全域性變數sp,上一張播放解釋sp++,然後sp%10,最後圖片顯示,這樣就完成了上一張圖片的切換,下一張就是sp--。
PC端:
PC端有一個上位機,可以通過串列埠控制下位機開啟相簿、關閉相簿、上一張和下一張切換圖片、同步校準時鐘、自動切換輪換時間的設定、字幕開啟關閉等。詳細功能請看下圖:
PC端上位機的編寫和介紹將會在後文中詳細介紹,上位機可以使用QT或者C#編寫,這裡只是對上位機的運用,只需要知道上位機每個按鍵給串列埠傳送的指令即可:
這些指令可以通過虛擬串列埠查看出來,指令中是自己定義的收發協議包,通過開啟相簿指令講解一下協議:
開啟相簿 FE03F10101EF首先是包頭FE和包尾EF,03是資料的長度,F1 01 01則是開啟相簿的指令。
說一下這個上位機控制下位機遇到的困難:
1、首先是對資料的接收控制,這方面以前沒怎麼遇到,後來找了一個模板實現了資料的接收:
int start = 0; { recv_data = UART_RecvData(UART0); if(start != 0 && recv_data != 0xEF) //如果已收到包頭並且當前收到的不是包尾 { buf[start-1]=recv_data; //快取資料 start++; } else if(start!=0&&recv_data==0xEF) //如果收到包尾 { start=0; if(buf[1] == 0x3 && buf[3] == 0xf1 && buf[5] == 0x1 && buf[7] == 0x1) {......} ...... } else if(recv_data==0xFE&&start==0) //如果收到的是包頭 start++; UFCON0 |= 0x1; //使能FIFO UFCON0 |= 0x2; //Rx FIFO 復位 UFCON0 &= ~0x2; //Rx FIFO 正常 IRQ_ClearSRCPND(INT_UART0); IRQ_ClearSUBSRCPND(SUBINT_RXD0); }
這樣就實現了資料的接收,可以對資料進行解析判斷。
2、串列埠接收快取溢位,每次上位機發送了9-10次資料之後就突然發現上位機這個時候沒有作用了,無論按什麼都沒反應,這個問題檢查思考了很久,最終發現串列埠接收快取溢位了,沒有將快取清空。我最終的解決辦法是:
#define UFCON0 (*(volatile unsigned long*)0x50000008)
UFCON0 |= 0x1; //使能FIFO
UFCON0 |= 0x2; //Rx FIFO 復位
UFCON0 &= ~0x2; //Rx FIFO 正常
這裡的關鍵就是UFCON這個暫存器,這個暫存器可以對接收資料的快取清空,具體資訊:
3、第三個遇到的困難就是時間的校準,時鐘配置的暫存器需要填入的是BCD資料,例如:17年 填入的是0X17,但是上位機給我傳送的資料是0X11,前者是BCD,後者是十六進位制,所以我在接收到時鐘校準資料的時候,需要對資料進行一個轉換。這兩個資料其實是有規律的:
十進位制 十六進位制 BCD結果
0 0x0 0x0
9 0x9 0x9
10 0xa +0x6 0x10
19 0x13 +0x6 0x19
20 0x14 +0x6 + 0x6 0x20
29 0x1D +0x6 + 0x6 0x29
30 0x1E +0x6 + 0x6 + 0x6 0x30
39 0x27 +0x6 + 0x6 + 0x6 0x39
40 0x28 +0x6 + 0x6 + 0x6 + 0x6 0x40
49 0x31 +0x6 + 0x6 + 0x6 + 0x6 0x49
50 0x32 +0x6 + 0x6 + 0x6 + 0x6 + 0x6 0x50
59 0x3B +0x6 + 0x6 + 0x6+ 0x6 + 0x6 0x51
根據這個規律就可以把兩者轉換了,即實現了時鐘的校準:
U8 hextobcd(U8 buf)
{
if(buf > 0 && buf < 10)
{
return buf;
}
else if(buf >= 10 && buf < 20)
{
return buf+0x6;
}
else if(buf >= 20 && buf < 30)
{
return buf+0x6+0x6;
}
else if(buf >= 30 && buf < 40)
{
return buf+0x6+0x6+0x6;
}
else if(buf >= 40 && buf < 50)
{
return buf+0x6+0x6+0x6+0x6;
}
else if(buf >= 50)
{
return buf+0x6+0x6+0x6+0x6+0x6;
}
return 0;
}
這些就是此次專案的大概思路和遇到的問題,做完這個專案對ARM9有了更深一步的瞭解,同時也對資料包協議的解析有了一定的瞭解,接下來上傳一些專案的圖片,同時也會將原始碼、上位機、虛擬串列埠安裝軟體上傳。
專案展示:
演示視訊:http://pan.baidu.com/s/1miaCSYW
圖片展示:
多功能電子相簿(上位機):http://pan.baidu.com/s/1dEPvP2T
虛擬串列埠:http://pan.baidu.com/s/1i5h49et
ARM裸機電子相簿原始碼:http://pan.baidu.com/s/1dFhCKXr