清华大学单片机课堂PPT.ppt_第1页
清华大学单片机课堂PPT.ppt_第2页
清华大学单片机课堂PPT.ppt_第3页
清华大学单片机课堂PPT.ppt_第4页
清华大学单片机课堂PPT.ppt_第5页
已阅读5页,还剩87页未读 继续免费阅读

下载本文档

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

文档简介

李晶 第4章 单片机的C语言编程 C51 一些例子 n LED先奇数亮,再偶数亮,循环3次; 从左到右流水灯,从右到左流水灯,循环3次; 两边到中间流水灯,中间到两边流水灯,循环3 次; 8个LED闪烁3次 关闭LED,停机 n 数码管从左到右流水显示0-F,-,. n 带蜂鸣(滴滴滴)的流水灯 n 数码管每隔0.1s显示765432-765398的值(六位数 ) 每隔0.5s流水灯 数码管显示结束,流水灯也停止 然后LED开始闪烁 3s后LED关闭,数码管显示HELLO n S17每按下一次,数码管显示+1 n S1按下,数码管显示0,S2按下,数码管显示1.S16 按下,数码管显示F n7. 1602液晶显示 n8. music n9. 温度数码管显示 n10. 温度液晶显示 n11. 继电器的吸合 n12. 步进电机 n此外,还有很多,有待你的开发 C51 nC语言是嵌入式系统中一种通用的程序设计语言 n特点 数据类型丰富 运算符丰富 代码率高(8051上的C语言的代码长度,已经做 到了汇编水平的1.21.5倍。4K字节以上的程度 ,C语言的优势更能得到发挥。 ) 在关键部位还能嵌入汇编语言代码,从而挖掘程 序的最高潜力 C51的优势 n应用广泛单片机、DSP、ARM等 nC语言程序本身不依赖于硬件系统,更易于移植 nC语言有丰富的数学函数,支持浮点运算 nC语言开发效率高,可读性强,可维护性强 C51相对于ASM51的优点 n对单片机的指令系统不需要了解,仅需知道存储结 构即可 n寄存器的分配、不同存储器的寻址及数据类型等细 节均由编译器管理 n程序结构化更强 n丰富的库 n模块化编程,移植性强 C51的数据类型 n数据类型的作用? n编译系统为数据安排存储单元,要决定数据单元的数量 数据类型长度(bit ) 长度(byte ) 值域范围 bit10,1 unsigned char810255 signed char81128127 unsigned int162065535 signed int162 3276832767 unsigned long32404294967295 signed long3242147483648 +2147483647 float3241.176E-383.40E+38 一般指针243存储空间065535 C51数据存储类型 存储类型与存储空间的对应关系 data直接寻址片内数据存储区,访问速度快(128字节) bdata可位寻址片内数据存储区,允许位与字节混合访问(16字节) idata 间接寻址片内数据存储区,可访问片内全部RAM地址空间(256 字节) pdata分页寻址片外数据存储区(256字节),由MOVX Ri访问 xdata寻址片外数据存储区(64K字节),有MOVX DPTR访问 code寻址代码存储区(64K字节),有MOVC A+DPTR访问 C51数据存储类型的扩充 C51定义SFR 定义方法:两个关键字:sfr和sbit 1.定义特殊功能寄存器用sfr sfr PSW=0xD0;/*定义程序状态字PSW的地址为D0H*/ sfr TMOD=0x89;/*TMOD的地址为89H*/ sfr P1=0x90;/*定义P1口的地址为90H*/ 2.定义可位寻址的特殊功能寄存器的位用sbit sbit CY=0xD7;/*定义进位标志CY的地址为D7H*/ sbit AC=0xD06;/*定义辅助进位标志AC的地址为D6H*/ sbit RS0=PSW3;/*定义RS0的地址为D3H*/ bit和sbit的不同 nsbit要在函数最外面定义,就是说必须定义成外部变 量. nbit可以在函数内部定义,也可以在函数外部定义 nsbit定义的是SFR(特殊功能寄存器)中可位寻址的某 一位 sbit aa=P10; nbit是一个数据类型,定义了位变量,在编译时,动 态分配1位的空间 bit cc=1; C51的运算符 1.算术运算符 模运算或取余运算符 为自增运算符 为自减运算符。 +i是先加后使用,i+是先使用后加 main() int i,j; i=5; j=i+; printf(“%d,%d“,i,j); main() int i,j; i=5; j=+i; printf(“%d,%d“,i,j); 关系运算符 小于 小于等于 大于 大于等于 等于 ! 不等于 前4个优先级高,后两个低 逻辑运算符 else if (a=2) c=20; else if (a=3) c=30; else if (a=4) c=40; else c=0; a=3,c=? switch/case语句 switch/case语句的一般形式如下: switch(表达式) case 常量表达式1:语句1; break; case 常量表达式2:语句2; break; case 常量表达式n:语句n; break; default :语句n+1; whilewhile语句语句 vv一般形式:一般形式: while(while(表达式表达式) ) 循环体语句循环体语句; vv执行流程:执行流程: 表达式 循环体 假(0) 真(非0) while 用用whilewhile语句实现循环语句实现循环 二 循 环 语 句 用用whilewhile语句实现循环语句实现循环 n n 特点:先判断表达式,后执行循环体特点:先判断表达式,后执行循环体 n n 说明:说明: 循环体有可能一次也不执行循环体有可能一次也不执行 循环体可为任意类型语句循环体可为任意类型语句 下列情况,退出下列情况,退出whilewhile循环循环 条件表达式不成立(为零)条件表达式不成立(为零) 循环体内遇循环体内遇break,gotobreak,goto 无限循环无限循环: while(1): while(1) 循环体循环体; ; do whiledo while语句语句 vv一般形式:一般形式: do do 循环体语句;循环体语句; while(while(表达式表达式);); vv执行流程:执行流程: do 循环体 表达式 假(0) 真(非0) while 用用do-whiledo-while语句实现循环语句实现循环 特点:特点:先执行先执行 循环体,后判循环体,后判 断表达式断表达式 说明:说明: 至少执行一至少执行一 次循环体次循环体 一般形式:一般形式:for( for( 表达式表达式1 1 ; ; 表达式表达式2 2 ; ; 表达式表达式3 3 ) ) 循环体语句;循环体语句; 执行流程:执行流程: 表达式表达式2 循环体 假(0) 真(非0) for 表达式表达式1 表达式表达式3 用用forfor语句语句实现循环实现循环 1)1) 先求解表达式先求解表达式1 1 2)2) 求解表达式求解表达式2,2,值为真则值为真则 执行循环体执行循环体, ,然后执行然后执行 第第3 3步步; ;值为假值为假, ,则结束则结束 循环循环, ,转到第转到第5 5步步. . 3)3) 求解表达式求解表达式3 3 4)4) 转回第转回第2 2步继续执行步继续执行 5)5) 循环结束循环结束, ,执行执行forfor语句语句 后面的程序后面的程序. . forfor语句一般应用形式语句一般应用形式: for(for(循环变量赋初值;循环条件;循环变量增值循环变量赋初值;循环条件;循环变量增值) ) 循环体语句;循环体语句; 说明:说明: l lforfor语句中语句中表达式表达式1, 1, 表达式表达式2 ,2 ,表达式表达式3 3 类型任意,都可省略,类型任意,都可省略,循环体也可循环体也可省略省略, ,但但 分号;不可省分号;不可省 l l无限循环无限循环: for(;): for(;) l lforfor语句可以转换成语句可以转换成whilewhile结构结构 n一般,发光二极管的点亮电流为3mA10mA nLED的压降为1.7V(红),2V(黄),2.2V(绿) 点亮1个LED 电路原理图 +5V 1.7V 3.3V 1K300 点亮1个LED 电路原理图 8位双向总线驱动器 DIR=1,数据AB DIR=0,数据BA 点亮一个LED 方法1:对P2操作 #include void main() P2=0xfe; 方法2:对P20操作 #include sbit P20=P20; void main() P20=0; 1个LED的闪烁 对P2操作 #include void main() P2=0xfe; P2=0xff; 现象:中度点亮LED 要实现闪烁,必须加延时操 作 #include #define uint unsigned int void main() while(1) /删去试试 uint a; P2=0xfe; a=51000; /选取 半秒 while(a-); P2=0xff; a=51000; while(a-); 8个 LED 的闪 烁 #include #define uint unsigned int void main() uint a; P2=0x00; a=51000; while(a-); P2=P2; a=51000; while(a-); 读程序,分析现象 #include void main() P2=0xfe; while(1) P2=P2 void main() P2=0xfe; while(1) unsigned int a; /注意 P2=P2 #define uint unsigned int void main() code uint pp9=0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f; uint i,a; while(1) for(i=0;i #include #define uchar unsigned char uchar a; void main() P2=0xfe; while(1) P2=_crol_(P2,1); a=51000;while(a-); 延时语句的位置合理否? 延时函数 void delay(uint z) uint x,y; for(x=z;x0;x-) for(y=56;y0;y-) ; void main() P2=0xfe; while(1) delay(1000); P2=_crol_(P2,1); 函数的定义 n一般格式 合法标识符 函数返回值类型 缺省int型 无返回值void 函数体 函数类型 函数名(形参类型说明表) 说明部分 语句部分 现代风格: 例 有参函数(现代风格) int max(int x,int y) int z; z=xy?x:y; return(z); 例 有参函数(传统风格) max(x,y) int x,y; int z; z=xy?x:y; return(z); 例 空函数 void dummy( ) 函数体为空 例 无参函数 void printstar( ) printf(“*n”); 函数调用时的数据传递方法函数调用时的数据传递方法 形式参数和实际参数形式参数和实际参数 在调用函数时,大多数情况下,主调函数和在调用函数时,大多数情况下,主调函数和 被调用函数之间有数据传递关系。这就是前面被调用函数之间有数据传递关系。这就是前面 提到的有参函数。前面已提到:在定义函数时提到的有参函数。前面已提到:在定义函数时 函数名后面括弧中的变量名称为函数名后面括弧中的变量名称为“形式参数形式参数” (简称(简称“形参形参”),在主调函数中调用一个函),在主调函数中调用一个函 数时,函数名后面括弧中的参数数时,函数名后面括弧中的参数( (可以是一个表可以是一个表 达式达式) )称为称为“实际参数实际参数”(简称(简称“实参实参”)。)。 n形参与实参 形式参数:定义函数时函数名后面括号中 的变量名 实际参数:调用函数时函数名后面括号中 的表达式 c=max(a,b); (main 函数) (max 函数) max(int x, int y) int z; z=xy?x:y; return(z); 例 比较两个数并输出大者 main() int a,b,c; scanf(“%d,%d“, c=max(a,b); printf(“Max is %d“,c); int max(int x, int y) int z; z=xy?x:y; return(z); 形参 实参 说明: 实参必须有确定的值 形参必须指定类型 形参与实参类型一致,个数相同 若形参与实参类型不一致,自动按形参 类型转换函数调用转换 形参在函数被调用前不占内存;函数调用 时为形参分配内存;调用结束,内存释 放 从左到右流水灯,从右到左流水 灯,熄灭,闪烁5次,重复 void main() while(1) uint i; P2=0xfe; /1 for(i=0;i #include #define uint unsigned int #define uchar unsigned char void delay(uint z) uint x,y; for(x=z;x0;x-)for(y=56;y0;y-); void main() uchar temp; unsigned int i,j; for(j=0;j main() a=c; int a=7,c; delay(10) void delay(); char i; for(i=0;i void delay(char zz) char i; for(i=zz;i n#include n#define uint unsigned int nvoid main() n n uint aa,bb; n xdata uint result; n aa=DBYTE0x20; n bb=DBYTE0x35; n result =aa*bb; n 思考:结果存到哪里去了 ? ? n若改成 xdata uchar result; 结果存放相同吗? 指针变量说明举例 (2)(2)被指数据类型被指数据类型 被指存贮类型被指存贮类型 * *指针变量存贮类型指针变量存贮类型 指针变量指针变量 例如 long code * xdata px; /*和上面定义等同*/ px为指针型 变量 被指向的存 贮器的数据 类型为长型 px指向程 存贮器 px自身在外部 数据存贮器中 longxdatacode*px ; 指针变量说明指针变量说明有两种格式:有两种格式: (1 1) 指针变量存储类型指针变量存储类型 被指数据类型被指数据类型 被指存储类型被指存储类型 * *指针变量名;指针变量名; ( 其中其中 为可选项为可选项 ) 如:如: data char xdata *pd; /*与上例等效*/ 例如 long xdata *px; /*指针变量px指向long型xdata区(被指的数据在 xdata区,每 个数据占四个单元,指针自身在默认存贮器(如不指定编译模 式在data区),指针长度为2个字节*/ 例如 char xdata *data pd; /* 指针变量pd指向字符型xdata区,自身在data区,长度2字节*/ n说明: 1.” * ”号不可少,它表示变量为指针变量。 2.指针变量说明格式中的 为可选项 如 被指存贮类型 缺省,则指针定义为通用型 如 指针变量存贮类型 缺省、指针变量则存放在默认 存贮区或者在data区。 n 如果指针可指向任何存贮空间,指针定义为通用型指 针, 表示此时指针长度为3字节 第一字节第二字节第三字节 存贮类型编码所指地址的高八位所指地址的低八位 存贮器类 型 idataxdatapdatadatacode 编 码(v4.0)12345 编 码(v5.0)001-2-1 通用型指针的存贮类型编码如下: 表中v4.0、v5.0表示 C51的版本 例如指针变量px值 为0x021203 (v4.0版) 或为0x001203 (v5.0版) 即指针指向xdata 区的1203H地址单元。 如: char *pd; /* pd 定义为通用型指针*/ 4.4.4 指向数组的指针变量 n如果用一个变量存放一个数组的地址,这个变量就 称为指向数组的指针变量. n数组的起始地址称为数组指针,一个数组a 的起 始地址用a表示。 n指向数组的指针变量的定义和赋值 设定义了一个数组a5和一个指针变量ap: char data a5; char data *ap; n 仅此两句并不能说明变量ap是指向数组的,还必须将 数组的起始地址赋给该变量: ap=a; /*数组a 的起始地址赋给指针变量ap*/ 或 ap= /*意义同上*/ 也可以使定义和赋值在一条语句完成: char data *apa; 或 char data * ap= 2) 利用指向数组的指针变量引用数组元素 指向数组的指针变量引用数组元素有两种方法: *(ap+i) 或 ap(i) ,它们等同于*(a+i)或a (i) 例 main() char a5=11,22,33,44,55; char b,c,d; char *ap; ap=a; /* ap等于数组a5的起始地址*/ b=a+2; /* b等于数组元素a2的地址 */ c=ap+3; /* c等于数组元素a3的地址 */ d=*(ap+3); /* d等于数组元素a3的值, 即d=44 ,等同于d=a (3) */ 编程将8051的内部数据存储器20H单元和35H单元 的数据相乘,结果存到外部数据存储器中(位置不定 ) #include void main() int data *point1=0x20; int data *point2=0x35; xdata int result; result=(*point1)*(*point2); 用并行口设计LED数码显示器 和键盘电路 n键盘和显示器是单片机应用系统中常用的输入输出装 置。 nLED数码显示器是常用的显示器之一 n下面介绍用单片机并行口设计LED数码显示电路和键盘 电路的方法。 用并行口设计LED显示电路 1. LED显示器及其原理 nLED有着显示亮度高,响应速度快的特点,最常用的是七 段式LED显示器,又称数码管。 n七段LED显示器内部由七个条形发光二极管和一个小圆点 发光二极管组成,根据各管的亮暗组合成字符。 n常见LED的管脚排列见图5.4(a)。其中COM为公共点,根据 内部发光二极管的接线形式,可分成共阴极型图(5.4(b) 和共阳极型图(5.4(c)。 a b c d e f g dp (a)(b)共阴极型(c)共阳极型 cd edp 12345 6 78910 a b f g com com a b c e f a b c d e f g dp com com 图5.4 g d 0 0 1 1 1 1 1 1 3fh dp g f e d c b a LED数码管的ga七个发光二极管因加正电压而发亮,因加零电压 而不能发亮,不同亮暗的组合就能形成不同的字形,这种组合称之 为字形码(段码) a b c d e f g dp cd edp 12345 6 78910 a b f g com com a b c e f com g d 如显示 ”0”,字形 码为3fh. a b c d e f g dp 12345 6 78910 a b f g com com a b c e f g x g f e d c b a 0 0 0 0 0 1 1 0 06h 显示”1”,字形码为06h. d 显示”2”,字形码为5bh. x g f e d c b a 0 1 0 1 1 0 1 1 5bh dp com a b c d e f g dp cd e 12345 6 78910 com com a b c e f g d 显示字符段符号 共阴共阳 03FH C0 106H F9 25BH A4 34FH B0 466H 99 56DH 92 67DH 82 707H F8 87FH 80 96FH 90 A 77H 88 B 7CH 83 C 39H C6 D 5EH A1 E 79H 86 F 71H 84 H 76H FF P F3H BF 显然共阳极和共阴 极的字形码是不同 的 ,其字形码见表 n2.LED数码管的接口 n数码管的接口有静态接口和动态接口。 n静态接口为固定显示方式,无闪烁,其电路可采用一个并行 口接一个数据管,数码管的公共端按共阴或共阳分别接地或 Vcc。这种接法占用接口多,如果PO口和P2口要用作数据线和 地址线,仅用单片机的并行口就只能接二个数码管。 n动态接口采用各数码管循环轮流显示的方法,当循环显示频 率较高时,利用人眼的暂留特性 ,看不出闪烁显示现象,这 种显示需要一个接口完成字形码的输出(字形选择),另一接口 完 成各数码管的轮流点亮(数位选择)。 原 理 图 P10 P11 P12 000 111 S11S14 S21S24 位选 P20 P27 DP20DP27 a b c d e f g dp 段选 Eg.左边第二个数码管显示0F,熄灭,停机 nuchar code duma=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00; /数 值0F 熄灭 void delay(uchar zz) uchar x,y; for(x=zz;x0;x-) for(y=56;y0;y-) ; void main() uchar i; P1=0x01; for(i=0;i1)|0x80; delay(1000); P2=0xff; delay(1000); for(k=0;k void delay(int a) while(a-); int i; unchar code tab16=0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x76, 0x73 ; void main() while(1) for(i=1;i16;i+) P1=i%8; P2=tabi; delay(51000); 数码管显示temp中的值(两位数) void main() uint temp=13; uint ge,shi; while(1) shi=temp/10; ge=temp%10; P1=weix0; P2=dumashi; delay(10); P1=weix1; P2=dumage; delay(10); 不加延时语句会是什么现象? 动态显示 写一个函数,调用它显示一个3位数 void display(uint temp) uint ge,shi,bai; ge=temp%10; shi=temp%100/10; bai=temp/100; P1=weix0;P2=dumabai;delay(10); P1=weix1;P2=dumashi;delay(10); P1=weix2;P2=dumage;delay(10); void main() uint num=123; while(1) display(num); 加1显示器(000999) void main() uint num=0; while(1) if(num=1000) num=0; display(num); delay(1000); num+; 什么现象? 十位,百位闪烁的厉害 刷新频率不够 正确思路 void main() uint num=0,time; while(1) for(time=0;time10;time+)display(num);/通过循环延 时 num+; if(num=1000) num=0; 作业: n用动态扫描方式,显示12345678 n用动态扫描方式,显示10009999 用并行口设计键盘电路 n键盘是计算机系统中不可缺少的输入设备,当按键 少时可接成线性键盘 LED +5V Vcc - EA RST 10uF 1K P2.0 89S51 P1.0 1K 30P 30P XTAL1 XTAL2 GND 89C51 +5V Vcc - EA RST 10uF 1K89S51 +5V 1K 30P 30P XTAL1 XTAL2 GND 89C51 S19 n独立键盘的检测: n先给对应I/O口P10赋1,然后读取I/O口P10的状态值 n如果P10=0,则按键按下 n否则,未按下 n写程序完成按下S19,点亮第一个LED(P20控制) sbit P10=P10; sbit P20=P20; void main() P10=1; while(1) if(P10=0) P20=0; else P20=1; S17(与P32相连)每按下一次,数码管显示+1(09 ) sbit key1=P32; uint num=0; void main() P1=0x02; P2=duma0; while(1) if(key1=0)/确定按键是否按下 num+; if(num=10) num=0; P2=dumanum; 什么现象

温馨提示

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

评论

0/150

提交评论