找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4863|回复: 3
打印 上一主题 下一主题
收起左侧

单片机讲义6:#define与typedef 软件延时If For语句 按键讲解

[复制链接]
跳转到指定楼层
楼主
ID:250285 发表于 2017-11-19 01:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第六讲 实验58
知识点:
1、 学会画程序流程图
2、 流程控制语句 if(){}else{}用法
3、 操作符 ”~ ”、“!”、“&&”含义
4、 带参函数
5、 函数调用
6、 理解宏定义 #define “替换”作用
7、 循环语句 for 的用法
8、 库函数 unsigned char_cror_ (unsigned char, unsigned char);
unsigned char _crol_ (unsignedchar, unsigned char);含义
9、 C51 扩展类型 code含义
10、   流程控制语句:switchcase 用法
11、   数组定义、引用方式
12、   延时函数


一、51单片机软件延时:
1、 几种周期介绍
  周期名称
  
  描述
  
  时间
  
  振荡
  
  
  的振荡源的周期
  
  T=1/f
  
  状态
  
  
  
  
  2T
  
  机器
  
  CPU 可以完成一个独立操
  作所需要的周期
  
  12T
  
  指令
  
  指 CPU 完成一条操作所需
  的全部时间
  
  n*12T
  


2、指令:
1、MUL、DIV:仅有的 4 周期指令
2、包含 DPTR 和 PC 的指令均为 2 周期指令
3、所有的绝对跳转和条件转移指令,均为 2 周期指令
4、所有包括 A 寄存器的指令,均为单周期指令
5、位操作指令中,ANL 和 ORL 是 2 周期指令
6、所有包含立即地址的指令,除 INC direct 及 DEC direct 外,均为 2 周期指令
7、剩下的均为单周期指令。如:
voiddelay(uint z)
{
uinti ,j;
for(i = z; i> 0;i--)


for(j =0; j < 921; j++)
}


分析:
1.先计算你单片机的振荡(时钟)周期 T=1/晶振(11.0592MHZ)
2.一次 i--操作为 12T
3.忽略变量定义,上述延时函数共需时间:921*z*12T
4.带入 T:921*12*T*z 约为 z us
3、计算误差出现的原因:
1.软件仿真时,函数调用的时候入栈出栈操作的耗时。
2.指令周期随指令的不同而不同导致的误差。
3.中断的影响。
4.变量的范围超过,从而与预计时间不一样。


while(i--):如果 i 为 char 型,执行一次大概为 5us 左右;如果 i 为 int 型则执行一次大概为 10us 左右。注意:软件延时通常用于时序要求较高的编程中,其它需延时较长的地方必须采用单片机内部定时器。

二、#define与 typedef 区别
1、typedef 的用法

在 C 语言中,typedef 常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分, 但它并不实际分配内存空间,
如:typedef    int       INT;

2、#define 的用法
#define 为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些 “表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,如:

#define   INT    int
#define   TRUE   1
#define   Add(a,b)     ((a)+(b));
#define   Loop_10    for (inti=0; i<10; i++)

3、typedef 与#define 的区别
从以上的概念便也能基本清楚,typedef 只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在 C 中是为了定义常量,到了 C++,const、enum、 inline 的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与 typedef 两者到 底该用哪个好,如#define INT int 这样的语句,用 typedef 一样可以完成,用哪个好 呢?我主张用 typedef,因为在早期的许多 C 编译器中这条语句是非法的,只是现今的 编译器又做了扩充。

为了尽可能地兼容,一般都遵循#define 定义“可读”的常量以及一些宏语句的任务, 而 typedef 则常用来定义关键字、冗长的类型的别名。

宏定义只是简单的字符串代换(原地扩展),而 typedef 则不是原地扩展,它的新名字具 有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点 代码的第三行:typedef    (int*)  pINT;以及下面这行:#define               pINT2 int*效果相同?实则不同!实践中见差别:pINT a,b;的效果同 int *a;int *b;表示定 义了两个整型指针变量。而 pINT2 a,b;的效果同 int*a, b;表示定义了一个整型指针 变量 a 和整型变量 b。

typedef 的四个用途和两个陷阱
用途一: 定义一种类型的别名,而不只是简单的宏替换
用途二: 用在旧的 C 代码中(具体多旧没有查),帮助 struct。

typedef   struct   tagPOINT
{
int   x;
int   y;
}POINT;

POINT   p1;   //   这样就比原来的方式少写了一个 struct,比较省事,尤其在大量 使用的时候 或许,在 C++中,typedef 的这种用途二不是很大,但是理解了它,对掌握 以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代 码。

用途三: 用 typedef 来定义与平台无关的类型。用途四:为复杂的声明定义一个新的简单的别名。

陷阱一: 记住,typedef 是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。字符串替换就行。



陷阱二: typedef 在语法上是一个存储类的关键字(如 auto、extern、mutable、static、 register 等一样),虽然它并不真正影响对象的存储特性,如: typedef   static   intINT2;  //不可行 编译将失败,会提示“指定了一个以上的存储类”。



三、按键:
按键是单片机系统中最常用的器件。各种仪器仪表、家用电器操作面板上都离不开按键,是最基本的输入部件。因此,掌握按键输入电路设计、按键驱动程序设计是十分必要的。按键的分类:从单片机获取按键信号类型的角度来讲,可以分为模拟按键和数字按键;从按键与单片机IO 端口对应关系上来讲,可以分为独立按键和矩阵式按键。独立按键很简单,就是一个按键对应一个 IO 端口;而矩阵式按键则相对复杂一些,通过行与列的交叉组合成 i 行*j 列个 按键。

按键的有效方式:
按下有效、按下松开(抬起)有效、长按 n 秒有效、连按 n 次有效、组合按键有效等。按键驱动程序设计步骤:
读取键值—按键消抖—键值处理


四、cror 与 crol 的区别
循环右移与循环左移



这是以前给小学生培训单片机做的一套讲义,尽可能的做到了通俗易懂,现分享给大家,绝对的纯原创资料.
全部资料下载地址(共15章,pdf格式):http://www.51hei.com/bbs/dpj-98524-1.html




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:610271 发表于 2019-9-11 08:15 | 只看该作者
谢谢楼主
回复

使用道具 举报

板凳
ID:635120 发表于 2019-11-12 20:47 来自手机 | 只看该作者
谢谢         
回复

使用道具 举报

地板
ID:8222 发表于 2021-12-13 10:27 | 只看该作者
谢谢楼主详细解释。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表