IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 学习笔记 51单片机通用软件延时方法 -> 正文阅读

[嵌入式]学习笔记 51单片机通用软件延时方法

对于STC51单片机来说,延时函数,想必都不陌生。而用的最多的延时基本都是通过软件方法实现的,但由于STC51不同系列的芯片所采用的指令集不同,各指令执行所用机器周期不同。例如STC12Cx的一个振荡周期=一个机器周期,相对STC89Cx的(12个振荡周期=一个机器周期)运行速度快了近10倍有余,就不能用同一个延时函数。

1. STC指令集(版本)

STC_Y1 :
STC89Cx/STC90Cx
STC89LEx/STC90LEx
STC_Y3 :
STC12Cx/STC12LEx
STC11Fx/STC11Lx/ STC10Fx/STC10Lx
STC15F104E/ STC15L104E(A版)
STC15F204EA/ STC15L204EA(A版)
STC_Y5 :
STC15Fxx/STC15Lxx
其中不包含:STC15F104E/STC15L104E (A版) 和 STC15F204EA/STC15L204EA(A版)
STC_Y6 :
STC8F/ STC8A/ STC8G/ STC8H
不同指令集下部分指令的时钟周期对比
通过STC官方提供的 软件STC-ISP可见,不同指令集版本下同一条指令执行所用时钟周期是不同的。因此可能你编写的软件延时函数就不能通用。

2. STC-ISP 软件生成延时函数

在这里插入图片描述
可以看到,这种方法还是比较可靠的,也是软件延时比较精确的一种,但是呢我比较喜欢那种想延时多久,给个参数就完了的不专业方法,于是呢就在这个软件生成的基础上进行了点小操作,让它具有通用性,不管是Y1,Y3还是Y5一个函数搞定。

2. STC-Y1/ Y3/ Y5 通用软件延时

首先为了做指令集区分,delay.h写法如下:其中包括了一些常用数据类型的定义,后续为了做通用库函数开发用。

// delay.h 文件
//       根据芯片型号 选择对应指令集 用于软件延时 区分
/* ==========================================================
 *     STC_Y1 : STC89Cx/STC90Cx  STC89LEx/STC90LEx 
 *    
 *     STC_Y3 : STC12Cx/STC12LEx STC11Fx/STC11Lx/STC10Fx/STC10Lx 
 *     			STC15F104E/STC15L104E(A版) 
 *    			STC15F204EA/STC15L204EA(A版)
 *    
 *     STC_Y5: STC15Fxx/STC15Lxx 
 *    	不包含:STC15F104E/STC15L104E (A版) 
 *             和 STC15F204EA/STC15L204EA(A版)
 * ==========================================================
 */
//#define _STC_Y1     
#define _STC_Y3    //测试芯片型号 : STC12C5A60S2
//#define _STC_Y5

#include "intrins.h"  //包含移位运算和空指令头文件

#ifndef _TYPE_H
#define _TYPE_H

typedef   signed char		   s8;          
typedef   unsigned char		   u8;        
typedef  signed   int          s16; 	      
typedef  unsigned int          u16;	     
typedef  signed   long int     s32;   
typedef  unsigned long int     u32;	
#endif

接下来是delay.c文件的写法,这里我主要使用C语言预编译指令的方法:

/***************************************************
 * 文件说明:STC51单片机通用软件延时函数
 * 本程序适用于STC除8以外系列外的单片机
 * 作 者:Guard_Byte
 * 时 间:2022-05-08
 **************************************************/
#include "delay.h" 

#ifdef _STC_Y1
/******************************************************************
 * 函数名:delay_ms(unsigned int m)
 * 说  明: ms 延时函数初始化
 * 晶 振 :@11.0592MHz
 *****************************************************************/
void delay_ms(u16 m)
{ 
	unsigned char i, j;
	for(m; m>0; m--){	
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}
#endif   /*  条件 _STC_Y1  完 */

#ifdef _STC_Y3
/******************************************************************
 * 函数名:delay_ms(unsigned int k)
 * 说  明: ms 延时函数初始化
 * 晶 振 :@11.0592MHz
 *****************************************************************/
void delay_ms(u16 m)
{ 
	unsigned char i, j;
	for(m; m>0; m--){	
		_nop_(); //1us
		i = 11,j = 190;
		do	//1ms延时
		{
			while (--j);
		} while (--i);
	}
}

/******************************************************************
 * 函数名:delay_us(unsigned int k)
 * 说  明:u us 延时函数初始化
 * 晶 振 :@11.0592MHz
 *****************************************************************/
void delay_us(u16 u)
{ 
	for(u;(u-1)>0;u--){	
		_nop_();	//1us延时,  大约1us 由于循环赋值耗时,值越大 误差越大
	}
}
#endif   /*  条件 _STC_Y3 完 */

#ifdef _STC_Y5
/******************************************************************
 * 函数名:delay_ms(unsigned int m)
 * 说  明: ms 延时函数初始化
 * 晶 振 :@11.0592MHz
 *****************************************************************/
void delay_ms(u16 m)
{ 
	unsigned char i, j;
	for(m; m>0; m--){	
		_nop_();
		_nop_();
//		_nop_(); //考虑循环耗时
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}

/******************************************************************
 * 函数名:delay_us(unsigned int u)
 * 说  明:u us 延时函数初始化
 * 晶 振 :@11.0592MHz
 *****************************************************************/
void delay_us(u16 u)
{ 
	for(u;u>0;u--){	
	_nop_();	//1us延时
	_nop_();
//	_nop_();
	}
}
#endif   /*  条件 _STC_Y5 完 */

总结:

这种软件延时的方法基本可以满足不同型号STC51单片机,但是由于没有经过精确计算函数调用和循环等一些指令的时间,如果延时参数过大 可能存在us到ms的误差,但是对于,对时间没有太高要求的任务,或者学习使用是没有问题的。经过简单测试,在STC89C52RC和STC12C5A60S2S上,500ms延时误差在几十微秒,还算可以接受。学习笔记 经供参考,大家有更精确的软件延时办法还望指正!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:04:54  更:2022-05-10 12:06:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:37:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码