单片机听课笔记1-8课(金沙滩2014年更新)

更新时间:2024-05-28 15:00:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

单片机听课笔记1-8课----金沙滩工作室2014年更新

Lesson 1:

1、 用公司用的单片机/视频用的单片机 2、 书是用来查的。

3、 单片机方面不怎么需要软件仿真

4、 KEIL软件安装 (keil c51)30分钟-35分钟

双击→next→√→next→默认路径→next→1,2,3,email格式→next→自动安装→去掉三个选项的√→finish。 桌面上出现KEIL快捷方式。

5、 文字大小,文字颜色的设定:edit→configuration→colour&font→:editor c files→只需要修改text, text

selection,number,keyword,string即可。

6、 下载软件stc-isp-v480.se win7系统第一次打开,右键,以管理员身份运行一次。 7、 《三傻大闹好莱坞》:追求卓越,成功就会在不经意间追上你。 Lesson2:

1、51单片机:兼容intel的MCS-51体系架构的一系列单片机 2、STC89C52RC---学习板上的第一个单片机。 3、单片机最小系统:

电源电路、

晶振电路(20PF起振电容,帮助晶振起振,并维持震荡信号的稳定)、 复位电路(0.1uF, 18R, 4.7K)。

4、单片机复位一般用三种:上电复位,手动复位,程序自动复位。 5、单片机原理图引脚位置与封装图可以不一样。 6、贴片发光二极管限流电阻的选用。

7、sfr P0 = 0X80,告诉我们编程软件P0在0X80的位置上,查手册可得。 8、打开KEIL软件→project→new project →选择路径→写工程名,不需写扩展名→

旧:选择单片机型号→NXP→P89V51 →copy,,,,,→否→新建文件file→new→保存→给文件起名led.c→ 新:选择单片机型号→intel→随便一个 →copy,,,,,→是→新建文件file→new→保存→给文件起名led.c 9、#include及函数名后不需要加分号。

10、单片机编程是根据硬件编程,不同的板子,程序可能不一样。

11、target 1右边的target options→target→11.0592M, output→creat hex选项框选中,点击ok,编译,连接就可生成hex文件。

12、hex文件大小的看法:在编译连接之后,build output对话框里看。 Program size: data = 9.0 xdata = 0 code = 29 表示:

其中data,xdata指RAM,两项加起来就是内存的值:0+9=9字节。 code指占程序存储空间的值:29个字节。 13、点亮小灯的程序 # include sbit LED = P0^0; sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4; void main() {

ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0; }

14、安装usb-串口的驱动;

查找COM口。我的电脑→设备管理器。

选择单片机型号→打开hex文件→选择使用的COM口→波特率默认→下次冷启动选择:与下载无关→(STC89C52RC冷启动单片机)先点下载后上电。 作业:

3.了解KEIL软件 的基本用法和单片机编程流程,能够独立完成编程下载等基本操作。

LED = 0; while(1);

Lesson 3:硬件基础学习

1、 电磁干扰EMI, 电磁兼容EMC

2、 低频滤波电容:去除电源低频纹波,稳定电源作用。

铝电解电容、钽电容(有色标的一端为正极,性能好)、陶瓷电容。 3、 高频滤波电容:对高频短路,可滤去高频干扰。(104 = 0.1uF) 4、 电容选取两个主要参数:耐压值、容值。

5、 三极管的功能:开关控制(100Ib>Ie,则工作在饱和状态)、信号放大、电平转换。 6、 三八译码器: 74HC138 地址输入端c/b/a及E3使能端接4.7K电阻上拉。

U?ADDR0ADDR1ADDR2123ABCY0Y1Y2Y3Y4Y5Y6Y715141312111097ENLEDADDR3456E1E2E374HC138

7、 双向缓冲器:74HC245 DIR为高,A→B;输入端接4.7K上拉电阻。

U?23456789191A0A1A2A3A4A5A6A7EDIR74HC245B0B1B2B3B4B5B6B71817161514131211

