当前位置:首页 >> 信息与通信 >>

51单片机C语言实例浅析


51 单片机 C 语言实例浅析
————第一版————

渤海三叠浪 著

前言
本书目的 学 C 语言和单片机将近 3 个月.写《实例浅析》的首要目的,就是希望将 3 个月所学进行归纳整理,并 与广大单片机学习爱好者一起分享. 谁适合阅读《实例浅析》 对单片机有着浓厚兴趣的初学者都适合作为《实例浅析》的读者. 《实例浅析》使用的编译器 Keil v8.02. 希望反馈 作为单片机爱好者,都知道信息反馈的重要性.因此,希望所有的读者都能够发邮件与我联系,指出在 本书中存在的错误,潜在的不足,改正的建议,以及内容中尚待挖掘的有用之处. 我的邮箱是 lch_29@163.com 渤海三叠浪 2009 年 1 月 18 日

目录
序_______________________________________________________________________________________ 第一章 C 语言_____________________________________________________________________________ 第一节 为何《实例浅析》选择 C 语言作为 51 单片机开发语言? 第二节 打好 C 语言基础 第三节《C 总结》 第二章 中断______________________________________________________________________________ 第一节 中断识别方式有哪两种? 第二节 中断控制寄存器 IE 第三章 定时/计数器与串行通信接口_________________________________________________________ 第一节 定时/计数器工作方式 1 和 2 第二节 串行通信工作方式 1 第四章 实例解析__________________________________________________________________________ 第一节 要求编写时钟程序,实现下图的仿真效果 第二节 如何提高论文被杂志社录取的概率? 第三节 设计方案 第四节 编写代码 附录_____________________________________________________________________________________


学习忌贪多,忌浮躁,忌急功近利,忌目中无人.把学习计划放的长一些,培养一个好的学习方法,一步 一步慢慢走,终能成为高手.

第一章
为何《实例浅析》 单片机开发语言? 第一节 为何《实例浅析》选择 C 语言作为 51 单片机开发语言?
原因至少包含以下三项: (1) 用机器语言开发单片机难度很大 (2) 用汇编语言开发单片机难度不小 (3) C 编译器越来越强大

C 语言

第二节 打好 C 语言基础
作为单片机初学者,很有必要把 C 语言的基础知识掌握牢固.如果您觉得您已经很精通 C 语言,那么请 解释下面两个问题: (1)1 个变量 a 和只有 1 个元素的数组 a[1]有什么区别与联系? (2)定义了一个数组 a[5], 而假如在程序中用到了 a[9]或者 a[-3],为什么并不是所有的编译器都认 为这是错误的,有的编译器甚至不会给出警告?

总结》 第三节 《C 总结》
见附录.

第二章
第一节 中断识别方式有哪两种? 第一节 中断识别方式有哪两种?
查询中断和向量中断.

中断

第二节 中断控制寄存器 IE
IE 的部分位的含义如下: EA: 允许/禁止全部中断 ES: 允许/禁止串行中断响应 ET0: 允许/禁止 Timer0 溢出中断响应 ET1: 允许/禁止 Timer1 溢出中断响应 可见,51 单片机的中断响应为两级控制.EA 为总的中断响应控制位.

第三章
定时/ 第一节 定时/计数器工作方式 1 和 2

定时/计数器与串行通信接口 定时/

工作方式寄存器 TMOD _________________________________________________________________________________________ 7 6 5 4 3 2 1 0 GATE CT M1 M0 GATE CT M1 M0 _________________________________________________________________________________________ M1 M0 0 1 定时/计数方式 1 计数范围 16 位 2 进制数 1 0 定时/计数方式 2 计数范围 8 位 2 进制数 (常用来产生串行通信波特率) _________________________________________________________________________________________ 定时/计数器控制寄存器 TCON TR0 定时/计数器 0 启/停控制位 TR1 定时/计数器 1 启/停控制位 TF0 定时/计数器 0 溢出中断请求标志位 当主机响应中断进入中断服务程序,由内部硬件自动复位 即:TF0 = 0 TF1 定时/计数器 1 溢出中断请求标志位 当主机响应中断进入中断服务程序,由内部硬件自动复位 即:TF1 = 0
【注】 若令 ET0 = 1; : EA = 1; 则程序中一定要存在 Timer0 的中断服务程序,否则主机无法找到 Timer0 的中断服务程序,主机就会跳转到不可预 知的位置且内部硬件不能自动执行 TF0 = 0.也就是说若允许某中断源响应中断,则程序中一定要存在相应的中断服 务程序.

