手把手教你学单片机的C语言程序设计(十一).pdf_第1页
手把手教你学单片机的C语言程序设计(十一).pdf_第2页
手把手教你学单片机的C语言程序设计(十一).pdf_第3页
手把手教你学单片机的C语言程序设计(十一).pdf_第4页
手把手教你学单片机的C语言程序设计(十一).pdf_第5页
全文预览已结束

手把手教你学单片机的C语言程序设计(十一).pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

手 学 习 单 片栅I C语言程序是由函数构成的。 函数 是 C语言中的一种基本模块。在 手教 手教你学单片机的 C语言程序设计 ( 三 ) 中, 我们已经介绍了C语言程序 的组成结构,即 C语言程序是由函数 构成的,一个 C源程序至少包括一个 名为 ma i n ( ) 的 函数( 主 函数) , 也 可能包 含其它函数。 C语言程序总是 由主函数 ma i n ( ) 开始执行的, ma i n ( ) 函数是一个控制程 序流程的特殊函数 , 它是程序的起点。 所有函数在定义时是相互独立的, 它们之间是平行关系, 所以不能在一个 函数内部定义另一个函数, 即不能嵌套 定义。函数之 间可 以互相调 用 , 但不能 调用主 函数。 从使用者的角度来看 。有两种函 数: 标准库函数和用户自定义功能子函 数。标准库函数是编译器提供的。 用户 不必自己定义这些函数。 C语言系统能 够提供功能强大、 资源丰富的标准函数 库, 作为使用者 , 在进行程序设计 时应 善于利用这些资源 。 以提高效率, 节省 开发时间。 函数定义的一般形式为: 函数类型标识符 函数名 ( 形式 参数) 形式参数类型说 明表列 局部 变量定 义 函数体语句 A NS I C标准允许在形式参数表中 对形式参数的类型进行说明。 因此也可 这样定义: 函数类型标识符 函数名 ( 形式参 数类型说明表列) 局部变量定义 函数体语 句 其中: “ 函数类型标识符”说明了函数返 回值的类型, 当“ 函数类型标识符” 缺省 时默认 为整型。 “ 函数名”是程序设计人员自己定 义的函数名字。 “ 形式参数类型说明表列”中列出 的是在主调用函数与被调用函数之间 传递数据的形式参数, 如果定义的是无 参 函数 。形式 参数类型说 明表列用 v o i d来注明。 “ 局部变量定义”是对在函数内部 使用的局部变量进行定义。 “ 函数体语句”是为完成该函数的 特定功能而设置的各种语句。 C语言采用函数之间的参数传递 方式, 便一个函数能对不同的变量进行 处理 , 从而大大提高了函数的通用性与 灵活性。在函数调用时, 通过主调函数 的实际参数与被调函数的形式参数之 间进 行数据传递来实现函数间参数的 传递。在被调 函数最后 , 通过 r e t u r n语 句返回函数的返回值给主调函数。 r e t u r n语句形式如下 : r e t u r n( 表达式) : 对于不需要有返回值的函数。 可以 将该函数定义为“ v o i d ” 类型。 v o i d类型 又称“ 空类型” 。这样。 编译器会保证在 函数调用结束时不使函数返回任何值。 为了使程序减少出错, 保证函数的正确 调用,凡是不要求有返回值的函数, 都 应将其定义成 v o id类型。 在定义函数中指定的变量 。 当未出 现函数调用的时候, 它们并不占用内存 中的存储单元。 只有在发生函数调用的 时候 ,函数的形参才被分配内存单元。 在调用结束后, 形参所占的内存单元也 被释放。实参可以是常量、 变量或表达 式, 要求实参必须有确定的值。在调用 时将实参的值赋给形参变量( 如果形参 是数组名, 则传递的是数组首地址而不 是变量的值 ) 。 从 函数 定 义 的 形 式 看 ,又 可 划 分为无参数函数、 有参数 函数 、 及空 函数 三 种 。 1 无参数函数 此种函数在被调用时无参数, 主调 函数并不将数据传送给被调用函数。 无 参数函数可以返回或不返回函数值, 一 般以不带返回值的为多。 2 有参数函数 调用此种函数时, 在主调函数和被 调函数之间有参数传递。也就是说, 主 调函数可以将数据传递给被调函数使 用, 被调函数中的数据也可以返回供主 调函数使用。 3 空函数 如果定义函数时只给 出一对大括 号 , 不给出其局帮变量和函数体语句 ( 即函数体内部是。 空 的) , 则该函数为 “ 空函数” 。 这种空函数开始时只设计最 基本的模块( 空架子 ) 。 其他作为扩充功 能在以后需要时再加上, 这样可使程序 的结构清晰。 可读性好。 而且易于扩充。 C语言程序 中函数是可以互相调 用的。 所谓 函数调用就是在一个 函数体 中引用另外一个已经定义了的函数。 前 者称为主调用函数 , 后者称为被调用函 数。 主调用 函数调用被调 用函数 的一般 形式 为: 函数名 ( 实际参数表列) 其 中 , “ 函数名”指 出被调 用的 函数 。 “ 实际参数表列”中可以包含多个 实际参数 ,各个参数之间用逗号隔开。 实际参数的作用是将它的值传递给被 维普资讯 调用函数 中的形式参数。需要注意的 是 , 函数调用中的实际参数与函数定义 中的形式参数必须在个数、 类型及顺序 上严格保持一致, 以便将实际参数的值 正确地传递给形式参数。 否则在函数调 用时会产生意想不到的错误结果。 如果 调用的是无参函数, 则可以没有实际参 数表列, 但圆括号不能省略。 C语言 中可 以采用三种方式完成 函数的调用。 1 函数语句 在主调函数中将函数调用作为一 条语句, 例如: f u n 1 ( ) : 这是无参调用 , 它不要求被调函数 返回一个确定的值 , 2 函数表达式 只要求它完成一定的操作。 在主调函数中将函数调用作为一 个运算对象直接出现在表达式中 这种 表达式称为函数表达式。例如 : c = p o w e r ( x , n ) + p o w e r ( y , m) : 这其实是一个赋值语句 , 它包括两 个函数调用, 每个函数调用都有一个返 回值 , 将两个返回值相加的结果。 赋值 给变量 c 。因此这种函数调用方式要求 被调函数返回一个确定的值。 3 函数参数 在主调函数中将函数调用作为另 一 个函数调用的实际参数。例如: m= ma x ( a , ma x ( b, c ) ) : ma x ( b, c ) 是一次函数调 用 , 它的 返回值作为函数 ma x另一次调用的实 参。最后 m的值为变量 a 、 b 、 c三者中 值最大者。 这种在调用一个函数的过程中又 调用了另外一个函数的方式 , 称为嵌套 函数调用。 在一个函数中调用另一个函数( 即 被调函数 ) , 需要具备如下的条件: 1 被调用的函数必须是已经存在 的函数( 库函数或者用户 自定义过的 函数 ) 。 2 如果程序使用了库函数, 或者使 用不在同一文件中的另外的自定义函 数 ,则要程序的开头用 # i n c l u d e预处 理命令将调用有关函数时所需要的信 息包含到本文中来。对于自定义函数 , 如果不是在本文件中定义的, 那么在程 序开始要用 e x t e r n 修饰符进行原型声 明。 使用库函数时, 用 # i n c lu d e 的形式 , 使用自己编辑的函数头文件等 时, 用 # i n c l u d e “ h c ” 的格 式。 下面做几个实验。 在 L E D 1 6 2字符液晶试验板上 实现参数传递的函数调用。 数码管的低 2位显示 3和 8 。3号键按下后( 即 P 3 0为低) 调用交换子函数 s wa p , 使得数 码管的低 2位交换显示为8和 3 。 在我的文档中建立一个文件 目录 ( c s 2 6) 。 然后 建立 c s 2 6 u v 2的工程 项 目, 最后建立源程序文件 ( c s 2 6 c o 输入 下面的程 序 : # in c l u d e 序号( 以下同 ) : 1 # d e f i n e u c h a r u n s i g n e d c h a r 2 u c h a r c o d e S E G 7 【 1 O = O x c O , O x f 9 , 0 x a 4 , O x b O , 0 x 9 9 , 0 x 9 2 , 0 x 8 2 ,0 x f 8 , 0 x 8 0 , 0 x 9 0 ; 3 s b it P 3 0 =P 3 O : 4 u c h a r n u r n b e r l , n u mb e r 2 ; 5 = : = = = = = = = = = = = = = = = - - - 6 v o id s wa p ( u c h a r x u c h a r y ) ; 7 = = =: = = = = = = = = = = = = = = = = = 8 v o id ma in ( v o id ) 9 1 0 u c h a r a , b : 1 1 n u mb e r 1 = 3 ; n u mb e r 2 = 8 ; 1 2 a = n u mb e r l : b =n u mb e r 2 ; 1 3 wh il e ( 1 ) 1 4 1 5 P 1 = S E G 7 n u mb e r 1 : 1 6 P 0 = S E G 7 n u m b e r 2 ; 1 7 P 3 = 0 x 0 f ; 1 8 if ( ! P 3 _ 0 ) s wa p ( a , b ) : 1 9 2 0 2 1 = = = = = = = = = = = = = = = = = = = : 2 2 v o id s wa p ( u c h a r x , u c h a r Y ) 2 3 2 4 n u mb e r 1 = y ; 2 5 n u mb e r 2 = x ; 2 6 2 7 编译通过后,将生成的 c s 2 6 h e x 文件烧录到 8 9 S 5 1芯片中,将芯片插 入到 L E D 1 6 2字符液晶试验板上 试 验板上接通 9 V电源, 右边 2个 L E D数 码管显示“ 3 8 ” 。按下 3号键右边 2个 L E D数码管显示“ 8 3 ” 。 我们分析一下程序 。 序号 1( 程序解释 以下同 ) :包含 头文件 REG51 H。 序号 2 : 数据类型的宏定义。 序号 3 : 数码管 0 9的字形码。 序号 4 : 定义 P 3 O 。 序号 5 : 定义两个无符号的字符型全局变量 n umber 1 、 n u mbe r 2 o 序号 6 : 程序分隔。 序号 7 : 子函数 s wa p声明。 序号 8 : 程序分 隔。 序号 9 : 定义 函数名 为 ma i n的主函数。 序号 1 0: ma in主函数开始。 序号 1 1 : 定 义无符号字 符型局部 变量 a、 b 。 序 号 1 2 : n u mb e r 1赋 值 3 、 n u mb e r 2赋 值 8。 序 号 1 3: n u mb e r 1值 送 a、 n u mb e r 2 赋 值 送 b。 序号 1 4 : 无限循环 。 序号 1 5 : 无限循环语句开始。 序号 1 6 : n u mb e r 1的值查表送 P 1口显示。 序号 1 7: n u mb e r 2的值查表送 P 0口显 示。 序号 侣 : P 3口置 0 x 0 f , 以便 读取 P 3 0的输 入状态。 序 号 1 9:如 果 P 3 0为 低 电 平 , 调 用 s w a p子 函数 ,实现 n u mb e r 1 、 n u mb e r 2 两 个 数 的交 换 。 序号 2 O : 无限循环语句结束。 序号 2 1 : ma in主函数结束。 序号 2 2 : 程序分 隔。 序号 2 3 : 定 义函数名为 s wa p的子 函数 。 序号 2 4 : s wa p子 函数开始 。 序号 2 5: y传递的值 送 n u mb e r 1 。 序号 2 6: x传递的值 送 n u mb e r 2 。 序号 2 7: s wa p子 函数结 束。 羹 羹 i 在 L E D 1 6 2字符 液晶试验板 上 实现三个数按大小自动排列。 数码管的 百、 十、 个位自动显示 a 、 b 、 c三个数中 的最大、 中间、 最小值。 在我的文档中建立一个文件 目录 ( c s 2 7 ) , 然 后建 立 c s 2 7 u v 2的 工程 项 目。 最后建立源程序文件( c s 2 7 c o 输入下面 的程序 : # i n c lu d e 序号 ( 以下同 ) : 1 # d e f i n e u c h a r u n s ig n e d c h a r 2 维普资讯 u c h a r c o d e S E G7 1 0 = 0 x c 0 0 x f 9 0 x a 4 , 0 x b 0 0 x 9 9 0 x 9 2 , 0 x 8 2 0 x f 8 , 0 x 8 0 0 x 9 0 ; 3 “4 v o id ma in ( v o id ) 5 6 u c h a r a = 3 b =1 , c = 9 : 7 “ “ 8 lf ( ( a 序号( 以下同 ) : 1 # i n c lu d e 2 # d e f i n e u c h a r u n s i g n e d c h a r 3 # d e f i n e u i n t u n s i g n e d i n t 4 u c h a r c o d e S E G7 【 1 O 】 : O x 3 f , 0 x 0 6 , 0 x 5 b 0 x 4 f , 0 x 6 6 0 x 6 d O x 7 d O x 0 7 0 x 7 f 0 x 6 f ; 5 u c h a r A CT 4 = 0 x e f , 0 x d f , 0 x b f , 0 x 7 f ; 6 广 7 in t C f : 8 in t t e mp ; 9 u c h a r s t a t u s ; 1 0 1 1 v oi d k e y _s 1 ( v o id ) ; 1 2 v oid k ey _s 2 ( v o i d ) ; v o id k e y s 4 ( v o i d ) ; i n t c o n v ( i n t f i n ) ; v oid delay _1 ms ( v o id ) | | 、 3 | | 、 4 | | 、 5 1 6 1 7 , v o id ma i n ( v o i d ) 1 8 i n t t e mp _ f t e mp c : 1 9 wh i l e ( 1 ) 2 O f 2 1 k e y s 1 ( ) :, 2 2 k e y _s 2 0 ;t t2 3 k e y _s 4 0 ; 2 4 if ( s t a t u s = = 0 ) 2 5 | | 笛 if ( f 5 0 ) t e mp = 0 ; 7 9 if ( t e mp = = 0 ) f + +; 8 0 if ( f 9 9 9 ) f = 9 9 9 ; 8 1 t e mp + +: 8 2 l 8 3 l 8 4 “ “ 8 v oid k ey _s 2 ( v o i d ) 8 6 8 7 P 2 = 0 x ff ; 8 8 if ( P 2 = 0 x f d ) 8 9 i f ( t e mp 5 0 ) t e mp = 0 ; 9 0 if ( t e mp = = 0 ) f - - ; 9 1 i f ( f = O 。 序号 3 9: 进入 if ( f = O 。 序号 6 3: 进 入 if ( c 0 ) 的否则语句。 序号 6 4 : 显示摄氏温度的个位。 序号 6 5: 延时 1 ms 。 序号 6 6 : 显示摄 氏温度的十位。 序号 6 7: 延时 1 ms 。 序号 6 8 : 显示摄氏温度的百位。 序号 6 9: 延时 1 ms 。 序号 7 0: if ( c 0 ) 的否则语句结束。 序号 7 1 : if ( s t a t u s = = 0 ) 的否则语句结束。 序号 7 2: 无限循环语句结束。 序号 7 3: ma i n主函数结束。 序号 7 4: 程序分隔。 序号 7 5:定义 函数 名为 k e y _ s 1的 S1键扫 描子 函数 。 序号 7 6 : k e y _ s 1子函数开始。 序 号 7 7 : P 2口置全高 。 准备读取输入状态。 序 号 7 8 : 若 P 2为 O x f e , 说 明 S 1键 被按下 。 进入 if ( P 2 = = 0 x f e ) 语句。 序号 7 9 : t e mp的计数值范围在 0 5 0之间。 序号8 O : 在 t e m p为0时改变( 增大) 华氏温 度值 f 。 使之与人眼的视觉相符。 序号8 1 : 华氏温度值的最大输入值为 9 9 9 。 序号8 2 : t e mp 计数值递增。 序号 8 3 : i f ( P 2 = = 0 x f e ) 语句结束。 序号 8 4 : k e y _ s 1子函数结束。 序号 8 5 : 程序分 隔。 序号 8 6 :定 义函数名为 k e y _ s 2的 S 2键扫 描子函数。 序号 8 7 : k e y _ s 2子 函数开始 。 序号 8 8 : P 2口置全 高 , 准备读取 输入状态。 序号 8 9: 若 P 2为 O x f d, 说 明 S 2键被 按下 , 进入 if ( P 2 = = 0 x f d ) 语句。 序号9 0 : t e mp的计数值范围在0 5 0之间。 维普资讯 用增强型 5 1 实验板控制步进电机 今天。 我们为大家讲解一下步进电 机的基本原理以及其使用方法。 步进电机是一种将电脉冲转化为 角位移的执行机构。 在没有超出负载的 情况下, 步进电机的转动速度、 停止的 位置只取决于送给电机脉; 中 信号的频 率和脉冲数 , 而不会受到负载变化的影 响 , 如 : 我们给步进电机加一个脉冲信 号 , 电机 则转过一个步距 角。 在初中物理课上 , 我们就 已经接 触到过电动机 的原理 , 现在我们所接 触到的常规交流或直流电机 , 都是加 上相应的电压后 ,电机开始转动 , 断 电后电机则停止转动。但对于步进 电 机 ,我们既能控制它的转动 方向, 又 能控制它的转动速度 , 如 : 我们想让 它顺时针转 2圈 ,逆时针转 3圈, 或 者是先正转 4圈再反转 5圈。由此看 来, 步进电机的动作方式比常规 电机 显得 更为 灵活 、 方便 , 多用性 。因此 它 已经涉及到了机械 、 电子及计算机等 众 多相 关行 业 , 如 : 打 印 机 , 绘 图 仪 , 机器人等应用。 我 们 所 使 用 的 是 1 2 V的 步 进 电 机 ,为了方便演示及方便我们学习, 我 们直接将步进电机插到实验板的专用 接口上 。 通过 5 V电源来供电。增强型 5 1实验板采用 U L N2 0 0 3步进 电机驱 动 电路 , 驱动 端 E l 为 p O 0, p O 1 , p 0 2 , p O , 3。 上面我们 曾讲到步 进电机是通 过脉冲量和频率来控制 电机 的运行 状况的 , 因此 , 我们 只要通过控制单 片 机 的 p O 0, p O 1, p 0 , 2, p 0 3这 几个端 口的高低 电平 ,就可 以指定 步进 电机 的转动 方向及转 动速 度。 那么 ,该如何来控制这些端 口的电 平呢?其实很简单 ,用表 1表 2就 可非 常直观 地反 映步进 电机正 、 反 转的控制时序。 如果要使步进电机正转, 应该依次 给单片机 P C ) 口送 出如表 1所示的控 制 字 , 即分 别向 P O口输 出 O x f e, O x f d , O x f b, O x f 7四个值 即可 。 如果 要使步进电机反转 , 应 该依 次 给单片机 P O口送出如表 2所示的控 制 字 , 即 分 别 向 P O 口 输 出 O x f 7 , O x f b , O x f d。 O x f e这 四个值 即可 。 徐玮 步数 P O 3 P O 2 P O 1 P O 0 O x f e 1 1 1 1 O Ox f d 2 1 1 0 1 0 b 3 1 0 1 1 0 ) c l7 4 0 1 1 1 步 数 P O 3 P O 2 P O 1 P O 0 0 ) ( f 7 1 0 1 1 1 Ox I b 2 1 0 1 1 Ox f d 3 1 1 O 1 O x f e 4 1 1 1 O 下面我们动手做一下步进电机的 实验。 首先 。 将 5 1微型仿真器和步进电 机插到增强型 5 1实验板的相应端 口 上, 同时插上外接电源变压器。 注意: 步 进电机一共有 4条线, 但我们与实验板 相连的白色插口上共有 6个孔, 在插口 的最左边空出了一个位置, 用于标记插 口方 向, 如图 1所示。 然后安装仿真及编程软 件 K E I L ( 位于配套光盘“ 仿真软件 K E I L ” 目录 序号 9 1 : 在 t e mp为 0时改变( 降低 ) 华氏温 序号 1 0 5 : c o n y子函数开始 , 定义整型局部 阵 图型液 晶显示模组( 邮购代号: L 2 ) : 度值 f , 使之与人眼的视觉相符。 变量 d d a t a 。 1 6 0 元 。5 V高稳定专用稳压电源( 邮购 序号9 2 : 华氏温度值的最小输入值为一 5 0 0 。 序号 1 0 6 1 0 7 : 数学计算。 代 号 : D 1 ) : 3 0 元 。每次邮费保价 费 1 2 黧 94 if(呻P2= =Oxfd)束 。 109 cony 。 95 k 序 号 : 语 句 结 束 。 序 号 : 子 函 数 结

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论