lesson3(增补)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
P0=????; P2=????; for(i=0;i<100;i++);
}
}
//继续往下写
心态要平和~一张一弛,有 条不紊! 切换时速度要快,不加延时, 但是切换完以后也得让数
码管亮一会儿
a f g b c e dp d
写程序时参考这两个吧~
main() { while(1) { P0=????; P2=????; for(i=0;i<100;i++);
有子函数,必然有父函数,或者 说是主函数。主函数调用子函数,子函 数为主函数完成指定的功能,一般不同 的子函数都有自己独特的功能。
不管是小李子还是三德 子,都受皇上的调遣。 因此皇帝就是主函数, 他们都是皇帝的子函数, 分别负责不同的事务。
调用
三 德 子
小 李 子
当然,皇帝也会偷懒~当他指派三 德子去调查一件事情后,自己就先歇一 会,等三德子的事干完了,回来汇报给 皇上以后,皇上再接着处理朝政。
void main() { //为书写方便,此处代码省 略 while(1) { for (i=0;i<16;i++) { P2=table[i]; Delay500ms(); } } }
程序从主函数main()开始执行,当遇到Delay500ms
}
子函数时,暂时离开主函数,跳转到子函数中继续执
行,子函数执行完毕后,返回到主函数中,继续执行 主函数接下来的内容
只要了解,不要记忆!
PxM1
0 0 1 1
PxM0
0 1 0 1
模式
传统51模式(默认) 低电平时可以有较大灌电流 高电平时只能提供小的拉电流 推挽模式,高低均提供大电流
高阻态,既不输出高电平也不输出低 电平 开漏态,若无上拉电阻只能输出低电 平
拉电流与灌电流
拉电流是从单片机引脚流出的电流,其作 用是把单片机引脚的电平拉成高电平 灌电流是流进单机引脚的电流,电流向水 一样灌到单片机的引脚里。
可以先定义变量,再初始化它,比如
int a,b;
a=0xFF; b=0x00;
初始化变量
也可以在定义的同时初始化它,比如
int a = 0xff , b = 0x00;
初始化数组
同样,可以先声明,再初始化,比如:
int a[4];
a[0]=0x00; a[1]=0x01;
a[2]=0x02;
a[3]=0x03;
选择【保存文件】,保存到d:\keil\c51\inc目 录下,文件名为【stc12c5a.h】
第二步,修改程序
修改头文件为刚才 保存的 stc12c5a.h 添加这两行代码
PxM0与PxM1的使用~~(尽量理解, 理解不了也没关系) 引脚模式控制寄存器有 【P0M0,P0M1】 控制P0端口的8个脚 【P1M0,P1M1】 控制P1端口的8个脚 【P2M0,P2M1】 控制P2端口的8个脚 【P3M3,P3M1】 控制P3端口的8个脚 M表示Mode~~
向西推进!
数码管
就是显示数字的小玩意~~~
共阴数码管~~ 负极是连在一起的哦!
共阳数码管~~ 正极是连在一起的哦!
第1位
第2位
第3位
每一个笔画叫做一段,每一段 还各有一个英文名字~~
a f g b c e dp
四位八段数码管~~
需要多少个引脚呢?每段是一个 LED,需要4*8+4=36个引脚吗?
还要注意:
定义Βιβλιοθήκη Baidu组时,既不是小括号【
(】和【)】
也不是大括号【
{】和【}】 ]
而是方括号【 】和【 】
[
初始化变量
如果一个变量只是定义,而没有给他赋初值,那么这个变 量可能是一个随机数,而不是期望的0(新买了一个桶,却发 现桶里有水);由于一个随机数可能使程序不能正常执行(没 准商店漏雨,桶里的水是从房顶漏下的脏水),因此,定义变 量后一般会把变量初始化为一个确定的值(把新买的桶刷一遍, 洗干净)。
0
1 1 0 0
0 0 0
0
0 0
0
看了这么长时间令人眼花缭乱的 东西——
孩儿们,操练起来!
让四个数码管同时显示数字
1
为了显示数字“1”,P2.7到P2.0分别为 00000110 即0x06 为了能够让4个数码管同时亮起,P0应该为xxxx0000 为了方便,不妨让P0=0x00
参考程序1
那么, 如何才能只点亮一个数码管呢?
很简单,改变P0的输出 即可~ 例如,要点亮最右边的 数码管,应该让P0的输 出为 xxxx1110 那么,P0=0x0e即可 当然,P0=0xfe也没关 系,因为高四位不起作 用~~
0 1 1 1
参考程序2
那么, 如何才能显示不同的数字呢?
还记得上一次制作的流水灯吗?
3、指令 集选择 Y3
2、填写 晶振频 率
1、选择【软 件延时计算器】
4、点击 生成C代 码
5、最后 点击复 制代码
将之前复制的代码粘贴到 #include<stc12c5a.h> 和 void main() 之间,位置很重要,千万不 要粘贴到别的地方 大家可以看到这里采用了三 重while嵌套循环来实现延 时。
P0=????; P2=????; for(i=0;i<100;i++); } //继续往下写
}
参考程序3
问题: 大家有没有觉得数码管很暗?
解决办法:加大单片机输出的电流
(专业一点:增强IO口的驱动能力)
(再专业一点:采用推挽输出)
(原理复杂,会用就行,有兴趣了解内幕的课下找我 们私聊~~)
用Delay500ms()子函数来替代 之前的for延时
下载到单片机中观察执行效果~~
void Delay500ms() { unsigned char i, j, k;
i = 46; j = 153; k = 245; do { do { while (--k); } while (--j); } while (--i);
这是大学C语言课程常考的东西哦~很无聊吧……
int a[3]={0x01,0x02,0x03};
a[0]=0x01 a[1]=0x02 a[2]=0x03
a[0]++;
a[2]=a[2]+a[0];
执 行 a[0]=0x02 a[1]=0x02 a[2]=0x05
a[0]=0x02 a[1]=0x02 a[2]=0x03
单片机第
3
课
哈尔滨工业大学业余无线电俱乐部
!
部分动画效 果可能不适 合在手机、 平板电脑等 移动设备上 观看!
上集回顾~~ C语言基础
数据类型及数据表示范围(水桶) 三种结构(顺序,循环,选择)(打豆豆)
流水灯
移位运算 软件延时
我们已经征服了开发板的一部分,下面
让我们把战场
子函数
子函数的定义格式v1.0: 先来最简单的,以后慢慢升级到2.0、3.0…… void 子函数名 ()
{
//在这里书写子函数需要做的事情
}
子函数
是不是感觉和main()函数长得很像呢?
子函数的位置
大家要先明白一个事儿,编译器很傻!只会 从上往下读程序!
No~~ 那就成毛毛虫了
a
b c d e
f
g dp 1
a
b c d e
f
g dp 1
2 3
4
a
b c d e
f
g dp 1
2 3
4
问题:想让数码管显示4个数 字1,应该怎么办?
a f g b c e dp d
我们的目标就 是让b、c两段 亮起来~~
0
1 1 0 0
0 0 0
0
0 0
0
下图中彩色部 分为有电流流 过的部分~~
简单理解一下拉电流作用
如果没有拉电流, I=0,则U=0 那么电阻两端没有电压,单片机引脚的 电压就会与GND是同样的电压~ 正是有了一个从引脚流出的电流,才使 得R上有了压降,单片机的引脚才输出 高低平。 单片的引脚的电平是被拉电流拉高的。
U=I*R
I
单片机
仅供参考,现在不必掌握,用 多了自己就会了!没听懂正常!
a[0]、a[1]、a[2]、……
这些变量中的1、2、3……称作数组的索引,或者
是下标,就像a0、a1、a2……一样。 常数——下标也可以是一个变量。
从上面的例子可以看出,数组的下标不一定是个
参考程序4
问题:
大家有没有发现数码管切换很 快,看不清?
如何实现较长时间的延时? 如何实现精确的延时?
如何实现较长时间的延时?
为了增加延时的时间,需要让单片机浪费更多 的时间。 方法一:把下图中的for语句继续复制粘贴,多 写几次,延时自然增加 方法二:使用嵌套循环
这样,相当于把内层的for延时复制了10次~~
如何实现精确的延时?
之前为了实现延时采用了大量执行无 用循环的方式,但是,这些循环到底延时 了多久?如果想实现指定时间长度的延时, 循环次数应该选多少呢? 为了实现这个功能,可以使用【延时计算 器】来帮助。
不仅仅是
一堆饭桶
而且还是
有序排列的饭桶
回忆原来变量定义的格式
变量类型 变量名1 ,变量名2 , ……;
例如: int a , b ; //定义了两个变量a和b,都是整形的
再比如:
饭桶 米明恒 , 黄柏维 ; //这两个家伙都是饭桶~~
如何定义一堆饭桶呢?
饭桶 饭桶名[饭桶数量] ;
例如:
饭桶 bucket[3] ;
P0 P0 P0 P0 P0 P0 P0 P0 P0 .7 .6 .5 .4 .3 .2 .1 .0 P0 1 0 0 1 0 1 0 0 M0 P0 1 1 0 0 1 0 0 1 M1 对于每一个针脚,都有M0与M1中的一位与之对 应,也就是说,对于每一列,M0和M1共可以有 4种组合,每种组合对应于一根针脚的一中工作 模式,一个端口(比如P0口)的8跟针脚可以工 作在不同的模式下
a[1]=a[a[0]];
a[0]=0x02 a[1]=0x05 a[2]=0x05
执行这一句之前,
a[0]=0x02,a[2]=0x05
a[1]=a[a[0]];
执行这一句时,程序先把a[0]的值读出 来(也就是2),再把a[0]所代表的值代 入a[a[0]]中,即读取a[2]的值,读出为 0x05,最后将0x05存入a[1]。
第一步:升级头文件
还记得我们之前用的头文件吗?Reg52.h
这个头文件是给最老最老的单片机用的,差 不多是上世纪80年代用的吧~~
我们用的是增强型51单片机,增强的功能 在reg52.h这个文件中没有定义出来! 所以,升级程序从升级头文件开始~~
在STC软件中选择【头文件】,并选择 STC12C5Axx系列
任务2:让数码管实现0~F的十 六进制计数器
效果如下:
如果还按照这样 的思路来写,代 码会好长好 长………… 有什么方法来简 化呢??? 让我们请出两位 大仙~~
有请~~
回忆一下~,用桶来做比喻 不同的变量类型就相当于不同的桶 可以有水桶、垃圾桶、饭桶……
如果把变量当做
饭桶
数组就是一堆饭桶
三 德 子
对于主程序,在调用子程序后,程序就暂时 离开了主函数,跳转到子函数去执行了, 子函数执行完,再返回主程序继续执行。
子函数的两大作用
将实现单个功能的代码片段封装在子函数里,再 由主程序调用子函数。这样,在功能上有联系的 一组代码被集合到一起,便于程序维护;否则所 有的功能都写在主函数中,主函数会变得非常臃 肿。(难以理解吧~~因为现在写的程序太短了! 大家慢慢就会有体会的!) 有些代码片段需要在不同的地方多次重复使用 (比如延时函数),每次都书写一遍太浪费,使 用子函数,只需书写一遍,即可多次重复调用。
在没有加延时的情况下,虽然流水灯在流动,但是我 们看起来它是全亮的~ 速度一快,眼睛就弱爆了~~
来个专业点的词语~~这个过程叫
动态扫描
第一个小比赛~~
让数码管显示英文单词
LOVE
学单片机是有用处滴 理工男 理工女
表白必备!!
main() { while(1) { P0=????; P2=????; for(i=0;i<100;i++);
定义了3个饭桶,分别为
bucket[0]、bucket[1]、bucket[2]
再例如:
int abc[5] ;
定义了5个int型的变量,分别为
abc[0]、abc[1]、abc[2] 、abc[3]、abc[4]
注意: 定义变量时的个数就是实际的个数,从1 开始计数。 但是使用变量时,是从0开始计数的
初始化数组
也可以在声明的同时初始化,比如: int a[4]={0x00,0x01,0x02,0x03};
注意
[]与{}的使用,要使用正
确的符号哦~~
来一个无聊的例子吧~~
int a[3]={0x01,0x02,0x03};
a[0]++;
a[2]=a[2]+a[0];
a[1]=a[a[0]];
请问最终a[1]=?
}
}
//继续往下写
心态要平和~一张一弛,有 条不紊! 切换时速度要快,不加延时, 但是切换完以后也得让数
码管亮一会儿
a f g b c e dp d
写程序时参考这两个吧~
main() { while(1) { P0=????; P2=????; for(i=0;i<100;i++);
有子函数,必然有父函数,或者 说是主函数。主函数调用子函数,子函 数为主函数完成指定的功能,一般不同 的子函数都有自己独特的功能。
不管是小李子还是三德 子,都受皇上的调遣。 因此皇帝就是主函数, 他们都是皇帝的子函数, 分别负责不同的事务。
调用
三 德 子
小 李 子
当然,皇帝也会偷懒~当他指派三 德子去调查一件事情后,自己就先歇一 会,等三德子的事干完了,回来汇报给 皇上以后,皇上再接着处理朝政。
void main() { //为书写方便,此处代码省 略 while(1) { for (i=0;i<16;i++) { P2=table[i]; Delay500ms(); } } }
程序从主函数main()开始执行,当遇到Delay500ms
}
子函数时,暂时离开主函数,跳转到子函数中继续执
行,子函数执行完毕后,返回到主函数中,继续执行 主函数接下来的内容
只要了解,不要记忆!
PxM1
0 0 1 1
PxM0
0 1 0 1
模式
传统51模式(默认) 低电平时可以有较大灌电流 高电平时只能提供小的拉电流 推挽模式,高低均提供大电流
高阻态,既不输出高电平也不输出低 电平 开漏态,若无上拉电阻只能输出低电 平
拉电流与灌电流
拉电流是从单片机引脚流出的电流,其作 用是把单片机引脚的电平拉成高电平 灌电流是流进单机引脚的电流,电流向水 一样灌到单片机的引脚里。
可以先定义变量,再初始化它,比如
int a,b;
a=0xFF; b=0x00;
初始化变量
也可以在定义的同时初始化它,比如
int a = 0xff , b = 0x00;
初始化数组
同样,可以先声明,再初始化,比如:
int a[4];
a[0]=0x00; a[1]=0x01;
a[2]=0x02;
a[3]=0x03;
选择【保存文件】,保存到d:\keil\c51\inc目 录下,文件名为【stc12c5a.h】
第二步,修改程序
修改头文件为刚才 保存的 stc12c5a.h 添加这两行代码
PxM0与PxM1的使用~~(尽量理解, 理解不了也没关系) 引脚模式控制寄存器有 【P0M0,P0M1】 控制P0端口的8个脚 【P1M0,P1M1】 控制P1端口的8个脚 【P2M0,P2M1】 控制P2端口的8个脚 【P3M3,P3M1】 控制P3端口的8个脚 M表示Mode~~
向西推进!
数码管
就是显示数字的小玩意~~~
共阴数码管~~ 负极是连在一起的哦!
共阳数码管~~ 正极是连在一起的哦!
第1位
第2位
第3位
每一个笔画叫做一段,每一段 还各有一个英文名字~~
a f g b c e dp
四位八段数码管~~
需要多少个引脚呢?每段是一个 LED,需要4*8+4=36个引脚吗?
还要注意:
定义Βιβλιοθήκη Baidu组时,既不是小括号【
(】和【)】
也不是大括号【
{】和【}】 ]
而是方括号【 】和【 】
[
初始化变量
如果一个变量只是定义,而没有给他赋初值,那么这个变 量可能是一个随机数,而不是期望的0(新买了一个桶,却发 现桶里有水);由于一个随机数可能使程序不能正常执行(没 准商店漏雨,桶里的水是从房顶漏下的脏水),因此,定义变 量后一般会把变量初始化为一个确定的值(把新买的桶刷一遍, 洗干净)。
0
1 1 0 0
0 0 0
0
0 0
0
看了这么长时间令人眼花缭乱的 东西——
孩儿们,操练起来!
让四个数码管同时显示数字
1
为了显示数字“1”,P2.7到P2.0分别为 00000110 即0x06 为了能够让4个数码管同时亮起,P0应该为xxxx0000 为了方便,不妨让P0=0x00
参考程序1
那么, 如何才能只点亮一个数码管呢?
很简单,改变P0的输出 即可~ 例如,要点亮最右边的 数码管,应该让P0的输 出为 xxxx1110 那么,P0=0x0e即可 当然,P0=0xfe也没关 系,因为高四位不起作 用~~
0 1 1 1
参考程序2
那么, 如何才能显示不同的数字呢?
还记得上一次制作的流水灯吗?
3、指令 集选择 Y3
2、填写 晶振频 率
1、选择【软 件延时计算器】
4、点击 生成C代 码
5、最后 点击复 制代码
将之前复制的代码粘贴到 #include<stc12c5a.h> 和 void main() 之间,位置很重要,千万不 要粘贴到别的地方 大家可以看到这里采用了三 重while嵌套循环来实现延 时。
P0=????; P2=????; for(i=0;i<100;i++); } //继续往下写
}
参考程序3
问题: 大家有没有觉得数码管很暗?
解决办法:加大单片机输出的电流
(专业一点:增强IO口的驱动能力)
(再专业一点:采用推挽输出)
(原理复杂,会用就行,有兴趣了解内幕的课下找我 们私聊~~)
用Delay500ms()子函数来替代 之前的for延时
下载到单片机中观察执行效果~~
void Delay500ms() { unsigned char i, j, k;
i = 46; j = 153; k = 245; do { do { while (--k); } while (--j); } while (--i);
这是大学C语言课程常考的东西哦~很无聊吧……
int a[3]={0x01,0x02,0x03};
a[0]=0x01 a[1]=0x02 a[2]=0x03
a[0]++;
a[2]=a[2]+a[0];
执 行 a[0]=0x02 a[1]=0x02 a[2]=0x05
a[0]=0x02 a[1]=0x02 a[2]=0x03
单片机第
3
课
哈尔滨工业大学业余无线电俱乐部
!
部分动画效 果可能不适 合在手机、 平板电脑等 移动设备上 观看!
上集回顾~~ C语言基础
数据类型及数据表示范围(水桶) 三种结构(顺序,循环,选择)(打豆豆)
流水灯
移位运算 软件延时
我们已经征服了开发板的一部分,下面
让我们把战场
子函数
子函数的定义格式v1.0: 先来最简单的,以后慢慢升级到2.0、3.0…… void 子函数名 ()
{
//在这里书写子函数需要做的事情
}
子函数
是不是感觉和main()函数长得很像呢?
子函数的位置
大家要先明白一个事儿,编译器很傻!只会 从上往下读程序!
No~~ 那就成毛毛虫了
a
b c d e
f
g dp 1
a
b c d e
f
g dp 1
2 3
4
a
b c d e
f
g dp 1
2 3
4
问题:想让数码管显示4个数 字1,应该怎么办?
a f g b c e dp d
我们的目标就 是让b、c两段 亮起来~~
0
1 1 0 0
0 0 0
0
0 0
0
下图中彩色部 分为有电流流 过的部分~~
简单理解一下拉电流作用
如果没有拉电流, I=0,则U=0 那么电阻两端没有电压,单片机引脚的 电压就会与GND是同样的电压~ 正是有了一个从引脚流出的电流,才使 得R上有了压降,单片机的引脚才输出 高低平。 单片的引脚的电平是被拉电流拉高的。
U=I*R
I
单片机
仅供参考,现在不必掌握,用 多了自己就会了!没听懂正常!
a[0]、a[1]、a[2]、……
这些变量中的1、2、3……称作数组的索引,或者
是下标,就像a0、a1、a2……一样。 常数——下标也可以是一个变量。
从上面的例子可以看出,数组的下标不一定是个
参考程序4
问题:
大家有没有发现数码管切换很 快,看不清?
如何实现较长时间的延时? 如何实现精确的延时?
如何实现较长时间的延时?
为了增加延时的时间,需要让单片机浪费更多 的时间。 方法一:把下图中的for语句继续复制粘贴,多 写几次,延时自然增加 方法二:使用嵌套循环
这样,相当于把内层的for延时复制了10次~~
如何实现精确的延时?
之前为了实现延时采用了大量执行无 用循环的方式,但是,这些循环到底延时 了多久?如果想实现指定时间长度的延时, 循环次数应该选多少呢? 为了实现这个功能,可以使用【延时计算 器】来帮助。
不仅仅是
一堆饭桶
而且还是
有序排列的饭桶
回忆原来变量定义的格式
变量类型 变量名1 ,变量名2 , ……;
例如: int a , b ; //定义了两个变量a和b,都是整形的
再比如:
饭桶 米明恒 , 黄柏维 ; //这两个家伙都是饭桶~~
如何定义一堆饭桶呢?
饭桶 饭桶名[饭桶数量] ;
例如:
饭桶 bucket[3] ;
P0 P0 P0 P0 P0 P0 P0 P0 P0 .7 .6 .5 .4 .3 .2 .1 .0 P0 1 0 0 1 0 1 0 0 M0 P0 1 1 0 0 1 0 0 1 M1 对于每一个针脚,都有M0与M1中的一位与之对 应,也就是说,对于每一列,M0和M1共可以有 4种组合,每种组合对应于一根针脚的一中工作 模式,一个端口(比如P0口)的8跟针脚可以工 作在不同的模式下
a[1]=a[a[0]];
a[0]=0x02 a[1]=0x05 a[2]=0x05
执行这一句之前,
a[0]=0x02,a[2]=0x05
a[1]=a[a[0]];
执行这一句时,程序先把a[0]的值读出 来(也就是2),再把a[0]所代表的值代 入a[a[0]]中,即读取a[2]的值,读出为 0x05,最后将0x05存入a[1]。
第一步:升级头文件
还记得我们之前用的头文件吗?Reg52.h
这个头文件是给最老最老的单片机用的,差 不多是上世纪80年代用的吧~~
我们用的是增强型51单片机,增强的功能 在reg52.h这个文件中没有定义出来! 所以,升级程序从升级头文件开始~~
在STC软件中选择【头文件】,并选择 STC12C5Axx系列
任务2:让数码管实现0~F的十 六进制计数器
效果如下:
如果还按照这样 的思路来写,代 码会好长好 长………… 有什么方法来简 化呢??? 让我们请出两位 大仙~~
有请~~
回忆一下~,用桶来做比喻 不同的变量类型就相当于不同的桶 可以有水桶、垃圾桶、饭桶……
如果把变量当做
饭桶
数组就是一堆饭桶
三 德 子
对于主程序,在调用子程序后,程序就暂时 离开了主函数,跳转到子函数去执行了, 子函数执行完,再返回主程序继续执行。
子函数的两大作用
将实现单个功能的代码片段封装在子函数里,再 由主程序调用子函数。这样,在功能上有联系的 一组代码被集合到一起,便于程序维护;否则所 有的功能都写在主函数中,主函数会变得非常臃 肿。(难以理解吧~~因为现在写的程序太短了! 大家慢慢就会有体会的!) 有些代码片段需要在不同的地方多次重复使用 (比如延时函数),每次都书写一遍太浪费,使 用子函数,只需书写一遍,即可多次重复调用。
在没有加延时的情况下,虽然流水灯在流动,但是我 们看起来它是全亮的~ 速度一快,眼睛就弱爆了~~
来个专业点的词语~~这个过程叫
动态扫描
第一个小比赛~~
让数码管显示英文单词
LOVE
学单片机是有用处滴 理工男 理工女
表白必备!!
main() { while(1) { P0=????; P2=????; for(i=0;i<100;i++);
定义了3个饭桶,分别为
bucket[0]、bucket[1]、bucket[2]
再例如:
int abc[5] ;
定义了5个int型的变量,分别为
abc[0]、abc[1]、abc[2] 、abc[3]、abc[4]
注意: 定义变量时的个数就是实际的个数,从1 开始计数。 但是使用变量时,是从0开始计数的
初始化数组
也可以在声明的同时初始化,比如: int a[4]={0x00,0x01,0x02,0x03};
注意
[]与{}的使用,要使用正
确的符号哦~~
来一个无聊的例子吧~~
int a[3]={0x01,0x02,0x03};
a[0]++;
a[2]=a[2]+a[0];
a[1]=a[a[0]];
请问最终a[1]=?