串行通信工作方式 第二节 串行通信工作方式 1
串行接口控制寄存器 SCON _________________________________________________________________________________________ 7 6 5 4 3 2 1 0 SM0 SM1 SM2 REN TB8 RB8 TI RI _________________________________________________________________________________________ REN 允许/禁止串行接收控制位 TI 发送中断请求标志位,必须用软件复位 即:TI = 0 RI 接收中断请求标志位,必须用软件复位 即:RI = 0 电源控制寄存器 PCON 的最高位 SMOD 是波特率选择位.
【注】 :若允许串行中断源响应中断,则程序中一定要存在串行中断服务程序. 【注】 :若进入中断服务程序,那么要先判断是 RI = 1 还是 TI = 1 ,再进行相关操作. 当然,如果整个程序只涉及到发送或只涉及到接收,是不用做上述判断的.但是无论什么情况,做上述判断是 个好习惯 【注】 : 《MCS-51 系列单片微型计算机及其应用(第三版)》 115 页说: 第 由于接收通道内设有输入移位寄存器和 SBUF 缓冲器,主机应在该帧接收结束前从 SBUF 缓冲器中将数据取走,否则前一帧数据将丢失.SBUF 以并行方 式送往内部数据总线.

第四章
第一节 要求编写时钟程序,实现下图的仿真效果 要求编写时钟程序,实现下图的仿真效果 编写时钟程序 的仿真

实例解析

第二节

如何提高论文被杂志社录取的概率? 如何提高论文被杂志社录取的概率? 论文被杂志社录取

这是来自《虚拟机的设计与实现》([美]Bill Blunden)的一段文字(有改动): 即使某位教授发现的东西用很简单的话就能解释清楚,他也经常啰里啰嗦地写出一篇很长的论文,里面 还会提到很多深奥的技术,使他的发现看起来比实际情况复杂的多.这是一种比较普遍的社会现象,因 为人们往往有这样一种思维定势:如果某个想法能够用很简单的道理解释清楚,它的重要性或独创性就 会大打折扣.要想给订阅科技刊物的人们留下深刻的印象,就必须把问题地解释隐藏在层层迷雾之中. 对想保住自己饭碗的教授来说,这无可厚非,但用 C 语言编程的单片机初学者可千万不能这样做. 简洁比性能更重要.我希望自己编写的代码更便于维护.我希望自己在一年之后还能毫不费力地对现在 的代码修改而不用找一群考古学家帮忙.

第三节

设计方案

编写程序代码之前要做一些准备工作.这里所谓的准备工作,指的就是设计方案.可以用流程图或其他 方式将设计方案得以体现.这就类似于建造一幢大楼之前,设计师要画大楼图纸. 作为一名单片机初学者,设计方案时最需要注意的问题是什么呢?本章的第二节似乎已经给出了一个很 不错的回答. 那么,现在开始设计方案吧! !当然,一定会存在多种方案,这就需要做出选择了! ! 作者选择的方案用流程图表示为:

现在开始考虑方案中的一些细节了! ! (1) 定时 1 秒的时间间隔.这个应该不难做到吧,就等同于让灯 1 秒钟闪 1 次. (2) 更新时钟.这个就更简单了,知道"时,分,秒"之间的关系就能 OK. (3) 发送时钟.这个会涉及到 ASCII 码和字符之间的转换.这是因为单片机通过串口发送的数据是 ASCII 码,而在本章第一节的图中的 "时钟数据"是用字符显示的.

