单片机:11章——12章笔记

第11章 UART串口通信

UART(Universal Asynchronous Receiver/Transmitter, 通用异步收发器)
波特率:baud,发送一位二进制数据的电平持续时间$ = \frac{1}{baud}$
在UART通信,规定:**当没有通信信号发生时,通信线路保持高电平,当要发送数据之前,先一位0表示起始位,然后发送8位数据位,数据位是先低后高的顺序,数据位发完后再发一位1表示停止位。

串口模块的波特率发生器只能由定时器T1或定时器T2产生,而不能由定时器T0产生,默认是使用定时器1的模式2,定时器T1的重载值计算公式为:TH1=TL1=256-晶振值/12/2/16/波特率
如果电源管理寄存器PCON的最高位=1,也就是如果PCON |=0x80;,计算公式就写为:TH1=TL1=256-晶振值/12/16/波特率;公式中的16重点说明,一位信号采集16次,取出第7、8、9次,如果这三次中有2次高电平,那么就认为是高电平,反之是低电平。
SBUF寄存器,地址:0x99

1. 利用定时器T0模拟串口通信程序

通过此程序能弄明白串口通信的原理

#include <reg52.h>

sbit TXD_PIN=P3^1;				//
sbit RXD_PIN=P3^0;				//
bit rxdOrTxd = 0;					//
bit rxdEnd = 0;						//
bit txdEnd = 0;						//
unsigned char rxdBuf=0;		//
unsigned char txdBuf=0;		//

void configUART(unsigned int baud);
void startTx(unsigned char dat);
void startRx(void);

void main()
{    
	EA=1;
	configUART(4800);
	while(1)
	{
		while(!RXD_PIN);  //
		startRx();
		while(!rxdEnd);
		startTx(rxdBuf+1);
		while(!txdEnd);
	}
}


/**
*  名称:configUART
*  功能:T0中断配置函数
*  参数:baud——串口波特率
**/
void configUART(unsigned int baud)
{
	unsigned int tmp;
	tmp=12000000/12/baud;   //256-TH0+(256-TH0)/2=
	TH0=256-tmp;
	TL0=TH0;
	TMOD &=0XF0;
	TMOD |=0x02;	
}

/**
*  名称:
*  功能:启动串口接收
*  参数:
**/
void startRx()
{
	TL0=256-((256-TH0)>>1);  //开始接收时,波特率减半,增大周期为原来的2倍
	ET0=1;
	TR0=1;
	rxdOrTxd=0;
	rxdEnd=0;
}

/**
*  名称:
*  功能:启动串口发送
*  参数:dat——要发送的字节
**/
void startTx(unsigned char dat)
{
	txdBuf=dat;		//
	TL0=TH0;			//
	ET0=1;				//
	TR0=1;				//
	TXD_PIN=0;		//发送起始位0
	rxdOrTxd=1;		//
	txdEnd=0;			//
}

/**
*  功能:T0中断服务函数,完成接收或发送数据的处理。
*  参数:无
**/
void timer0() interrupt 1
{
	static unsigned char cnt=0;
	if (rxdOrTxd)  //发送
	{
		cnt++;		//
		if (cnt <=8)
		{
			TXD_PIN =txdBuf & 0x01;
			txdBuf >>= 1;
		}
		else if (cnt == 9)
		{
			TXD_PIN=1;
		}
		else
		{
			TR0=0;
			ET0=0;
			cnt=0;
			txdEnd=1;
		}
	}
	else					//处理接收
	{
		if (cnt==0)
		{
			if (RXD_PIN)
			{
				TR0=0;
			}
			else
			{
				rxdBuf=0;
				cnt++;
			}
		}
		else if (cnt <=8)
		{
			rxdBuf >>=1;
			if(RXD_PIN)
			{
				rxdBuf |= 0x80;
			}
			cnt++;
		}
		else
		{
			TR0=0;
			cnt=0;
			if (RXD_PIN)
			{
				rxdEnd=1;
			}
		}
	}
}

2.串口演示例程

体验指针和 sizeof()的用法。例程首先接收上位机下发的命令,根据命令值分别把不同数组的数据回发给上位机。在上位机串口调试助手中分别下发 1、2、3、4,就会得到不同的数组回发,注意这里都用十六进制发送和十六进制显示

