11_UART串口

11_UART


串口打印调试信息,外界各种设备

1、串口连接芯片图

在这里插入图片描述

2、串口传输一个字节的过程

在这里插入图片描述
传输数据时的逻辑电平如下两图:
在这里插入图片描述
在这里插入图片描述

3、发送接收过程

在这里插入图片描述
波特率:115200,8n1
每一位:t = 1/115200
传输1Byte:需要10位(start, Data, Stop)
t = 10 / 115200
1秒能传输:1/t = 115200/10 = 11520 byte

4、编写UART函数

4.1、初始化函数uart0_init()

编写初始化函数:void uart0_init()

4.1.1、设置引脚用于串口

//GPH2,3用于TxD0,RxD0 
GPHCON &= ~((3<<4) | (3<<6));
GPHCON |=  ((2<<4) | (2<<6));

4.1.2、使能上拉

//使能内部上拉使得引脚在平时为高电平
GPHUP &= ~((1<<2) | (1<<3));

4.1.3、设置波特率

设置UCON0寄存器
UBRDIV0 = (int)( UART clock / ( buad rate x 16) )1
UART clock = PCLK = 50MHz
UBRDIV0 = (int)( 50000000 / ( 115200 x 16) )1 = 26

UCON0 = 0x00000005;
/* PCLK,中断/查询模式 
* UCON0[11:10] = 00(0x00000005),10(0x00000805) :选为PCLK
* UOCN0[3:2] = 01,Interrupt request or polling mode
* UOCN0[1:0] = 01,Interrupt request or polling mode
*/

4.1.4、设置数据格式

ULCON0 = 0x00000003;
/* 8n1: 8个数据位,无校验位,一个停止位 
* ULCON0[5:4:3] = 0xx :No parity(无校验位)
* ULCON0[2] = 0 :One stop bit per frame(一个停止位)
* ULCON0[1:0] = 11 :8-bits(8个数据位)
*/

4.2、int putchar(int c)函数

4.2.1、判断状态

while (!(UTRSTAT0 & (1<<2)));
此位为0表明上一次的数据还没发送出去,等待。

4.2.2、发送数据

UTXH0 = (unsigned char)c;
寄存器UTXH0定义为unsigned char类型。

4.3、int getchar(void)函数

4.3.1、判断状态

while (!(UTRSTAT0 & (1<<0)));	
此位为0表明上一次的数据还没接收,等待。

4.3.2、返回接收到的数据

	return 	URXH0;

4.4、int puts(const char *s)函数

输出字符串函数:
	while(*s)
	{
		putchar(*s);
		s++;
	}

5、UART头文件

//uart.h
#ifndef _UART_H
#define _UART_H
void uart0_init();
int putchar(int c);
int getchar(void);
int puts(const char *s);
#endif

6、main函数

#include "s3c2440_soc.h"
#include "uart.h"
int main(void) 
{
	unsigned char c;
	uart0_init();
	puts("Hello,world!\n\r");
	while(1) {
		c = getchar();
		if (c == '\r') {
			putchar('\n');
		}
		if (c == '\n') {
			putchar('\r');
		}		
		putchar(c);	/* 若无这个则串口不显示输入的字符,即没有回显 */
	}
	return 0;
}

7、编写自己的printf测试函数

Printf中的格式字符:
在这里插入图片描述
my_printf测试函数:

#include <stdio.h>
//#include <stdarg.h>

typedef char *  va_list;
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
//#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
//#define va_arg(ap,t)	(ap = ap +_INTSIZEOF(t), *(t *)(ap -_INTSIZEOF(t)))
#define va_arg(ap,t)	(*(t *)(ap = ap +_INTSIZEOF(t),ap -_INTSIZEOF(t)))

#define va_end(ap)      ( ap = (va_list)0 )

struct person{
	char *name;
	int age;
	char score;
	int id;
}; 

/* 由于在x86(32位机器)平台下,GCC编译器默认按4字节对齐 */
/*int printf(ocnst char *formt, ...);
 *依据: x86平台,函数调用参数是使用堆栈来实现的
 *目的: 将所有传入的参数全部打印出来
 */
int push_test(const char *format, ...)
{
	//char *p = (char *)&format;
	int i;
	struct person per;
	char c;
	double d;//float d;
	va_list p;
	
	//1==========================
	/* 指针对连续空间操作时: 1)取值 2)移动指针 */	
	printf("arg1: %s\n",format);
		
	//2==========================
	//p = p +sizeof(char *);
	va_start(p, format);
	/* 指针对连续空间操作时: 1)取值 2)移动指针 */
	//i = *((int *)p);
	//p = p + sizeof(int);
	i = va_arg(p, int);
	printf("arg2: %d\n",i);

	//3==========================
	/* 指针对连续空间操作时: 1)取值 2)移动指针 */	
	//per = *((struct person *)p);
	//p = p + sizeof(struct person);
	per =  va_arg(p, struct person);
	printf("arg3: .name = %s, .age = %d, .score= %c, .id=%d\n",\
		       per.name,   per.age,   per.score,  per.id);

	//4==========================
	/* 指针对连续空间操作时: 1)取值 2)移动指针 */
	//c = *((char *)p);
	/* p = p + ((sizeof(char) + 3) & ~3); 
	 * #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
	 * 当sizeof(n)=1/2/4时,_INTSIZEOF(n)都等于4
	 */	
	c = va_arg(p, int); /*c = va_arg(p, char);
	                由于传递参数时保持字符对齐,
	                需要把char类型转换成int类型*/
	printf("arg4: %c\n",c);

	//5==========================
	/* 指针对连续空间操作时: 1)取值 2)移动指针 */	
	//d = *((double *)p); /* 默认按照doubled = *((float *)p); */
	//p = p + sizeof(double);
	d = va_arg(p, double);

	/* 避免"野指针"出现 */
	//p = (char *)0;
	va_end( p );
	printf("arg5: %f\n",d);
	
	return 0;
}

int main(int argc,char **argv)
{
	struct person per={"Zhang Dengyu",23,'A',191040043};

	printf("sizeof(char   )=%d\n",sizeof(char   ));
	printf("sizeof(int    )=%d\n",sizeof(int    ));
	printf("sizeof(char  *)=%d\n",sizeof(char  *));
	printf("sizeof(char **)=%d\n",sizeof(char **));	
	printf("sizeof(struct person)=%d\n",sizeof(struct person));	

	//push_test("HDU_DZ_ZDY");
	//push_test("HDU_DZ_ZDY",8023);
	//push_test("HDU_DZ_ZDY",8023,per);	
	//push_test("HDU_DZ_ZDY",8023,per,'c');
	push_test("HDU_DZ_ZDY",8023,per,'c',3.14);	
	
	return 0;
}	

代码解析:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhangDaniel_ZD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值