细节 OK 之后,到了编写程序代码的时候了! ! 在编写程序代码前,请先看如下一些观点: (1) 如果编写程序代码共用 10 小时,那么设计方案至少用 3 小时. (2) 为变量和函数起个好名字是非常重要却不容易做好的事情. (3) 一个函数只做一件事情. (4) 每编完一个函数就要对其进行测试,而不是在整个 C 程序编完之后才进行测试. 您同意以上这些观点么?
【注】《C 程序设计(第二版)》(谭浩强)第 50 页说:字符数据以 ASCII 码存储. : 【注】 :ASCII 码与字符的对应关系 ASCII 码 48 49 50 51 52 53 54 55 56 57 58 字符 '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ': ' 空字符为 ' '

换行字符为 '\n' 根据 ASCII 码与字符的对应关系可以看出: '0'= 48; '1'= 49;

'2'= 50; '3'= 51; ……………. 也可以换一种方式表示, '1' = 1 +'0' ; '2' = 2 +'0' ; '3' = 3 +'0' ; ……………. 【注】 :下一节的程序代码中的"变量和函数的命名规则" 局部变量名:首个单词首字母小写,余者首字母大写. 如 interruptCount (中断次数) 全局变量名:每个单词的首字母皆大写,且单词之间用下划线隔开. 如 Time_Interval_OK(时间间隔到). 无返回值函数名:函数名为动宾词组.每个单词的首字母皆大写,且单词之间用下划线隔开. 如 Update_Clock (更新时钟) .

第四节

编写代码

(1) 实现第一个细节:定时 1 秒的时间间隔. 用定时器 0 工作方式 1 编程,采用中断方式.晶振 22.1184MHz.

写好代码后,要做什么呢?当时是调试了!看看是不是 Time_Interval_OK 每隔 1 秒为"真"一次. (2) 实现第二个细节:更新时钟代码(略) (3) 实现第三个细节:发送时钟代码(略) (采用查询中断方式)

下面给出实现三个细节(即:实现本章第一节仿真效果)的时钟程序源代码. //建立头文件 USER.H

//开始写 C 源文件吧! !

//到这里 C 源文件结束 如果您确保已经彻底明白了上面的代码,那么请试着考虑这个问题——如何"修改时钟数据"? 将单片机与 PC 通过串口线连接,让 PC 上的串口调试助手发送时钟数据,则单片机接收时钟数据.将 上面代码中的子程序"初始化 UART"中的表达式 ES = 0 改为 ES = 1 然后再添加"接收数据"子程序 就可以了, "接收数据"子程序如下所示:

附录
《C 总结》 学习 C 一个月整,对某些内容进行了整理.对于自我理解的内容,都以【注】作为标注. 【序】K&Rxv:标准本身和各个特定的编译器是解释语言的最终权威.ANSI 标准的文档首先是写给编译 器的编写者看的,因此,对程序员来说不一定最合适. 控制流之选择控制 if 语句 (K&R55)控制流:控制语句执行次序. (K&R55)复合语句:在语法上等价于单条语句,其内部可声明变量.
【注】对于表达式:用 THQ 的赋值表达式,逻辑表达式,关系表达式理论

(MISRA20)在 C 标准中,条件语句需要的是布尔值. (MISRA21)规则 13.1 赋值表达式不能用在需要布尔值的地方,防止"="与"= ="混淆. eg:INT8U x; INT8U y; If (x = y) { foo(); } 应为: INT8U x; INT8U y; x = y; if (x != 0) { foo(); } (MISRA21)规则 13.2(推荐)判断一个值是否为 0 应该是显式的,除非该操作数是一个布尔值. (MISRA23)规则 14.9 if 语句后面必须是一个复合语句,else 后面必须是一个复合语句或另一个 if 语句. (MISRA24) 规则 14.10if…else 结构必须由一个 else 结束. 除非只有一个 if 语句, else 是不必须的. (THQ94)else 总是与它上面最近的未配对的 if 配对. Switch 语句 (THQ99)switch 后面括弧内的"表达式" ,ANSI 标准允许它为任何类型.
【注】switch 后的括弧内表达式,ANSI 标准允许它为任何类型,但是表达式的值是有限制的,如:若表达式的值是 浮点数, 则在 VC++6.0 环境下验证不通过. K&R48 说: 每一个分支都由一个或多个整数值常量或常量表达式标记.

