[经验分享] C51 us延时实现

[复制链接]
小海师 发表于 2025-8-26 08:44 | 显示全部楼层 |阅读模式
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

您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

210

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部