專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

arm裸機編程

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2014年04月27日   【字體:

 

 
裸機編程(匯編+C):
 
在windows下的工具:
ARM公司:
ARM  DS-5:armV5、armV6、armV7。
Keil  MDK-ARM:arm7、arm9、M、R4。
RVDS:RealView Development Studio,已被DS-5取代。
 
在Linux下工具:
編輯器:vi
編譯器:arm-linux-gcc
工具:makefile
-------------------------------------------------------------------------------
CPU架構(gòu)和資源:
 
1.CPU  Core:(cpu核心)
32KB  I/D  cache  1MGhz
L2  cache  512kb
NEON
 
2.System peripheral:
時鐘
系統(tǒng)定時器
RTC:Real-Time Clock,實時時鐘
Timer with PWM:帶有脈沖寬度調(diào)制電路控制的定時器
Watachdog timer:看門狗定時器
PLL:倍頻器(鎖相環(huán))
DMA:Direct Memory Access,直接內(nèi)存存取
ADC:Analog-to-Digital Converter,模擬/數(shù)字轉(zhuǎn)換器。
Keypad:鍵盤
Touch Screen:觸屏
 
3.Connectivity:
 
Audio IF:(音頻處理)
IIS:Internet Information Services,互聯(lián)網(wǎng)信息服務(wù)
PCM:Pulse Code Modulation,脈沖編碼調(diào)制
SPDIF:Sony/Philips Digital Interface Format,SONY、PHILIPS數(shù)字音頻接口
AC97:Audio Codec97 ,AC97軟聲卡
 
Storage IF:(擴展存儲)
MMC:MultiMedia Card,世界上最小的Flash Memory存貯卡
SD:Secure Digital Memory Card,安全數(shù)碼卡
ATA:Advanced Technology Attachment,硬盤接口技術(shù),全球硬盤標(biāo)準(zhǔn)
 
Connectivity:(接口)
USB Host/OTG
UART
IIC
SPI:serial peripheral interface
Modem IF:modem interface
GPIO
 
4.Multimedia:(多媒體)
Camera IF:camera interface
MIPI(DSIM\CSIS) : Mobile Industry Processor Interface, 移動產(chǎn)業(yè)處理器接口
DSIM:
CSIS:
CSI:Channel State Information ,信道狀態(tài)信息
MFC: Multi Format Codec, 多格式編碼器
2D VG/3D graphics engine:圖形處理引擎
JPEG:
Image Rotator:
NTSC:National Television Standards Committee,國家電視標(biāo)準(zhǔn)委員會
PAL:電視廣播制式
HDMI:High Definition Multimedia Interface,高清晰度多媒體接口
TV out:
Video DAC:
TFT  LCD:
 
5.Memory interface:(自帶存儲)
SRAM/ROM(cpu內(nèi)部存儲)
OneNAND(擴展存儲)
NOR(擴展存儲)(沒有)
NAND(SLC/MLC) (擴展存儲)
LPDDR1/OneDRAM/LPDDR2/DDR2(內(nèi)存,DRAM、SDRAM)
 
6.Power Management:(電源管理)
 
7.Multi layer AHB/AXI Bus:(高速總線,cpu核心和外圍的接口)
Internal SRAM 96Kb(內(nèi)部的靜態(tài)的隨機存儲器)(二級高速緩存)(IRAM、ISRAM)
Internal ROM 64Kb (內(nèi)部的隨機存儲器)(固件)(IROM)
Crypto Engines(系統(tǒng)安全)
 
237個多功能輸入輸出口,142個存儲器口;34組通用管腳分組,2組存儲器借口管腳分組。
 
GPIO:
控制146個GPIO中斷;
控制32個外部中斷;
237多功能輸入輸出口;
控制除了GPH0-3之外的所有管腳在睡眠模式的狀態(tài)。
 
 
-------------------------------------------------------------------------------------
裸板編程
 
.s:純匯編
.S:兼容C的匯編
 
編程步驟:
看電路原理圖,知道硬件電路工作原理。
找到硬件對應(yīng)的CPU管腳。
查看CPU手冊,找到對應(yīng)的管腳控制器。
 
編寫啟動程序start.S
編寫頭文件.h和源文件.c
編寫makefile文件
燒寫程序到開發(fā)板
 
編程用到的寄存器一般都是特殊功能寄存器SFR:0xE000_0000——0xFFFF_FFFF(512MB)。
 
--------------------------
代碼的重定位
 
程序有兩個地址:
程序的當(dāng)前地址:程序在運行時所處的當(dāng)前地址。
程序的鏈接地址:程序運行時應(yīng)該位于的地址,編譯程序時可以指定鏈接地址。
 
對于裸機編程,只拷貝啟動設(shè)備(sd或nand)中的前16KB代碼到IRAM的BL1中,
如果代碼超過16KB,需要用前16KB的代碼將整個程序拷貝到DRAM中,
然后跳轉(zhuǎn)到DRAM中運行程序,這就叫做重定位。
 
可以將不超過16KB的代碼重定向到iSRAM中的其他地址,而不一定要從0xD0020010開始;
也可以將超過16KB的代碼重定位到DRAM中的某個地址。
 
重定位到IRAM或重定位到DRAM
 
程序中需要進行3步操作完成重定位:
1.重定位
2.清bss
3.跳轉(zhuǎn)
 
在makefile中指定鏈接地址:
-T FILE   arm-linux-ld 的       -T選項 可以指定一個鏈接腳本
arm-linux-ld -Tsdram.lds -o sdram.elf $^        #DRAM
 
鏈接腳本:程序鏈接時的參考文件,擴展名一般為.lds,以DRAM為例:
********************
SECTIONS
{
     . = 0x0;
     .text : {
          start.o
          * (.text)
     }
     .data : {
          * (.data)
     }
     bss_start = .;
     .bss : {
          * (.bss)
     }
     bss_end  = .;
}
********************
 
鏈接腳本語法:
. = 0x0;表示程序的鏈接地址;.表示當(dāng)前地址。
后面表示各個段的內(nèi)容,*表示所有文件;
start.o表示代碼段需要和入口函數(shù)start.o合并。
start和end記錄bss段的起始地址和結(jié)束地址,在匯編程序中調(diào)用。
 
------------------------------------------
第一個裸機程序——LED測試
 
看電路原理圖,LED測試電路工作原理。
找到LED對應(yīng)的CPU管腳。
查看CPU手冊,找到對應(yīng)的管腳控制器。
 
GPIO控制LED,在三星官方手冊查找GPIO:
四個LED分別用的GPIO的GPJ2_0-3;
GPJ2有8個管腳GPJ2[n](n=0-7);
GPJ2有六個寄存器
 
GPJ2CON [0]表示GPJ2_0管腳,由[3:0]四位控制該管腳的作用;
GPJ2CON[1]表示GPJ2_1,由[4:7]四位控制,以此類推,共32位,控制八個管腳。
CON控制寄存器有32位:0xE020_0280
0000 = Input
0001 = Output
0010 = MSM_DATA[0]
0011 = KP_COL[1]
0100 = CF_DATA[0]
0101 = MHL_D7
0110 ~ 1110 = Reserved
1111 = GPJ2_INT[0]
 