8、 保存过后的c文件,文件名旁边没有※。

作业:

4、能够独立点亮开发板上的每一个小灯,并且可以实现小灯亮和灭以及闪烁。

Lesson 4 C语言基础以及流水灯实现 1、进制

2、C语言变量类型及范围

Unsigned char 0-255 signed char -128—127 Unsigned int 0-65535 signed int -32768---32767

Unsigned long 0-4294967275 signed long -2147483648---2147483647 Float -3.4×10-38—3.4×10-38 double:C51里等同于float 能用一个字节的变量能完成的工作,不要用两个字节变量。 3、C语言基本运算符

+ - * / %(取余) ++ -- = == != 4、for语句的用法(作延时,作循环运算)

一、for(表达式1; 表达式2; 表达式3) {

(需要执行的语句)

} 执行顺序:1,2,4,3, 2,4,3, 2,4,3

二、for(i= 0 ; i<30000; i++); 是用法一的特殊情况,相当于执行语句为不执行。 三、for(;;) 相当于while(1) 5、while语句的用法 一、while(条件表达式) {

循环语句;

}

6、函数名的类型,就是return值的类型。Void main() void表示函数名,无返回值,int main(),返回值为整型。 7、变量在使用之前,先定义。 8、51单片机延时常用方法: 非精确延时:for(I = 0 ; i<100; i++); I = 100; while(i--); 精确延时:用定时器定时 利用库函数-nop-();

9、肉眼分辨率:20ms一下看不到闪烁;50ms间隔能清楚看见亮灭。

10、软件仿真: 先设置target options→target→11.0592M, debug→选中use simulator→ok 点击 start debug session 图标,进入仿真界面。

设置断点:双击,若设置不了target options→C51→level,设置优化登记一般选8。 RST 复位 run全速运行。然后看时间情况。(50分钟附近) 11、程序一:小灯的闪烁 (视频位置与笔记顺序不一致) # include

sbit LED = P0^0; sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

void main() { }

12、程序二:流水灯程序(法一) # include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

void main() {

while(1) {

unsigned int i = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0; LED = 0; for(;;)//while(1) { LED = 0;

for(i = 0; i<20000; i++); LED = 1;

for(i = 0; i<20000; i++); }

unsigned int i = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;

}

P0 = 0XFE;

for(i = 0; i<30000; i++); P0 = 0XFD;

for(i = 0; i<30000; i++); P0 = 0XFB;

for(i = 0; i<30000; i++); P0 = 0XF7;

for(i = 0; i<30000; i++); P0 = 0XEF;

for(i = 0; i<30000; i++); P0 = 0XDF;

for(i = 0; i<30000; i++); P0 = 0XBF;

for(i = 0; i<30000; i++); P0 = 0X7F;

for(i = 0; i<30000; i++); }

13、移位指令(<< >>)、取反指令(~)。 14、程序二:流水灯程序(法二) # include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

void main() {

unsigned char cnt = 0; unsigned int i = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;

} 作业:

4、独立完成流水灯右移操作。

5、独立完成左移到头,接着右移,右移到头,接着左移的程序。

Lesson 5 定时器和数码管基础

1、逻辑运算 逻辑与:&& 逻辑或:|| 逻辑非:! 按位与:& 按位或:| 按位取反:~ 按位异或:^

while(1) {

P0 = ~(0x01<= 8) { } }

cnt = 0;

0b11001100 |0b11110000 等于0b11111100 2、数字电路常用符号

3、机器周期是定时器的计数周期,打开定时器后,每经过一个机器周期,定时器“存储寄存器”的值加1。 8位定时器存储的值的范围:0-225 16位定时器0-65535 4、标准51里有两个定时器:T0和 T1。 5、定时器/计数器模式示意图。 5、使用定时器的方法

