一、
串口通讯常识
1. 串口角色解析
2. 串口通讯参数
串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。
波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的 bit的个数。例如 300波特表示每秒钟发送 300个 bit。常用的波特率有 38400,115200。
起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。
3. 串口硬件引脚
我们通常使用的 RS232的 9帧串
口,其中最为重要的是 2,3,5脚
2 :RXD:接收数据
3 :TXD:发送数据
5 :GND:接地
二、 串口驱动程序设计
2. 1 串口初始化
①引脚设置
②帧格式设置
③工作模式设置
④波特率设置
2.2 导读 210 串口初始化
2.3
串口初始化
先看原理图,串口电路中2,3脚是RSTXD0、TSRXD0。对应于底板的原理图,位GPH2、GPH3
2.4 串口收发
为了测试串口是否可用可以在main.c中增加下列代码。
三、 串口控制台建立
1、控制台框架搭建
1.1 控制台类型:
①菜单型:串口选择序号
②解析型:判断指令是否是所支持的,来搜索运行。
1.2 菜单型控制台搭建
在main.c函数中打印信息,输出菜单,并判断。
2、printf/scanf函数实现
2.1 了解printf和scanf函数
2.2 实现printf函数、scanf函数
然而报错了:
va_start这些宏需要自己来定义,所以要把内核中的文件集成到gboot中来。通过修改Makefile,使用上提供的代码。
lib目录下的Makefile,最后生成lib.o
修改自己的Makefile文件:
阅读(73) | 评论(0) | 转发(0) |
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
1. 串口角色解析
2. 串口通讯参数
串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。
波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的 bit的个数。例如 300波特表示每秒钟发送 300个 bit。常用的波特率有 38400,115200。
起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。
3. 串口硬件引脚
我们通常使用的 RS232的 9帧串
口,其中最为重要的是 2,3,5脚
2 :RXD:接收数据
3 :TXD:发送数据
5 :GND:接地
二、 串口驱动程序设计
2. 1 串口初始化
①引脚设置
②帧格式设置
③工作模式设置
④波特率设置
2.2 导读 210 串口初始化
- void uart_init()
- {
- //1.配置引脚用于RX/TX功能
- GPA0CON = 0x22222222;
- GPA1CON = 0X2222;
-
- //2.设置数据格式等
- UFCON0 = 0X1;
- //无流控
- UMCON0 = 0X0;
- //数据位:0,无校验,停止位:1
- ULCON0 = 0X3;
- //时钟:PCLK,禁止中断,使能UART发送、接收
- UCON0 = 0X5;
-
- //3. 设置波特率
- UBRDIV0 = UART_UERDIV_VAL;
- UDIVSLOT0 = UART_UDIVSLOT_VAL;
- }
-
- //接收一个字符
- char getc(void)
- {
- //如果RX_FIFO空,等待
- while(!(UTRSTAT0 & (1<<0)));
- //取数据
- return URXH0;
- }
-
- //发送一个字符
- void getc(char c)
- {
- //如果TX_FIFO满,等待
- while(!(UTRSTAT0 & (1<<2)));
- //些数据
- UTXH0 = c;
- }
先看原理图,串口电路中2,3脚是RSTXD0、TSRXD0。对应于底板的原理图,位GPH2、GPH3
- #define GPHCON *((volatile unsigned long*) 0x56000070)
- #define ULCON0 *((volatile unsigned long*) 0x50000000)
- #define UCON0 *((volatile unsigned long*) 0x50000004)
- #define UBRDIV0 *((volatile unsigned long*) 0x50000028)
- #define UTRSTAT0 *((volatile unsigned long*) 0x50000010)
- #define UTXH0 *((volatile unsigned long*) 0x50000020)
- #define URTH0 *((volatile unsigned long*) 0x50000024)
-
- #define PCLK 50000000
- #define BAUD 115200
-
- void uart_init()
- {
- //1.配置引脚功能
- GPHCON &= ~(0xf<<4); //先清0
- GPHCON |= (0xa<<4); //设置成TX和RX,0b1010
-
- //2.1设置数据格式
- ULCON0 = 0b11;
- //2.2设置工作模式
- UCON0 = 0b0101;
-
- //3.设置波特率,这里使用的是PCLK
- UBRDIV0 = (int)(PCLK / (BAUD *16) - 1);
- }
-
-
-
- void putch(unsigned char ch)
- {
- //和210的基本一样
- while(!(UTRSTAT0 & 1<<2));
- UTXH0 = ch;
- }
-
- unsigned char getch(void)
- {
- unsigned char ret;
- //和210的基本一样
- while(!(UTRSTAT0) & (1<<0));
- ret = URTH0;
- if((ret == 0x0d) ||(ret == 0x0a))
- {
- putch(0x0d);
- putch(0x0a);
- }
- else
- putch(ret);
-
- return ret;
- }
2.4 串口收发
为了测试串口是否可用可以在main.c中增加下列代码。
- int gboot_main()
- {
- unsigned char buf[2048];
-
- #ifdef MMU_ON
- mmu_init();
- #endif
-
- led_init();
- led_on();
-
- button_init();
- init_irq();
-
- uart_init();
-
- while(1)
- {
- getch();
- }
-
- return 0;
- }
三、 串口控制台建立
1、控制台框架搭建
1.1 控制台类型:
①菜单型:串口选择序号
②解析型:判断指令是否是所支持的,来搜索运行。
1.2 菜单型控制台搭建
在main.c函数中打印信息,输出菜单,并判断。
- int gboot_main()
- {
- int num;
-
- #ifdef MMU_ON
- mmu_init();
- #endif
-
- led_init();
- led_on();
- button_init();
- init_irq();
- uart_init();
-
- while(1)
- {
- printf("\n***************************************\n\r");
- printf("\n*************GBOOT*********************\n\r");
- printf("1.Download Linux kernel from TFTP Server!\n\r");
- printf("2.Boot Linux from RAM!\n\r");
- printf("3.Boot Linux from Nand Flash!\n\r");
- printf("\n Plsase Select:");
- scanf("%d",&num);
-
- switch(num)
- {
- case 1:
- //tftp_load();
- break;
- case 2:
- //boot_linux_ram();
- break;
- case 3:
- //boot_linux_nand();
- break;
- default:
- printf("Error: wrong Selection!\n\r");
- break;
- }
- }
- return 0;
- }
2、printf/scanf函数实现
2.1 了解printf和scanf函数
- #man 3 printf
- int printf(const char *format, ...); //...是变参
- int printf(const char* fmt, ...)
- {
- int i;
- va_list args;
-
- //1.将变参转化为字符串
- va_start(args,fmt); //设置args指向fmt(第一个参数)
- vsprintf((char*)outbuf, fmt, args); //将args存放到outbuf中
- va_end(); //结束
-
- //2.打印字符串到串口
- for(i = 0; i< strlen((char *)outbuf); i++)
- {
- putc(outbuf[i]);
- }
- return i;
- }
-
- int scanf(const char *fmt, ...)
- {
-
- unsigned char c;
- int i = 0;
- va_list args;
-
- //1.获取输入字符串
- while(1)
- {
- c = getc();
- if((c == 0x0d) || (c == 0x0a))
- {
- inbuf[i] = '\n';
- break;
- }
- else
- {
- inbuf[i] = c;
- i++;
- }
- }
-
- //2.格式转换
- va_start(args, fmt);
- vsscanf((char *)inbuf, fmt, args);
- va_end(args);
- return i;
- }
va_start这些宏需要自己来定义,所以要把内核中的文件集成到gboot中来。通过修改Makefile,使用上提供的代码。
lib目录下的Makefile,最后生成lib.o
- objs := div64.o lib1funcs.o ctype.o muldi3.o printf.o string.o vsprintf.o
-
- all : $(objs)
- arm-linux-ld -r -o lib.o $^
-
- %.o : %.c
- arm-linux-gcc ${CFLAGS} -c $^
-
- %.o : %.S
- arm-linux-gcc ${CFLAGS} -c $^
-
- clean:
- rm -f *.o
- OBJS := start.o main.o dev/dev.o lib/lib.o //这里增加了lib/lib.o
-
- CFLAGS := -fno-builtin -I$(shell pwd)/include //编译时所需的选项,-fno-builtin:去掉内联函数选项 -I$(shell pwd)/include 增加头文件寻找路径
- export CFLAGS //导出,是的lib下的Makefile也能用CFLAGS
-
- all : gboot.elf
- arm-linux-objcopy -O binary gboot.elf gboot.bin
-
- gboot.elf : $(OBJS)
- arm-linux-ld -Tgboot.lds -o gboot.elf $^
-
- %.o : %.S
- arm-linux-gcc -g -c $^
-
- %.o : %.c
- arm-linux-gcc $(CFLAGS) -c $^
-
- lib/lib.o : //增加依赖/lib/lib.o
- make -C lib all //执行make all在lib目录下,
-
- dev/dev.o :
- make -C dev all
-
- .PHONY: clean
- clean:
- rm -f gboot.elf gboot.bin *.o
- make -C lib clean
- make -C dev clean
给主人留下些什么吧!~~
评论热议