// 設(shè)置GPJ2CON的bit[0:15],配置GPJ2_0/1/2/3引腳為輸出功能
    ldr r1, =0xE0200280
    ldr r0, =0x00001111
    str r0, [r1]
 
GPJ2DAT[7:0]表示八個管腳由[7:0]八位控制;每一位控制一個管腳。
DAT數(shù)據(jù)寄存器有8位:0xE020_0284
1:高電平
0:低電平
 
// 設(shè)置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引腳輸出低電平,LED亮
     ldr r1, =0xE0200284
     mov r0, #0
     str r0, [r1]
 
// 設(shè)置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引腳輸出高電平,LED滅
     ldr r1, =0xE0200284
     mov r0, #0xf
     str r0, [r1]
 
在c中定義和使用寄存器
 
#define      GPJ2CON      (*(volatile unsigned long *) 0xE0200280)
#define      GPJ2DAT       (*(volatile unsigned long *) 0xE0200284)
 
void led_blink()
// LED閃爍
{
     GPJ2CON = 0x00001111;// 配置引腳
     while(1)
     {
          GPJ2DAT = 0;// LED on
          delay(0x100000);
          GPJ2DAT = 0xf;// LED off
          delay(0x100000);
     }
}
 
******************
匯編點亮led源程序
匯編程序:
見led_s中的start.S
******************
 
Makefile文件:
led.bin: start.o
arm-linux-ld -Ttext 0x0 -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis
gcc mkv210_image.c -o mkmini210
./mkmini210 led.bin 210.bin
%.o : %.S
arm-linux-gcc -o $@ $< -c
%.o : %.c
arm-linux-gcc -o $@ $< -c clean: rm *.o *.elf *.bin *.dis –f
 
將led測試程序燒寫到SD卡的write2sd腳本:
sudo dd iflag=dsync oflag=dsync if=210.bin of=/dev/sdb seek=1
執(zhí)行./write2sd后210.bin文件會被燒寫到sd卡的扇區(qū)1中,sd卡的起始扇區(qū)為0,一個扇區(qū)的大小為512byte,sd啟動時,IROM里的固化代碼是從扇區(qū)1開始拷貝代碼的。
 
------------------------
燒寫裸機程序:
 
1.用dd燒寫到sd卡
燒寫到SD卡:
sudo dd iflag=dsync oflag=dsync if=XXX.bin of=/dev/sdb seek=1
友善的板子需要用sdflasher將sd卡隔出一個無格式區(qū),然后燒寫到這個區(qū)域。
注意:程序中要實現(xiàn)添加一個16byte的頭。
 
2.用minitools直接燒寫
minitools直接用usb就可以進行燒寫,不需要使用串口控制。
 
minitools燒寫程序有兩種方法:
直接燒寫到DRAM;
燒寫到NAND;
 
直接燒寫到DRAM中運行:
需要從已經(jīng)燒寫了superboot的sd卡啟動,同時設(shè)置為usb傳輸模式;
燒寫裸機程序到DRAM中的地址為0x20000000~0x3F5FFFFF的區(qū)域運行,共502MB空間;其他10mb空間用來運行superboot。uboot來初始化內(nèi)存和搬運代碼。
 
燒寫到NAND中:
需要從已經(jīng)燒寫了superboot的sd卡啟動,同時設(shè)置為usb傳輸模式;
superboot會燒寫到nand,用來加載裸機程序;
快速啟動后,superboot會把裸機程序拷貝到DRAM的0x20000000地址處,然后跳轉(zhuǎn)到給地址運行裸機程序。
當(dāng)設(shè)置為從nand啟動時(需要燒寫裸機程序同時燒寫uboot),nand中的superboot會引導(dǎo)裸機程序到nand中運行。
 
注意:
在makefile中要指定程序運行地址(在內(nèi)存中運行):
arm-linux-ld -Ttext 0x20000000 -o led.elf $^
程序不能在nand中運行,只能在內(nèi)存中運行。
 
-------------------------------------
手動關(guān)閉看門狗編程
 
看門狗用于監(jiān)控cpu的運行,保證在故障干擾情況下能盡快回復(fù)正常,看門狗和定時器都能定時,而定時器不能發(fā)出復(fù)位信號,看門狗可以發(fā)出復(fù)位信號,在啟動時IROM會自動關(guān)閉看門狗;這里學(xué)習(xí)手動關(guān)閉看門狗(關(guān)閉復(fù)位功能)。
 
看數(shù)據(jù)手冊得到看門狗的寄存器信息:
 
看門狗定時器有四個寄存器:
WTCON:控制寄存器;0xE2700000
WTDAT:數(shù)據(jù)寄存器;0xE2700004
WTCNT:計數(shù)寄存器;0xE2700008
WTCLRINT:中斷清除寄存器;0xE270000C
 
WTCON控制寄存器有32位:0xE2700000
[0]: Reset enable/disable
0:disable the reset function of the watchdog timer.
1:asserts reset signal of the S5PV210 at watchdog timer-out.
 
     // 關(guān)閉看門狗
     ldr     r0, =0xE2700000
     mov   r1, #0
     str     r1, [r0]
 
-------------------------------------
控制I cache(協(xié)處理器)
 
cache:在主存和cpu通用寄存器之間設(shè)置了一類高速的容量小的存儲器,
把正在執(zhí)行的指令地址附近的一部分指令或數(shù)據(jù)從主存調(diào)入到這類存儲器,
供cpu在一段時間使用,提高程序運行速度。這種介于主存和cpu之間的高速小容量存儲器就是cache。
 
常見的cache包括icache和dcache。
 
系統(tǒng)剛上電時,cache中的內(nèi)容是無效的,并且cache的功能是關(guān)閉的,
往cp15協(xié)處理器中的寄存器1的bit[12]寫入1可以啟動icache,
寫入0可以停止icache。
往cp15的協(xié)處理器中的寄存器1的bit[2]寫入1可以啟動dcache,
寫入0可以停止dcache。
dcache必須在mmu被啟動后才能被啟動,裸機編程一般不啟動mmu。
 
// 打開icache可提高運行速度
#ifdef CONFIG_SYS_ICACHE_OFF
// clear bit 12 (I) I-cache
bic     r0, r0, #0x00001000
#else
// set bit 12 (I) I-cache
orr     r0, r0, #0x00001000
#endif
mcr     p15, 0, r0, c1, c0, 0
 
-------------------------------------
設(shè)置棧
 
代碼段:存放代碼。
數(shù)據(jù)段:存放已經(jīng)初始化的全局變量和用static申明的變量。
BSS段:存放沒有初始化的變量。
堆(heap):存放進程運行中被動態(tài)分配的內(nèi)存段。
 
棧(stack):用戶存放程序臨時創(chuàng)建的局部變量(不包括全局變量和static申明的變量);保護現(xiàn)場;函數(shù)調(diào)用時傳遞參數(shù)(參數(shù)個數(shù)超過四個);保存臨時變量。
 
