51单片机串口通信--发送字符、接收字符、发送字符串、接收字符串

相关寄存器

SCON:串口控制寄存器(可位寻址)
串行控制寄存器SCON用于选择串行通信的工作方式和某些控制功能。其格式如下:
在这里插入图片描述
SM0、SM1:
在这里插入图片描述

SM2:允许方式2或方式3多机通信控制位;
REN:允许/禁止穿行接收控制位。
○ 由软件置位REN,REN=1为允许串行接收状态,可启动串行接收器RxD,开始接收信息;
○ 软件复位REN,即REN=0,则禁止接收;
TB8:在方式2或方式3,它为要发送的第9位数据,按需要由软件置位或清0;
RB8:在方式2或方式3,是接收到的第9位数据;
TI: 发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件自动置位,即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位;
RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1,向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1(例外情况见SM2说明),必须由软件复位,即RI=0。

PCON:电源控制寄存器
在这里插入图片描述

SMOD:波特率选择位。
○ 当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;
○ SMOD=0,则各工作方式的波特率不加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。
○ 当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;
○ 当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0

printf重定向

因为在单片机中,printf函数是放在stdio文件中的,需要引用stdio文件;然后printf函数也是需要挨个字节输出的,而输出单字节底层是用的putchar函数,所以就需要将原有putchar函数内部改成串口输出单字节去。

char putchar(char c)//重定向
{
	uart_send_byte(c);
	return c;
}

代码

uart.c

#include "uart.h"

void uart_init()
{
	 TMOD=0x20;
	 SCON=0x50;
	 TR1=1;
	 TH1=0xfd;
	 TL1=0xfd;
	 EA=1;
	 ES=1;
	 ET1 = 0;		//禁止定时器1中断
}

//发送一个字符
void uart_send_byte(u8 byte_data)
{
 	SBUF = byte_data;
	while(!TI);
	TI=0;
}

//发送一串字符串
void uart_send_string(u8 *str)
{
 	while(*str)
	{
	 	uart_send_byte(*str++);	
		delay(10);
	}
}

char putchar(char c)//重定向
{
	uart_send_byte(c);
	return c;
}

uart.h

#ifndef __UART__H
#define __UART__H

#include "reg52.h"
#include "delay.h"

void uart_init();
void uart_send_byte(u8 byte_data);
void uart_send_string(u8 *str);

#endif

main.c

#include "reg52.h"	
#include "uart.h"
#include "string.h"
#include "stdlib.h"

sbit led1 = P0^6;

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	uart_init();
	while(1);
}

/*******************************************************************************
* 函数名         : uart_irq() interrupt 4
* 函数功能		  : 串口通信中断函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void uart_irq() interrupt 4
{
	u8 byte_data = 0;
	static u8 rec_str[32] = {0};
	if(RI)
 { 
	 RI=0;//清标志位
	 byte_data =SBUF;	 
	if(byte_data != 'o')
	 {
		 strncat(rec_str,&byte_data,1);
	 }	
	 else if(byte_data == 'o')
	 {
		 printf("%s\r\n",rec_str);
		 memset(rec_str,0,sizeof(rec_str)); 
	 } 
 }
}
	 
  • 36
    点赞
  • 381
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值