Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498896
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: 嵌入式

2016-10-05 22:35:27

一、串口通讯常识
1.串口角色解析

2.串口通讯参数
串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。

波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300bit。常用的波特率有38400,115200
起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。

3.串口硬件引脚
我们通常使用的RS2329帧串
口,其中最为重要的是2,3,5
2 :RXD:接收数据
3 :TXD:发送数据
5 :GND:接地


二、串口驱动程序设计
2.1串口初始化
①引脚设置
②帧格式设置
③工作模式设置
④波特率设置

2.2 导读210串口初始化
  1. void uart_init()
  2. {
  3.     //1.配置引脚用于RX/TX功能
  4.     GPA0CON = 0x22222222;
  5.     GPA1CON = 0X2222;

  6.     //2.设置数据格式等
  7.     UFCON0 = 0X1;
  8.     //无流控
  9.     UMCON0 = 0X0;
  10.     //数据位:0,无校验,停止位:1
  11.     ULCON0 = 0X3;
  12.     //时钟:PCLK,禁止中断,使能UART发送、接收
  13.     UCON0 = 0X5;

  14.     //3. 设置波特率
  15.     UBRDIV0 = UART_UERDIV_VAL;
  16.     UDIVSLOT0 = UART_UDIVSLOT_VAL;
  17. }

  18. //接收一个字符
  19. char getc(void)
  20. {
  21.     //如果RX_FIFO空,等待
  22.     while(!(UTRSTAT0 & (1<<0)));
  23.     //取数据
  24.     return URXH0;
  25. }

  26. //发送一个字符
  27. void getc(char c)
  28. {
  29.     //如果TX_FIFO满,等待
  30.     while(!(UTRSTAT0 & (1<<2)));
  31.     //些数据
  32.     UTXH0 = c;
  33. }
2.3 串口初始化
先看原理图,串口电路中2,3脚是RSTXD0、TSRXD0。对应于底板的原理图,位GPH2、GPH3
              

  1. #define GPHCON *((volatile unsigned long*) 0x56000070)
  2. #define ULCON0 *((volatile unsigned long*) 0x50000000)
  3. #define UCON0 *((volatile unsigned long*) 0x50000004)
  4. #define UBRDIV0 *((volatile unsigned long*) 0x50000028)
  5. #define UTRSTAT0 *((volatile unsigned long*) 0x50000010)
  6. #define UTXH0 *((volatile unsigned long*) 0x50000020)
  7. #define URTH0 *((volatile unsigned long*) 0x50000024)

  8. #define PCLK 50000000
  9. #define BAUD 115200

  10. void uart_init()
  11. {
  12.     //1.配置引脚功能
  13.     GPHCON &= ~(0xf<<4);                                //先清0
  14.     GPHCON |= (0xa<<4);                                 //设置成TX和RX,0b1010

  15.     //2.1设置数据格式
  16.     ULCON0 = 0b11;
  17.     //2.2设置工作模式
  18.     UCON0 = 0b0101;

  19.     //3.设置波特率,这里使用的是PCLK
  20.     UBRDIV0    = (int)(PCLK / (BAUD *16) - 1);
  21. }



  22. void putch(unsigned char ch)
  23. {
  24.     //和210的基本一样
  25.     while(!(UTRSTAT0 & 1<<2));
  26.     UTXH0 = ch;
  27. }

  28. unsigned char getch(void)
  29. {
  30.     unsigned char ret;
  31.     //和210的基本一样
  32.     while(!(UTRSTAT0) & (1<<0));
  33.     ret = URTH0;
  34.     if((ret == 0x0d) ||(ret == 0x0a))
  35.     {
  36.         putch(0x0d);
  37.         putch(0x0a);
  38.     }
  39.     else
  40.         putch(ret);

  41.     return ret;
  42. }

2.4 串口收发
为了测试串口是否可用可以在main.c中增加下列代码。

  1. int gboot_main()
  2. {
  3.     unsigned char buf[2048];

  4. #ifdef MMU_ON
  5.     mmu_init();
  6. #endif

  7.     led_init();
  8.     led_on();

  9.     button_init();
  10.     init_irq();

  11.     uart_init();

  12.     while(1)
  13.     {
  14.         getch();
  15.     }

  16.     return 0;
  17. }