(THQ99)case 后面常量表达式的值与 switch 后括弧表达式相等时,就执行 case 后面的语句. (THQ99)case 常量表达式只起到语句标号作用. (K&R48)switch(表达式){ case 常量表达式:语句序列 case 常量表达式:语句序列 default :语句序列 } 若没有 default 分支也没有其他分支与表达式匹配, switch 语句不执行任何动作. 则 各分支及 default 分支的排列次序是任意的.各分支表达式必须互不相同. (K&R49)作为一种良好的程序设计风格,在 switch 语句最后一个分支(即 default 分支)的后面也 加上一个 break 语句. (MISRA23)规则 15.2 所有非空的 switch 子句都应该用 break 语句结束. (MISRA23)规则 15.3switch 的最后一个子句必须是 default 子句,若 default 中没有任何语句,那 么应注释为什么没有任何操作. (MISRA23)规则 15.4switch 表达式不能是一个有效的布尔值.下列代码是不允许的:

switch(x = = 0) {…..} 控制流之循环控制 (K&R49)while(表达式) 语句 (K&R49)for(表达式 1;表达式 2;表达式 3) 语句 等价于下列 while 语句: 表达式 1; while(表达式 2){ 语句 表达式 3; }
【注】与 if 一样,while 的表达式和 for 的表达式 2 要判断的是"真"或"假" ,即判断布尔值.

(K&R49)若 for 语句省略表达式 2,则 for( ; ; ){….}是一个无限循环语句. (K&R50) 牵强地把一些无关的计算放到 for 语句的初始化和变量递增部分是一种不好的程序设计风格. (MISRA22)规则 13.5for 语句 3 个表达式只能和循环控制相关.即第一个表达式只能为循环变量赋初 值,第二个表达式只能进行循环条件判断,第三个表达式只能进行循环变量增(减)值. (THQ108)while 语句的主体必须为复合语句,否则 while 语句范围只到 while 后面的第一个分号处.
【注】 (K&R23)规则 14.8 也如此说.

(K&R23)规则 14.8for 语句主体必须是复合语句. 【注】否则,for 只执行第一条语句(在 VC++6.0 下验证) . break 语句,continue 语句,return 语句 (K&R53)break 语句能使程序从 switch 语句或最内层循环中立即跳出. (MISRA24)规则 14.5 不允许使用 continue 语句. (MISRA24)规则 14.6 循环体中最多只能出现一个 break 语句用于结束循环. (MISRA24)规则 13.3 不允许对浮点数进行相等或不相等的比较,即使是非直接的比较也是不允许的. (K&R18)我们在以后的 main 函数中包含 return 语句,以提醒大家注意,程序还要向执行环境返回状 态. (K&R19)函数原型中的参数名是可选的.但是合适的参数名起到很好的说明性作用. (THQ149)若调用函数中没有 return 语句,并不带回一个确定的,用户所希望的函数.但是实际上并 不是不带回值,而只是不带回有用的值,带回的是一个不确定的值. (THQ149)为明确表示"不带回值" ,可以用 void 定义. (K&R59)当 return 语句后面没有表达式时,函数将不向调用者返回值.当被调用函数执行到最后的 右花括号而结束执行,控制同样也会返回给调用者(不返回值) .如果某个函数从一个地方返回时有 返回值,而从另一个地方返回时没有返回值,该函数并不非法,但可能是一种出问题的征兆.
【注】正像(MISRA24)规则 14.7 函数只能有一个出口,这个出口必须在函数末尾.

