程序流程:首先上电复位,进入复位异常处理,关闭看门狗。然后将控制权交给main函数进入C文件,在main函数里首先调用init_sys: 首先用 init_clk 初始化系统时钟(FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ),然后再用init_uart 初始化串口(无检验位,1位停止位,8位数据位,115200bps),最后进入死循环,在循环里等待用户输入
数据(一个字节),如果用户输入了数据就把数据加1发送出去,此时在另一端可以看到被+1了的数据。
主文件 main.c 代码:
//==================================================== #include "2440addr.h" #include "def.h" //==================================================== void init_clk(void); void init_uart(void); void init_sys(void); void write_rec(byte data); byte read_rec(void); /******************************************************************** // Óï·šžñÊœ : void Main(void) *********************************************************************/ void main(void) { init_sys(); char ch = '0'; while(1) { ch = read_rec(); ch ++; write_rec(ch); } } void init_sys(void) { init_clk(); init_uart(); } void init_clk(void) { rLOCKTIME = 0x00ffffff; rCLKDIVN = 0x05; __asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* read control register */ " orr r1 , r1, #0xc0000000\n" /* set asynchronous bus mod */ " mcr p15, 0, r1, c1, c0, 0\n"); /* write control register */ rMPLLCON = 0x5c011; rUPLLCON = 0x38022; // (0x38<<12) | (0x02<<4) | (0x02) Upll = (m * Fin) / (p * 2s) } void init_uart(void) { rGPHCON = 0xa0; rULCON0 = 0x03; rUCON0 = 0x05; rUBRDIV0 = 0x1a; } void write_rec(byte data) { while( (rUTRSTAT0 & 0x04) != 0x04 ); rUTXH0 = data; } byte read_rec(void) { byte data; while( (rUTRSTAT0 & 0x01) != 0x01 ); data = rURXH0; return data; }
另外开发板一端的程序还可以用汇编语言来写:
//寄存器物理地址宏定义 #define WTCON 0x53000000 #define LOCKTIME 0x4C000000 #define MPLLCON 0x4C000004 #define UPLLCON 0x4C000008 #define CLKDIVN 0x4C000014 #define CAMDIVN 0x4C000018 #define ULCON0 0x50000000 #define UCON0 0x50000004 #define UTRSTAT0 0x50000010 #define UTXH0 0x50000020 #define URXH0 0x50000024 #define UBRDIV0 0x50000028 #define GPHCON 0x56000070 #define GPHUP 0x56000078 //Pull-up control H #define UFCON0 0x50000008 //UART 0 FIFO control #define UMCON0 0x5000000c //UART 0 Modem control .global _start _start: b reset reset: bl disable_watchdog bl init_clock bl init_uart b test_uart //关闭看门狗 disable_watchdog: ldr r0,=WTCON bic r1,r0,#0x20 str r1,[r0] mov pc,lr //FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ //UCLK=48MHZ init_clock: ldr r0,=LOCKTIME ldr r1,=0x00ffffff str r1,[r0] ldr r0,=CLKDIVN ldr r1,=0x05 str r1,[r0] //设为异步总线模式(因为FCLK不等于HCLK) mrc p15,0,r1,c1,c0,0 orr r1,r1,#0xc0000000 mcr p15,0,r1,c1,c0,0 ldr r0,=MPLLCON ldr r1,=0x5c011 str r1,[r0] ldr r0,=UPLLCON ldr r1,=0x38022 // (0x38<<12) | (0x02<<4) | (0x02) Upll = (m * Fin) / (p * 2s) str r1,[r0] // m = (MDIV + 8), p = (PDIV + 2), s = SDIV mov pc,lr //初始化串口 init_uart: //IO口设置为串口功能 ldr r0,=GPHCON ldr r1,=0xa0 /// 1010 0000 str r1,[r0] ldr r0,=GPHUP ldr r1,=0x0c /// str r1,[r0] //无检验位,1位停止位,8位数据位 ldr r0,=ULCON0 ldr r1,=0x03 /// 11 ~8bit str r1,[r0] //PCLK作为时钟源(50MHZ) ldr r0,=UCON0 ldr r1,=0x05 /// 中断请求或查询模式 str r1,[r0] ldr r0,=UFCON0 ldr r1,=0x00 str r1,[r0] ldr r0,=UMCON0 ldr r1,=0x00 str r1,[r0] //波特率115200bps ldr r0,=UBRDIV0 ldr r1,=0x1a str r1,[r0] //发送一个字节 send_one_byte: wait_se: //读发送状态位 ldr r0,=UTRSTAT0 ldr r1,[r0] and r1,r1,#0x4 cmp r1,#0x4 //如果发送状态位不为0则不断读状态位 bne wait_se //写入要发送的数据(用户输入的数据+1) ldr r3,=UTXH0 add r4,r4,#1 str r4,[r3] mov pc,lr test_uart: wait_rec: //读接收状态位 ldr r0,=UTRSTAT0 ldr r1,[r0] and r1,r1,#0x1 cmp r1,#0x1 //如果接收状态位不为1则不断读状态位 bne wait_rec //读入用户输入的数据 ldr r2,=URXH0 ldr r4,[r2] //调用发送函数 bl send_one_byte b test_uart //不断循环
上面涉及到的工程文件:
http://s.yunio.com/uC4fqs
参考链接:
http://www.cnblogs.com/lknlfy/archive/2012/08/30/2663282.html