三、串口控制台建立
1、控制台框架搭建
1.1 控制台类型:
①菜单型:串口选择序号
②解析型:判断指令是否是所支持的,来搜索运行。
1.2 菜单型控制台搭建
在main.c函数中打印信息,输出菜单,并判断。
  1. int gboot_main()
  2. {
  3.     int num;

  4. #ifdef MMU_ON
  5.     mmu_init();
  6. #endif

  7.     led_init();
  8.     led_on();
  9.     button_init();
  10.     init_irq();
  11.     uart_init();

  12.     while(1)
  13.     {
  14.         printf("\n***************************************\n\r");
  15.         printf("\n*************GBOOT*********************\n\r");
  16.         printf("1.Download Linux kernel from TFTP Server!\n\r");
  17.         printf("2.Boot Linux from RAM!\n\r");
  18.         printf("3.Boot Linux from Nand Flash!\n\r");
  19.         printf("\n Plsase Select:");
  20.         scanf("%d",&num);

  21.         switch(num)
  22.         {
  23.         case 1:
  24.             //tftp_load();
  25.             break;
  26.         case 2:
  27.             //boot_linux_ram();
  28.             break;
  29.         case 3:
  30.             //boot_linux_nand();
  31.             break;
  32.         default:
  33.             printf("Error: wrong Selection!\n\r");
  34.             break;
  35.         }
  36.     }
  37.     return 0;
  38. }

2、printf/scanf函数实现
2.1 了解printf和scanf函数
  1. #man 3 printf
  2. int printf(const char *format, ...);                    //...是变参
2.2 实现printf函数、scanf函数
  1. int printf(const char* fmt, ...)
  2. {
  3.     int i;
  4.     va_list args;

  5.     //1.将变参转化为字符串
  6.     va_start(args,fmt);                                //设置args指向fmt(第一个参数)
  7.     vsprintf((char*)outbuf, fmt, args);                //将args存放到outbuf中
  8.     va_end();                                          //结束

  9.     //2.打印字符串到串口
  10.     for(= 0; i< strlen((char *)outbuf); i++)
  11.     {
  12.         putc(outbuf[i]);
  13.     }
  14.     return i;
  15. }

  16. int scanf(const char *fmt, ...)
  17. {

  18.     unsigned char c;
  19.     int i = 0;
  20.     va_list args;

  21.     //1.获取输入字符串
  22.     while(1)
  23.     {
  24.         c = getc();
  25.         if((c == 0x0d) || (c == 0x0a))
  26.         {
  27.             inbuf[i] = '\n';
  28.             break;
  29.         }
  30.         else
  31.         {
  32.             inbuf[i] = c;
  33.             i++;
  34.         }
  35.     }
  36.     
  37.     //2.格式转换
  38.     va_start(args, fmt);
  39.     vsscanf((char *)inbuf, fmt, args);
  40.     va_end(args);
  41.     return i;
  42. }
然而报错了:

va_start这些宏需要自己来定义,所以要把内核中的文件集成到gboot中来。通过修改Makefile,使用上提供的代码。
lib目录下的Makefile,最后生成lib.o
  1. objs := div64.o lib1funcs.o ctype.o muldi3.o printf.string.o vsprintf.o

  2. all : $(objs)
  3.     arm-linux-ld --o lib.o $^
  4.     
  5. %.: %.c
  6.     arm-linux-gcc ${CFLAGS} -c $^
  7.     
  8. %.: %.S
  9.     arm-linux-gcc ${CFLAGS} -c $^

  10. clean:
  11.     rm -*.o
修改自己的Makefile文件:
  1. OBJS := start.o main.o dev/dev.o lib/lib.o                                          //这里增加了lib/lib.o

  2. CFLAGS := -fno-builtin -I$(shell pwd)/include                                       //编译时所需的选项,-fno-builtin:去掉内联函数选项 -I$(shell pwd)/include 增加头文件寻找路径
  3. export CFLAGS                                                                       //导出,是的lib下的Makefile也能用CFLAGS
  4.     
  5. all : gboot.elf
  6.     arm-linux-objcopy -O binary gboot.elf gboot.bin

  7. gboot.elf : $(OBJS)
  8.     arm-linux-ld -Tgboot.lds -o gboot.elf $^
  9.         
  10. %.: %.S
  11.     arm-linux-gcc --c $^
  12.     
  13. %.: %.c
  14.     arm-linux-gcc $(CFLAGS) -c $^
  15.     
  16. lib/lib.:                                                                          //增加依赖/lib/lib.o
  17.     make -C lib all                                                                  //执行make all在lib目录下,

  18. dev/dev.:
  19.     make -C dev all
  20.     
  21. .PHONY: clean
  22. clean:
  23.     rm -f gboot.elf gboot.bin *.o
  24.     make -C lib clean
  25.     make -C dev clean

阅读(736) | 评论(0) | 转发(0) |
0

上一篇:Nandflash学习

下一篇:DMA学习

给主人留下些什么吧!~~