预处理之宏定义 (MISRA30)规则 19.7(推荐)应优先考虑使用函数,而非函数式宏定义.
【注】注意宏定义次序.

(K&R76)仔细考虑 max 的展开式就会发现它存在一些缺陷. (THQ188-190)宏名一般用大写字母表示;宏名代替字符串,只是置换,不作正确性检查,不分配内存; #undef 作用域到本源文件结束.若定义#undef,则到#undef 行终止. " "内的内容不被宏名置换.
【注】宏定义应放在程序中替换处之前,正像函数原型声明一样.

预处理之文件包含与条件编译 (THQ195)头部文件用".c"作后缀或没有后缀也是可以的,但是用".h"作后缀更能表示此文件的 性质. (THQ198) (2)#ifndef 标识符 程序段 1 #else

程序段 2 #endif
【注】要注意文件包含次序.

数据类型之变量 (K&R27)由于库例程的名字通常以下划线开头,因此变量名不要以下划线开头.大写字母与小写字母 是有区别的. (K&R27)对于内部变量而言,至少前 31 个字符是有效的.对于外部名,ANSI 标准仅保证前 6 个字符 的唯一性,并且不区分大小写. (THQ40)建议变量名的长度不要超过 8 个字符. (THQ169) (作用域)全局变量:有效范围从定义位置开始到本源文件结束. (作用域)局部变量:只在本函数内有效.形式参数也是局部变量. (THQ171)要限制使用全局变量. (K&R63)使用外部变量可能对程序结构产生不良影响,而且会导致程序中各个函数之间具有太多的数 据联系. (THQ172) (生存期)静态存储方式:全局变量,static 局部变量 (生存期)动态存储方式:函数的形式参数,auto 局部变量
【注】要在显性初始化和未显性初始化初始值时,注意"编译"的情况. 【注】下面 2 条是关于外部变量的文件范围与内外函数的文件范围的归纳.

(THQ176)用 extern 声明外部变量(1)在一个文件内声明外部变量;在多文件程序声明外部变量(2) 用 static 声明外部变量. (THQ182)内部函数与外部函数(1)static(2)extern (THQ180)请注意用 auto,static 声明局部变量时,是在定义变量的基础上加上这些关键字的,不能 单独使用.
【注】上条中"局部"二字为自我添加.

变量初始化 (THQ53)初始化不是在编译阶段完成的(只有第八章介绍的静态存储变量和外部变量的初始化是在编 译阶段完成的) ,而是在程序运行时执行本函数时赋予初值的.
【注】K&R72 说对于外部变量和静态变量来讲,初始化表达式必须是常量表达式,且只初始化一次(从概念上讲是 在程序开始执行前进行初始化) . 【注】Keil 可以实现外部变量的初始化仿真(且必须满足 K&R72 说的初始化表达式必须是常量表达式) ,但 Keil 无 法仿真静态变量的初始化. 【注】Keil 对外部变量和局部变量的编译检查不按一个标准进行. eg:外部变量 i; int i; I = 3; 则 Keil 编译器出现如下信息: error c231: 'i'redefination 这正与 K&R72 说的一致.而在 VC++6.0 环境下竟然编译通过了. 可见,各个编译器的编译标准是不一样的,并不是所有的编译器编写者都完全按照 ANSI 的标准编写编译器.

函数 (K&R57)编译与加载的具体实现细节在各个编译系统中各不相同. (THQ147)在调用函数时将实参的值赋给形参(如果形参是数组名,则传递的是数组的首地址而不是 数组的值) . (THQ147)实参与形参类型应相同或赋值兼容. (THQ149)应做到函数类型与 return 返回值类型一致. (THQ150)调用形式如下, 函数名(实参表列) ; 但应说明,如果实参表列包含多个实参,对实参求值的顺序并不确定. (THQ153)编译是从上到下逐行进行的.

