随笔分类 - 51学习
51单片机学习
摘要:根据矩阵键盘的原理图可知,当没有按键按下时,P1=0xf0;然后依次将P1^0~P1^3单独置低电平,其他置高,再扫描各列的状态,来判断是哪个按键按下,比如,将P1^0输出低电平,其他的引脚都输出高电平,即P1=0xfe,那么当第1行有按键按下时P1的相应值为,1X1(01111110=0x7e) ...
阅读全文
摘要:根据电路原理图,键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有
阅读全文
摘要:利用独立按键设计一个抢答器,代码很简单,但是却花了近一个小时,接错线,线8位的顺序出错等,原以为很简单的东西,却花了大量时间在代码之外,或许这就是单片机的特点吧,不光是代码要正确,还要外部连接正确才能最终达到预期的效果。#include sbit Key1 = P0^0; //按键1sbit Key2 = P0^1; //按键2sbit Key3 = P0^2; //按键3sbit Key4 = P0^3; //按键4void main(void){ bit Flag = 0; // bit类型,做布尔变量 标识是否有键按下 P1 = 0xFF; // 先将L...
阅读全文
摘要:长按是在短按的基础上,以一个很短的时间(10ms)再次判断按键是否片于按下状态,当达到一定的时间(1s)后,按键还处于按下状态,说明是长按状态,结合上一节的短按,下面实现一个从0-99的累加,短按时一次加1,长按后,进入快速累加的过程,同时使用了定时器来定时刷新数码管,在Display的处理上就和之前的不同,原来在Display里通过循环刷新每个数码管的显示,现在放到了定时器定时触发的事件里,设置定时时间为2ms,这2ms只负责刷新共阴极的8位数码的一位,所以需要在定时事件里处理每次刷新不同位置的数码管。#include sbit KeyAdd = P0^0;sbit LED = P0^1;s
阅读全文
摘要:前面学习了数码管和按键,将两者结合,完成一个用两个按键控制加减数字的小程序,一个按键控制加1另一个控制减1。#include sbit KeyAdd = P0^0; //加1按键sbit KeyDec = P0^1; //减1按键sbit LATCH1 = P2^2; //段锁存sbit LATCH2 = P2^3; //位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb
阅读全文
摘要:上一节的按键的使用中,效果是按下键亮,弹起后又灭,无法保持状态,下面的实现按下弹起后,实现一次切换;#include sbit LED = P0^2; //控制引脚sbit Key = P0^0; //按键void main(void){ LED = 0; //初始亮 while (1) { if (!Key) //如果按下 { LED = !LED; //切换LED状态 } }}测试后发现,按键按下弹起的时间间隔不同,效果也不同,...
阅读全文
摘要:我有学习板上独立按键共有8个,可以把它做为一个输入端口的8位控制。按下时输出0,松开时输出1,下面是用按键控制一个LED的亮灭,按下时亮,松开时灭。#include sbit LED = P0^2; sbit KEY = P0^0; // 注意输入要使用P0或P3,这两个口同时支持输入和输出void main(){ while(1) { if (KEY == 0) // 按下 LED = 0; else // 松开 LED = 1; //LED = KEY; ...
阅读全文
摘要:定时器的几种工作方式中,除0和前面的1类似都需要初始化计数值,然后开始计数,计数溢出后,需要再次控制计数的初值,但工作模式2不同于此,工作方式2将THx和TLx分开处理,将初值存放在THx中,计数时只处理TLx的8位,所以计数最大值为2^8=256,方式2的另一个特点是,当计数溢出后,不需要控制初值,而是会自动将THx中的值做为计数初值重新开始计数。用工作方式2,实现1s延时程序如下:查询方式#include sbit LED = P0^2;unsigned int vT = 0;void main(){ LED = 0; // 初始亮灯 TMOD = 0x02; ...
阅读全文
摘要:中断方式比较特殊,需要使用单片机内部的中断处理机制,同时指定中断函数。#include sbit LED = P0^2;unsigned int vT = 0;void main(){ LED = 0; TMOD = 0x01; TH0 = 0x3C; // 计数初值3CB0H = 15536 (65536-15536=50000 * 1us = 50ms) TL0 = 0xB0; ET0 = 1; // EA即IE^1 等于1时申请中断定时器0中断打开 EA = 1; // 总中断打开 TR0 = 1; /...
阅读全文
摘要:以查询控制器的控制位状态来实现1s定时。#include sbit LED = P0^2; unsigned int vT = 0;void main (){ LED = 0; // 点亮 TMOD = 0x01; // 定时模式1 16位定时计数器 TR0 = 1; // 启动定时器0 TH0 = 0x3C; // 计数初值 15536 (65536-15536=50000 * 1us = 50ms) TL0 = 0xB0; while(1) { if (TF0 ==...
阅读全文
摘要:上一节,稀里糊涂地照着demo测试了定时计数的效果,但对内部和参数的控制还是不解,准备从基础原理学习定时计数器的工作原理和方式。8051单片机的结构是由一内部总线连接各功能模块,通过特殊功能寄存器(SFR)集中控制,不同型号引脚定义和SFR定义不同,因此一个功能模块,可以从相关引脚功能和相关SFR功能学习了解该模块。以8051为例,其定时计数模块的特点有2个16位定时计数器,最大计数范围:0H-FFFFH;相关的SFR:TMOD、TCON、TH0、TL0、TH1、TL1;相关引脚:T0、T1、INT0、INT1;4种工作方式;其中,T0、T1做为计数脉冲输入,定时方式时不用,作I/O用,对应P
阅读全文
摘要:通过前面的定时器理论了解到,使用一个定时器,要经过下面四步:1、设置定时器/计数器的工作模式TMOD(常用的是模式1:TMOD=0x01);2、装入预置数到THx和TLx中(THx=TLx=MAX(8192/65536/256)-计数次数);3、如果工作在中断方式,则需要开定时器/计数器的中断TCON中的标志位:TF0/TF1=0/1;4、启动定时器/计数器:TR0/TR1=1;//1、设置定时器/计数器的工作模式TMOD(常用的是模式1:TMOD=0x01);//2、装入预置数到THx和TLx中(THx=TLx=MAX(8192/65536/256)-计数次数);//3、如果工作在中断方式,
阅读全文
摘要:定时器则是由单片机自身提供的一个非常稳定的计数器,这个稳定的计数器就是单片机上连接的晶振部件,晶振经过12分频之后提供给单片机的只有1MHZ的稳定脉冲;晶振的频率是非常准确的,所以单片机的计数脉冲之间的时间间隔也是非常准确的,这个准确的时间间隔是1微秒;12MHZ晶振内部的工作频率(时钟脉冲频率)是12MHZ/12=1MHZ=1000000次/秒=1000000条指令/秒=1000000次/1000000微秒=1次/微秒=1条指令/微秒;也就是说,晶振振荡一次,就会给单片机提供一个时钟脉冲,花费的时间是1微秒,此时,CPU会执行一条指令,经历一个机器周期;即:1个时钟脉冲=1个机器周期=1微秒
阅读全文
摘要:#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[10]; //存储显示值的数组void Delay(unsigned int t); //
阅读全文
摘要:数码管闪烁,利用一个布尔变量控制各数码管的显示值,为真(True)是赋对应的数值,为假(False)时熄灭,还是利用一定的时间间隔,在人眼的视觉暂留时间段内,快速的切换熄灭和点亮,可用下面的代码测试。#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值01234567unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef
阅读全文
摘要:按照我的开发板,共阴极数码管共8个,也就是说,只能显示8位数字,0-99999999,当显示的数字不足8位时,需要将不显示的数码管熄灭即消隐,代码原理就是将存储显示值的数组变量中,不显示的位在P1口输出0(熄灭),以下显示0-9999四位有效数字为例,从第2位数码管开始,显示最多4位有效数字:#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned
阅读全文
摘要:数码管的小数点单独有一位来控制,这就是物理世界和数字世界的神奇之处,数码管用来显示数字和字母的led段有7个,再加上小数点共8个,正好对应一个字节的位数,这样使用单片机的一个口正好可以全部操作,通过http://www.cnblogs.com/coloregg/p/3565486.html 可以看到点是单独位来操作,比如显示2.,只需将数字2对应的二进制数第1位改为1即可,在实际中,我们将要带点显示的数字和0x80相或就可以,其原理如下:共阴极(1亮0灭): DPGF E DC B A 0101 1 0 1 1 = 0x5B 1 0 0 0 0...
阅读全文
摘要:累减是和累加相反的过程#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量void Delay(unsigne
阅读全文
摘要:同理0-9999累加的代码是#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量void Delay(unsi
阅读全文
摘要:实现0-999累加#includesbit LATCH1=P2^2;//段锁存sbit LATCH2=P2^3;//位锁存unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量void Delay(unsigned
阅读全文

浙公网安备 33010602011771号