在匯編中設(shè)置棧,棧的地址由用戶分配。
// 設(shè)置棧,以便調(diào)用c函數(shù)
ldr     sp, =0xD0037D80
 
ISRAM的內(nèi)部空間的分配:
0xD003_7780——0xD003_7D80      SVC(管理模式)棧(1.5KB)
0xD003_7D80——0xD003_7F80      IRQ(中斷模式)棧(512B)
 
-------------------------------------
蜂鳴器
1.從電路原理圖得知蜂鳴器由GPD0_0管腳控制,高電平動作。
 
2.從cpu數(shù)據(jù)手冊得知:
GPD0有四個管腳,六個寄存器:
 
GPD0CON:控制寄存器:
有16位,每四位控制一個管腳,GPD0_0由bit[3:0]控制,地址為0xE020_00A0。
0000 = Input
0001 = Output
0010 = TOUT_X
0011 ~ 1110 = Reserved
1111 = GPD0_INT[X]
 
#define GPD0CON          (*(volatile unsigned long *)0xE02000A0)
void buzzer_init(void)
{
     GPD0CON |= 1<<0;
}
 
GPD0DTA:數(shù)據(jù)寄存器:
有4位,每一位控制一個管腳,GPD0_0由bit[0]控制,地址為0xE020_00A4。
0:低電平
1:高電平
 
#define GPD0DAT          (*(volatile unsigned long *)0xE02000A4)
void buzzer_on(void)
{
     GPD0DAT |= 1<<0;
}
 
void buzzer_off(void)
{
     GPD0DAT &= ~(1<<0);
}
 
-------------------------------------
按鍵
 
1.     由電路原理圖得知cpu提供的keypad可以通過GPH2(column)和GPH3(row)擴展出8行和8列的矩陣鍵盤,開發(fā)板中使用GPH2_0——GPH2_3來控制4個按鍵,GPH3_0——GPH3_3來控制4個按鍵,共八個按鍵。按鍵為輸入模式,如果按鍵按下,那么讀入低電平,彈起時讀入高電平。
 
2.     從數(shù)據(jù)手冊得知:
GPH2和GPH3各有8個管腳,各有6個寄存器,以一個為例。
 
GPH2CON:控制寄存器,地址:0xE020_0C40
有32位,每四位控制一個管腳,bit[0:3]控制GPH2_0管腳,其他類推。
0000 = Input
0001 = Output
0010 = Reserved 0011 = KP_COL[0]
0011 ~ 1110 = Reserved
1111 = EXT_INT[16]
 
#define      GPH2CON      (*(volatile unsigned long *) 0xE0200C40)
#define      GPH2_0_INTPUT      ~(0xf<<(0*4))
#define      GPH2_1_INTPUT      ~(0xf<<(1*4))
#define      GPH2_2_INTPUT      ~(0xf<<(2*4))
#define      GPH2_3_INTPUT      ~(0xf<<(3*4))
GPH2CON = GPH2_0_INTPUT&GPH2_1_INTPUT&GPH2_2_INTPUT&GPH2_3_INTPUT;
 
GPH2DAT:數(shù)據(jù)寄存器,地址:0xE020_0C44
有8位,每一位控制一個管腳,bit[0]控制GPH2_0管腳。
0:低電平
1:高電平
 
#define      GPH2DAT          (*(volatile unsigned long *) 0xE0200C44)
 
// 讀取KEY相關(guān)的引腳值,用于判斷KEY是否被按下
          unsigned long dat;
          dat = GPH2DAT;
 
// 判斷KEY1:GPH2_0
     if(dat & (1<<0))                    // KEY1被按下,則LED1亮,否則LED1滅
          GPJ2DAT |= 1<<0;               // OFF
     else
          GPJ2DAT &= ~(1<<0);          // ON
 
-------------------------------------
串口(UART)
 
串行異步通信:異步協(xié)議以字符為數(shù)據(jù)傳輸單位,在每個字符開始傳輸時對字符內(nèi)的比特位進行同步,通信中,兩個字符之間的間隔是不固定的,但是每個字符內(nèi)的時間間隔是固定的。
 
字符的組成:起始位(用0表示)+5-8個數(shù)據(jù)位+校驗位+1-2個停止位(以1表示)
不進行傳輸時是空閑位或停止位(以1表示)。
 
傳輸過程:由一個低電平的起始位開始,然后按收、發(fā)雙方約定的頻率對約定的字符比特數(shù)進行逐位接收,數(shù)據(jù)位按照低位在前,高位在后的順序進行傳輸,最后以約定的算法進行錯誤檢驗,最后傳送的是高電平的停止位,傳輸結(jié)束。
 
RS232采用EIA電平,開發(fā)板和計算機接口采用TTL電平,所以,串口使用了電平轉(zhuǎn)換電路;RS232主要有DB25和DB9兩種類型的連接器。
 
210提供了四個串口,9針的串口實際只用到了第2和第3兩個管腳,2是RSR用來接收數(shù)據(jù),3是RST用來發(fā)送數(shù)據(jù)。每個串口由GPA0和GPA1復(fù)用,每個串口有自己的內(nèi)部串口寄存器來控制。
 
1.從底板電路原理圖得到串口和核心板的接口,從核心板得到串口的控制管腳:
 
COM0:
GPA0_0 : XuRXD0 : RSRXD0
GPA0_1 : XuTXD0 : RSTXD0
 
2.從數(shù)據(jù)手冊得到cpu控制串口的寄存器的信息:
GPA0和GPA1都是有8個管腳。
 
GPA0CON:控制寄存器,32位,每四位控制一個管腳,地址:0xE020_0000=0x(222222)22
COM0的RSR由GPA0_0管腳控制,由GPA0CON寄存器的bit[3:0]控制:
0000 = Input
0001 = Output
0010 = UART_0_RXD
0011 ~ 1110 = Reserved
1111 = GPA0_INT[0]
COM0的RST由GPA0_1管腳控制,由GPA0CON寄存器的bit[7:4]控制:
0000 = Input
0001 = Output
0010 = UART_0_TXD
0011 ~ 1110 = Reserved
1111 = GPA0_INT[1]
 
3.讀數(shù)據(jù)手冊,獲取串口控制寄存器信息
串口寄存器很多,分別控制四個串口,以COM0為例,n都可以換成0-3。
沒有列出都是保留位(reserved)。
 
ULCON0:串口線控寄存器,32位,地址:0xE290_0000=0x3(常規(guī)模式,不校驗,一位停止位,8位數(shù)據(jù)位)
 
bit[1:0]: 數(shù)據(jù)位:
00:5位
01:6位
10:7位
11:8位(串口通信)
 
bit[2]: 停止位:
0:一位(串口通信)
1:兩位
 
bit[5:3]: Parity(校驗位):
0XX:不校驗(串口通信)
100:奇校驗
101:偶校驗
 
bit[6]: Infrared(紅外模式):
0:常規(guī)模式操作(串口通信)
1:紅外模式
 
UCON0:串口控制寄存器,32位,地址:0xE290_0004=0x5(PLCK時鐘,中斷請求或查詢方式收發(fā)數(shù)據(jù))
 