(MISRA24)规则 14.7 函数只能有一个出口,这个出口必须在函数末尾. (MISRA28)规则 16.1 不允许定义函数数量是不确定的数. (MISRA28)MISRA 从系统安全角度考虑,选择了最为安全的做法,不准使用递归调用. (THQ153)编译系统根据函数原型对函数调用的合法性进行全面检查. (K&R203)参考手册:函数可返回算数类型,结构,联合,指针或 void 类型值,但是那是不能返回函 数或数组类型. (K&R203)参考手册:函数声明中的声明必须是显式指定所声明的标识符具有函数类型. 特别是,不能通过 typedef 定义函数类型. (THQ147)在内存中,实参单元与形参单元是不同的单元. 数据类型之整型数据 (THQ41)整形变量 整形数据在内存中的存储方式为 原码(补码形式表示) 整形数据在内存中的存储方式 : ANSI 标准规定的'最小'取值范围: [signed] int 16 -32768~32767 unsigned int 16 0~65536 (THQ44)整型数据的溢出 一个 char 型变量最大允许值为 127,若再加 1,会怎么样? 0111 1111 + 1 = 1000 0000 而 -128 的补码为 1000 0000 这就是溢出. 就像汽车里程表一样,达到最大值又从最小值开始计数. 数据类型之字符型数据 (THQ48-50) (字符常量)编译器都规定以一个字节来存放一个字符. (字符常量)C 的字符常量是用单撇号括起来的一个字符,如'a''X''D'' ?'等. , , , (字符常量)特殊形式的字符常量 (字符串常量)用双撇号括起来的字符表列,如"How are you" (字符串常量)C 规定:每一个字符串末尾加一个结束标志以便系统判断字符串是否结束. eg 一个字符串"CHINA"则内存中 CHINA\0 如果想让一个字符串放到变量里,必须用字符数组. (字符变量)字符存储方式:将字符的 ASCII 码放到内存中,以二进制形式存放. 常用的运算符的表达式 (THQ48-50)赋值部分 赋值符号"="就是赋值运算符. 赋值表达式:赋值表达式的值就是被赋值变量的值. eg: "a = 5"这个赋值表达式的值为 5. 再 eg: "a = (b = 4) + (c = 6)"这个表达式的值为 10. (THQ56)算数部分 C 语言规定了运算符的优先级与结合性.算术运算符的结合性为自左向右.++ 和 - - 结合方向为自 右向左. eg:printf( "%d" ,-i++) 设 i 原值为 3,则先取出 i 的值为 3,输出 –i 值为 -3,然后 i 增值为 4. (THQ90)在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行. (THQ58)ANSIC 并没有具体规定表达式的子表达式的求值顺序,允许各编译系统自己安排. eg:a = f1( ) + f2( ) 类似问题还有,例如:在调用函数时,对于实参数的求值顺序,C 标准并没有统一的规定. eg:printf("%d,%d", i, i++) 数组定义之初始化