#include <reg52.h>

bit cmdArrived=0;		//
unsigned char cmdIndex=0;	//
unsigned char cntTxd=0;		//
unsigned char *ptrTxd;		//

unsigned char a1[1]={1};
unsigned char a2[2]={1,2};
unsigned char a3[4]={1,2,3,4};
unsigned char a4[8]={1,2,3,4,5,6,7,8};

void configUART(unsigned int baud);

void main()
{    
	EA=1;
	configUART(4800);
	while(1)
	{
		if (cmdArrived)
		{
			cmdArrived=0;
			switch(cmdIndex)
			{
				case(1): ptrTxd = a1; cntTxd=sizeof(a1);TI=1;break;
				case(2): ptrTxd = a2; cntTxd=sizeof(a2);TI=1;break;
				case(3): ptrTxd = a3; cntTxd=sizeof(a3);TI=1;break;
				case(4): ptrTxd = a4; cntTxd=sizeof(a4);TI=1;break;
				default: break;
			}
		}
	}
}

/**
*  名称:configUART
*  功能:T1中断配置函数
*  参数:baud——串口波特率
**/
void configUART(unsigned int baud)
{
	unsigned int tmp;
	SCON=0X50;										//配置串口为模式1
	TMOD &=0X0F;									//
	TMOD |=0x20;
	tmp=12000000/12/2/16/baud; 		//
	TH1=256-tmp;
	TL1=TH0;											//
	ET1=0;	
	ES=1;													//使能串口中断
	TR1=1;
}

/**
*  功能:串口中断服务函数,完成接收或发送数据的处理。
*  参数:无
**/
void UART() interrupt 4
{
	if(RI)
	{
		RI=0;
		cmdIndex=SBUF;
		cmdArrived=1;
	}
	if (TI)
	{
		
		TI=0;
		if (cntTxd>0)
		{
			SBUF=*ptrTxd;
			cntTxd=0;
			ptrTxd++;
		}
	}
}

第12章 指针基础与1602认识

sizeof()操作,相当于一个常量,因它是在程序编译的时候进行的,sizeof()括号中可以是变量名,也可以是变量类型名

  • 常量:直接常量与符号常量
    符号常量声明的两种方式:
    : const 类型 符号常量名字 = 常量值;
    : #define 符号常量名 常量值
    字符型常量有两种,普通字符和转义字符
    字符串常量在内存中按顺序逐个存储字符串中的字符的ASCII码值,最后有一个字符’\0’

单片机读外部状态前,必须先保证自己是高电平

1602操作时序

#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;

  1. 读状态:RS=L, R/W=H, E=H;
LCD1602_DB = 0XFF;
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_E=1;
sta = LCD1602_DB;

如果1602设备处于忙的状态,需要等待;由于P0总线被多个设备共用,因此需及时释放P0总线,避免干扰其它设备的使用。因此改写上面程序:

LCD1602_DB=0xFF;
LCD1602_RS=0;
LCD1602_RW=1;
do {
    LCD1602_E=1;
    sta=LCD1602_DB;
    LCD1602_E=0;
} while(sta & 0x80)
  1. 读数据:RS=H, R/W=L,E=H;

  2. 写指令:RS=L, R/W=L, D0~D7=指令码, E=高脉冲;
    E=高脉冲的意思就是:E使能引脚先从低拉高,再从高拉低,形成一个高脉冲。

  3. 写数据:RS=H, R/W=L, D0~D7=指令码, E=高脉冲;

版权声明:本文为CSDN博主「acktomas」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/acktomas/article/details/104655795

生成海报
点赞 0

acktomas

我还没有学会写个人说明!

暂无评论

相关推荐

单片机:串口通信

RS-422A RS-422A输出驱动器为双端平衡驱动器。如果其中一条线为逻辑“1”状态,另一条线就为逻辑“0”,比采用单端不平衡驱动对电压的放大倍数大一倍。差分电路能从地线干扰中拾取有效信号,差分接收

单片机:EEPROM(IIC总线)

I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。 I2C总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低&#xff

单片机:DS18B20温度传感器原理

DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