bit[1:0]: Rx  模式:
00:禁用
01:中斷請求或查詢方式(串口通信)
10:DMA(直接內(nèi)存訪問)模式
 
bit[3:2]: Tx  模式:
00:禁止
01:中斷請求或查詢方式(串口通信)
10:DMA模式
 
bit[4]: break signal:
0:常規(guī)傳送(默認0)
1:發(fā)送break signal
 
bit[5]: 回路模式:用來測試硬件是不是OK。
0:常規(guī)操作(默認0)
1:回路模式
 
bit[6]: Rx  錯誤狀態(tài)中斷使能位:
0:不產(chǎn)生Rx錯誤狀態(tài)中斷(默認0)
1:產(chǎn)生Rx錯誤狀態(tài)中斷
 
bit[7]: Rx   time out使能位:
0:禁止(默認0)
1:使能
 
bit[8]: Rx  中斷類型:
0:pulse(默認0)
1:level
 
bit[9]: Tx  中斷類型:
0:pulse(默認0)
1:level
 
bit[10]: 時鐘選擇位:
0:PCLK,通用外設(shè)時鐘(默認0)
1:SCLK_UART,串口時鐘
 
bit[16]:Rx  DMA觸發(fā)大小:
0:1byte(默認0)
1:4byte
 
bit[20]:Tx  DMA觸發(fā)大小
0:1byte(默認0)
1:4byte
 
UFCON0:uart fifo control register,串口先進先出控制寄存器,32位,地址:0xE290_0008=0x1(啟用FIFO)
FIFO等價于串口的發(fā)送緩沖和接收緩沖。
 
bit[0]:FIFO使能位:
0:禁止
1:使能
 
bit[1]:Rx  FIFO復(fù)位:
0:常規(guī)
1:Rx FIFO 復(fù)位
 
bit[2]:Tx  FIFO 復(fù)位:
0:常規(guī)
1:Tx FIFO復(fù)位
 
bit[6:4]:Rx FIFO觸發(fā)等級:有兩個通道:
 
bit[10:8]:Tx FIFO 觸發(fā)等級:有四個通道:
 
UTRSTAT0:uart   Tx/Rx   status   register:狀態(tài)寄存器,32位,地址:0xE290_0010.
接收數(shù)據(jù)讀取bit【0】,發(fā)送數(shù)據(jù)讀取bit【1】或bit【2】。
 
bit[0]:接收緩沖區(qū)數(shù)據(jù)準(zhǔn)備
0:緩沖區(qū)寄存器為空,說明沒接收成功,循環(huán)等待
1:緩沖區(qū)寄存器有一個被接收的數(shù)據(jù)
 
bit[1]:發(fā)送緩沖區(qū)為空
0:發(fā)送緩沖區(qū)寄存器不為空,說明沒發(fā)送成功,循環(huán)等待
1:發(fā)送緩沖區(qū)寄存器為空
 
bit[2]:發(fā)送器為空
0:不為空,發(fā)送不成功,循環(huán)等待
1:發(fā)送器為空
 
UTXH0:uart transmit buffer register:發(fā)送緩沖區(qū)寄存器,32位,地址:0xE290_0020.
發(fā)送的數(shù)據(jù)。
bit[7:0]:UTXH0,UART0的傳輸數(shù)據(jù)
 
URXH0:uart recive buffer register:接收緩沖區(qū)寄存器,32位,地址:0xE290_0024.
接收的數(shù)據(jù)。
bit[7:0]:URXH0,UART0的接收數(shù)據(jù)
 
UBRDIV0:uart channel baud rate division register:波特率配置寄存器,32位,地址:0xE290_0028
我們用35。
bit[15:0]:UBRDIVn:
 
#define UART_UBRDIV_VAL          35
UBRDIV0 = UART_UBRDIV_VAL;
 
UDIVSLOT0:uart channel dividing slot register: 波特率微調(diào)寄存器,32位,地址:0xE290_002C
我們用0x1.
bit[15:0]:UDIVSLOTn:一般不配置,頻率低需要微調(diào)
 
#define UART_UDIVSLOT_VAL     0x1
UDIVSLOT0 = UART_UDIVSLOT_VAL;
 
波特率計算方法:
DIV_VAL = (PCLK / (bps x 16)) −1
PCLK是66.5*10^6,bps是115200,DIV_VAL取整數(shù)寫入寄存器UBRDIVn。
 
波特率微調(diào)計算方法:
將DIV_VAL的小數(shù)部分乘以16得到的整數(shù)部分查表(見手冊),得到寫入UDIVSLOT0寄存器的值。
 
串口編程:
1.初始化GPIO寄存器設(shè)置為串口模式
2.初始化串口寄存器
3.設(shè)置串口波特率
4.進行數(shù)據(jù)收發(fā)
 
開發(fā)板接收的數(shù)據(jù)由串口終端發(fā)出
開發(fā)板發(fā)送的數(shù)據(jù)在串口終端顯示
 
28 //通過調(diào)用該函數(shù)將接收緩沖區(qū)的數(shù)據(jù)返回給開發(fā)板
29 char uart_getchar()
30 {
31         while (! (UTRSTAT0 & (1 << 0)));
32         return URXH0;
33 }
34
35 //通過調(diào)用該函數(shù),向發(fā)送緩充區(qū)放入數(shù)據(jù),發(fā)送出去
36 void  uart_putchar(char thechar)
37 {
38         while (! (UTRSTAT0 & (1 << 2)));
39         UTXH0 = thechar;
40 }
 
通過串口工具進行調(diào)試
 
------------------------------------
移植printf函數(shù)和scanf函數(shù)
 
函數(shù)的移植:
1.移植linux內(nèi)核中的printk(linux內(nèi)核有自己的庫)
2.移植u-boot中的printf和scanf(u-boot有自己的庫)
3.自己實現(xiàn)
 
庫函數(shù)(printf和scanf)
 
start.S
 
main.c
 
uart.c
 
Makefile
 
通過串口終端進行調(diào)試。
 
------------------------------------
增加命令功能:
類似于linux中的shell
 
實現(xiàn)簡單的幾個命令:
help:獲取命令信息
md:獲取內(nèi)存信息
mw:寫內(nèi)存
loadb:向內(nèi)存上傳文件
go:運行內(nèi)存中的程序
 
start.S
 
main.c
 
uart.c
 
shell.c
 
command.c
 
lib.c
 
stdio.c
 
Makefile
 
通過串口中斷進行調(diào)試。
 
轉(zhuǎn)義字符的使用:
c語言中的/n表示\n(換行)和\r(回車)兩個動作。
 
下面為串口中的識別方法(終端設(shè)備的識別方法):
\r:表示回車,回到當(dāng)前行的行首,也就是最左邊。
\n:表示換行,換到當(dāng)前列的下一行位置。
\b:表示退格,將當(dāng)前位置向前移動一位。
\0:表示空字符。
 
