OK6410笔记 -- UART串口(OK6410上测试成功)

完成功能:编写串口程序,波特率为115200.当在pc终端上输入一个字符的时候,返回来该字符加1之后的值,比如按下1则返回2,按下a则返回b。

start.S

   
   
   
   
1 .globl _start 2 _start: 3 4 /* 硬件相关的设置 */ 5 /* Peri port setup */ 6 ldr r0, =0x70000000 7 orr r0, r0, #0x13 8 mcr p15, 0 ,r0,c15,c2, 4 @ 256M(0x70000000-0x7fffffff) 9 10 /* 关看门狗 */ 11 /* 往WTCON(0x7E004000)写0 */ 12 13 ldr r0, =0x7E004000 14 mov r1, # 0 15 str r1, [r0] 16 17 /* 设置栈 */ 18 ldr sp, = 8 * 1024 19 20 /* 设置时钟 */ 21 bl clock_init 22 23 bl main 24 halt: 25 b halt 26

波特率的时钟是建立在别的时钟基础上的,我这里选择的是PCLK,所以先得配置好PCLK的频率,下面的程序配置PCLK为50MHz,不要弄错了,否则最后算的波特率也是错误的,结果就会出错。

clock.c

   
   
   
   
1 #define APLL_LOCK (*((volatile unsigned long *)0x7E00F000)) 2 #define MPLL_LOCK (*((volatile unsigned long *)0x7E00F004)) 3 #define EPLL_LOCK (*((volatile unsigned long *)0x7E00F008)) 4 #define OTHERS (*((volatile unsigned long *)0x7e00f900)) 5 #define CLK_DIV0 (*((volatile unsigned long *)0x7E00F020)) 6 #define ARM_RATIO 0 /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1) */ 7 #define HCLKX2_RATIO 4 /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) = 100MHz */ 8 #define HCLK_RATIO 0 /* HCLK = HCLKX2 / (HCLK_RATIO + 1) = 100MHz */ 9 #define PCLK_RATIO 1 /* PCLK = HCLKX2 / (PCLK_RATIO + 1) = 50MHz */ 10 #define MPLL_RATIO 0 /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) */ 11 12 #define APLL_CON (*((volatile unsigned long *)0x7E00F00C)) 13 #define APLL_CON_VAL ((1<<31) | (250 << 16) | (3 << 8) | (1)) 14 #define MPLL_CON (*((volatile unsigned long *)0x7E00F010)) 15 #define MPLL_CON_VAL ((1<<31) | (250 << 16) | (3 << 8) | (1)) 16 #define CLK_SRC (*((volatile unsigned long *)0x7E00F01C)) 17 /* ARMCLK = 500MHz, HCLK = 100MHz, PCLK = 50MHZ */ 18 void clock_init( void ) 19 { 20 APLL_LOCK = 0xffff ; 21 MPLL_LOCK = 0xffff ; 22 EPLL_LOCK = 0xffff ; 23 /* set async mode 当CPU时钟 != HCLK时,要设为异步模式 */ 24 OTHERS &= ~ 0xc0 ; 25 while ((OTHERS & 0xf00 ) != 0 ); 26 CLK_DIV0 = (ARM_RATIO) | (MPLL_RATIO << 4 ) | (HCLK_RATIO << 8 ) | (HCLKX2_RATIO << 9 ) | (PCLK_RATIO << 12 ); 27 APLL_CON = APLL_CON_VAL; /* 500MHz */ 28 MPLL_CON = MPLL_CON_VAL; /* 500MHz */ 29 CLK_SRC = 0x03 ; 30 }

uart.h

   
   
   
   
1 #ifndef __UART_H__ 2 #define __UART_H__ 3 4 void myputchar( char c); 5 char mygetchar( void ); 6 void init_uart( void ); 7 8 #endif

uart.c

   
   
   
   
1 #define ULCON0 (*((volatile unsigned long *)0x7F005000)) 2 #define UCON0 (*((volatile unsigned long *)0x7F005004)) 3 #define UFCON0 (*((volatile unsigned long *)0x7F005008)) 4 #define UMCON0 (*((volatile unsigned long *)0x7F00500C)) 5 #define UTRSTAT0 (*((volatile unsigned long *)0x7F005010)) 6 #define UFSTAT0 (*((volatile unsigned long *)0x7F005018)) 7 #define UTXH0 (*((volatile unsigned char *)0x7F005020)) 8 #define URXH0 (*((volatile unsigned char *)0x7F005024)) 9 #define UBRDIV0 (*((volatile unsigned short *)0x7F005028)) 10 #define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C)) 11 12 #define GPACON (*((volatile unsigned long *)0x7F008000)) 13 14 void init_uart( void ) 15 { 16 GPACON &= ~ 0xff ; 17 GPACON |= 0x22 ; 18 /* ULCON0 */ 19 ULCON0 = 0x3 ; /* 数据位:8, 无较验, 停止位: 1, 8n1 */ 20 UCON0 = 0x5 ; /* 使能UART发送、接收 */ 21 UFCON0 = 0x01 ; /* FIFO ENABLE */ 22 UMCON0 = 0 ; 23 24 /* 波特率 */ 25 /* DIV_VAL = (PCLK / (bps x 16 ) ) - 1 26 * bps = 115200 27 * DIV_VAL = (50000000 / (115200 x 16 ) ) - 1 28 * = 26.13 29 */ 30 UBRDIV0 = 26 ; 31 /* x/16 = 0.13 32 * x = 2 (到S3C6410手册上查对应2应该赋什么值) 33 */ 34 UDIVSLOT0 = 0x0808 ; 35 } 36 37 char mygetchar( void ) 38 { 39 while ( ! (UFSTAT0 & 0x7f )); 40 return URXH0; 41 } 42 43 void myputchar( char c) 44 { 45 while (UFSTAT0 & ( 1 << 14 )); 46 UTXH0 = c; 47 } 48

main.c

   
   
   
   
1 #include " uart.h " 2 int main() 3 { 4 char c; 5 init_uart(); 6 while ( 1 ) 7 { 8 c = mygetchar(); 9 myputchar(c + 1 ); 10 } 11 return 0 ; 12 }

Makefile

   
   
   
   
1 uart. bin: start.o main.o uart.o clock.o 2 arm-linux-ld -Ttext 0 -o uart.elf $^ 3 arm-linux-objcopy -O binary uart.elf uart.bin 4 arm-linux-objdump -D uart.elf > uart.dis 5 6 %.o : %.S 7 arm-linux-gcc -o $@ $< -c 8 9 %.o : %.c 10 arm-linux-gcc -o $@ $< -c 11 12 clean: 13 rm *.o uart.elf uart.bin uart.dis

你可能感兴趣的:(OK6410笔记 -- UART串口(OK6410上测试成功))