这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STC51单片机实例之17串口的使用

共8条 1/1 1 跳转至

STC51单片机实例之17串口的使用

高工
2014-05-17 01:43:23     打赏
/********************************************************************
* 文件名  : 串口发送试验.c
* 描述    :  该文件实现通过串口把数据从单片机发送到电脑,通过串口调试助手显示出来。
			 晶振需要用11.0592的。
			 按51复位按键,会在串口输出一串数据。

*注意:我们开发板直接用我们配的USB线,就可以进行串口调试了。因为我们在开发板上做了PL2303的USB转串口芯片。
***********************************************************************/
#include
#include

#define uchar unsigned char
#define uint  unsigned int 
/********************************************************************
* 名称 : Com_Init()
* 功能 : 初始化串口程序,晶振11.0592, 波特率9600
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;			
     TH1 = 0xFd;
     TL1 = 0xFd;
     TR1 = 1;			
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
	uchar i = 0;
	uchar code Buffer[] = "Welcome To The MCU World.           http://dlmcu.taobao.com               QQ:85536436                          ";	 //所要发送的数据
	uchar *p;
	Com_Init();
	p = Buffer;
	while(1)
	{		
		SBUF = *p;
		while(!TI)                   //如果发送完毕,硬件会置位TI
		{
			_nop_();	
		}
		p++;
		if(*p == '\0') break;		//在每个字符串的最后,会有一个'\0'
		TI = 0;		                //TI清零
	}
	while(1);
}




/********************************************************************
* 文件名  : 串口接收试验.c
* 描述    :  该文件实现通过单片机从电脑接收数据(数据位数字)。通过数码管显示
			 该试验使用的晶振是11.0592,如果使用12M晶振,会出现串口接收
			 不正常的情况。原因是用12M晶振,波特率9600时的误差率达 8%
			 当下载这个程序到单片机时,单片机的最高为为乱码,是正常现象,
			 按一下复位键便可。是由于单片机下载也是通过串口下载引起的。

***********************************************************************/
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int 

uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar LED_Buffer[8] = {0};      //从串口接收的数据

/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
	uchar x,j;
	for(j=0;j<i;j++)
	for(x=0;x<=148;x++);	
}

/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4
{
	static uchar i = 7;    //定义为静态变量,当重新进入这个子函数时 i 的值不会发生改变
	EA = 0;
	if(RI == 1)   //当硬件接收到一个数据时,RI会置位
	{
		LED_Buffer[i] = SBUF - 48; //这里减去48是因为从电脑中发送过来的数据是ASCII码。
		RI = 0;  
		if(i==0) i = 8;  
		i--;		
	}
	EA = 1;
}

/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;			
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;		//启动定时器1
	 ES = 1;		//开串口中断
	 EA = 1;		//开总中断		
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
	uchar i = 0;
	Delay_1ms(100);
	Com_Init();
	while(1)
	{
		for(i=0;i<8;i++)
		{
			P0 = table[LED_Buffer[i]];
			P2 = i;
			Delay_1ms(1);
		}
	}
}						   

 


/********************************************************************
* 文件名  : 串口接收试验.c
* 描述    :  该程序从串口接收数据,通过LCD显示数据。在LCD的第一行显示出来,
			 当数据过多时(超过16个字符),LCD第一行将会被覆盖。
			 该试验使用的晶振是11.0592,如果使用12M晶振,会出现串口接收
			 不正常的情况。原因是用12M晶振,波特率9600时的误差率达 8%。			 

*1602接到J17的插座上。
***********************************************************************/
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int 

/*LED_Buffer[16]用来存储串口发送的数据,com_dat用来记录串口发送的个数*/
uchar LED_Buffer[16], *q, com_dat;      //从串口接收的数据

//这三个引脚参考资料
sbit E=P2^7;		//1602使能引脚
sbit RW=P2^6;		//1602读写引脚	
sbit RS=P2^5;		//1602数据/命令选择引脚

/********************************************************************
* 名称 : Delay(uint del)
* 功能 : 延时10ms * del
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
	uint i,j;
	for(i=0; i<del; i++)
	for(j=0; j<1827; j++)    
	;
}

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay()
{
	int i,j;
	for(i=0; i<=10; i++)
	for(j=0; j<=2; j++)
;
}

/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/

void enable(uchar del)
{
	P0 = del;
	RS = 0;
	RW = 0;
	E = 0;
	delay();
	E = 1;
	delay();
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
	P0 = del;
	RS = 1;
	RW = 0;
	E = 0;
	delay();
	E = 1;
	delay();
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
	enable(0x01);
	enable(0x38);
	enable(0x0c);
	enable(0x06);
	enable(0xd0);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
	 	 L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
	uchar a;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	enable(a);
	while(1)
	{
		if(*p == '\0') break;
		write(*p);
		p++;
	}
}

/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4
{
	EA = 0;
	if(RI == 1)   //当硬件接收到一个数据时,RI会置位
	{
		LED_Buffer[com_dat] = SBUF; 		//把从串口读出的数存到数组
		RI = 0; 
		com_dat++;
		if(com_dat == 16) com_dat = 0;		//当com_dat = 16时,清0,防止数组溢出
	} 
	EA = 1;
}

/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;   //定时器工作在定时器1的方式2
     PCON = 0x00;   //不倍频
     SCON = 0x50;	//串口工作在方式1,并且启动串行接收	
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;		//启动定时器1
	 ES = 1;		//开串口中断
	 EA = 1;		//开总中断		
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
	uchar i = 0, com_dat = 0;	
	L1602_init();
	Delay(100);
	Com_Init();
	while(1)
	{
		q = LED_Buffer;	
		L1602_string(1,1,q);
		com_dat = 0;	
		Delay(100);
	}
}

 


高工
2014-05-17 18:12:39     打赏
2楼

还是51的代码看上去简洁



院士
2014-05-17 21:15:17     打赏
3楼
这种系列性的,最好弄一个总贴,这样大家看起来比较好,方便

高工
2014-05-23 22:16:56     打赏
4楼
LZ好用心,顶起

菜鸟
2014-09-14 10:32:07     打赏
5楼

又来看看咯!!!!

有没有程序原稿了?


高工
2014-09-14 19:57:57     打赏
6楼
这就是原稿

菜鸟
2018-03-27 00:15:49     打赏
7楼

学习学习,谢谢分享


专家
2018-04-02 09:19:50     打赏
8楼

谢谢楼主分享源码。


共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]