【第22期】观点:IT 行业加班,到底有没有价值?

bootloader---15.串口

原创 2016年08月29日 13:56:33

串口时钟使用了PCLK,所以在初始化串口之前需要先将系统时钟初始化,(除非想一直使用默认时钟)。

一、代码
1. start.S 主要功能是:
     a.关闭看门狗
     b. 初始化系统时钟
     c. 设置堆栈
     d. 跳到main函数

点击(此处)折叠或打开

  1. .text
  2. .global _start
  3. _start:
  4.     /*disable watchdog*/
  5.     ldr r0, =0x53000000    
  6.     mov r1, #0x0
  7.     str r1, [r0]
  8.     
  9. #define COCKTIME    0x4C000000    
  10. #define MPLLCON        0x4C000004
  11. #define UPLLCON        0x4C000008
  12. #define CLKCON        0x4C00000C
  13. #define CLKSLOW        0x4C000010
  14. #define CLKDIVN     0x4C000014
  15. #define CAMDIVN     0x4C000018
  16.     /*FCLK:HCLK:PCLK=1:4:8*/
  17.     ldr r0, =CLKDIVN
  18.     mov r1, #0x05
  19.     str r1, [r0]

  20.     mrc p15, 0, r0, c1, c0, 0
  21.     orr r0, r0, #0xc0000000
  22.     mcr p15, 0, r0, c1, c0,0

  23.     /*MPLL=(2*m*Fin)/(P*(1<<S)), m=(MDIV+8), p=PDIV+2 s=SDIV*/
  24.     ldr r0, =MPLLCON 
  25.     ldr r1, =((0x5C<<12)|(0x01<<4)|(0x01))
  26.     str r1, [r0]
  27.     
  28.     ldr r0, =0x10000
  29. 1:
  30.     sub r0, r0, #1
  31.     bne 1b

  32.     /*UPLL=(m*Fin)/(P*(1<<S)), m=(MDIV+8), p=(PDIV+2), s=SDIV*/
  33.     ldr r0, =UPLLCON
  34.     ldr r1, =((0x10<<12)|(0x01<<4)|(0x01))
  35.     str r1, [r0]

  36.     ldr r0, =0x10000
  37. 1:
  38.     sub r0, r0, #1
  39.     bne 1b

  40.     /* set up the stack    */
  41.     ldr sp, =1024*4
  42.     bl main

  43. loop:
  44.     b loop
2. main.c 主要功能是:
a. 初始化串口
b. 进入死循环,每次点亮一个led灯,顺便打印一个字母'a'

点击(此处)折叠或打开

  1. #include "uart.h"
  2. #define GPBCON (*(volatile unsigned int *) 0x56000010)
  3. #define GPBDAT (*(volatile unsigned int *) 0x56000014)

  4. static inline void delay (unsigned long loops)
  5. {
  6.     __asm__ volatile ("1:\n"
  7.             "subs %0, %1, #1\n"
  8.             "bne 1b":"=r" (loops):"0" (loops));
  9. }

  10. void main()
  11. {
  12.     int i = 1;
  13.     GPBCON = 0x15400;
  14.     init_uart();
  15.     while(1)
  16.     {
  17.         GPBDAT = 0x7FF&(~i<<5);
  18.         i *= 2;
  19.         if(16==i)
  20.             i = 1;
  21.         delay(400000);
  22.         putc('a');
  23.     }
  24.     return ;
  25. }
3.uart.c 主要功能:
a. 初始化串口
b. 实现发送与接收函数getc与putc

点击(此处)折叠或打开

  1. #define GPHCON (* (volatile unsigned int *) 0x56000070)
  2. #define GPHUP (* (volatile unsigned int *) 0x56000078)

  3. #define ULCON0 (* (volatile unsigned int *) 0x50000000)
  4. #define UCON0 (* (volatile unsigned int *) 0x50000004)
  5. #define UFCON0 (* (volatile unsigned int *) 0x50000008)
  6. #define UMCON0 (* (volatile unsigned int *) 0x5000000C)
  7. #define UTRSTAT0 (* (volatile unsigned int *) 0x50000010)
  8. #define UERSTAT0 (* (volatile unsigned int *) 0x50000014)
  9. #define UFSTAT0 (* (volatile unsigned int *) 0x50000018)
  10. #define UMSTAT0 (* (volatile unsigned int *) 0x5000001C)
  11. #define UTXH0 (* (volatile unsigned char *) 0x50000020)
  12. #define URXH0 (* (volatile unsigned char *) 0x50000024)
  13. #define UBRDIV0 (* (volatile unsigned int *) 0x50000028)

  14. #define BAUD_RATE 115200

  15. void uart_init(void)
  16. {
  17.     GPHCON = 0x000000A0;
  18.     GPHUP = 0x000007FF;
  19.     ULCON0 = (0x03); //8N1        
  20.     UCON0 = (0x01<<2)|(0x01);
  21.     UFCON0 = 0;
  22.     UMCON0 = 0;
  23.     UBRDIV0 = (int)((50*1000*1000)/(BAUD_RATE*16))-1;
  24. }

  25. unsigned char uart_getc(void)
  26. {
  27.     while(!(UTRSTAT0 & 0x01))
  28.         ;
  29.     return (URXH0 & 0xff);
  30. }

  31. void uart_putc(char c)
  32. {
  33.     while (!(UTRSTAT0&0x02))
  34.         ;
  35.     UTXH0 = c;
  36.     if('\n' == c)
  37.         uart_putc('\r');
  38. }

  39. void uart_puts(char *s)
  40. {
  41.     while (*s)
  42.     {
  43.         uart_putc(*s++);
  44.     }
  45. }
注: uart.c中的uart_putc函数(ascii中: \n__换行__LF__0x10   \r__回车__CR__0x13 )
1. 当键盘敲下 Enter键时,从串口收到的按键是0x0d(即:\r 回车符:将光标移动到行首,而不换行)。
2. 当调用puts("hello\n");时putc收到\n后,将换行但光标的列不变,然后再输出\r,将光标移动到换行之后的行首,这样效果就跟平常的回车一样了。
4. uart.h

点击(此处)折叠或打开

  1. void uart_init(void);
  2. unsigned char uart_getc(void);
  3. void uart_putc(char c);

编译时只需要在Makefile的OBJS中添加uart.o就可以了。

二、测试一下getc函数
2.1 将main中主循环改为接收一个字符然后打印

点击(此处)折叠或打开

  1. uart_init();
  2. while(1)
  3.     {
  4.         c=uart_getc();
  5.         uart_putc(c);
  6.     }

版权声明:本文为博主原创文章,转载请注明出处。 举报

相关文章推荐

【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资...
  • haiwil
  • haiwil
  • 2015-01-14 23:05
  • 5188

【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

作者 : 韩曙亮 <span style="color: #000

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

ARM的嵌入式Linux移植体验之BootLoader

您正在看的其它编程教程是:ARM的嵌入式Linux移植体验之BootLoader。   BootLoader指系统启动后,在操作系统内核运行之前运行的一段小程序。通过BootLoader,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内...

bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理

bootloader功能介绍 初始化开发板上主要硬件(时钟,内存,硬盘), 把操作系统从硬盘拷贝到内存,然后让cpu跳转到内存中执行操作系统。 boot阶段 1.关闭影响CPU正常执行...

宋宝华谈 ARM 的嵌入式 Linux 移植体验之二:BootLoader

宋宝华谈 ARM 的嵌入式 Linux 移植体验之二:BootLoader BootLoader 指系统启动后,在操作系统内核运行之前运行的一段小程序。通过 BootLoader,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)