1.用定时器生成us延时
/******************************************************************************
*延时函数
*
*
*******************************************************************************/
void delayus(u16 us)
{
u16 i;
for(i = 0; i < us; i++)
{
TMOD &= 0xF0; // 清除定时器0设置位
TMOD |= 0x01; // 定时器0 模式1(16位)
TH0 = 0xFF; // 设置初值(适合11.0592MHz时钟)
TL0 = 0xFF;
TF0 = 0; // 清除溢出标志
TR0 = 1; // 启动定时器
while (!TF0); // 等待1us溢出
TR0 = 0; // 停止定时器
TF0 = 0; // 清除溢出标志
}
}
2.空跑实现10us左右延时
/*******************************************************************************
* 函数名 : Delay10us()
* 函数功能 : 延时10us
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Delay10us()
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
3.修改串口实现延时打印,和中断接收
/**************************************************************************************
* 串口通信实验 *
实现现象:下载程序后打开串口调试助手,将波特率设置为9600,选择发送的数据就可以显示
在串口助手上。
注意事项:无。
***************************************************************************************/
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include <string.h>
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
u8 a[] = "hello word\r\n"; // 定义字符数组存字符串
u8 receiveData;
#define RX_BUF_LEN 64
unsigned char rxBuffer[RX_BUF_LEN]; // 接收缓冲区
unsigned char rxIndex = 0; // 缓冲区索引
bit frameReceived = 0; // 一帧接收完毕标志
/******************************************************************************
*延时函数
*
*
*******************************************************************************/
void delayus(u16 us)
{
u16 i;
for(i = 0; i < us; i++)
{
TMOD &= 0xF0; // 清除定时器0设置位
TMOD |= 0x01; // 定时器0 模式1(16位)
TH0 = 0xFF; // 设置初值(适合11.0592MHz时钟)
TL0 = 0xFF;
TF0 = 0; // 清除溢出标志
TR0 = 1; // 启动定时器
while (!TF0); // 等待1us溢出
TR0 = 0; // 停止定时器
TF0 = 0; // 清除溢出标志
}
}
/*******************************************************************************
* 函数名 :UsartInit()
* 函数功能 :设置串口
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void UsartInit()
{
SCON=0X50; //设置为工作方式1,允许接收
TMOD=0X20; //定时器1工作在模式2(8位自动重载)
PCON = 0x00; //波特率不加倍,SMOD=0
TH1 = 0xFD; //253,10进制
TL1 = 0xFD; //初值和TH1一样
ES=1; //打开串口中断
EA=1; //打开总中断
TR1=1; //启动定时器1
}
void UART_SendString(u8 *str)
{
while(*str)
{
SBUF = *str++;
while(!TI);
TI = 0;
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
UsartInit(); // 串口初始化
while(1){
delayus(500000);
UART_SendString(a);
delayus(500000);
if (frameReceived)
{
frameReceived = 0;
UART_SendString(rxBuffer);
rxIndex = 0; // 准备下一帧接收
memset(rxBuffer, 0, 64);
}
};
}
/*******************************************************************************
* 函数名 : Usart() interrupt 4
* 函数功能 : 串口通信中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Usart() interrupt 4
{
if (RI)
{
RI = 0; // 清除接收中断标志
receiveData = SBUF;
// 存入缓冲区
if (rxIndex < RX_BUF_LEN)
{
rxBuffer[rxIndex++] = receiveData;
if (receiveData == '\n') // 接收到换行符,帧结束
{
frameReceived = 1;
// 注:rxIndex 已经是帧长度,包括 '\n'
}
}
else
{
// 超过缓冲区长度,丢弃/清空
rxIndex = 0;
}
}
}

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