一维数组: int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 二维数组: int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; 字符数组: char c[ ] = {"I am happy"}; //数组长度为 11. (THQ133)需要说明的是:字符数组并不要求它的最后一个字符 '\0', 甚至可以不包括 '\0' .像 以下这样写是完全合法的. Char c[5] = {'C', 'H', 'I', 'N', 'A'}; (K&R83) 声明 int a[10]; 定义了一个由 10 个对象组成的集合,这 10 个对象存储在相邻区域中. (THQ122)数组中的每一个元素都属于同一个数据类型. 指针 (THQ203)int *pointer_1 , *pointer_2; 左端 int 为定义指针变量时必须指定的"基类型" .指针变量的基类型用来指定该指针变量可以指向 的变量的类型. (THQ206)*&a 与 a 等价. (THQ211)C 语言规定数组名代表数组的首地址. (K&R84)数组名所代表的就是该数组最开始的一个元素的地址. (MISRA10)指针类型转换是个高风险的操作,所以应该尽量避免进行这个操作. 规则 11.4(推荐)指向不同数据类型的指针不能相互转化. (MISRA11)ISOC 标准中,仅对数组成员的指针运算(包括算数运算,比较等)做了规范定义,除此之 外的指针运算属于未定义范围,具体实现有赖于具体编译器,其安全性无法得到保证. 规则 17.1 只有指向数组的指针才允许进行算术运算 规则 17.2 只有指向同一个数组的两个指针才允许用 >, >=, <, <= 等关系运算符进行比较 规则 17.4 只允许用数组索引做指针运算 (K&R81)由于指针也是变量,所在程序中可以直接使用. eg:int *ip; 如果 iq 是另一个指向整型的指针,那么语句 iq = ip 将把 ip 中的值拷贝到 iq 中.这样指针 iq 也将指向 ip 指向的对象. 结构体. (MISRA14)规则 18.1 所有结构和联合体的定义必须保持完整性. (THQ260)将有联系的不同类型数据组合成结构体. (THQ261)声明结构体类型不分配内存单元; 定义结构体变量分配内存单元. (THQ263)只能对最低级的成员进行赋值或存取的运算. (MISRA114)struct date{ int month; int day; int year; } date1, date2; 位运算 (MISRA75)移位运算并不能改变原变量本身. (K&R39)对 unsigned 类型的无符号数进行右移位时,左边空出的部分将用 0 填补;当对 signed 类型 的带符号值进行右移时,某些机器将对左边空出的部分用符号位填补(即算数右移,而另一些机器则 对左边空出的部分用 0 填补(即"逻辑移位". )
【注】keil 有符号位时为算数右移.VC++6.0 亦如此.



相关文章:
《51单片机C语言应用程序实例精讲》
51单片机C语言应用程序实例精讲》 - /***/ /* Copyright (c) 2004, 通信工程学院戴佳 *...
实用的51单片机C语言编程实例_图文
实用的51单片机C语言编程实例 - http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 基础知识:51 单片机编程基础(实...
51单片机C语言编程100例
51单片机C语言编程100例 - 目录 实例 3:用单片机控制第一个灯亮 ......
51单片机c语言实例100
51单片机c语言实例100_信息与通信_工程科技_专业资料 暂无评价|0人阅读|0次下载 | 举报文档 51单片机c语言实例100_信息与通信_工程科技_专业资料。51单片机c...
51单片机c语言总结
51单片机c语言总结 - 入门有针对性的解决一些简单的实际问题,边理论边实践学一样会一样 基本实验:LED流水灯,数码管显示,键盘控制,音乐播放,继电器控制I2C通信 ...
51单片机C语言程序设计源代码
51单片机C语言程序设计源代码 - -1- 51 单片机 C 语言教程 例 2.2.1 编写程序,点亮第一个发光二极管(part2_1.c #include <reg52.h> //52 系列...
51单片机C语言入门实例
51单片机C语言入门实例 - 1. 闪烁灯 1. 实验任务 如图 4.1.1 所示:在 P1.0 端口上接一个发光二极管 L1,使 L1 在不停地一亮一 灭,一亮一灭的时间间隔...
51单片机C语言编程实例
51单片机C语言编程实例_理学_高等教育_教育专区。51单片机C语言编程实例 ...接上电复位电路,以及手动复位电路,分析复位工作原理 接配置:EA(PIN31)。说明...
51单片机C语言经典事例程
- 142 例 21.3.1 舵机应用 C 语言程序设计实例:开机时舵机角度自动转为 0...- 145 - -4- 51 单片机 C 语言经典事例教程 例 1 编写程序,点亮第一个...
51单片机C语言教程
51单片机C语言教程 - 手把手教你学 51 单片机 C 语言教程(C 语言基础) 电平特性 数字电路中只有两种电平:高和低(本学习笔记中)定义单片机为 TTL 电平:高 +...
更多相关标签: