ARM 系列 -- FS2410 开发板上通过串口实现 printf

出处:21ic 发布于:2018-07-20 13:51:16

  一、目的
  到目前为止我们所编写的程序都是直接烧到裸板(FS2410)上运行,没有借助操作系统,如果哪个环节出错了,就只能揣测代码的逻辑,无法借助 GDB 调试,这无形增加了编写代码的难度,如果任意时刻我们能把某个变量的值打印出来多好啊...呵呵, 你也许有同样的困惑,上一个实验我们对 UART 串口编程实现了对超级终端接收和发送数据,也许我们可以编写一个类似 C 语言里的 printf,作用就是向上位机的超级终端发送我们指定的任何数据。怀着这样美好的愿望,随我一起踏上征程吧。
   二、代码
  很多代码是在前面几个实验的基础上进行整理复用之,更多细节请参考前面随笔,这里
  仅附简略注解。
  @ 文件 head.s
  @ 作用:关闭看门狗、SDRAM 的初始化设置、搬移 Nand Flash 4K 以后
  @ 的代码到 SDRAM 的指定位置、执行 SDRAM 中的代码
  .text
  .global _STart
  _start:
  ldr r0, =0x53000000@ Close Watch Dog Timer
  mov r1, #0x0
  str r1, [r0]
  bl memory_setup@ Initialize memory setting
  bl flash_to_sdram@ Copy code to sdram
  ldr sp, =0x34000000@ Set stack pointer
  ldr pc, =main @ execute the code in SDRAM
  @ 文件 mem.s
  @ 作用:SDRAM 的初始化设置
  @ 关于初始化的更多细节,请参考我前面的随笔
  .global memory_setup
  memory_setup:
  mov r1, #0x48000000
  adrl r2, mem_cfg_val
  add r3, r1, #13*4
  1:
  @ write initial values to registers
  ldr r4, [r2], #4
  str r4, [r1], #4
  cmp r1, r3
  bne 1b
  mov pc, lr
  .align 4
  mem_cfg_val:
  .lONg 0x22111110 @ BWSCON
  .long 0x00000700 @ BANKCON0
  .long 0x00000700 @ BANKCON1
  .long 0x00000700 @ BANKCON2
  .long 0x00000700 @ BANKCON3
  .long 0x00000700 @ BANKCON4
  .long 0x00000700 @ BANKCON5
  .long 0x00018005 @ BANKCON6
  .long 0x00018005 @ BANKCON7 9bit
  .long 0x008e07a3 @ REFRESH
  .long 0x000000b2 @ BANKSIZE
  .long 0x00000030 @ MRSRB6
  .long 0x00000030 @ MRSRB7
  @ 文件 flash.s
  @ 作用:设置 Nand Flash 的控制寄存器、读取 Nand Flash
  @ 中的代码到 SDRAM 的指定位置,更多细节请参考我前面的随笔
  .equ NFCONF, 0x4e000000
  .equ NFCMD, 0x4e000004
  .equ NFADDR, 0x4e000008
  .equ NFDATA, 0x4e00000c
  .equ NFSTAT, 0x4e000010
  .equ NFECC, 0x4e000014
  .global flash_to_sdram
  flash_to_sdram:
  @ Save return addr
  mov r10,lr
  @ Initialize Nand Flash
  mov r0,#NFCONF
  ldr r1,=0xf830
  str r1,[r0]
  @ First reset and enable Nand Flash
  ldr r1,[r0]
  bic r1, r1, #0x800
  str r1,[r0]
  ldr r2,=NFCMD
  mov r3,#0xff
  str r3,[r2]
  @ for delay
  mov r3, #0x0a
  1:
  subs r3, r3, #1
  bne 1b
  @ Wait until Nand Flash bit0 is 1
  wait_nfstat:
  ldr r2,=NFSTAT
  ldr r3,[r2]
  tst r3,#0x01
  beq wait_nfstat
  @ Disable Nand Flash
  ldr r0,=NFCONF
  ldr r1,[r0]
  orr r1,r1,#0x8000
  str r1,[r0]
  @ Initialzie stack
  ldr sp,=4096
  @ Set arguments and call
  @ function nand_read defined in nand_read.c
  ldr r0,=0x30000000
  mov r1,#0
  mov r2,#1024*40
  bl nand_read
  @ return
  mov pc,r10
  /* 文件 nand_read.c
  * 作用:从 Nand Flash 中读取一块数据到 SDRAM 中的指定位置
  */
  #define NFCONF (*(volatile unsigned long *)0x4e000000)
  #define NFCMD (*(volatile unsigned long *)0x4e000004)
  #define NFADDR (*(volatile unsigned long *)0x4e000008)
  #define NFDATA (*(volatile unsigned long *)0x4e00000c)
  #define NFSTAT (*(volatile unsigned long *)0x4e000010)
  #define NFECC (*(volatile unsigned long *)0x4e000014)
  #define NAND_SECTOR_SIZE 512
  #define NAND_BLOCK_MASK 0x1ff
  void wait_idle() {
  int i;
  for (i = 0; i < 50000; ++i) ;
  }
  int nand_read(unsigned char *buf, unsigned long start_addr, int size){
  int i, j;
  /*
  * detect the argument
  */
  if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
  return -1;
  }
  /* chip Enable */
  NFCONF &= ~0x800;
  for (i=0; i<10; i++) {
  ;
  }
  for (i=start_addr; i < (start_addr + size); i+=NAND_SECTOR_SIZE) {
  NFCMD = 0;
  /* Write Address */
  NFADDR = i & 0xff;
  NFADDR = (i >> 9) & 0xff;
  NFADDR = (i >> 17) & 0xff;
  NFADDR = (i >> 25) & 0xff;
  wait_idle();
  for(j=0; j < NAND_SECTOR_SIZE; j++) {
  *buf++ = (NFDATA & 0xff);
  }
  }
  NFCONF |= 0x800; /* chip disable */
  return 0;
  }
  /* 头文件 serl.h
  * 作用:定义相关寄存器、UART 初始化函数声明、串口读写函数的声明
  */
  #ifndef __SERL_H__
  #define __SERL_H__
  #define GPHCON (*(volatile unsigned long *)0x56000070)
  /* PORT PULL-UP REGISTER*/
  #define GPHUP (*(volatile unsigned long *)0x56000078)
  /* UART FIFO control register 0*/
  #define UFCON0 (*(volatile unsigned long *)0x50000008)
  /* UART line control register 0*/
  #define ULCON0 (*(volatile unsigned long *)0x50000000)
  /* UART CONTROL REGISTER 0*/
  #define UCON0 (*(volatile unsigned long *)0x50000004)
  /* UART modem control register 0*/
  #define UMCON0 (*(volatile unsigned long *)0x5000000C)
  /* UART baud rate pisor register 0*/
  #define UBRDIV0 (*(volatile unsigned long *)0x50000028)
  /* UART TX/RX STATUS REGISTER 0*/
  #define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
  #define UTXH0 (*(volatile unsigned char *)0x50000020)
  #define URXH0 (*(volatile unsigned char *)0x50000024)
  #define TXD0_READY 0x2
  #define RXD0_READY 0x1
  void init_uart();
  unsigned char uart_getc();
  void uart_putc(unsigned char ch);
  void uart_puts(unsigned char* src);
  #endif

关键词:ARM串口

版权与免责声明

凡本网注明“出处:维库电子市场网”的所有作品,版权均属于维库电子市场网,转载请必须注明维库电子市场网,https://www.dzsc.com,违反者本网将追究相关法律责任。

本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。

如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。

广告
上传BOM文件: BOM文件
*公司名:
*联系人:
*手机号码:
QQ:
应用领域:

有效期:
OEM清单文件: OEM清单文件
*公司名:
*联系人:
*手机号码:
QQ:
有效期:

扫码下载APP,
一键连接广大的电子世界。

在线人工客服

买家服务:
卖家服务:

0571-85317607

客服在线时间周一至周五
9:00-17:30

关注官方微信号,
第一时间获取资讯。

建议反馈

联系人:

联系方式:

按住滑块,拖拽到最右边
>>
感谢您向阿库提出的宝贵意见,您的参与是维库提升服务的动力!意见一经采纳,将有感恩红包奉上哦!