分析:
在c語言程序中通過串口終端發(fā)送\n,實際是想發(fā)送轉(zhuǎn)義字符使串口終端能實現(xiàn)回車鍵的功能(回車和換行),需要再發(fā)送一個\r,才能真正實現(xiàn)這個功能。
在c語言中程序通過串口終端接收\r,實際是想讓開發(fā)板接收到回車,需要再返回一個\n。
 
------------------------------------
時鐘
 
S5pV210有三類時鐘:
主系統(tǒng)時鐘domain(MSYS);
顯示相關(guān)的時鐘domain(DSYS);
外圍設(shè)備的時鐘domain(PSYS)。
 
MSYS:用來給處理器、DRAM控制器,3D、IRAM、IROM、中斷控制器等提供時鐘。
DSYS:用來給顯示部件提供時鐘,F(xiàn)IMC、FIMD、JPEG、IPs等
PSYS:用來給外圍設(shè)備提供時鐘,I2C、SPI、I2S、GPIO,uart等
 
210外接晶振(FIN)24Mhz,通過四個倍頻器(鎖相環(huán),PLL)提高系統(tǒng)時鐘:
APLL(MSYS);
MPLL(DSYS);
EPLL(PSYS);
VPLL(video相關(guān)時鐘使用);
 
MSYS:
ARMCLK         :100MHZ,傳給cpu的時鐘
HCLK_MSYS      :200MHZ
PCLK_MSYS      :100MHZ
HCLK_IMEM      :100MHZ
SCLK_DMC0      :200MHZ
 
DSYS:
HCKL-DSYS      :166MHZ
PCLK_DSYS      :83MHZ
 
PSYS:
HCLK_PSYS           :133MHZ
PCLK_PSYS           :66MHZ
SCLK_ONENAND    :166MHZ
CLK_DPM              :
CLK_DVSEM           :
 
時鐘的硬件組成有:
鎖相環(huán)(倍頻器);
多路選擇器;
分頻器;
 
以下均已配置ARMCLK為例,的到1MHZ輸出個cpu。
 
鎖相環(huán)(PLL)控制寄存器有四類(APLL、MPLL、EPLL、VPLL),以APLL為例:
 
APLL_CON0:APLL控制寄存器0,32位,地址0xE0100100
 
bit[2:0]:SDIV:pll  S分頻值
 
bit[13:8]:PDIV:pll  P 分頻值
 
bit[25:16]:MDIV:pll  M 分頻值
 
bit[29]:Pll  鎖指示位,只讀位
0:解鎖
1:鎖
 
bit[31]:使能位
0:禁止
1:使能
 
S值 P值 M值用下列公式計算:
FOUT = MDIV X FIN / (PDIV × 2^(SDIV-1))
PDIV: 1 ≤ PDIV ≤ 63
MDIV: 64 ≤ MDIV ≤ 1023
SDIV: 1 ≤ SDIV ≤ 5
Fref (=FIN / PDIV): 1MHz ≤ Fref ≤ 12MHz
FVCO (=2 × MDIV × FIN / PDIV): 1000MHz ≤ FVCO ≤ 2060MHz
FOUT就是需要的輸出頻率,根據(jù)以上條件求出SPM三個值給寄存器。
 
APLL_CON1:APLL控制寄存器1(分頻器(鎖相環(huán))),32位,地址0下E0100104
 
bit[4:0]:AFC,AFC值
 
bit[31]:AFC_ENB,AFC使能位
0:禁止
1:使能
 
時鐘的多路選擇器很多,所以時鐘源控制寄存器很多,以0為例:
 
CLK_SRC0:時鐘源控制寄存器0(多路選擇器),32位,地址0xE0100200.
 
bit[0]:APLL_SEL:控制MUXAPLL(和ARMCLK有關(guān))
0:FINAPLL(多路選擇器MUX_APLL的0路輸入)
1:FOUTAPLL(多路選擇器MUX_APLL的1路輸入)
FINAPLL:來自于外接晶振24MHZ
FOUTAPLL:鎖相環(huán)APLL的輸出
 
bit[4]:MPLL_SEL:控制MUXMPLL
0:FINPLL
1:FOUTMPLL
 
bit8]:EPLL_SEL:控制MUXEPLL
0:FINPLL
1:FOUTEPLL
 
bit[12]:VPLL_SEL:控制MUXVPLL
0:FINVPLL
1:FOUTVPLL
 
bit[16]:MUX_MSYS_SEL:控制MUX_MSYS(和ARMCLK有關(guān))
0:SCLKAPLL(多路選擇器MUX_MSYS的0路輸入)
1:SCLKMPLL(多路選擇器MUX_MSYS的1路輸入)
 
bit[20]:MUX_DSYS_SEL:控制MUX_DSYS
0:SCLKMPLL
1:SCLKA2M
 
bit[24]:MUX_MSYS_SEL:控制MUX_PSYS
0:SCLKMPLL
1:SCLKA2M
 
bit[28]:ONENAND_SEL:控制MUXFlash
0:HCLK_PSYS
1:HCLK_DSYS
 
時鐘的分頻器很多,所以時鐘分頻控制寄存器很多,以0為例:
 
CLK_DIV0:時鐘分頻器控制寄存器,32位,地址0xE0100300。
 
bit[2:0]:APLL_RATIO:DIVAPLL時鐘分頻器的比率(和ARMCLK有關(guān))
ARMCLK=MOUT_MSYS / (APLL_RATIO + 1)
MOUT_MSYS為多路選擇器MUX_MSYS的輸出;
ARMCLK為分頻器DIV_APLL的輸出,送給cpu。
 
bit[6:4]:A2M_RATIO:
 
bit10:8]:HCLK_MSYS_RATIO:
 
bit[14:12]:PCLK_MSYS_RATIO:
 
bit[19:16]:HCLK_DSYS_RATIO:
 
bit[22:20]:PCLK_DSYS_RATIO:
 
bit[27:24]:HCLK_PSYS_RATIO:
 
bit[30:28]:PCLK_PSYS_RATIO:
 
時鐘編程參考數(shù)據(jù)手冊實現(xiàn)
 
-------------------------------------
異常處理
 
程序正常執(zhí)行流程中,程序計數(shù)器PC在其地址范圍內(nèi)連續(xù)增加,還可以跳轉(zhuǎn)到附近程序標(biāo)號,
或跳轉(zhuǎn)并連接到子例程。當(dāng)這個常規(guī)執(zhí)行流程被轉(zhuǎn)向到啟用處理器內(nèi)部或外部資源產(chǎn)生的事件時,就發(fā)生了異常。異常是由于軟件錯誤引起的,是不正,F(xiàn)象。
 
210有7中異常(5種異常模式):
1.復(fù)位異常(管理模式)
2.軟件中斷異常(管理模式)
3.未定義指令異常(未定義模式)
4.預(yù)取異常(數(shù)據(jù)訪問終止模式)
5.數(shù)據(jù)異常(數(shù)據(jù)訪問終止模式)
6.IRQ(外部中斷模式)
7.FIQ(快速中斷模式)
 
1.復(fù)位異常:
發(fā)生在處理器上電、或上電后的復(fù)位,是一種硬件異常。
 
2.軟件中斷異常(SWI指令觸發(fā))
用戶定義的同步中斷指令,使得在user模式下運行的程序能夠請求在管理模式下運行的特權(quán)操作。
 
3.未定義指令異常(指令觸發(fā))
當(dāng)處理器或協(xié)處理器都沒有定義該指令時產(chǎn)生。
 
4.預(yù)取指異常
在處理器試圖執(zhí)行一個未取指指令時發(fā)生,因為地址非法。
 
5.數(shù)據(jù)異常
在數(shù)據(jù)傳送指令試圖在非法地址載入或存儲數(shù)據(jù)時發(fā)生。
 
6.IRQ(外部中斷異常)
在處理器外部中斷申請管腳有效(低電平),且cpsr中的I位為清除時發(fā)生。
 
7.FIQ(快速中斷異常)
在處理器外部中斷申請管腳有效(低電平),且cpsr中的F位為清除時發(fā)生。
 
異常發(fā)生時硬件自動處理四件事:
1.PC值變了,pc值跳轉(zhuǎn)到異常向量表;
2.PC跳轉(zhuǎn)之前,pc的值保存到異常模式中的lr中;
3.cpsr更改了;
4.cpsr更改之前,cpsr的值保存到異常模式中的spsr中。
 
異常向量表和異常優(yōu)先級:
向量表占用32字節(jié)空間,向量表為每個異常房分配一個字空間,七種異常占用28字節(jié),加上一個保留字就是32字節(jié)。向量表中保存的是跳轉(zhuǎn)指令或載入pc指令來調(diào)整到相應(yīng)的異常處理程序。當(dāng)多個異常發(fā)生時,從優(yōu)先級高的到優(yōu)先級低的順序處理。
 
異常向量表和優(yōu)先級:
1:復(fù)位異常,在向量表中的地址0x0,異常模式為管理模式
6:未定義指令,地址0x4,未定義模式
6:軟中斷,地址0x8,管理模式
5:預(yù)取指令,地址0xc,數(shù)據(jù)訪問終止模式
2:數(shù)據(jù)異常,地址0x10,數(shù)據(jù)訪問終止模式
4:中斷異常,地址0x18,IRQ模式
3:快速中斷異常,地址0x1c,F(xiàn)IQ模式
 
1.中斷向量表的實現(xiàn)
程序?qū)崿F(xiàn)(以swi為例):
 
//往pc加載一個標(biāo)號
ldr pc,_reset
ldr pc,_und
ldr pc,_swi
ldr pc,_prefetch
ldr pc,_data
b .
ldr pc,_irq
ldr pc,_fiq
 
//用函數(shù)來實現(xiàn)
_swi:
     .word swi
 
2.恢復(fù)通用寄存器和cpsr的異常
(所以在正常模式中要設(shè)置六種模式的六個棧(五個異常模式和正常模式))
stmfd sp!,{r0-3,r14}     //壓棧
//異常處理
ldmfd sp!,{r0-r3,pc}^     //出棧,^用來恢復(fù)cpsr(將異常模式中的spsr給正常模式的cpsr)
 
3.恢復(fù)pc的異常
產(chǎn)生異常時,程序計數(shù)器指向的實際位置取決于異常的類型,也就是說pc跳轉(zhuǎn)前保存到lr中的pc值和異常類型有關(guān)。
如果異常發(fā)生在arm狀態(tài),就將pc-4保存在lr中(正在執(zhí)行的指令占一個字,已經(jīng)讀取的指令占用一個字,pc指向的指令占用一個字,所以pc-4就是返回到已經(jīng)讀取還沒執(zhí)行的指令繼續(xù)執(zhí)行);
如果是thumb狀態(tài),那個每種異常下的保存到pc中的值是不同的,所以需要軟件程序中指定pc值,才能在異常處理完后正常返回到arm代碼。
 
軟中斷和未定異常:
從已經(jīng)取指的指令繼續(xù)執(zhí)行即可
 
異常返回:
mov pc,lr
 
異常處理:
stmfd sp!,{r0-3,r14}     
//異常處理
ldmfd sp!,{r0-r3,pc}^  
 
FIQ和IRQ異常:
pc被更新,存入lr的位pc-4,需要從正在執(zhí)行的指令開始執(zhí)行
 
從異常返回:
subs pc,lr,#4     
 
異常處理:
sub lr,lr,#4     
stmfd sp!,{r0-3,r14}     
//異常處理
ldmfd sp!,{r0-r3,pc}^ 
 
 
預(yù)取指令異常:
由于取指令失敗,所以pc還沒有更新,也就是說pc指向正在執(zhí)行的指令的下一條取指失敗的指令位置,而不是已經(jīng)取指的指令的下一條指令位置,返回的程序需要回到正在執(zhí)行的指令處,重新取指。
 
從異常返回:
subs pc,lr,#4     
異常處理
sub lr,lr,#4     
stmfd sp!,{r0-3,r14}     
//異常處理
ldmfd sp!,{r0-r3,pc}^ 
 
數(shù)據(jù)中斷異常:
pc被更新,指向已經(jīng)取指的下一條指令位置,返回時,需要返回到發(fā)生異常的指令。
從異常返回
subs pc,lr,#8
異常處理
sub lr,lr,#8
stmfd sp!,{r0-3,r14}     
//異常處理
ldmfd sp!,{r0-r3,pc}^ 
 
函數(shù)的實現(xiàn)(swi為例):
swi:
     stmfd sp!,{r0-r3,r14}
     //可以實現(xiàn)自己需要的一些操作,跳轉(zhuǎn)過去即可
     ldmfd sp!,{r0-r3,pc}^
 
4.觸發(fā)異常(以swi為例)
添加命令,在中斷輸入命令就可以觸發(fā)軟中斷。
 
swi_test1:
     stmfd sp!,{lr}
     swi 1
     ldmfd sp!,{pc}
 
------------------------------------
中斷(一種特殊的異常)
 
中斷:cpu對系統(tǒng)發(fā)生的某個時間作出的反應(yīng),cpu暫停正在執(zhí)行的程序,保留現(xiàn)場后自動的轉(zhuǎn)去執(zhí)行相應(yīng)的處理程序,處理完該時間后再返回斷點繼續(xù)執(zhí)行被打斷的程序。
 
中斷時cpu硬件具備的功能,是正,F(xiàn)象,系統(tǒng)停止當(dāng)前正在運行的程序而轉(zhuǎn)向其他服務(wù),可能是因為優(yōu)先級高的請求了服務(wù),或者人為的安排。
 
210的中斷控制器組成:
4個向量中斷控制器VIC;
ARM PrimeCell PL192;
4個TrustZone Interrupt Controller (TZIC);
 
210支持93個中斷源。
 
cpu處理中斷過程:
cpu執(zhí)行每條指令前都會檢查有沒有中斷發(fā)生,若有硬件進行如下處理:
1.cpu進入irq模式;
2.將cpsr保存到spsr;
3.使用irq模式的r13和r14;
4.把下一條指令的地址存到r14;
5.跳轉(zhuǎn)到irq程序入口地址。
 