一、设置TMOD(模式寄存器M1、M0位,常用模式1、模式2自动重装),配置好工作模式 例如:TMOD = 1; 二、设计数寄存器 TH0 、TL0的初值。例如:TH0 = 0XB8; TL0 = 0X00;定时20ms TH0 = 0XB8; TL0 = 0X00; 定时1ms 三、设TCON(控制寄存器 TF位,TR位),通过TR0置1来让定时器开始计数 例如:TR0 = 1; 四、判断TCON寄存器的TF0位,检测定时器的溢出情况。

计算计数寄存器初值的方法:12*(65536-X)/11059200 = 20ms

6、1s闪烁一次的小灯程序 #include

sbit LED = P0^0; sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

void main() {

while(1) {

if(TF0 == 1) {

TF0 = 0; TH0 = 0XB8; TL0 = 0X00; cnt++; if(cnt >= 50) {

cnt = 0; LED = ~LED;

//定时20ms

TMOD = 0x01; TH0 = 0XB8; TL0 = 0X00; TR0 = 1;

unsigned char cnt = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;

}

}

} }

7、数码管分: 位、段(A/B/C/D/E/F/G/DOP)两个概念 8、第一个数码管显示“1”的程序 #include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

void main() { }

P0 = 0XF9; while(1);

unsigned char cnt = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;

9、 1位数码管从1-F(每隔1秒加1) #include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

unsigned char code ledchar[] = {0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8,

void main() {

TMOD = 1; TH0 = 0XB8; TL0 = 0X00; TR0 = 1; while(1) {

if(TF0 == 1) {

TF0 = 0; TH0 = 0XB8;

unsigned char cnt = 0; unsigned char sec = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;

0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e};

TL0 = 0X00;

}

cnt++;

if(cnt>= 50) {

cnt = 0;

P0 = ledchar[sec]; sec++; if(sec>= 16) { }

sec = 0;

}

}

}

作业:

1、 熟练掌握单片机定时器的原理和应用方法

2、 通过研究定时器模式1的示意图,自己打开STC89C52RC手册的定时器部分,独立研究模式0,模式1,模式2,

和模式3的示意图,锻炼研究示意图的能力。 3、 使用定时器实现延时,完成左右移动的流水灯程序。 4、 了解数码管的原理,掌握数码管的真值表计算方法。 5、 编程实现数码管静态显示秒表的倒计时。

Lesson 6 中断与数码管动态显示 1、 if语句的用法

(1) if (条件表达式)

{

语句1;

} 只判断一次,只执行一次,然后执行下面的程序。

(2) if (条件表达式)

{ } else { }

(3) if(表达式1) {语句1;} elseif(表达式1) {语句1;}

elseif(表达式1) {语句1;}

else {语句n} 一旦有一个为真,执行完相应语句后,跳出if语句。

2、 switch语句的用法

法一: Switch(表达式) { }

Case 常量表达式n:语句n; Default: 语句n+1;

Case 常量表达式1:语句1; Case 常量表达式2:语句2;

语句2; 语句1;

法二:

Switch(表达式) { }

Case 常量表达式n:语句n;break; Default: 语句n+1;

break;

Case 常量表达式1:语句1; break; Case 常量表达式2:语句2; break;

3、动态显示 利用人肉眼的视觉暂留现象(余晖效应) 10ms以内必须重新刷新同一个数码管。

ENLED ADDR3 选中 ADDR2 ADDR1 ADDR0 切换 4、6位显示的秒表程序(if语句)

#include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

unsigned char code ledchar[] = {0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e};

