|
5Àå¿¡¼´Â ¿ì¸®°¡ ½Ç½À¿¡ »ç¿ëÇÒ Mini2440 °³¹ßº¸µå¸¦ °¡Áö°í Áö±Ý±îÁö ÀÌ·ÐÀ¸·Î¸¸ °øºÎÇß´ø ¾î¼Àºí¸®¾î¿Í C¾ð¾î¸¦ ÀÌ¿ëÇؼ ÁÖº¯ ÀåÄ¡µéÀ» Á¦¾îÇÏ´Â ½Ç½ÀÀ» Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ½ÇÁ¦ ŸÄϺ¸µå¿¡ ³»°¡ ÀÛ¼ºÇÑ ÇÁ·Î±×·¥À» ´Ù¿î·ÎµåÇÏ¿© µ¿ÀÛÀ» È®ÀÎÇÏ´Â ÀÏÀº Ç×»ó °¡½¿ÀÌ ¼³·¹ÀÔ´Ï´Ù.
5. S3C2440 °³¹ßº¸µå ½Ç½À
5.1 S3C2440 Startup ÄÚµå ºÐ¼®
ARM°³¹ßº¸µåÀÇ ºÎÆ®ÄÚµå(Startup)¿¡´Â Áö±Ý±îÁö ÀÌ·ÐÀ¸·Î ¹è¿ü´ø ³»¿ëµéÀÌ °ÅÀÇ ¸ðµÎ Æ÷ÇÔÀÌ µÇ¾î ÀÖ½À´Ï´Ù. ºÎÆ® Äڵ常 Àß ºÐ¼®Çصµ CPUÀÇ 50% ÀÌ»óÀº ¾Ë°í ÀÖ´Ù°í Çصµ °ú¾ðÀÌ ¾Æ´Õ´Ï´Ù. ºÎÆ®ÄÚµå ±â´ÉÀ» °£·«ÇÏ°Ô ¿ä¾àÇØ º¸¸é ¾Æ·¡¿Í °°½À´Ï´Ù.
– Clock & Power Initialization
– Setup each exception handler
– Memory (SDRAM) Initialization
– Peripheral Initialization
– Stack Initialization for each Processor Mode
– Interrupt Handler Setup
– Segment Initialization
– Jump to User Application
ÀÌÁ¦ºÎÅÍ ºÎÆÃÀÌ µÇ´Â ¼ø¼´ë·Î ½ÇÁ¦ Äڵ带 ºÐ¼®ÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.
(1) Exception Vector Table
__program_start
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
|
CPU¿¡ Àü¿øÀÌ Àΰ¡µÇ¸é óÀ½À¸·Î ½ÃÀ۵Ǵ Vector Table(0x0000 0000) ÀÔ´Ï´Ù.
(2) Watchdog Disable
Watchdog °¡ ¹«¾ùÀϱî¿ä? Á÷¿ªÀ» Çϸé "ÁöÅ°´Â°³" ÀÌ·± ¶æÀ̳׿ä. Watchdog´Â º¸Åë S/W ÀûÀ¸·Î ¼³Á¤ÇÑ ½Ã°£µ¿¾È Kick(ÁýÁöÅ°´Â °³¸¦ Çѹø¾¿ Â÷ÁÖ¾î¾ß ÀáÀ» ÀÚÁö ¾Ê°ÚÁÒ ... ^) À» ÇØÁÖÁö ¾ÊÀ¸¸é CPU¸¦ Reset ½ÃÅ°´Â ±â´ÉÀ¸·Î ÁÖ·Î »ç¿ëÇÕ´Ï´Ù. ¿Ö ÀÌ·± ±â´ÉÀÌ ÇÊ¿äÇÑ °É±î¿ä ? ¿ì¸®°¡ ÀÚÁÖ »ç¿ëÇÏ´Â ½º¸¶Æ®ÆùÀ» ¿¹·Î µé¾î º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ½º¸¶Æ®Æù »ç¿ëÁß¿¡ ¾î¶² AppÀ» ½ÇÇà½ÃÄ״µ¥ ±× ÀÌÈÄ·Î ½º¸¶Æ®ÆùÀÌ ±× App¶§¹®¿¡ ÅÍÄ¡µµ µÇÁö¾Ê°í, Àü¿ø ¹öÆ°µµ ÀÔ·ÂÀÌ µÇÁö ¾Ê°Ô ¸ÔÅëÀÌ µÇ¾ú´Ù°í °¡Á¤À» ÇÏ¸é º£Å͸®¸¦ ºÐ¸®½ÃŲ ÈÄ ´Ù½Ã ¿¬°áÇÏ´Â ¹æ¹ýÀÌ¿Ü¿¡´Â ¹æ¹ýÀÌ ¾ø½À´Ï´Ù. À̶§ ¸¸¾à Watchdog°¡ È°¼ºÈ µÇ¾î ÀÖ´Ù¸é ½º¸¶Æ®ÆùÀÌ ¸ÔÅëÀÌ µÇ´Â ¼ø°£ S/W ÀûÀ¸·Î ¼³Á¤ÇÑ ½Ã°£µ¿¾È KickÀÌ ¾øÀ¸¸é ½º¸¶Æ®ÆùÀÌ Reset(Àç ºÎÆÃ)ÀÌ µÇ¾î ´Ù½Ã »ç¿ëÇÒ ¼ö ÀÖ´Â »óÅ°¡ µÉ°ÍÀÔ´Ï´Ù. º£Å͸®¸¦ ºÐ¸®Çϴ°żҴٴ ³´°ÚÁÒ..
±×¸®°í ºÎÆ®Äڵ忡¼ Watchdog Disable Çϴ°ÍÀº ºÎÆÃÀÌ ¿Ï·áµÇ±âµµ Àü¿¡ Watchdog¿¡ ÀÇÇؼ CPU°¡ ResetÀÌ µÇ´Â°ÍÀ» ¹æÁöÇϱâ À§Çؼ ÇÏ´Â°Í ÀÔ´Ï´Ù.
0x5300 0000 ¹øÁöÀÇ SFR ·¹Áö½ºÅ͸¦ Á¦¾îÇϸé WTCONÀ» ¼³Á¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. ½ÇÁ¦·Î´Â 5¹ø ºñÆ®¸¸ "0 = Disable" Çصµ µË´Ï´Ù.
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
|
(3) Interrupt Disable
ºÎÆÃÁß¿¡ ¿¹ÃøÇÏÁö ¸øÇÏ´Â ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏÁö ¾Êµµ·Ï Disable Çϴ°ÍÀÌ ¾ÈÀü ÇÕ´Ï´Ù.
- Core Level Disable: CPSR ·¹Áö½ºÅÍÀÇ I, F Çʵ带 "1" ·Î MaskÇÕ´Ï´Ù.
CPSR.I (1), CPSR.F(1) : ºÎÆýÿ¡ "1" ·Î ¸¶½ºÅ·µÇ¾î ÀÖ½À´Ï´Ù.
- S3C2440 CPU Level ÀÇ Interrupt Controller ¸¦ Disable ÇÕ´Ï´Ù.
Interrupt Mask Register
Interrupt SubMask Register
¾Æ·¡ ±×¸²Àº S3C2440 CPUÀÇ ÀÎÅÍ·´Æ® ÄÁÆ®·Ñ·¯ ºí·°µµ ÀÔ´Ï´Ù. " S3C2440 CPU Level ÀÇ Interrupt Controller ¸¦ Disable" ÇÑ´Ù´Â °ÍÀº ¾Æ·¡ ºí·°µµ¿¡¼ ¹Ù·Î "SUBMASK", "MASK" ¸¦ Disable("1" ·Î Mask) ÇÑ´Ù´Â °ÍÀÔ´Ï´Ù.
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]
|
(4) PLL ¼³Á¤
¿ì¸®°¡ »ç¿ëÇÏ´Â S3C2440 Mini °³¹ßº¸µå´Â ¿ÜºÎ Crystal·Î 12MHz¸¦ »ç¿ë ÇÕ´Ï´Ù.
Input Frequency °¡ 12MHz À϶§, FCLK:HCLK:PCLK = 400MHz : 100MHz : 40MHz, Áï 1:4:8 ºñÀ²·Î ºÐÁÖ°¡ µÇµµ·Ï ¼³Á¤ ÇÕ´Ï´Ù.
(4.1) Clock Divider Control Register(CLKDIVIN) ¼³Á¤
CLKDIV_VAL°ªÀÌ "b0101" À¸·Î ¼¼ÆÃÀÌ µÇ¾î ÀÖ¾î¼ FCLK:HCLK:PCLK = 1:4:8 ºñÀ²·Î ºÐÁÖ°¡ µÇµµ·Ï ¼³Á¤ÀÌ µË´Ï´Ù.
ÃÖÁ¾ÀûÀ¸·Î´Â 12MHzÀÇ ÀÔ·ÂÁÖÆļö¸¦ ¹Þ¾Æ¼ µ¿ÀÛ ÁÖÆļö°¡ 400MHz°¡ µÇµµ·Ï ¼³Á¤ ÇÕ´Ï´Ù.
(4.2) UPLL Control Register(USB CLK) ¼³Á¤
Upll = (m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
Fin = FCLKÀÔ·ÂÀ¸·Î µé¾î¿À´Â Crystal ÁÖÆļö 12MHz
UPLL = ((56+8)*12) / ((2+2)*2*2) = 48MHz
UPLLÀº USBÄÁÆ®·Ñ·¯¿¡¼ »ç¿ëÇÒ CLK À¸·Î °á±¹Àº 12MHz Crystal ÀÔ·ÂÀ» ¹Þ¾Æ¼ 48MHz¸¦ ¸¸µé¾î¼ »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù.
(4.3) MPLL Control Register(Main CLK) ¼³Á¤
Mpll = (2 * m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
MPLL = (2*(92+8)*12) / ((1+2)*2*1) = 400MHz
MPLLÀº °á±¹Àº 12MHz Crystal ÀÔ·ÂÀ» ¹Þ¾Æ¼ FCLK = 400MHz,
HCLK = 100MHz,
PCLK = 50MHz ¸¦ ¸¸µé¾î¼ »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù. HCLK°ú PCLKÀÇ °è»êÀº
CLKDIV ·¹Áö½ºÅÍ ¼³Á¤À» FCLK:HCLK:PCLK = 1:4:8 ºñÀ²·Î ºÐÁÖºñ¸¦ ¼³Á¤ Ç߱⠶§¹®¿¡ ÀÚµ¿À¸·Î °è»êÀÌ µË´Ï´Ù.
- ÂüÁ¶·Î PLL °è»ê ¹æ½ÄÀº S3C2440 Datasheet ¸¦ ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù.
ldr r0,=CLKDIVN ; 0x4C000014
ldr r1,=CLKDIV_VAL ; CLKDIV_VAL=5 ---> 1:4:8
str r1,[r0]
;Configure UPLL
ldr r0,=UPLLCON ; 0x4C000008
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ; U_MDIV=56, U_PDIV=2, U_SDIV=2
str r1,[r0]
;Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
str r1,[r0]
|
(5) Internal Bus Mode
- Synchronous : Core Clock System Clock(HCLK) ¿¡ µ¿±âÈ µÇ¾î »ç¿ë
- Asynchronous : System Clock(HCLK)°ú °ü°è¾øÀÌ Free Running Clock(FCLK) À» ÀÌ¿ë
¿ì¸®´Â FCLKÀ» ÀÌ¿ëÇÒ °ÍÀ̱⠶§¹®¿¡ MMU_SetAsyncBusMode ÇÔ¼ö¸¦ È£Ãâ ÇÏ¿´½À´Ï´Ù.
(6) Memory System ÃʱâÈ
½Ã½ºÅÛ¿¡ ¿¬°áµÇ FLASH, SDRAM, I/O Device µî°ú °°Àº ÀåÄ¡µéÀ» Á¦¾îÇϱâ À§Çؼ Memory Controller¸¦ ÃʱâÈ ÇØ¾ß ÇÕ´Ï´Ù.
– Access Timing
– Data Bus Width
– Wait Cycle
– Refresh Rate
– Bank Memory Size
¼Ò½º ÄÚµåµéÀÌ ²Ï ¾Ë¾Æ¸Ô±â Èûµç ÄÚµåµéÀ̳׿ä. º¹ÀâÇØ º¸ÀÌÁö¸¸ ÇÏ´Â ÀÏÀº BWSCONÁÖ¼ÒÀÇ SFR ¿¡ SMRDATA ÀÇ 4Byte(32-bit) µ¥ÀÌÅ͵éÀ» ·çÇÁ¸¦ µ¹¸é¼ Write ÇÏ´Â °ÍÀÔ´Ï´Ù.
- SMRDATA : ¸Þ¸ð¸® ÄÁÆ®·Ñ·¯ SFR¿¡ ±â·ÏÇÒ ³»¿ëµéÀ» 4Byte ±æÀÌ·Î Çؼ Å×À̺í ÇüÅ·Πµ¥ÀÌÅ͸¦ ¼øÂ÷ÀûÀ¸·Î °¡Áö°í ÀÖ½À´Ï´Ù.
- BWSCON : S3C2440 ¸Þ¸ð¸® ÄÁÆ®·Ñ·¯ÀÇ SFR ÁÖ¼Ò ÀÔ´Ï´Ù.
¼Ò½º ÆÄÀÏÀÇ memcfg.inc ¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ½À´Ï´Ù.
;BWSCON
DW8 EQU (0x0)
DW16 EQU (0x1)
DW32 EQU (0x2)
WAIT EQU (0x1<<2)
UBLB EQU (0x1<<3)
B1_BWSCON EQU (DW32)
B2_BWSCON EQU (DW16)
B3_BWSCON EQU (DW16+WAIT+UBLB)
B4_BWSCON EQU (DW16) ; N.C.
B5_BWSCON EQU (DW16) ; N.C.
B6_BWSCON EQU (DW32) ; MINI2440 SDRAM(K4S281632C)-2M*16bit*4Bank*2, SDRAM(K4S561632C) 32MBx2, 32-bit
B7_BWSCON EQU (DW32) ; N.C.
SMRDATAÀÇ ¸Çù¹ø° µ¥ÀÌÅ͵éÀÌ ¹«¾ùÀ» ÀǹÌÇϴ°ÍÀϱî¿ä ?
(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
-->
(0+(0x2<<4)+(0x1<<8)+(0xD<<12)+(0x1<<16)+(0x1<<20)+(0x2<<24)+(0x2<<28))
»óÀ§ ºñÆ®ºÎÅÍ »ìÆ캸µµ·Ï ÇÏ°Ú½À´Ï´Ù.
- (0x2<<28) = DW7[29:28] = Bank7¿¡´Â ¾î¶² Memory µð¹ÙÀ̽ºµµ ¿¬°áµÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù. »ç½ÇÀº ¹«ÀǹÌÇÑ ÄÚµå ÀÔ´Ï´Ù.
- (0x2<<24) = DW6[25:24] = Bank6Àº SDRAMÀÌ ¿¬°áµÇ¾î ÀÖ´Â ¸Þ¸ð¸® ¹ðÅ© ÀÔ´Ï´Ù. µ¥ÀÌÅÍ ¶óÀÎÀº 32bit(2b10) ÀÔ´Ï´Ù.
- (0x1<<20) = DW5[21:20] = N.C(Not connected)
- (0x1<<16) = DW4[17:16] = N.C(Not connected)
- (0xD<<12) = ST3[15], WS3[14], DW3[13:12] = 16-bit DM9000 Ehternet ÄÁÆ®·Ñ·¯ ¼³Á¤ ÀÔ´Ï´Ù.
- (0x1<<8) = DW2[9:8] = N.C(Not connected)
- (0x2<<4) = DW1[5:4] = N.C(Not connected)
- DW0[2:1] = Read only ¿µ¿ªÀ¸·Î OM[1:0] ÇÉ¿¡ ÀÇÇؼ °áÁ¤ µË´Ï´Ù . ¿ì¸®°¡ »ç¿ëÇÏ´Â °³¹ßº¸µå´Â 16bit Data widthÀÇ NOR Flash ÀÔ´Ï´Ù.
³ª¸ÓÁö µ¥ÀÌÅÍ ¼³Á¤°ªµéµµ Datasheet¸¦ ÂüÁ¶Çؼ ºÐ¼®ÇØ º¸½Ã±â ¹Ù¶ø´Ï´Ù.
;Set memory control registers
ldr r0,=SMRDATA
ldr r1,=BWSCON ; 0x48000000
add r2, r0, #52 ;End address of SMRDATA
L5
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne L5
.
.
.
LTORG
SMRDATA DATA
DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7 CL=3clk
DATA
|
(7) Stack Pointer ÃʱâÈ
°¢ ÇÁ·Î¼¼¼ ¸ðµåº°(7°³ µ¿ÀÛ¸ðµå)·Î Processor Mode¸¦ ÀüȯÇÏ¸é¼ StackÀ» ÃʱâÈ ÇØ¾ß ÇÕ´Ï´Ù. ÀÌÀü °ÁÂÀÎ ARM ArchitectureÀÇ ARM Register ºÎºÐÀ» ´Ù½Ã º¸½Ã¸é R13(SP) ´Â °¢ µ¿ÀÛ ¸ðµåº°·Î ¹ðÅ©µÇ µÇ¾î ÀÖ´Â ·¹Áö½ºÅÍÀÓÀ» È®ÀÎ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿©±â¼ ÁÖÀÇÇØ¾ß ÇÒ Á¡Àº User Mode StackÀº Á¦ÀÏ ¸¶Áö¸·¿¡ ÃʱâÈ ÇØ¾ß ÇÕ´Ï´Ù. ¿Ö ±Û·²±î¿ä ? User Mode ´Â ºñ Ư±Ç ¸ðµåÀ̹ǷΠÇѹø User Mode·Î ÁøÀÔÀ» Çϸé SWI ¸í·ÉµîÀ» »ç¿ëÇÏÁö ¾ÊÀ¸¸é ´Ù½Ã Ư±Ç ¸ðµå·Î ÁøÀÔÀ» ÇÒ ¼ö ¾ø¾î¼ ´Ù¸¥ Processor ModeÀÇ Stack Pointer¸¦ ÃʱâÈ ÇÒ ¼ö°¡ ¾ø½À´Ï´Ù. ÀÌ·± ÀÌÀ¯·Î Çؼ User Mode ÀÇ Stack Pointer¸¦ Á¦ÀÏ ¸¶Áö¸·¿¡ ÃʱâÈ Çϵµ·Ï ÇØ¾ß ÇÕ´Ï´Ù.
;function initializing stacks
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1
;AbortMode
ldr sp,=AbortStack
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
;// ¾Æ·¡(System Mode Stack) ºÎºÐ Ãß°¡ ÇÔ.
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SYSMODE
msr cpsr_cxsf,r1 ;SYSMode
ldr sp,=SYSStack
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack
;USER mode has not be initialized. We use always SVC mode.
mov pc,lr
;The LR register won't be valid if the current mode is not SVC mode.
|
(8) Segment Initialization
ROM Binary°¡ ¸¸µé¾î Áö°í ³ª¼ ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ±â À§Çؼ´Â ¹Ýµå½Ã RAM ÀÌ ÀÖ¾î¾ß ÇÕ´Ï´Ù. Segment Initialization Àº RAM¿¡¼ ÇÁ·Î±×·¥ÀÌ ¿Ã¹Ù¸¥ µ¥ÀÌÅ͸¦ °¡Áö°í ½ÇÇà µÉ¼ö ÀÖµµ·Ï RAM ¿µ¿ª¿¡ Àü¿ªº¯¼öÀÇ ÃʱⰪµéÀ» ÀúÀåÇÏ´Â ÀÏÀ» ÇÕ´Ï´Ù. Á»´õ ÀÚ¼¼ÇÑ »çÇ×Àº ÀÌÀü °ÁÂÀÎ ARM Architecture 4.4 Linker ºÎºÐÀ» ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù.
À§ÀÇ ±×¸²¿¡¼ ¿ÞÂÊÀÌ ROM Binary ÀÌ°í ¿À¸¥ÂÊÀÌ RAM ¿µ¿ª ÀÔ´Ï´Ù.
- .data
: C¾ð¾î µî¿¡¼ ¼±¾ðÇÑ Àü¿ªº¯¼öµéÀÇ ÃʱⰪÀÌ ÀúÀåµÇ¾î ÀÖ´Â ¿µ¿ª ÀÔ´Ï´Ù.
- .bss : 0 À¸·Î ÃʱâÈ µÇ´Â ¿µ¿ª ÀÔ´Ï´Ù. ÃʱⰪÀ» ÁöÁ¤ÇÏÁö ¾ÊÀº Àü¿ªº¯¼öµîÀÌ ¿©±â¿¡ ÇØ´ç ÇÕ´Ï´Ù.
- .textrw : ÄÄÆÄÀÏ·¯¿¡ÀÇÇØ »ý¼ºµÈ RAM¿¡¼ ½ÇÇàµÇ´Â ÇÔ¼öµé ÀÔ´Ï´Ù.
#pragma segment = ".bss"
#pragma segment = ".data"
#pragma segment = ".data_init"
#pragma segment = ".rodata"
#pragma segment = ".textrw"
#pragma segment = ".textrw_init"
#pragma segment = "CSTACK"
void
InitSegment()
{
unsigned int k, n;
unsigned char *pdst, *psrc;
//
// initialize zero-initialized segment
//
n = (unsigned int)__section_end(".bss") - (unsigned int)__section_begin(".bss");
pdst = (unsigned char *)__section_begin(".bss");
for(k=0; k<n; k++)
{
*(pdst + k) = 0;
}
//
// initialize non-zero-initialized segment
//
n = (unsigned int)__section_end(".data_init") - (unsigned int)__section_begin(".data_init");
pdst = (unsigned char *)__section_begin(".data");
psrc = (unsigned char *)__section_begin(".data_init");
for(k=0; k<n; k++)
{
*(pdst + k) = *(psrc + k);
}
//
// initialize segment for ram-function
//
n = (unsigned int)__section_end(".textrw_init") - (unsignedint)__section_begin(".textrw_init");
pdst = (unsigned char *)__section_begin(".textrw");
psrc = (unsigned char *)__section_begin(".textrw_init");
for(k=0; k<n; k++)
{
*(pdst + k) = *(psrc + k);
}
return;
} |
(9) main ÇÔ¼ö·Î À̵¿
EXTERN main
ldr pc, =main
µåµð¾î ¸ðµç StackÃʱâÈ¿Í Segment ÃʱâÈ °úÁ¤À» ³¡³»°í C ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ÀÖ°Ô µÇ¾ú½À´Ï´Ù. ÀÌÁ¦ ºÎÅÍ´Â C Äڵ带 ÀÌ¿ëÇؼ °¢ µð¹ÙÀ̽ºµéÀ» Å×½ºÆ® ÇÒ¼ö ÀÖ°Ô µÇ¾ú³×¿ä.
5.2 GPIO Output( LED On/Off )
LED¸¦ ÄÁÆ®·Ñ Çϱâ À§Çؼ´Â Æ÷Æ®¸¦ OutputÀ¸·Î ¼³Á¤ÇÑ ÈÄ¿¡ GPIO(General Purpose Input Output) Æ÷Æ®¿¡ Low or High ¸¦ Ãâ·ÂÇÏ¸é µË´Ï´Ù. ¾Æ·¡ ȸ·Îµµ´Â ¿ì¸®°¡ ½Ç½À¿¡ »ç¿ëÇÏ°í ÀÖ´Â Mini2440ÀÇ LED ȸ·Îµµ ÀÔ´Ï´Ù. 4°³ÀÇ LED°¡ Àִµ¥ °¢ LED´Â GPB5 ~ 8 ¿¡ ¿¬°áÀÌ µÇ¾î ÀÖ½À´Ï´Ù. ±×·¸´Ù¸é LED1À» Äѱâ À§Çؼ GPB5 Æ÷Æ®¿¡ Low(0) ·Î ÇØ¾ß ÇÒ±î¿ä ? ¾Æ´Ï¸é High(1) ·Î ÇØ¾ß ÇÒ±î¿ä ? Á¤´äÀº LEDÀÇ ÇÑÂÊ ³¡ÀÌ VDD33V ¿¡ ¿¬°áÀÌ µÇ¾î Àֱ⠶§¹®¿¡ Low·Î ¼³Á¤ ÇØ¾ß Àü·ùÀÇ È帧ÀÌ ¹ß»ýÇÏ¿© LED°¡ ÄÑÁö°Ô µË´Ï´Ù.
* ½ÇÇ迹Á¦
LED1, LED2 ´Â OnÀ» ÇÏ°í LED3, LED4´Â Off ½ÃÄÑ º¾´Ï´Ù.
(1) GPBCON ·¹Áö½ºÅÍ¿¡ GPB5 ~ GPB8 À» OutputÀ¸·Î ¼³Á¤ ÇÕ´Ï´Ù.
// GPB5 Output
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);
// GPB6 Output
rGPBCON = rGPBCON & ~(0x3 << 12);
rGPBCON = rGPBCON | (0x1 << 12);
// GPB7 Output
rGPBCON = rGPBCON & ~(0x3 << 14);
rGPBCON = rGPBCON | (0x1 << 14);
// GPB8 Output
rGPBCON = rGPBCON & ~(0x3 << 16);
rGPBCON = rGPBCON | (0x1 << 16);
(3) GPBDAT ·¹Áö½ºÅÍÀÇ GPB5, GPB6 À» Low ·Î, GPB7, GPB8 À» High·Î ¼¼Æà ÇÕ´Ï´Ù.
// LED1 On
rGPBDAT = rGPBDAT & ~(0x1 << 5);
// LED2 On
rGPBDAT = rGPBDAT & ~(0x1 << 6);
//rGPBDAT = rGPBDAT | (0x1 << 6);
// LED3 Off
rGPBDAT = rGPBDAT | (0x1 << 7);
// LED4 Off
rGPBDAT = rGPBDAT | (0x1 << 8);
diag.c - led_test()
// GPB5 Output
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);
// GPB6 Output
rGPBCON = rGPBCON & ~(0x3 << 12);
rGPBCON = rGPBCON | (0x1 << 12);
// GPB7 Output
rGPBCON = rGPBCON & ~(0x3 << 14);
rGPBCON = rGPBCON | (0x1 << 14);
// GPB8 Output
rGPBCON = rGPBCON & ~(0x3 << 16);
rGPBCON = rGPBCON | (0x1 << 16);
// LED1 On
rGPBDAT = rGPBDAT & ~(0x1 << 5);
// LED2 On
rGPBDAT = rGPBDAT & ~(0x1 << 6);
// LED3 Off
rGPBDAT = rGPBDAT | (0x1 << 7);
// LED4 Off
rGPBDAT = rGPBDAT | (0x1 << 8);
|
* ¼Ò½ºÄÚµå ºÐ¼®
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
GPBCON ·¹Áö½ºÅÍÀÇ ÁÖ¼Ò°¡ 0x50000010 ÀÔ´Ï´Ù. 0x3(b11) À» ¿ÞÂÊÀ¸·Î 10¹ø ½¬ÇÁÆ®¸¦ Çϸé b110000000000 ÀÌ°í ÀÌ°ÍÀ» "~" (Bit clear) ½ÃÅ°¸é GPB5[11:10] ºÎºÐÀÌ "00" À¸·Î Clear µË´Ï´Ù.
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);
0x1(b01) À» ¿ÞÂÊÀ¸·Î 10¹ø ½¬ÇÁÆ®¸¦ Çϸé b010000000000 ÀÌ°í ÀÌ°ÍÀ» "|" (OR) ½ÃÅ°¸é GPB5[11:10] ºÎºÐÀÌ "01" À¸·Î OutputÀ¸·Î ¼³Á¤ µË´Ï´Ù.
¼Ò½º ÄÚµåÁß¿¡ volatile À̶ó´Â °ÍÀ» »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù. ÀÌ°ÍÀº ÄÄÆÄÀÏ·¯ ÃÖÀûÈ¿¡¼ Á¦¿ÜµÇ´Â È¿°ú°¡ ÀÖ½À´Ï´Ù.
ÄÄÆÄÀÏ·¯ ÃÖÀûÈ Àü
|
ÄÄÆÄÀÏ·¯ ÃÖÀûÈ ÈÄ |
int a = 0; // Àü¿ª º¯¼ö
int b = 0; // Àü¿ª º¯¼ö
int i; // ·ÎÄà º¯¼ö
for(i=0;i<100;i++)
b = b + a * 100; |
int a = 0; // Àü¿ª º¯¼ö
int b = 0; // Àü¿ª º¯¼ö
int i; // ·ÎÄà º¯¼ö
for(i=0;i<100;i++)
b = b + 0; // a * 100; |
À§ÀÇ Äڵ忡¼ ¿À¸£ÂÊ ÄÚµåó·³ °³¹ßÀÚ°¡ ÀǵµÇÏÁö ¾Ê°Ô ÄÄÆÄÀÏ·¯¿¡ ÀÇÇØ ÃÖÀûÈ°¡ µÇ¾î "a*100" ºÎºÐÀ» ÃÖÀûÈ ÇÏ¿© b º¯¼ö¿¡ Ç×»ó 0À¸·Î ÀúÀåÀÌ µÇµµ·Ï ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¹°·Ð ÀϹÝÀûÀÎ »óȲ¿¡¼´Â ¾Æ¹« ¹®Á¦°¡ µÇÁö ¾ÊÁö¸¸ for ·çÇÁ ¼öÇàÁß¿¡ ¿ÜºÎ ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ¿© ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾ¿¡¼ a ÀÇ °ªÀ» 0ÀÌ ¾Æ´Ñ ´Ù¸¥ °ªÀ¸·Î º¯ÇÏ°Ô ÇÑ ÈÄ ´Ù½Ã for ·çÇÁ¸¦ ¼öÇà ÇÏ¸é °³¹ßÀÚ´Â b¿¡ 0ÀÌ ¾Æ´Ñ ´Ù¸¥°ªÀÌ ÀúÀåµÇ±â¸¦ ±â´ëÇÏ°í ÀÖ°ÚÁö¸¸ ÃÖÀûÈµÈ Äڵ忡¼´Â b ¿¡ Ç×»ó 0 ÀÌ ÀúÀåÀÌ µÇ¾î ÀÖÀ»°ÍÀÔ´Ï´Ù. ÀÌ°ÍÀº °³¹ßÀÚ°¡ ÀǵµÇÑ °á°ú°¡ ¾Æ´Õ´Ï´Ù. ÀÌ·± Çö»óÀ» ¹æÁöÇϱâ À§Çؼ´Â º¯¼ö a ¸¦ volatile ·Î ¼±¾ðÀ» ÇÏ¸é µË´Ï´Ù. ƯÈ÷³ª SFR ·¹Áö½ºÅ͵ °ªÀ» ¼¼ÆÃÇÏ´Â ÀÛ¾÷À» ÇÑ´Ù¸é Ç×»ó volatile ·Î ¼±¾ðÀ» Çؼ »ç¿ëÇÏ´Â Çϴ°ÍÀÌ ÁÁ½À´Ï´Ù.
5.3 GPIO Input( KEY Input) - Polling
LED¸¦ Ä×À»¶§¿Í ¹Ý´ë·Î À̹ø¿¡´Â GPIOÆ÷Æ®¸¦ ÀÌ¿ëÇؼ ÀÔ·ÂÀ» ¹Þ¾Æ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. Æ÷Æ®¿¡¼ ÀÔ·ÂÀ» ¹Þ±â À§Çؼ´Â Æ÷Æ®¸¦ Input À¸·Î ¼³Á¤ÇÑ ÈÄ¿¡ GPIO(General Purpose Input Output) Æ÷Æ®¸¦ ÀÐÀ¸¸é µË´Ï´Ù. 6°³ÀÇ KEY°¡ Àִµ¥ ¿ì¸®´Â INT11, INT13 ¿¡ ¿¬°áµÇ¾î ÀÖ´Â K2, K3 ¿¡ ´ëÇؼ Æú¸µ¹æ½ÄÀ¸·Î ÀÔ·ÂÀ» °¨ÁöÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. Âü°í·Î Æú¸µ ¹æ½ÄÀ̶õ Äڵ忡¼ ¹«ÇÑ ·çÇÁ¸¦ µ¹¸é¼ ƯÁ¤ ÇàÀ§¸¦ Çϴ°ÍÀ» ¸»ÇÕ´Ï´Ù. À̹ø °æ¿ì¿¡´Â Key°¡ ´·ÁÁ³´ÂÁö¸¦ °¨½ÃÇÏ´Â °ÍÀÌ°ÚÁö¿ä. Æú¸µ°ú ´Ù¸¥ ¹æ½ÄÀ¸·Î´Â ÀÎÅÍ·´Æ® ¹æ½ÄÀÌ ÀÖ½À´Ï´Ù. ´ÙÀ½Àý¿¡¼ °øºÎÇÏ°ÔµÉ ³»¿ëÀÔ´Ï´Ù.
* ½ÇÇ迹Á¦
K2, K3 ¸¦ ÀÐ¾î¼ KEY°¡ ´·ÁÁ® ÀÖÀ¸¸é LED2, LED3 ¸¦ OnÀ¸·Î ÇÏ°í ´·ÁÁ® ÀÖÁö ¾ÊÀ¸¸é Off ·Î ¼³Á¤ÇØ º¾½Ã´Ù.
(1) GPGCON ·¹Áö½ºÅÍ¿¡ GPG3, GPG5 ¸¦ InputÀ¸·Î ¼³Á¤ ÇÕ´Ï´Ù.
// KEY3, GPG5 Input
rGPGCON = rGPGCON & ~(0x3 << 10);
// KEY2, GPG3 Input
rGPGCON = rGPGCON & ~(0x3 << 6);
(2) GPGDAT ·¹Áö½ºÅÍÀÇ GPG3, GPG5 ¸¦ ÀÐ¾î¼ "0" À̸é KEY°¡ ´¸° »óÅÂÀÌ°í, "1" À̸é KEY ´·ÁÁöÁö ¾ÊÀº »óÅ ÀÔ´Ï´Ù.
diag.c - key_test()
// KEY3, GPG5 Input
rGPGCON = rGPGCON & ~(0x3 << 10);
// KEY2, GPG3 Input
rGPGCON = rGPGCON & ~(0x3 << 6);
while(1)
{
if( (rGPGDAT & (0x1 << 3)) == 0 ) // KEY2 pressed
// LED2 On
rGPBDAT = rGPBDAT & ~(0x1 << 6);
else
// LED2 Off
rGPBDAT = rGPBDAT | (0x1 << 6);
if( (rGPGDAT & (0x1 << 5)) == 0 ) // KEY3 pressed
// LED3 On
rGPBDAT = rGPBDAT & ~(0x1 << 7);
else
// LED3 Off
rGPBDAT = rGPBDAT | (0x1 << 7);
Delay(80);
};
|
5.4 GPIO Input( KEY Input) - Interrupt
À̹ø¿¡´Â ÀÎÅÍ·´Æ® ¹æ½ÄÀ¸·Î K2, K3 ÀÔ·ÂÀ» °¨ÁöÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ÀÎÅÍ·´Æ® ¹æ½ÄÀº Æú¸µ¹æ½Äº¸´Ù È¿À²ÀûÀ̱â´Â ÇÏÁö¸¸ Á»´õ º¹ÀâÇÕ´Ï´Ù. ¿©±â¼ È¿À²ÀûÀ̶ó°í Çϴ°ÍÀº CPU»ç¿ëÀ» È¿°úÀûÀ¸·Î ÇѴٴ°ÍÀÌÁö Æú¸µ¹æ½Äº¸´Ù ºü¸£´Ù´Â ¸»Àº ¾Æ´Õ´Ï´Ù. ÀÎÅÍ·´Æ®¹æ½ÄÀº ÀÎÅÍ·´Æ®¿äûÀÌ ¿ÔÀ»¶§ ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾÀ¸·Î ºÐ±âÇÒ¶§±îÁö Áö¿¬½Ã°£ÀÌ ÀÖ¾î Æú¸µ ¹æ½Äº¸´Ù ´À¸±¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ Æú¸µ¹æ½Äó·³ °è¼Ó ·çÇÁ¸¦ µ¹¸é¼ ´ë±âÇÏÁö ¾Ê¾Æµµ µÇ±â ¶§¹®¿¡ CPUÈ°¿ë¸é¿¡¼´Â È¿À²ÀûÀÔ´Ï´Ù.
* ½ÇÇ迹Á¦
K2, K3 ¸¦ ÀÐ¾î¼ KEY°¡ ´·ÁÁ® ÀÖÀ¸¸é LED2, LED3 ¸¦ OnÀ¸·Î ÇÏ°í ´·ÁÁ® ÀÖÁö ¾ÊÀ¸¸é Off ·Î ¼³Á¤ÇØ º¾½Ã´Ù.
(1) GPGCON ·¹Áö½ºÅÍ¿¡ GPG3, GPG5 ¸¦ EINT(0x2) À¸·Î ¼³Á¤ ÇÕ´Ï´Ù.
// KEY3, GPG5 EINT13
rGPGCON = rGPGCON & ~(0x3 << 10);
rGPGCON = rGPGCON | (0x2 << 10);
// KEY2, GPG3 EINT11
rGPGCON = rGPGCON & ~(0x3 << 6);
rGPGCON = rGPGCON | (0x2 << 6);
(2) EXTINT1 ·¹Áö½ºÅÍ¿¡ EINT11, EINT13À» Falling Edge·Î ¼³Á¤ ÇÕ´Ï´Ù.
// set eint13 falling edge trigger
rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);
// set eint11 falling edge trigger
rEXTINT1 &= ~(0x7 << 12);
rEXTINT1 |= (0x2 << 12);
(3) EINTPEND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.
// clear eint 11,13
rEINTPEND |= (1 << 11)|(1 << 13);
"It is cleard by writing 1" À̶ó´Â ¹®±¸°¡ º¸À̴µ¥¿ä. ¹«½¼ ÀÇ¹Ì Àϱî¿ä ? ÀϹÝÀûÀ¸·Î ¿ì¸®°¡ SFR ·¹Æ¼½ºÅ͸¦ ¼³Á¤ ÇÒ¶§¿¡ ¾Æ·¡¿Í °°ÀÌ ¸ÕÀú Bit¸¦ Clear ½ÃÅ°°í Set ÇÏ´Â 2´Ü°è °úÁ¤À» °ÅÄ¡°Ô µË´Ï´Ù.
rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);
ÇÏÁö¸¸ ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾ ¾È¿¡¼´Â ÀÌ°Í Á¶Â÷µµ ºñÈ¿À²ÀûÀϼö ÀÖ°í Atmoic Operation ÀÌ ¾Æ´Ï±â ¶§¹®¿¡ Pending Clear¸¦ ÇÏ´Â °úÁ¤¿¡¼ »õ·Î¿î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÒ °æ¿ì¿¡ »õ·Î¿î ÀÎÅÍ·´Æ®°¡ Áö¿¬µÉ¼öµµ ÀÖ½À´Ï´Ù.
rEINTPEND |= (1 << 11)|(1 << 13);
ÀÌ·¯ÇÑ ÀÌÀ¯·Î À§¿Í °°ÀÌ "1" À» ½á³Ö¾î¼ ¹Ù·Î PendingÀ» Clear ÇÒ¼ö ÀÖµµ·ÏÇÑ °ÍÀÔ´Ï´Ù.
(4) EINTMASK ·¹Áö½ºÅÍ¿¡¼ Interrupt¸¦ Enable ÇÕ´Ï´Ù.
// enable eint 11,13
rEINTMASK &= ~((1 << 11)|(1 << 13));
(5)
SRCPND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.
rSRCPND = (0x1<<5); // Clear pending bit
(6) INTPND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.
rINTPND = (0x1<<5); // Clear pending bit
(7) EINT ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾÀÇ ÇÔ¼ö Æ÷ÀÎÅ͸¦ ¼³Á¤ ÇÕ´Ï´Ù.
pISR_EINT8_23 = (U32)isr_eint_8_23;
(8) INTMSK ¿¡¼ EINT8_23 ÀÇ ÀÎÅÍ·´Æ®¸¦
Enable ÇÕ´Ï´Ù.
rINTMSK &= ~((0x1<<5));
(9) Startup ÄÚµåÀÇ IRQ Exception ¿¡¼ ÀÎÅÍ·´Æ® ¹øÈ£¸¦ È®ÀÎÇÏ°í ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾÀ¸·Î ºÐ±â ÇÕ´Ï´Ù.
Startup ÄÚµå ¼³¸íÇÒ¶§ À̺κÐÀº ¼³¸íÀ» ÇÏÁö ¾Ê°í ±×³É ³Ñ¾î°¬½À´Ï´Ù. ¾î¶² ¸¶¹ýÀÇ ÄÚµå·Î ÀÎÇؼ ¼ö¸¹Àº ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼ö°¡ 1°³ÀÇ ·çƾÀ¸·Î ÇØ°áÀÌ µÉ±î¿ä ? À̹ø¿¡ »ó¼¼ÇÏ°Ô ¼³¸í Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù.
IsrIRQ
sub sp,sp,#4 ;reserved for PC --> 1
stmfd sp!,{r8-r9} ; --> 2
ldr r9,=INTOFFSET ; --> 3
ldr r9,[r9] ; --> 4
ldr r8,=HandleEINT0 ; --> 5
add r8,r8,r9,lsl #2 ; --> 6
ldr r8,[r8] ; --> 7
str r8,[sp,#8] ; --> 8
ldmfd sp!,{r8-r9,pc} ; --> 9
|
--> 1 : ½ºÅÃÆ÷ÀÎÅ͸¦ 1 °¨¼ÒÇÏ¿© ºó °ø°£À» ¸¸µì´Ï´Ù. ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ ÁÖ¼Ò°ªÀÌ ÀúÀåµÉ °ø°£ ÀÔ´Ï´Ù.
--> 2 : r8, r9 ¸¦ »ç¿ëÇÏ°í º¹¿øÇØ¾ß ÇϹǷΠstack¿¡ ÀúÀå ÇÕ´Ï´Ù. stmfd´Â ¸ÕÀú ¾îµå·¹½º¸¦ °¨¼ÒÇÏ°í ÀúÀåÇϹǷΠ1 ¿¡¼ ¸¸µé¾îÁø ºó°£°øÀº ±×´ë·Î ³²¾Æ ÀÖ½À´Ï´Ù.
--> 3, 4 : INTOFFSET À» r9 ·¹ ·Îµå ÇÕ´Ï´Ù.
--> 5 :
HandleEINT0 ¸¦ r8 ¿¡ ·Îµå ÇÕ´Ï´Ù. HandleEINT0´Â Startup ÄÚµåÀÇ ¾Æ·¡ ºÎºÐ¿¡ Á¤ÀǵǾî ÀÖ½À´Ï´Ù.
--> 6,7 : HandleEINT0 + INTOFFSET*4 ÀÇ ¼ö½ÄÀÌ µË´Ï´Ù. INTOFFSET ·¹Áö½ºÅÍ¿¡´Â ¹ß»ýÇÑ ÀÎÅÍ·´Æ® ¼Ò½ºÀÇ Offset °ªÀÌ µé¾îÀÖ´Â ·¹Áö½ºÅÍ ÀÔ´Ï´Ù.
¿ì¸®´Â EINT8_23 À» ÀÌ¿ëÇÒ °ÍÀ̱⠶§¹®¿¡ INTOFFSET ·¹Áö½ºÅÍ¿¡´Â 5°¡ ÀúÀåµÇ¾î ÀÖÀ»°ÍÀÔ´Ï´Ù. ±×·¯¹Ç·Î HandleEINT0 + 5*4 Áï HandleEINT8_23ÀÇ ÁÖ¼Ò°¡ µË´Ï´Ù.
¼Ò½ºÄڵ忡¼ key_test_eint() ÇÔ¼ö¿¡¼ pISR_EINT8_23 = (U32)isr_eint_8_23; ÀÇ Äڵ带 »ðÀÔÇϸé EINT8_23 ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇϸé isr_eint_8_23 ÇÔ¼ö·Î ºÐ±â¸¦ ÇÏ°Ô µË´Ï´Ù.
--> 8 :
str r8,[sp,#8] ¿¡ ÀÇÇؼ ¸Ç óÀ½¿¡ StackÀÇ ºó°£°øÀ» ¸¸µé¾î µÎ¾ú´ø °÷À¸·Î ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ Æ÷ÀÎÅÍÁÖ¼Ò°ªÀ» ÀúÀå ÇÕ´Ï´Ù.
--> 9
: r8, r9 ¸¦ Stack ¿¡¼ º¹¿øÇÏ°í pc ¿¡ ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ ÁÖ¼Ò°¡ ÀúÀåÀÌ µÇ¾î ½ÇÁ¦·Î ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼ö°¡ ½ÇÇàÀÌ µË´Ï´Ù.
(10) ÀÎÅÍ·´Æ® ¼ºñ½º ·çƾ¿¡¼ GPGDAT ·¹Áö½ºÅÍÀÇ GPG3, GPG5 ¸¦ ÀÐ¾î¼ "0" À̸é KEY°¡ ´¸° »óÅÂÀÌ°í, "1" À̸é KEY ´·ÁÁöÁö ¾ÊÀº »óÅ ÀÔ´Ï´Ù.
Áö±Ý±îÁö ¼³¸íÇÑ ÀÎÅÍ·´Æ® °ü·Ã ¼³Á¤µéÀ» S3C2440 ÀÎÅÍ·´Æ® ÄÁÆ®·Ñ·¯ ºí·°µµ¿Í ºñ±³Çؼ º¸½Ã±â ¹Ù¶ø´Ï´Ù.
Interrupt MODEµµ IRQ/FIQ ¼³Á¤À» ÇØ¾ß ÇÏÁö¸¸ S3C2440ÀÇ ±âº» ÀÎÅÍ·´Æ® ¼³Á¤ °ªÀÌ IRQ À̱⠶§¹®¿¡ »ý·« ÇÏ¿´½À´Ï´Ù.
¿ÜºÎ ÀÎÅÍ·´Æ® 1°³¸¦ ¼ºñ½º ¹Þ±â À§Çؼ Á¤¸» ¸¹Àº °úÁ¤ÀÌ ÇÊ¿ä Çϳ׿ä. ARM Applications ÀÌÈÄ¿¡ ÇÏ°ÔµÉ Cortex-M3 Architecture ºÎºÐ¿¡¼µµ ÀÎÅÍ·´Æ® ¼ºñ½º¿¡ ´ëÇؼ ¼³¸íÀ» ÇÒÅÙµ¥, ±×¶§ Cortex-M3 °¡ ¾ó¸¶³ª °£°áÇÏ°í È¿À²ÀûÀÎÁö ºñ±³ÇØ º¸½Ã±â ¹Ù¶ø´Ï´Ù.
diag.c - key_test_eint()
__irq __arm void isr_eint_8_23(void)
{
if(rINTPND==BIT_EINT8_23)
{
ClearPending(BIT_EINT8_23);
if(rEINTPEND&(1<<11))
{
rEINTPEND |= 1 << 11;
rGPBDAT = rGPBDAT ^ (0x1 << 6); // toggle
}
if(rEINTPEND&(1<<13))
{
rEINTPEND |= 1 << 13;
rGPBDAT = rGPBDAT ^ (0x1 << 7); // toggle
}
}
}
void key_test_eint(void)
{
// KEY3, GPG5 EINT13
rGPGCON = rGPGCON & ~(0x3 << 10);
rGPGCON = rGPGCON | (0x2 << 10);
// KEY2, GPG3 EINT11
rGPGCON = rGPGCON & ~(0x3 << 6);
rGPGCON = rGPGCON | (0x2 << 6);
// set eint13 falling edge trigger
rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);
// set eint11 falling edge trigger
rEXTINT1 &= ~(0x7 << 12);
rEXTINT1 |= (0x2 << 12);
// clear eint 11,13 --> clear by writing "1" test
rEINTPEND |= (1 << 11)|(1 << 13);
// enable eint 11,13
rEINTMASK &= ~((1 << 11)|(1 << 13));
rSRCPND = (0x1<<5); // Clear pending bit --> clear by writing "1" test
rINTPND = (0x1<<5); // Clear pending bit --> clear by writing "1" test
pISR_EINT8_23 = (U32)isr_eint_8_23;
// Enable EINT8_23 Interrupt
rINTMSK &= ~((0x1<<5));
}
|
5.5 Timer
ÀÓº£µðµå ½Ã½ºÅÛ¿¡¼ Timer´Â °¡Àå Áß¿äÇÏ°í ÇʼöÀûÀÎ ¿ä¼ÒÁßÀÇ Çϳª·Î OS¿¡¼ Task ½ºÄÉÁÙ¸µÀ» À§Çؼ »ç¿ëµÇ±âµµ ÇÕ´Ï´Ù. ÀüÀÚ¾×ÀÚ, Â÷·®¿ë ºí·¢¹Ú½º µîÀÇ ÀÀ¿ë ¾îÇø®ÄÉÀ̼ǿ¡¼µµ ƯÁ¤ ½Ã°£ ÀÌÈÄ¿¡ ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ Á¤ÇØÁø ÀÏÀ» ¼öÇàÇÏ´Â °æ¿ìµî ÀÀ¿ëºÐ¾ß´Â ¹«¼öÈ÷ ¸¹½À´Ï´Ù.
½Ã°£ À̾߱Ⱑ ³ª¿Í¼ À̾߱â Çϴµ¥ CPUÀÇ Å¬·° ¼Óµµ°¡ 1Hz ¶ó´Â °ÍÀº ¹«¾ùÀ» ÀǹÌÇÏ´Â °ÍÀϱî¿ä ? ÀÌ°ÍÀº 1ÃÊ¿¡ 1¹øÀÇ Tick ÀÌ ¹ß»ýÇÑ´Ù´Â °ÍÀÔ´Ï´Ù. ¾ÆÁÖ Á¤È®ÇÑ °ÍÀº ¾Æ´ÏÁö¸¸ ij½Ã°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼ ij½Ã Hit(ij½Ã¿¡¼ µ¥ÀÌÅÍ È¤Àº ¸í·É¾î¸¦ °¡Áö°í ¿Ã °æ¿ì)ÀÏ °æ¿ì¿¡ 1ÃÊ¿¡ 1°³ÀÇ ¸í·É¾î¸¦ ¼öÇàÇÑ´Ù´Â °Í°ú °°½À´Ï´Ù. S3C2440ÀÌ 400MHz ·Î µ¿ÀÛ ÇÑ´Ù¸é 1ÃÊ¿¡ 4¾ï¹øÀÇ TickÀÌ ¹ß»ýÇÏ´Â °ÍÀÔ´Ï´Ù. Á¤¸» ¾î¸¶¾î¸¶ ÇÏÁö¿ä. »ó»óÇØ º¸¼¼¿ä. ¿äÁò ÃֽŠ½º¸¶Æ®ÆùµéÀº 2GHz CPUÀÌ¸é¼ ±×°Íµµ µà¾ó ÄÚ¾î ÀÔ´Ï´Ù. ¾Æ·¡´Â ½Ã°£°ú ÁÖÆļö »çÀÌÀÇ °ü°è ÀÔ´Ï´Ù. Timer ¼³Á¤Çϴµ¥ ÀÌÁ¤µµ´Â ¾Ë°í ÀÖ¾î¾ß ÇÕ´Ï´Ù. Àß ±â¾ï ÇϽñ⠹ٶø´Ï´Ù.
- 1sec = 1,000ms = 1,000,000us = 1,000,000,000ns
- 1Hz = 1KHz = 1MHz = 1GHz
* ½ÇÇ迹Á¦
S3C2440 CPUÀÇ ³»ÀåµÈ Timer4¸¦ ÀÌ¿ëÇؼ 1ÃÊ¿¡ Çѹø¾¿ Timer ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ LDE2¸¦ Blink(On/Off) ÇÏ´Â ½ÇÇèÀ» Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.
(1) TCFG0 ·¹Áö½ºÅÍÀÇ Timer4 Prescaler¸¦ 15 ·Î ¼³Á¤ ÇÕ´Ï´Ù.
// Timer4 Prescaler = 15
rTCFG0 = 0x0;
rTCFG0 = (15 << 8);
(2) TCFG1 ·¹Áö½ºÅÍÀÇ Timer4 Divider¸¦ 1/2 ·Î ¼³Á¤ ÇÕ´Ï´Ù.
// Timer4 Divider = 2
rTCFG1 = 0x0;
rTCFG1 = (0x0 << 16);
À§¿Í °°ÀÌ ¼³Á¤Çϸé Datasheet ¿¡ ÀÖ´Â ¾Æ·¡ °ø½Ä¿¡ ÀÇÇؼ
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
Timer input clock Frequency = 50000000/(15+1)/2 = 1562500
À§ÀÇ °è»ê½ÄÀÇ Àǹ̴ Timer4ÀÇ Å¬·°ÀÌ 1ÃÊ¿¡ 1562500 ¹ø ¹ß»ý ÇÑ´Ù´Â ÀÇ¹Ì ÀÔ´Ï´Ù. ±×·¯¹Ç·Î Timer4 buffer count(TCNTB4) ¸¦ 15625 ·Î ¼³Á¤ÇØ ÁÖ¸é 10ms ¸¶´Ù Auto Reload(Timer Overflow) °¡ µÇ¾î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ°Ô µË´Ï´Ù. ¹°·Ð °£´ÜÇÏ°Ô TCNTB4¸¦ 1562500·Î ¼³Á¤ÇØ ÁÖ¸é 1ÃÊ¿¡ Çѹø ¹ß»ýÇÏ´Â ÀÎÅÍ·´Æ®¸¦ ¸¸µé¼ö ÀÖ°ÚÁö¸¸, ¾ÈŸ±õ°Ôµµ S3C2440ÀÇ Å¸À̸Ӵ 16ºñÆ® ŸÀÌ¸Ó À̹ǷΠÃÖ´ë °ªÀ¸·Î 0xFFFF(65535) ÀÌ»óÀ» »ç¿ëÇÒ¼ö°¡ ¾ø½À´Ï´Ù.
(3) TCNTB4 ·¹Áö½ºÅÍ¿¡ Timer4 buffer count ¸¦ 15625·Î ¼³Á¤ ÇÕ´Ï´Ù.
// buffer count
rTCNTB4 = 15625; // interrupt resolution 10msec
(4) TCON ·¹Áö½ºÅÍ¿¡ Update TCNTB4¿Í Auto Reload¸¦ ¼³Á¤ ÇÕ´Ï´Ù.
rTCON = rTCON & ~(0xffffff) | 0x1<<21 ; // Manual update : Update TCNTB4, TIMER Stop
rTCON = rTCON | (1 << 22); // Auto reload
(5) TCON ·¹Áö½ºÅ͸¦ ¼³Á¤ÇÏ¿© Timer¸¦ Start ½Ãŵ´Ï´Ù.
// Start Timer 4
rTCON |= (1<<20);
(6) TCON
¿¡¼ Manual Update¸¦ ÇØÁ¦ÇÏ°í INTMSK ¿¡¼ ÀÎÅÍ·´Æ® ¸¶½ºÅ©¸¦ Clear ½Ãŵ´Ï´Ù.
// clean manual update
rTCON &= ~(1<<21);
// Enable interrupt
rINTMSK &= ~(0x1<<14);
ÀÌ·¸°Ô Çϸé Timer4 ÀÎÅÍ·´Æ®°¡ 10msec ¸¶´Ù Çѹø¾¿ ¹ß»ýÇÏ°Ô µË´Ï´Ù.
diag.c - timer4_test()
__irq __arm void isr_timer4(void)
{
rSRCPND = BIT_TIMER4; //Clear pending bit
rINTPND = BIT_TIMER4;
// Timer°¡ 10msec ¸¶´Ù ¹ß»ýÇϹǷΠ1ÃÊ¿¡ Çѹø¾¿ toggle ½ÃÅ°±â À§Çؼ
if( ++one_seconds_var == 100 )
{
rGPBDAT = rGPBDAT ^ (0x1 << 6); // toggle LED2
one_seconds_var = 0;
}
void timer4_test(void)
{
/*
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
{prescaler value} = 0~255
{divider value} = 2, 4, 8, 16
period = (prescaler value + 1) * (divider value) * buffer count / PCLK = 10 ms
e.g.; PCLK = 50 Mhz
10 ms = (15 + 1) * 2 * 15625 / (50000 * 1000)
15626 = 10 ms * (50000 * 1000) / 2 / (15 + 1)
*/
// Timer4 Prescaler = 15
rTCFG0 = 0x0;
rTCFG0 = (15 << 8);
// Timer4 Divider = 2
rTCFG1 = 0x0;
rTCFG1 = (0x0 << 16);
// Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
// 50000000/(15+1)/2 = 1562500 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick
// buffer count
rTCNTB4 = 15625; // interrupt resolution 10msec
rTCON = rTCON & ~(0xffffff) | 0x1<<21 ; // Manual update : Update TCNTB4, TIMER Stop
rTCON = rTCON | (1 << 22); // Auto reload
pISR_TIMER4 = (int)isr_timer4;
// Start Timer 4
rTCON |= (1<<20);
// clean manual update
rTCON &= ~(1<<21);
// Enable interrupt
rINTMSK &= ~(0x1<<14);
}
|
¿©±â¼ Àá±ñ ÀϹÝÇÔ¼ö¿Í "__irq __arm" °¡ ÀÖ´Â ÇÔ¼öÀÇ Â÷ÀÌÁ¡Àº ¹«¾ùÀϱî¿ä ?
* ÀÏ¹Ý ÇÔ¼öÀÇ Return ºÎºÐ
* ISR ÇÔ¼öÀÇ Return ºÎºÐ
ISR ÇÔ¼ö´Â ARM Architecture ¿¡¼ ¹è¿îµ¥·Î ReturnÀ» SUBS PC,LR,#4 ·Î ÇÏ°í ÀÖ½À´Ï´Ù. Àß ±â¾ïÀÌ ³ªÁö ¾ÊÀ¸½Ã¸é ARM Architecture ÀÚ·á¿¡¼ Pipeline°ú Interrupt ºÎºÐÀ» ´Ù½Ã º¸½Ã±â ¹Ù¶ø´Ï´Ù.
5.6 PWM Buzzer
Buzzer, LED µîÀÇ ¹à±â Á¶Á¤µî¿¡ ÀÀ¿ëÀ» ÇÒ ¼ö ÀÖ½À´Ï´Ù.
* ½ÇÇ迹Á¦
BuzzerÀ» ¿ï¸®µµ·Ï ÇÏ°í ¿ÜºÎ ÀÎÅÍ·´Æ® ¹æ½ÄÀ¸·Î Key K2¸¦ ´©¸£¸é ÁÖÆļö¸¦ 10Hz ¿Ã¸®°í K3¸¦ ´©¸£¸é 10Hz ÁÖÆļö°¡ ³»·Á°¡µµ·Ï Çغ¾½Ã´Ù.
(1)
GPBCON ·¹Áö½ºÅÍ¿¡¼ GPB0¸¦ TOUT0(Timer0 Output) À¸·Î ¼³Á¤ ÇÕ´Ï´Ù.
rGPBCON &= ~0x3; // set GPB0 as tout0, pwm output
rGPBCON |= 0x2;
(2) TCFG0 ·¹Áö½ºÅÍÀÇ Timer0 Prescaler¸¦ 15 ·Î ¼³Á¤ ÇÕ´Ï´Ù.
rTCFG0 &= ~0xff;
rTCFG0 |= 15; // prescaler = 15+1
(3) Timer0ÀÇ Divider ¸¦ 1/8 ·Î ¼³Á¤ ÇÕ´Ï´Ù.
rTCFG1 &= ~0xf;
rTCFG1 |= 2; // mux = 1/8
(4)
Timer0 ÀÇ Count buffer register, compare buffer register ¸¦ ¼³Á¤ ÇÕ´Ï´Ù.
rTCNTB0 = (Pclk>>7)/buzzer_freq;
rTCMPB0 = rTCNTB0>>1; // rTCNTB0/2
¿©±â±îÁö ¼³Á¤À» ÇÏ¸é ¾Æ·¡¿Í °°ÀÌ 1KHzÀÇ ÁÖÆļö°¡ ¸¸µé¾î Áü.
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
Timer input clock Frequency = 50000000/(15+1)/8 = 390625 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick
50000000Hz(PCLK) >> 7 = 390625 --> °á±¹Àº 1ÃÊ¿¡ 1¹ø 1Hz °ª,
buzzer_freq(1000) À¸·Î ³ª´©¾î ÁÖ¸é TCNTBnÀº 1KHz °¡ µË´Ï´Ù.
Ãß°¡·Î TCMPBn Àº TCNTBn/2 ·Î Çϸé ÃÖÁ¾ÀûÀ¸·Î 1KHzÀÎ Timer0(TOUT0) À¸·Î 1KHzÀÎ PWM ÆÄÇüÀÌ Ãâ·Â µË´Ï´Ù.
(5) Timer0 ¸¦ Start ½Ãŵ´Ï´Ù.
rTCON &= ~0x1f;
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit
diag.c - pwm_buzzer_test()
__irq __arm void isr_eint_8_23(void)
{
if(rINTPND==BIT_EINT8_23)
{
ClearPending(BIT_EINT8_23);
if(rEINTPEND&(1<<11)) // KEY2
{
rEINTPEND |= 1 << 11;
rGPBDAT = rGPBDAT ^ (0x1 << 6); // LED2 toggle
buzzer_freq += 100;
pwm_buzzer_test();
}
if(rEINTPEND&(1<<13)) // KEY3
{
rEINTPEND |= 1 << 13;
rGPBDAT = rGPBDAT ^ (0x1 << 7); // LED3 toggle
buzzer_freq -= 100;
pwm_buzzer_test();
}
}
}
void pwm_buzzer_test(void)
{
rGPBCON &= ~0x3; // set GPB0 as tout0, pwm output
rGPBCON |= 0x2;
rTCFG0 &= ~0xff;
rTCFG0 |= 15; // prescaler = 15+1
rTCFG1 &= ~0xf;
rTCFG1 |= 2; // mux = 1/8
// Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
// 50000000/(15+1)/8 = 390625 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick
// PCLK = 50000000Hz >> 7 = 390625 --> °á±¹Àº 1ÃÊ¿¡ 1¹ø 1Hz °ªÀÌ´Ù.
// buzzer_freq(1000) À¸·Î ³ª´©¾î ÁÖ¸é 1KHz°¡ µÈ´Ù.
rTCNTB0 = (PCLK>>7)/buzzer_freq;
rTCMPB0 = rTCNTB0>>1; // rTCNTB0/2
rTCON &= ~0x1f;
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit
}
|
5.7 UART
ÀÓº£µðµå ÇÁ·Î±×·¥¿¡¼ Timer¿Í ÇÔ²² UARTµµ ÇʼöÀûÀÎ ÀÎÅÍÆäÀ̽º ÀÔ´Ï´Ù. °³¹ßÃʱ⿡ µð¹ö±×¸ð´ÏÅÍ¿ëÀ¸·Î È°¿ëÀ» Çϱ⵵ ÇÏ°í °³¹ßÀÌ ¿Ï·áµÈ ÀÌÈÄ¿¡´Â Á¦Ç°ÀÇ Setting, Firmware ¾÷±×·¹ÀÌµå µî¿¡µµ È°¿ëÀ» ÇÕ´Ï´Ù.
* ½ÇÇ迹Á¦
UART0¸¦ PC¿Í 115200bps Baudrate·Î Åë½Å(RX, TX)À» ÇÏ´Â Echo server·Î ¸¸µé¾î º¾½Ã´Ù.
(1) GPH2¸¦ TXD·Î GPH3À» RXD·Î ¼³Á¤ÇÏ°í, GPHÀÇ PullupÀ» Disable ÇÕ´Ï´Ù.
rGPHCON &= ~( (0x3 << 6) | (0x3 << 4) );
rGPHCON |= ( (0x2 << 6) | (0x2 << 4) );
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
(2) UART0ÀÇ FIFO Buffer¸¦ Disable ÇÕ´Ï´Ù.
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
(3) UART0ÀÇ Auto Flow ControlÀ» Disable ÇÕ´Ï´Ù.
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable
(4) UART Line Control Regier ¼³Á¤(Normal Mode, No Parity, One Stop Bit, Word Length = 8)
rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
(5) UART Control Regier ¼³Á¤
rUCON0 = (0x0 << 10) | (0x1 << 6) | (0x0 << 5) | (0x0 << 4) | (0x1 << 2) | (0x1 << 0);
(6) UART Baudrate Divisor Register ¼³Á¤
rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26
UBRDIV = (int)( UART clock / ( buad rate x 16) ) –1
( UART clock : PCLK, FCLK/n or UEXTCLK )
¿ì¸®´Â UART ClockÀ¸·Î PCLK 50MHz(50000000)À» »ç¿ëÇÏ°í ÀÖÀ¸¹Ç·Î °è»ê½ÄÀº ´ÙÀ½°ú °°½À´Ï´Ù.
UBRDIV =
( PCLK / (115200*16) ) - 1 = 26
diag.c - uart0_test()
void uart0_send_byte(int data)
{
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
Delay(10);
WrUTXH0(data);
}
void uart0_test(unsigned int baud)
{
rGPHCON &= ~( (0x3 << 6) | (0x3 << 4) );
rGPHCON |= ( (0x2 << 6) | (0x2 << 4) );
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable
//UART0
rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
rUCON0 = (0x0 << 10) | (0x1 << 6) | (0x0 << 5) | (0x0 << 4) | (0x1 << 2) | (0x1 << 0);
rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26
while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty.
uart0_send_byte('E');
uart0_send_byte('c');
uart0_send_byte('h');
uart0_send_byte('o');
uart0_send_byte('\r');
uart0_send_byte('\n');
while(1)
{
Delay(10);
while(!(rUTRSTAT0 & 0x1)); //Receive data ready
uart0_send_byte((*(volatile unsigned char *)0x50000024));
}
}
|
À§ÀÇ ÄÚµå´Â Å͹̳Îâ¿¡ "Echo" ¸¦ Display ÇÏ°í Å͹̳ο¡¼ ÀÔ·ÂÇÑ ¹®ÀÚ¸¦ ¹Ù·Î Echo ÇÏ¿© ´Ù½Ã Å͹̳Πâ¿¡ Ç¥½ÃÇÏ°Ô µË´Ï´Ù.
|