本文由hngz101贡献
    doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。
    单片机 C 语言教程
    语言教程-基础语句 单片机 C 语言教程 基础语句 C 语言入门之基础语句 从程序流程的角度来看,程序可以分为三种基本结构,即顺序结构、分支结构、循环结 构。这三种基本结构可以组成所有的各种复杂程序。c 语言提供了多种语句来实现这些程序 结构。本文将介绍这些基本语句及其应用,使读者对 c 程序有一个初步的认识,为以后的学 习打下基矗 c 程序的语句 c 程序的执行部分是由语句组成的。程序的功能也是由执行语句实现的。 c 语句可分为以下五类: 1.表达式语句 2.函数调用语句 3.控制语句 4.复合语句 5.空语句 1.表达式语句 表达式语句由表达式加上分号“;”组成。其一般形式为:表达式;执行表达式语句就是 计算表达式的值。例如: x=y+z;赋值语句 y+z;加法运算语句,但计算结果不能保留,无 实际意义 i++;自增 1 语句,i 值增 1 2.函数调用语句 由函数名、实际参数加上分号“;”组成。其一般形式为:函数名(实际参数表);执行函 数语句就是调用函数体并把实际参数赋予函数定义中的形式参数, 然后执行被调函数体中的 语句,求取函数值。(在第五章函数中再详细介绍)例如 printf(\"c program\");调用库函 数,输出字符串。 3.控制语句 控制语句用于控制程序的流程,
以实现程序的各种结构方式。 它们由特定的语句定义符组成。c 语言有九种控制语句。可分成以下三类: (1)条件判断语句 if 语句,switch 语句 (2)循环执行语句 do while 语句,while 语句,for 语句 (3)转向语句 break 语句,goto 语句,continue 语句,return 语句 4.复合语句 把多个语句用括号{}括起来组成的一个语句称复合语句。在程序中应把复合语句看成 是单条语句,而不是多条语句,例如 {
    x=y+z; a=b+c; printf(“%d%d”,x,a); } 是一条复合语句。复合语句内的各条语句都必须以分号“;”结尾,在括号“}”外不能加分 号。 5.空语句 只有分号“;”组成的语句称为空语句。空语句是什么也不执行的语句。在程序中空语句 可用来作空循环体。例如 while(getchar()!=\'\\n\');本语句的功能是,只要从键盘输入 的字符不是回车则重新输入。这里的循环体为空语句。 赋值语句 赋值语句是由赋值表达式再加上分号构成的表达式语句。 其一般形式为: 变量=表达式; 赋值语句的功能和特点都与赋值表达式相同。 它是程序中使用最多的语句之一。 在赋值语句 的使用中需要注意以下几点: 1.由于在赋值符“=”右边的表达式也可以又是一个赋值表达式,因此,下述形式变量 =(变量=表达式);是成立的,从而形成嵌套的情形。其展开之后的一般形式为:变量=变量 =…=表达式; 例如: a=b=c=d=e=5;按照赋值运算符的右接合性,因此实际上等效于: e=5; d=e; c=d; b=c; a=b; 2.注意在变量说明中给变量赋初值和赋值语句的区别。 给变量赋初值
是变量说明的一部 分, 赋初值后的变量与其后的其它同类变量之间仍必须用逗号间隔, 而赋值语句则必须用分 号结尾。 3.在变量说明中, 不允许连续给多个变量赋初值。 如下述说明是错误的: int a=b=c=5 必须写为 int a=5,b=5,c=5;而赋值语句允许连续赋值。 4.注意赋值表达式和赋值语句的区别。 赋值表达式是一种表达式, 它可以出现在任何允 许表达式出现的地方,而赋值语句则不能。 下述语句是合法的: if((x=y+5)>0) z=x; 语句的功能是,若表达式 x=y+5 大于 0 则 z=x。 下述语句是非法的: if((x=y+5;)>0) z=x; 因为=y+5;是语句,不能出现在表达式中。
    语言教程-运算符和表达式 单片机 C 语言教程 运算符和表达式
    单片机 C 语言教程-运算符和表达式 运算符的种类、优先级和结合性 c 语言中运算符和表达式数量之多,在高级语言中是少见的。正是丰富的运算符和表达 式使 c 语言功能十分完善。这也是 c 语言的主要特点之一。 c 语言的运算符不仅具有不同的优先级,而且还有一个特点,就是它的结合性。在表达 式中, 各运算量参与运算的先后顺序不仅要遵守运算符优先级别的规定, 还要受运算符结合 性的制约, 以便确定是自左向右进行运算还是自右向左进行运算。 这种结合性是其它高级语 言的运算符所没有的,因此也增加了 c 语言的复杂性。 运算符的种类 c 语言的运算符可分为以下几类: 1.算术运算符 用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增 (++)、自减(--)共七种。 2.关系运
算符 用于比较
运算。包括大于(>)、小于(<)、等于(==)、大于等于(>=)、小于等于(<=) 和不等于(!=)六种。 3.逻辑运算符 用于逻辑运算。包括与(;;)、或(||)、非(!)三种。 4.位操作运算符 参与运算的量,按二进制位进行运算。包括位与(;)、位或(|)、位非( ̄)、位异 或(^)、左移(<<)、右移(>>)六种。 5.赋值运算符 用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算 赋值(;=,|=,^=,>>=,<<=)三类共十一种。 6.条件运算符 这是一个三目运算符,用于条件求值(?:)。 7.逗号运算符 用于把若干表达式组合成一个表达式(,)。 8.指针运算符 用于取内容(*)和取地址(;)二种运算。 9.求字节数运算符 用于计算数据类型所占的字节数(sizeof)。 10.特殊运算符 有括号(),下标[],成员(→,.)等几种。 优先级和结合性 c 语言中,运算符的运算优先级共分为 15 级。1 级最高,15 级最低。在表达式中,优 先级较高的先于优先级较低的进行运算。 而在一个运算量两侧的运算符优先级相同时, 则按 运算符的结合性所规定的结合方向处理。 c 语言中各运算符的结合性分为两种,即左结合 性(自左至右)和右结合性(自右至左)。例如算术运算符的结合性是自左至右,即先左后右。 如有表达式 x-y+z 则 y 应先与“-”号结合,执行 x-y 运算,然后再执行+z 的运算。这种自
    左至右的结合方向就称为“左结合性”。而自右至左的结合方向称为“右结合性”。最典型的右 结合性运算符是赋值运算符。如 x=y=z,由于“=”的右结合性,应先执行 y=z 再执行 x=(y=z)运算。 c 语言运算符中有不少为右结合性,应注意区别,以避免理解错误。 算术运算符和算术表达式基本的算术运算符 1.加法运算符“+”加法运算符为双目运算符, 即应有两个量参与加法运算。 a+b,4+8 如 等。具有右结合性。 2.减法运算符“-”减法运算符为双目运算符。 但“-”也可作负值运算符, 此时为单目运算, 如-x,-5 等具有左结合性。 3.乘法运算符“*”双目运算,具有左结合性。 4.除法运算符“/”双目运算具有左结合性。参与运算量均为整型时,结果也为整型,舍 去小数。如果运算量中有一个是实型,则结果为双精度实型。 void main(){ printf(\"\\n\\n%d,%d\\n\",20/7,-20/7); printf(\"%f,%f\\n\",20.0/7,-20.0/7); } 双目运算具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算 量中有一个是实型,则结果为双精度实型。 printf(\"\\n\\n%d,%d\\n\",20/7,-20/7); printf(\"%f,%f\\n\",20.0/7,-20.0/7); 本例中,20/7,-20/7 的结果均为整型,小数全部舍去。而 20.0/7 和-20.0/7 由于 有实数参与运算,因此结果也为实型。 5.求余运算符(模运算符)“%”双目运算,具有左结合性。要求参与运算的量均为整型。 求余运算的结果等于两数相除后的余数。 void main(){ printf(\"%d\\n\",100%3); } 双目运算,具有左结合性。求余
运算符%要求参与运算的量均为整型。本例输出 100 除以 3 所得的余数 1。 自增 1,自减 1 运算符 自增 1 运算符记为“++”,其功能是使变量的值自增 1。自减 1 运算符记为“--”,其功 能是使变量值自减 1。自增 1,自减 1 运算符均为单目运算,都具有右结合性。可有以下几 种形式: ++i i 自增 1 后再参与其它运算。--i i 自减 1 后再参与其它运算。 i++i 参与运算后,i 的值再自增 1。 i--i 参与运算后,i 的值再自减 1。 在理解和使用上容易出错的是 i++和 i--。特别是当它们出在较复杂的表达式或语句中 时,常常难于弄清,因此应仔细分析。 void main(){ int i=8; printf(\"%d\\n\",++i); printf(\"%d\\n\",--i); printf(\"%d\\n\",i++); printf(\"%d\\n\",i--);
    printf(\"%d\\n\",-i++); printf(\"%d\\n\",-i--); } i<--8 i<--i+1 i<--i-1 i<--i+1 i<--i-1 i<--i+1 i<--i-1 int i=8; printf(\"%d\\n\",++i); printf(\"%d\\n\",--i); printf(\"%d\\n\",i++); printf(\"%d\\n\",i--); printf(\"%d\\n\",-i++); printf(\"%d\\n\",-i--); i 的初值为 8 第 2 行 
i 加 1 后输出故为 9; 第 3 行减 1 后输出故为 8; 第 4 行输出 i 为 8 之后再加 1(为 9); 第 5 行输出 i 为 9 之后再减 1(为 8); 第 6 行输出-8 之后再加 1(为 9); 第 7 行输出-9 之后再减 1(为 8) void main(){ int i=5,j=5,p,q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); printf(\"%d,%d,%d,%d\",p,q,i,j); } i<--5,j<--5,p<--0,q<--0 i+i+i>p,i+1-->i,i+1-->i,i+1-->i j+1->j,j+1->j,j+1->j,j+j+j->q int i=5,j=5,p,q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); 这个程序中,对 p=(i++)+(i++)+(i++)应理解为三个 i 相加,故 p 值为 15。然后 i 再自增 1 三次相当于加 3 故 i 的最后值为 8。 而对于 q 的值则不然, q=(++j)+(++j)+(++j) 应理解为
 q 先自增 1,再参与运算,由于 q 自增 1 三次后值为 8,三个 8 相加的和为 24, j 的最后值仍为 8。算术表达式表达式是由常量、变量、函数和运算符组合起来的式子。一 个表达式有一个值及其类型, 它们等于计算表达式所得结果的值和类型。 表达式求值按运算 符的优先级和结合性规定的顺序进行。单个的常量、变量、函数可以看作是表达式的特例。
    1本文由tgowgntbip贡献
    本文由welzyk贡献
    doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。
    单片机的 c 语言教程
    51 单片机 C 语言学习
    第一课:建立您的第一个 C 项目
    学习单片机实在不是件易事,一来要购买高价格的编程器,仿真器,二来要学习编程语言,还有众多种类的单片机选 择真是件让人头疼的事。在众多单片机中 51 架构的芯片风行很久,学习资料也相对很多,是初学的较好的选择之一。51 的编程语言常用的有二种,一种是汇编语言,一种是 C 语言。汇编语言的机器代码生成效率很高但可读性却并不强,复杂 一点的程序就更是难读懂,而 C 语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超 过汇编语言,而且 C 语言还可以嵌入汇编来解决高时效性的代码编写问题。对于开发周期来说,中大型的软件编写用 C 语 言的开发周期通常要小于汇编语言很多。综合以上 C 语言的优点,我在学习时选择了 C 语言。以后的教程也只是我在学习 过程中的一些学习笔记和随笔,在这里加以整理和修
改,希望和大家一起肥翼,一起交流,一起学习,一起进步。
    第一课
    建立您的第一个 C 项目
    使用 C 语言肯定要使用到 C 编译器,以便把写好的 C 程序编译为机器码,这样单片机才能执行编写好的程序。KEIL uVISION2 是众多单片机应用开发软件中优秀的软件之一,它支持众多不同公司的 MCS51 架构的芯片,它集编辑,编译, 仿真等于一体,同时还支持,PLM,汇编和 C 语言的程序设计,它的界面和常用的微软 VC++的界面相似,界面友好,易 学易用,在调试程序,软件仿真方面也有很强大的功能。因此很多开发 51 应用的工程师或普通的单片机爱好者,都对它十 肥也欢。 以上简单介绍了 KEIL51 软件,要使用 KEIL51 软件,必需先要安装它。KEIL51 是一个商业的软件,对于我们这些普 通爱好者可以到 KEIL 中国代理周立功公司的网站上下载一份能编译 2K 的 DEMO 版软件,基本可以满足一般的个人学习 和小型应用的开发。 (安装的方法和普通软件相当这里就不做介绍了) 安装好后,你是不是迫不及待的想建立自己的第一个 C 程序项目呢?下面就让我们一起来建立一个小程序项目吧。或 许你手中还没有一块实验板,甚至没有一块单片机,不过没有关系我们可以通过 KEIL 软件仿真看到程序运行的结果。 首先当然是运行 KEIL51 软件。怎么打开?噢,天!那你要
从头学电脑了。呵呵,开个玩笑,这个问题我想读者们也 不会提的了:P。运行几秒后,出现如图 1-1 的屏幕。
    图 1-1 接着按下面的步骤建立您的第一个项目:
    启动时的屏幕
    (1)点击 Project 菜单,选择弹出的下拉式菜单中的 New Project,如图 1-2。接着弹出一个标准 Windows 文件对话 窗口,如图 1-3,这个东东想必大家是见了 N 次的了,用法技巧也不是这里要说的,以后的章节中出现类似情况将不再说 明。在"文件名"中输入您的第一个 C 程序项目名称,这里我们用"test",这是笔者惯用的名称,大家不必照搬就是了,只要
    符合 Windows 文件规则的文件名都行。"保存"后的文件扩展名为 uv2,这是 KEIL uVision2 项目文件扩展名,以后我们可以 直接点击此文件以打开先前做的项目。
    图 1-2
    New Project 菜单
    图 1-3
    文件窗口
    (2)选择所要的单片机,这里我们选择常用的 Ateml 公司的 AT89C51。此时屏幕如图 1-4 所示。AT89C51 有什么功能、 特点呢?不用急,看图中右边有简单的介绍,稍后的章节会作较详细的介绍。完成上面步骤后,我们就可以进行程序的编 写了。 (3) 首先我们要在项目中创建新的程序文件或加入旧程序文件。 如果你没有现成的程序, 那么就要新建一个程序文件。 在 KEIL 中有一些程序的 Demo,在这里我们还是以一个 C 程序为例介绍如何新建一个 C 程序和如何加到您的第一个项目中 吧。点击图 1-5 中 1 的新建文件的快捷按钮,在 2 中出现一个新的文字编辑窗口,这个操作也可以通过菜单 File-New 或快捷键 Ctrl+N 来实现。好了,现在可以编写程序了,光标已出现在文本编辑窗口中,等待我们的输入了。第一程序嘛, 写个简单明了的吧。下面是经典的一段程序,呵,如果你看过别的程序书也许也有类似的程序: #include #include void main(void) { SCON = 0x50; //串口方式 1,允许接收    TMOD = 0x20; //定时器 1 定时方式 2 TCON = 0x40; //设定时器 1 开始计数 TH1 = 0xE8; //11.0592MHz 1200 波特率 TL1 = 0xE8; TI = 1; TR1 = 1; //启动定时器 while(1) { printf ("Hello World!\n"); //显示 Hello World } }
    图 1-4 选取芯片
单片机printf函数    图 1-5 新建程序文件 这段程序的功能是不断从串口输出"Hello World!"字符,我们先不管程序的语法和意思吧,先看看如何把它加入到项目中和 如何编译试运行。 (4)点击图 1-5 中的 3 保存新建的程序,也可以用菜单 File-Save 或快捷键 Ctrl+S 进行保存。因是新文件所以保存 时会弹出类似图 1-3 的文件操作窗口,我们把第一个程序命名为 test1.c,保存在项目所在的目录中,这时你会发现程序单 词有了不同的颜,说明 KEIL 的 C 语法检查生效了。如图 1-6 鼠标在屏幕左边的 Source Group1 文件夹图标上右击弹出 菜单,在这里可以做在项目中增加减少文件等操作。我们?quot;Add File to Group 'Source Group 1'"弹出文件窗口,选择刚刚 保存的文件,按 ADD 按钮,关闭文件窗,程序文件已加到项目中了。这时在 Source Group1 文件夹图标左边出现了一个小 +号说明,文件组中有了文件,点击它可以展开查看。
    图 1-6 把文件加入到项目文件组中 (5)C 程序文件已被我们加到了项目中了,下面就剩下编译运行了。这个项目我们只是用做学习新建程序项目和编译 运行仿真的基本方法,所以使用软件默认的编译设置,它不会生成用于芯片烧写的 HEX 文件,如何设置生成 HEX 文件就 请看下面的第三课。我们先来看图 1-7 吧,图中 1、2、3 都是编译按钮,不同是 1 是用于
编译单个文件。2 是编译当前项
    目,如果先前编译过一次之后文件没有做动编辑改动,这时再点击是不会再次重新编译的。3 是重新编译,每点击一次均 会再次编译链接一次,不管程序是否有改动。在 3 右边的是停止编译按钮,只有点击了前三个中的任一个,停止按钮才会 生效。5 是菜单中的它们,我个人就不习惯用它了。嘿嘿,这个项目只有一个文件,你按 123 中的一个都可以编译。按了? 好快哦,呵呵。在 4 中可以看到编译的错误信息和使用的系统资源情况等,以后我们要查错就靠它了。6 是有一个小放大 镜的按钮,这就是开启\关闭调试模式的按钮,它也存在于菜单 Debug-Start\Stop Debug Session,快捷键为 Ctrl+F5。
    图 1-7 编译程序 (6)进入调试模式,软件窗口样式大致如图 1-8 所示。图中 1 为运行,当程序处于停止状态时才有效,2 为停止,程序 处于运行状态时才有效。3 是复位,模拟芯片的复位,程序回到最开头处执行。按 4 我们可以打开 5 中的串行调试窗口, 这个窗口我们可以看到从 51 芯片的串行口输入输出的字符, 这里的第一个项目也正是在这里看运行结果。 这些在菜单中也 有,这里不再一一介绍大家不妨看,其它的功能也会在后面的课程中慢慢介绍。首先按 4 打开串行调试窗口,再按运 行键,这时就可以看到串行调试窗口中不断的打?quot;Hello World!"。呵呵,是不是不难呀?这样就完成了您的第一个 C 项目。最后我们要停止程序运行回到文件编辑模式中,就要先按停止按钮再按开启\关闭调试模式按钮。然后
我们就可以进 行关闭 KEIL 等相关操作了。 到此为止,第一课已经完结了,初步学习了一些 KEIL uVision2 的项目文件创建、编译、运行和软件仿真的基本操作 方法。其中一直
有提到一些功能的快捷键的使用,的确在实际的开发应用中快捷键的运用可以大大提高工作的效率,建议 大家多多使用,还有就是对这里所讲的操作方法举一反三用于类似的操作中。
    图 1-8 调试运行程序 第二课 初步认识 51 芯片
    上一课我们的第一个项目完成了,可能有懂 C 语言的朋友会说,"这和 PC 机上的 C 语言没有多大的区别呀"。的确没 有太大的区别,C 语言只是一种程序语言的统称,针对不同的处理器相关的 C 语言都会有一些细节的改变。编写 PC 机的 C 程序时,如要对硬件编程你就必须对硬件要有一定的认识,51 单片机编程就更是如此,因它的开发应用是不 可与硬件脱节的,所以我们先要来初步认识一下 51 苾片的结构和引脚功能。MSC51 架构的芯片种类很多,具体特点 和功能不尽相同(在以后编写的附录中会加入常用的一些 51 芯片的资料列表) ,在此后的教程中就以 Atmel 公司的 AT89C51 和 AT89C2051 为中心对象来进行学习,两者是 AT89 系列的典型代表,在爱好者中使用相当的多,应用 资料很多,价格便宜,是初学 51 的首选芯片。嘿嘿,口水多多有点卖广告之嫌了。 :P
    图 2-1 AT89C51 和 AT89C2051 引脚功能图 AT89C51 AT89
C2051
    4KB 可编程 Flash 存储器(可擦写 1000 次) 三级程序存储器保密 静态工作频率:0Hz-24MHz 128 字节内部 RAM 2 个 16 位定时/计数器 一个串行通讯口 6 个中断源 32 条 I/O 引线 片内时种振荡器 表 2-1
    2KB 可编程 Flash 存储器(可擦写 1000 次) 两级程序存储器保密 静态工作频率:0Hz-24MHz 128 字节内部 RAM 2 个 16 位定时/计数器 一个串行通讯口 6 个中断源 15 条 I/O 引线 1 个片内模拟比较器
    AT89C51 和 AT89C2051 主要性能表
    图 2-1 中是 AT89C51 和 AT89C2051 的引脚功能图。而表 2-1 中则是它们的主要性能表。以上可以看出它们是 大体相同的,由于 AT89C2051 的 IO 线很少,导致它无法外加 RAM 和程序 ROM,片内 Flash 存储器也少,但它的体 积比 AT89C51 小很多,以后大家可根据实际需要来选用。它们各有其特点但其核心是一样的,下面就来看看 AT89C51 的引脚具体功能。 1.电源引脚 Vcc GND 40 20 电源端 接地端
    *工作电压为 5V,另有 AT89LV51 工作电压则是 2.7-6V, 引脚功能一样。 2.外接晶体引脚
    图 2-2 XTAL1 XTAL2 19 18
    外接晶体引脚
    XTAL1 是片内振荡器的反相放大器输入端,XTAL2 则是输出端,使用外部振荡器时,外部振荡信号应直接加到 XTAL1,而 XTAL2 悬空。内部方式时,时钟发生器对振荡脉冲二分频,如晶振为 12MHz,时钟频率就为 6MHz。晶振的 频率可以在 1MHz-24MHz 内选择。电容取 30PF 左右。 *型号同样为 AT89C51 的芯片, 在其后面还有频率编号, 12,16,20,24MHz 可选。 有 大家在购买和选用时要注意了。 如 AT89C51 24PC 就是最高振荡频率为 24MHz,40P6 封装的普通商用芯片。
    3.复位
    RST
    9
    在振荡器运行时,有两个机器周期(24 个振荡周期)以上的高电平出现在此引腿时,将使单片机复位,只要这个 脚保持高电平,51 芯片便循环复位。复位后 P0-P3 口均置 1 引脚表现为高电平,程序计数器和特殊功能寄存器 SFR 全部清 零。当复位脚由高电平变为低电平时,芯片为 ROM 的 00H 处开始运行程序。常用的复位电路如图 2-3 所示。 *复位操作不会对内部 RAM 有所影响。
    图 2-3 4.输入输出引脚
    常用复位电路
    (1) P0 端口[P0.0-P0.7] P0 是一个 8 位漏极开路型双向 I/O 端口,端口置 1(对端口写 1)时作高阻抗输入端。作为 输出口时能驱动 8 个 TTL。 对内部 Flash 程序存储器编程时,接收指令字节;校验程序时输出指令字节,要求外接上拉电阻。 在访问外部程序和外部数据存储器时,P0 口是分时转换的地址(低 8 位)/数据总线,访问期间内部的上拉电阻 起作用。 (2) P1 端口[P1.0-P1.7] P1 是一个带有内