unsigned char ledbuff[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; //初始值 0XFF

void main() { unsigned int cnt = 0; unsigned long sec = 0; unsigned char i = 0; ENLED = 0; ADDR3 = 1; TMOD = 0X01; TH0 = 0XFC; TL0 = 0X67; TR0 = 1; while(1)

{ if(TF0 == 1) { }

}

}

TF0 = 0; TH0 = 0XFC; TL0 = 0X67; cnt++; if(cnt>=1000) { cnt = 0; sec++; ledbuff[0] = ledchar[sec]; ledbuff[1] = ledchar[sec/10]; ledbuff[2] = ledchar[sec/100]; ledbuff[3] = ledchar[sec/1000]; ledbuff[4] = ledchar[sec/10000]; ledbuff[5] = ledchar[sec/100000]; // } if(i == 0) { ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; i++; P0 = ledbuff[0]; }

else if (i == 1) { ADDR2 = 0; ADDR1 = 0; ADDR0 = 1; i++; P0 = ledbuff[1]; }

else if (i == 2) { ADDR2 = 0; ADDR1 = 1; ADDR0 = 0; i++; P0 = ledbuff[2]; }

else if (i == 3) { ADDR2 = 0; ADDR1 = 1; ADDR0 = 1; i++; P0 = ledbuff[3]; }

else if (i == 4) { ADDR2 = 1; ADDR1 = 0; ADDR0 = 0; i++; P0 = ledbuff[4]; }

else if (i == 5) { ADDR2 = 1; ADDR1 = 0; ADDR0 = 1; i = 0; P0 = ledbuff[5]; }

5、6位显示的秒表程序(switch语句) #include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

unsigned char code ledchar[] = {0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e};

unsigned char ledbuff[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; //初始值 0XFF

void main() { unsigned int cnt = 0; unsigned long sec = 0; unsigned char i = 0; ENLED = 0; ADDR3 = 1; TMOD = 0X01; TH0 = 0XFC; TL0 = 0X67; TR0 = 1; while(1) { if(TF0 == 1) { TF0 = 0; TH0 = 0XFC; TL0 = 0X67; cnt++; if(cnt>=1000) { cnt = 0; sec++; ledbuff[0] = ledchar[sec]; ledbuff[1] = ledchar[sec/10]; ledbuff[2] = ledchar[sec/100]; ledbuff[3] = ledchar[sec/1000]; ledbuff[4] = ledchar[sec/10000]; ledbuff[5] = ledchar[sec/100000]; //

}

}

} P0 = 0XFF;//消除鬼影操作。 switch(i) { case 0:ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; i++; P0 = ledbuff[0]; break; case 1:ADDR2 = 0; ADDR1 = 0; ADDR0 = 1; i++; P0 = ledbuff[1];break; case 2:ADDR2 = 0; ADDR1 = 1; ADDR0 = 0; i++; P0 = ledbuff[2];break; case 3:ADDR2 = 0; ADDR1 = 1; ADDR0 = 1; i++; P0 = ledbuff[3];break; case 4:ADDR2 = 1; ADDR1 = 0; ADDR0 = 0; i++; P0 = ledbuff[4];break; case 5:ADDR2 = 1; ADDR1 = 0; ADDR0 = 1; i = 0; P0 = ledbuff[5];break; default:break; } }

6、 使用中断实现秒表程序(中断)

#include

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

unsigned char code LedChar[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,

0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};

unsigned char LedBuff[6]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

unsigned int cnt = 0; void main() {

unsigned long sec = 0;

ENLED = 0; ADDR3 = 1; TMOD = 0x01; TH0 = 0xFC; TL0 = 0x67; TR0 = 1; EA = 1; ET0 = 1;

while(1) {

if(cnt >= 1000) { cnt = 0; sec++; LedBuff[0] = LedChar[sec];

LedBuff[1] = LedChar[sec/10]; LedBuff[2] = LedChar[sec/100]; LedBuff[3] = LedChar[sec/1000]; LedBuff[4] = LedChar[sec/10000]; LedBuff[5] = LedChar[sec/100000]; } } }

unsigned char i = 0;

void InterruptTimer0() interrupt 1 {

TH0 = 0xFC; TL0 = 0x67; cnt++;

P0 = 0xFF;//消隐 switch(i) { case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0];break; case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1];break; case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2];break; case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3];break; case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4];break; case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5];break; default:break; } }

7、 数码管不亮的地方发暗,数码管鬼影怎么解决?秒表加1时,显示抖动怎么解决?

消除鬼影:见程序二上面黄色部分。 显示抖动:使用中断消除。

8、 中断优先级(固有优先级) 中断函数编号 0 1 2 3 4 5

中断名称 外部中断 T0 外部中断 T1 UART T2 中断标志位 IE0 TF0 IE1 TF1 TI/RI TF2/EXF2 中断使能位 EX0 ET0 EX1 ET1 ES ET2 中断向量地址 0x0003 0x000B 0x0013 0x001B 0x0023 0x002B 默认优先级 1(最高) 2 3 4 5 6 9、中断58分钟后。 进入中断条件:第一打开中断、符合中断条件 、中断入口正确。 10、 11、

中断使能寄存器:IE 可位寻址。关注:EA、ET0位。 中断向量地址:决定中断入口号 x*8 +3 = 中断向量地址。 定时器0:中断入口号1;定时器1,中断入口号3。

作业:

3、 彻底理解中断的原理和应用方法,关闭教程自己把本章节程序编写完毕,下载实践。 4、 尝试修改程序,只显示有效位

5、 尝试写一个从999999开始倒计时的程序,通过改用定时器T1的中断来完成。

Lesson 7 变量进阶与LED点阵(点阵部分需要完善) 1、 变量的作用域

(1) 局部变量:只在函数内部使用的变量 (2) 全局变量: 2、 全局变量的副作用:

A, 降低函数的独立性—修改,对任何一个函数的修改,都可能影响其他函数。 B, 降低函数的通用性—不利于函数重复调用

C, 降低程序的清晰度---每个函数执行,都可能改变全局变量的值。 D, 全局变量永久占据内存。

3、 原则:能用局部变量,就不用全局变量。

全局变量和局部变量同名,在局部变量作用域范围内,局部变量有效。 4、 变量的存储类别:

自动变量:函数中的局部变量,如不加static关键字修饰,都属于自动变量,也叫做动态变量。 静态变量:所有全局函数都属于静态变量,局部变量如果加了static 关键字修饰,也是静态变量。 5、 点阵取模软件的用法

A,新建图像:8*8,

B,模拟动画:放大格点值最大,画图,选中的点为灭,白色的为亮, C,修改图像;黑白反选,确定要显示的内容。 D,取模方式:C51格式。

E,参数设置: →其他选项→选择横向取模+

其他默认(选中:字节倒序(点阵第一行左侧DB0),保留、任何时候都)

F,基本操作:保存图像,打开图像,便于下次操作。 6、 显示汉字:需要至少16*16的显示屏。

7、 动态显示:例如,I ? u 可以新建一个8*40行的点阵。

(点阵显示部分重看之后待完善)

8、 左右移动方法一,图像侧过来,把板子侧过来就可以了。 9、 左右移动方法二:二维数组。 10、 Unsigned char a[2][3] = {{1,2,3},{4,5,6}};

Lesson 8 函数进阶与按键 一、单片机最小系统解析

1、电源:5V、3.3V两种;

数字电路电源:24V、12V、5V、3.3V、2.5V、1.8V

2、无源晶振(晶体):需接起振电容,不依赖电源电压,接好电路就工作;

有源晶振(振荡器):需接电源,输出端直接接XTAL1,依赖工作电压,适用高精度场合。 3、复位电路

上电复位:复位时间t = 1.2RC 故:t = 1.2*4.7K* 0.1*0.000001F = 564us, 大于两个机器周期约2us,故能起

到复位作用。

手动复位:人手按下按键的时间一般100ms以上,快的也有几十ms,故满足复位条件。

18欧的电阻作用是放电时,K、R、C形成闭合回路,消除干扰。

软件复位。 二、函数的调用

1、例如:利用void secondcount() void ledrefresh()函数优化秒表程序。 2、静态变量只第一次有效。

3、函数调用时,不加函数类型(无void等),加分号; 函数调用之前,必须进行定义或声明;

函数声明的时候必须加:函数类型,函数的形参,最后加一个分号。 4、函数体顺序:函数声明→main()→子函数排序→中断函数。 5、实参,形参27-32分钟。

三、独立式按键

VCC+5RR4.7kMCU的i/o口U1A内部输出1NOT2Q?NPNk1内部输入准双向I/O口

只有内部输出为高电平,MCU的I0口就为高电平,才能读键。故有P2 = 0XF7; 程序一:

#include // 用K1-K4控制LED6-9的亮灭

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

sbit LED9 = P0^7; sbit LED8 = P0^6; sbit LED7 = P0^5; sbit LED6 = P0^4;

sbit KEY1 = P2^4; sbit KEY2 = P2^5; sbit KEY3 = P2^6; sbit KEY4 = P2^7; main() { } (法二) Main程序 #include #include\main() {

while(1) P0 = 0Xff; KEYOUT1 = 0; ENLED = 0;

ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0; while(1) { }

LED9 = KEY1; //把读的KEY1的值赋给LED9; LED8 = KEY2; LED7 = KEY3; LED6 = KEY4;

P2 = 0XF7; //KEY1=4接高电平、KEYOUT4接低电平 ENLED = 0;

ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;

}

{ }

P0 = (P2>>4)|0xf0;

头文件

#ifndef _KEY_H_ #define _KEY_H_

sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;

sbit KEY1 = P2^4; sbit KEY2 = P2^5; sbit KEY3 = P2^6; sbit KEY4 = P2^7; sbit KEYOUT1 = P2^3; sbit KEYOUT2 = P2^2; sbit KEYOUT3 = P2^1; sbit KEYOUT4 = P2^0; #endif

程序二:K1、K2控制数字加减的程序,防抖动 #include #include \

void delay() { } main() {

unsigned char n = 0; P0 = 0XFF; KEYOUT1 = 0; ENLED = 0; ADDR3 = 1;

ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; //控制最右边数码管DS1亮 unsigned int i = 2000; while(i--);

}

P0 = ledchar[0]; while(1) { }

if(!KEY1) //相当于 if(KEY1 == 0) 判断键是否按下 { } if(!KEY2) { }

delay(); if(!KEY2) { }

if(n <= 0) { } else n--;

P0 = ledchar[n]; while(!KEY2);

n = 9;

delay();

if(!KEY1)//再判断健是否按下 { }

if(n >= 9) { } else n++;

P0 = ledchar[n];

while(!KEY1); //等待按键1松开的语句。

n = 0;

程序三、用小灯构成的5位二进制数表示16个按键,1-1,2-2,16-0; #include #include \void delay(); main() {

ENLED = 0; ADDR3 = 1;

ADDR2 = 1; ADDR1 = 1; ADDR0 = 0; P0 = 0xFF; while(1) { KEYOUT1 = 0; KEYOUT2 = 1; KEYOUT3 = 1; KEYOUT4 = 1; if(KEY1 == 0) { delay(); if(KEY1 == 0) { P0 = ~1;

}

}

if(KEY2 == 0) { delay(); if(KEY2 == 0) { P0 = ~2; }

}

if(KEY3 == 0) { delay(); if(KEY3 == 0) { P0 = ~3; }

}

if(KEY4 == 0) { delay(); if(KEY4 == 0) { P0 = ~4; }

}

while((KEY1 == 0)||(KEY2 == 0)||(KEY3 == 0)||(KEY4 == 0));

//第一行检测完

KEYOUT1 = 1; KEYOUT2 = 0; KEYOUT3 = 1; KEYOUT4 = 1; if(KEY1 == 1) { }

if(KEY2 == 0) { }

if(KEY3 == 0) { }

if(KEY4 == 0) { }

while((KEY1 == 0)||(KEY2 == 0)||(KEY3 == 0)||(KEY4 == 0));//第二行检测完 KEYOUT1 = 1; KEYOUT2 = 1; KEYOUT3 = 0; KEYOUT4 = 1; if(KEY1 == 1)

delay(); if(KEY4 == 0) { }

P0 = ~8; delay(); if(KEY3 == 0) { }

P0 = ~7; delay(); if(KEY2 == 0) { }

P0 = ~6; delay(); if(KEY1 == 0) { }

P0 = ~5;

{ delay(); if(KEY1 == 0) { P0 = ~9;

}

}

if(KEY2 == 0) { delay(); if(KEY2 == 0) { P0 = ~10; }

}

if(KEY3 == 0) { delay(); if(KEY3 == 0) { P0 = ~11; }

}

if(KEY4 == 0) { delay(); if(KEY4 == 0) { P0 = ~12; }

}

while((KEY1 == 0)||(KEY2 == 0)||(KEY3 == 0)||(KEY4 == 0)); KEYOUT1 = 1; KEYOUT2 = 1; KEYOUT3 = 1; KEYOUT4 = 0; if(KEY1 == 1) { delay(); if(KEY1 == 0) { P0 = ~13;

}

//第三行检测完

}

if(KEY2 == 0) { delay(); if(KEY2 == 0) { P0 = ~14;

}

}

if(KEY3 == 0) { delay(); if(KEY3 == 0) { P0 = ~15; }

}

if(KEY4 == 0) { delay(); if(KEY4 == 0) { P0 = ~16; }

}

while((KEY1 == 0)||(KEY2 == 0)||(KEY3 == 0)||(KEY4 == 0));

}

}

void delay() { unsigned int i = 1000; while(i--);

}

8课未完待续

Lesson 12 指针与LCD1602初识

57分钟后为1602

程序一:用显示字符的形式在LCD上显示 字符串与数字 #include

//第四行检测完

sbit RS = P1^0; sbit RW = P1^1; sbit EN = P1^5; sbit BUSY = P0^7; //等待繁忙标志 void wait() { }

void w_dat(unsigned char dat) { }

void w_cmd(unsigned char cmd) { }

void init_lcd1602(void)

wait(); EN = 0; P0 = cmd; RS = 0; RW = 0; EN = 1; EN = 0; wait(); EN = 0; P0 = dat; RS = 1; RW = 0; EN = 1; EN = 0; P0 = 0XFF; do { }

while(BUSY == 1); EN = 0;

RS = 0; RW = 1; EN = 0; EN = 1;

{ } main() { }

程序二:用发送字符串的形式在LCD上显示字符串。 #include

sbit RS = P1^0; sbit RW = P1^1; sbit EN = P1^5; sbit BUSY = P0^7;

unsigned char code word1[] = {\ my god!%unsigned char code word2[] = {\//等待繁忙标志 void wait() {

while(1); w_cmd(0xc0); w_dat(1+'0'); w_dat(2+'0'); w_dat(3+'0'); w_dat(4+'0'); w_dat(5+'0'); w_dat(6+'0'); w_dat(7+'0'); w_cmd(0x80); w_dat(65); w_dat(66); w_dat(67); w_dat(68); w_dat(69); w_dat(70); w_dat(71);

//w_dat('A');

init_lcd1602(); w_cmd(0x38); w_cmd(0x0c); w_cmd(0x06); w_cmd(0x01);

}

P0 = 0XFF; do { }

while(BUSY == 1); EN = 0;

RS = 0; RW = 1; EN = 0; EN = 1;

void w_dat(unsigned char dat) { }

void w_cmd(unsigned char cmd) { }

void init_lcd1602(void) { }

void w_string(unsigned char addr_start, unsigned char *p)

w_cmd(0x38); w_cmd(0x0c); w_cmd(0x06); w_cmd(0x01); wait(); EN = 0; P0 = cmd; RS = 0; RW = 0; EN = 1; EN = 0; wait(); EN = 0; P0 = dat; RS = 1; RW = 0; EN = 1; EN = 0;

{ } main() { }

while(1);

w_string(0x80,word1); w_string(0xc0,word2); init_lcd1602(); w_cmd(addr_start); while(*p != '\\0') { }

w_dat(*p++);

本文来源:https://www.bwwdw.com/article/9n37.html

Top