軟件進行的處理:
1.保存現(xiàn)場;
2.處理中斷(判斷中斷,調(diào)用相應(yīng)的處理函數(shù),清中斷);
3.恢復(fù)現(xiàn)場。
 
1.從數(shù)據(jù)手冊得到中斷控制寄存器的信息:
p565
 
2.程序編寫
將按鍵的管腳設(shè)置為中斷管腳(按下按鍵產(chǎn)生中斷來點亮led)
設(shè)置中斷向量表;
初始化中斷控制器;
保護現(xiàn)場;
進入中斷模式;
判斷中斷;
中斷處理函數(shù);
清中斷;
恢復(fù)現(xiàn)場。
 
初始化中斷控制器:
禁止所有中斷;
選擇中斷類型為irq;
清VICxADDR;
 
------------------------------------
系統(tǒng)定時器
 
參考數(shù)據(jù)手冊
-------------------------------------
pwm定時器
 
210有5個32位的PWM定時器,其中0、1、2、3有pwm功能,4沒有輸出引腳。
 
PWM使用PCLK_PSYS作為時鐘源。
-------------------------------------
watchdog定時器
 
看門狗定時器相當(dāng)于一個16位的普通定時器?撮T狗定時器和pwm定時器的區(qū)別在于它可以產(chǎn)生reset信號。
------------------------------------
RTC實時時鐘
 
RTC就是實時時鐘芯片,用于在系統(tǒng)斷電時,利用備用的電池記錄時間。
-----------------------------------------------------------------------------------------------------------------------------------------------
外圍編程
----------------------------------------------------
DMA(Direct Memory Access)
DMA關(guān)閉外設(shè)從內(nèi)存獲取數(shù)據(jù)需要經(jīng)過cpu,有了cpu外設(shè)可以直接從內(nèi)存獲取數(shù)據(jù)。
DMA可以從內(nèi)存直接讀取數(shù)據(jù),解放cpu,由DMA控制器來從內(nèi)存獲取數(shù)據(jù)。
對DMA控制器進行操作,設(shè)置DMA控制器的源地址、目的地址、長度,數(shù)據(jù)傳送到DMA之后產(chǎn)生一個中斷,表示數(shù)據(jù)傳輸完成。
 
1.從數(shù)據(jù)手冊得到DMA寄存器信息:
p754
----------------------------------------------------
MMU(Memory Management Unit)
 
存儲管理單元的作用:
1.權(quán)限管理
2.地址映射
 
cpu內(nèi)核-MMU-存儲管理器-DRAM
------------------------------------------------------
DRAM(內(nèi)存)(以DDR2為例)
 
有四塊ddr2,每塊128Mb,共512Mb。
 
管腳分析:
CK/nCK:兩個不同的時鐘輸入
CKE:時鐘使能輸入
nCS:片選輸入
nWE/nRAS/nCAS:命令輸入
ODT:死亡終點輸入
DM:輸入數(shù)據(jù)掩碼
DQS:輸入輸出口,讀數(shù)據(jù)輸出,寫數(shù)據(jù)輸入
nDQS:輸入輸出口,
BA0-BA2:bank地址輸入口
A0-A13:地址輸入總線
DQ0-7:輸入輸出口,數(shù)據(jù)總線
 
1.從電路原理圖得接口信息:
CK:       Xm1SCLK
nCK:       Xm1SCLKn
CKE:       Xm1CKE0
nCS:       Xm1CSn0
nWE:    Xm1WEn
nRAS:   Xm1RASn
nCAS:     Xm1CASn
DM:        Xm1DM0
DQS:       Xm1DQS0
nDQS:     Xm1DQSn0
BA0:     Xm1BA0
BA1:      Xm1BA1
BA2:      Xm1CSn1/BA2:Xm1CSn1
A0-A13:  Xm1ADDR[13:0]:Xm1ADDR0-13
DQ0-7:   Xm1DATA[7:0]:Xm1DATA0-7
 
2.從數(shù)據(jù)手冊得到DRAM初始化信息
 
P596
3.從收據(jù)手冊得DRAM控制寄存器信息
P614
參考uboot的實現(xiàn)
------------------------------------------------------
存儲設(shè)備(以NAND為例)
 
內(nèi)存(RAM):掉電易失,DRAM/SDRAM等,pc機叫DDR內(nèi)存。
閃存(Flash/ROM):非掉電易失,NOR(很少用),NAND(SLC、MLC),U盤、MMC卡和SD卡(TF卡已經(jīng)被淘汰)也算NAND,pc機叫硬盤。
 
RAM:分為SRAM和DRAM(SDRAM已經(jīng)淘汰);SRAM開機就可以用,通常集成在CPU內(nèi)部;SDRAM開機需要初始化才能用。
ROM:一般集成在CPU內(nèi)部,作為固件使用。
 
對flash閃存的寫入操作只能在空或已擦出的單元進行,NAND的擦除是以8-32kb的塊進行的;NAND的接口使用復(fù)雜的I/O口來串行的存取數(shù)據(jù),NAND的讀和寫采用512byte的塊。
 
以三星的單片128MB的NAND SLC為例:
512MB*8bit,48pin
 
輸入和輸出是相對于NAND芯片的,輸入(寫)為從cpu到nand,輸出(讀)為從nand到cpu。
讀:數(shù)據(jù)從nand到cpu;
寫:數(shù)據(jù)從cpu到nand。
 
I/O 0-7:八位數(shù)據(jù)位,命令、地址、數(shù)據(jù)都通過這八位輸入和輸出,和cpu進行數(shù)據(jù)交換?臻e時為高阻態(tài)。
CLE:命令鎖存使能,當(dāng)CLE=1時,I/O口的輸入為命令在~WE的上升沿被鎖存。
ALE:地址鎖存使能,當(dāng)ALE=1時,I/O口的輸入為地址在~WE的上升沿被鎖存。
當(dāng)CLE和ALE都是低電平時,I/O的輸出為數(shù)據(jù)。
#CE:芯片使能,輸入,設(shè)備選擇控制引腳,低電平使能。
#RE:讀使能,輸入,,在~RE下降沿數(shù)據(jù)讀入有效,數(shù)據(jù)從nand到cpu,同時自動使內(nèi)部列地址計數(shù)器加1,下降沿鎖存。
#WE:寫使能,輸入,控制I/O口的寫操作,低電平有效,數(shù)據(jù)從cpu到nand,I/O口在~WE的上升沿被鎖存。
#WP:寫保護,輸入,低電平時,內(nèi)部高壓產(chǎn)生器復(fù)位,nand只讀。
R/#B:就緒/忙碌輸出信號,輸出,指明設(shè)備狀態(tài),低電平時,表示一個編程、擦出或隨機讀操作正在進行(也就是busy),操作完成變成高電平(也就是ready)。
 
NAND的單位:
5地址周期
頁   :1page=2kb+64byte(校驗)
塊   :1block=64pages
設(shè)備:1device=8192blocks
 
NAND操作方法:
NAND內(nèi)部固化了命令,可以直接使用,通過命令進行操作。
寫入命令、地址、數(shù)據(jù)時,需要將~WE、~CE同時拉低,數(shù)據(jù)在~WE的上升沿被NAND鎖存;
命令鎖存信號CLE、地址鎖存信號ALE用來分辨、鎖存命令或地址;
 
存取NAND上的數(shù)據(jù)需要五個地址序列:
2個序列的列地址(頁內(nèi)偏移);
3個序列的行地址(頁號)。
塊擦除只需要3個行地址序列,因為頁內(nèi)偏移為0,就是從頁首開始擦除。
 
NAND訪問方法:
先傳輸命令,然后傳輸?shù)刂,最后讀寫數(shù)據(jù);
 
1.從電路原理圖得到管腳信息:
#CE:   Xm0CSn2/NFCSn0:            MP01_2
CLE:    Xm0FCLE/ONDAVD:          MP03_0
ALE:    Xm0FALE/ONDSMCLK:       MP03_1
#WE:   Xm0FWEn/ONDRPn:         MP03_2
#RE:    Xm0FREn:                      MP03_3
R/#B:     Xm0FRnB0/ONDXL_INT0: MP03_4
I/O 7-0:Xm0DATA[7:0]:                   MP06_7——0
 
2.從數(shù)據(jù)手冊得到cpu控制nand的寄存器的信息:
 
MP01,MP03,MP04,MP05,MP06,MP07各有八個管腳,MP02只有4個管腳。
MP01,MP02,MP03位控制位,MP04,MP05位地址位,MP06,MP07為數(shù)據(jù)位。
在nand中只使用他們的控制寄存器,將所有管腳設(shè)置為nand模式相關(guān)即可。
 
MP0_1CON:MP0_1控制寄存器,32位,每四位控制一個管腳,地址:0xE02002E0
MP0_1CON = 0x22333322;
 
MP0_2CON:MP0_2控制寄存器,32位,每四位控制一個管腳,地址0xE0200300
MP0_2CON = 0x00002222;
MP0_3CON:MP0_3控制寄存器,32位,每四位控制一個管腳,地址0xE0200320
MP0_3CON = 0x22222222;
 
3.從數(shù)據(jù)手冊得到nand控制寄存器的信息:
 
NFCONF:nand flash configuration register,nand flash配置寄存器,32位,地址:0xB0E00000
 
bitf[1]:地址周期
0: 1page=512bytes,為3地址周期;1page=2k或4k,為4地址周期;
1:1page=512bytes,為4地址周期;1page=2k或4k,為5地址周期(nand使用);
 
bit[2]:頁大小
0:MLCFlash=0,2k;(nand使用)         MLCFlash=1,4k;
1:MLCFlash=0,512bytes;                  MLCFlash=1,2K
 
bit[3]:MLCFlash,判斷那種flash,SLC和MLC
0:SLC(nand使用)
1:MLC
 
bit[7:4]:TWRPH1:從#WE開始結(jié)束使能(上升沿)開始,到CLE和ALE開始結(jié)束鎖存之前(下降沿開始之前)這段時間
1111:給最長的時間
 
bit[11:8]:TWRPH0:從#WE開始使能(下降沿)之后,到#WE結(jié)束使能之前(上升沿開始之前)這段時間
1111:給最長的時間
 
bit[15:12]:TACLS:從CLE和ALE鎖存(上升沿)開始,到#WE開始使能(下降沿)之前的這段時間
1111:給最長的時間
 
bit[24:23]:ECC type0:校驗類型
00:不校驗
 
bit[25]:MsgLength
0:512byte(不用,給0)
 
NFCONT:控制寄存器,32位,地址:0xB0E00004.
 
bit[0]:mode:模式位
0:禁用nand控制器(默認值)
1:啟用nand控制器(設(shè)置值)
 
bit[1]:Reg_nCE0:nand flash memory nRCS[0] signal control
0:給低電平,片選使能(設(shè)置值)
1:給高電平,片選禁止(默認值)
 
bit[2]:Reg_nCE1:nand flash memory nRCS[1] signal control
0:給低電平,片選使能
1:給高電平,片選禁止
 
bit[3]:HW_nCE
 
bit[4]:initSECC:
 
bit[5]:initMECC
 
bit[6]:SECCLock
 
bit[7]:MECCLock
 
bit[8]:RnB_TransMode
 
bit[9]:EnblRnBINT
 
bit[10]:EnblllegalAccINT
 
bit[12]:EnbMLCDecINT
 
bit[13]:EnbMLCEncINT
 
bit[16]:LOCK
 
bit[17]:LockTight
 
bit[18]:MLCEccDirction
 
bit[22]:Reg_nCE2:nand flash memory nRCS[2] signal control
0:給低電平,片選使能
1:給高電平,片選禁止
 
bit[23]:Reg_nCE3:nand flash memory nRCS[3] signal control
0:給低電平,片選使能
1:給高電平,片選禁止
 
NFCMMD:nand 命令寄存器,32位,8位有效,地址:0xB0E00008
 
bit[7:0]:REG_CMMD,nand 命令值
 
NFADDR:nand地址寄存器,32位,8位有效,地址:0xB0E0000C
 
bit[7:0]:REG_ADDR,nand 地址值
 
NFDATA:nand 數(shù)據(jù)寄存器,32位,地址:0xB0E00010
 
bit[31:0]:nand 數(shù)據(jù)值
 
NFSTAT:NFCON status register:nand控制狀態(tài)寄存器,32位,地址:0xB0E00028。
 
bit[0]:flash_RnB:RnB[0]輸入管腳狀態(tài),只讀位
0:nand busy
1:nand ready to operate
 
bit[2]:falsh_nCE[0]:nCE[0]輸出管腳狀態(tài),只讀位
 
bit[3]:flash_nCE[1]:nCE[1]輸出管腳狀態(tài),只讀位
 
bit[4]:RnB_TansDetect:檢測RnB[0]管腳的狀態(tài)
0:RnB 的變化不會被捕獲,為busy,不能用
1:RnB的變化會被捕獲,為ready,可用
 
bit[5]:IllegalAccess
 
bit[6]:MLCDecodeDone:
 
bit[7]:MCLEncodeDone:
 
bit[11:8]:flash_nCE[3:0]:nCE[3:0]輸出管腳的狀態(tài),只讀位
 
bit[27:24]:RnB_TransDetect_GRP:檢測RnB[3:0]管腳的狀態(tài)
0:RnB變化不會被捕獲
1:RnB變化會被捕獲
 
bit[31:28]:flash_RnB_GRP:RnB[3:0]輸入管腳的狀態(tài),只讀位
0:nand busy
1:nand ready to operate
 
程序?qū)崿F(xiàn):
參考數(shù)據(jù)手冊的時序和nand命令來實現(xiàn)。
------------------------------------------------------
ADC(210cpu內(nèi)置ADC功能)
 
210的ADC支持10bit和12bit,支持10路輸入,然后將輸入的模擬信號轉(zhuǎn)換成10bit或12bit的二進制數(shù)字信號。
關(guān)閉窗口

相關(guān)文章