企业网站内页,哪个厂家的logo品牌设计,移动端显卡天梯图2024,云霄城乡建设局网站目录 1.独立按键介绍
2.独立按键控制LED亮灭
1.1按下时LED亮#xff0c;松手LED灭#xff08;按一次执行亮灭#xff09; 1.2首先按下时无操作#xff0c;松手时LED亮#xff08;再按下无操作#xff0c;所以LED亮#xff09;#xff0c;松手LED灭#xff08;松手时…目录 1.独立按键介绍
2.独立按键控制LED亮灭
1.1按下时LED亮松手LED灭按一次执行亮灭 1.2首先按下时无操作松手时LED亮再按下无操作所以LED亮松手LED灭松手时执行取反操作按两次执行亮灭 1.3.独立按键控制LED按二进制递增亮 1.4.两个独立按键控制LED移位左移右移
1.5一个独立按键控制流水灯方向
方法一一个代码编程所有
方法2模块化编程 1.独立按键介绍 独立按键的原理图 所有单片机I/O口上电时都是默认高电平独立按键没有按下就是高电平按下时外部接地时强下拉与地相接I/O就会变为低电平,这里讲一下什么是I/O口I/O口也叫input/output口输入输出口cpu可以给寄存器写值比如上一节LED灯CPU写值给寄存器,由于单片机内部是弱上拉所以要加驱动器加强电流最后连接到I/O口寄存器通过数据总线把值给I/O口此时I/O口就是output,input刚好就是相反的操作比如I/O口读取外部信息把值给寄存器CPU再识别寄存器的值 讲一下编程的命名问题前面我们讲了sbit对单个I/O口命名就像一个人一样要有名字不过称呼一个人是不是也可以取外号啊C51编程就给了这样的命名规则
#include REGX52.H这个函数就相当于父母一样里面对I/O口八位或单个I/O都命名了 我们用单个I/O口就直接用P0_0,P0_0就像父母给的名字一样但是也可以外号称呼sbit LEDP2^0,此时LED就是外号LED和P2_0都可以指向P2^0口看成一个人
记住sbit LEDP2_0;是错的把名字给外号显然不是喊你P2^10;也是错的赋值就像别人要称呼你称呼你喊你的名字肯定不是叫哎这个人吧 延时消抖 主要原因还是单片机运算速度太快了us级别这些抖动他是可以识别出来的 比如上面这个图你按一下由于有抖动出现高-低--高--低--高--低...这样的话单片机会误以为你按了5/6下 实际上你就按了一下所以这样的操作就会与人们期望的不符所以我们延时一段时间来消除抖动按下与松手都加个延时当然也可以加一个电路消抖动有点麻烦
2.独立按键控制LED亮灭
1.1按下时LED亮松手LED灭按一次执行亮灭
最终代码如下
#include REGX52.H
sbit LEDP2^0;
void Delay1ms(unsigned int xms) //12.000MHz
{unsigned char i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}void main()
{while(1){if(P3_10)//按下{Delay1ms(20);//消抖真正的按下P2_00;}else//松手{Delay1ms(20);LED0;}}
}1.2首先按下时无操作松手时LED亮再按下无操作所以LED亮松手LED灭松手时执行取反操作按两次执行亮灭 代码如下
#include REGX52.H
sbit LEDP2^0;
void Delay1ms(unsigned int xms) //12.000MHz
{unsigned char i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}void main()
{while(1){if(P3_10){Delay1ms(20);//消抖确定按下}else{Delay1ms(20);//消抖确定松手LED~LED;while(P3_11);}}
}这段代码的现象是没有按之前LED从1变为0LED亮 如果没有按独立按键LED就一直亮按下独立按键没有任何反应松手LED从0变为1LED灭一直是灭的状态假如没有while(P3_11);这句现象是LED一直在闪烁无论按不按都是闪烁为什么呢P3_1默认为高电平一上电我们没有按开关执行else语句LED~LED10101010.......延迟20ms的闪烁按了就是多了延迟只是增加了闪烁时间不同而已有了这句话之后松手的话死循环一直不执行保持着了LED的状态而不要让他一直变
最后按一下松手执行下面操作
亮----灭-----亮------灭.....
当然下面代码可以执行下面现象.
灭-----亮------灭.....亮........
void main()
{while(1){if(P3_10){Delay1ms(20);while(P3_10);Delay1ms(20);LED~LED;}}
}
没有按下不执行任何操作保持原有状态 按下时一直按着的话就什么都不操作执行while语句一旦松手跳出while语句LED取反再跳出if语句 1.3.独立按键控制LED按二进制递增亮 引入中间变量LEDNum,为什么呢因为P2 ,上电默认是不是1111 1111加1变为0000 0000全部亮加一0000 0001刚好与我们的预想的相反而P2取反就会1111 1111变为0000 0000取反you变为1111 1111无法达到我们的效果而引入中间变量LEDNum,LEDNum把值存起来再给P2赋值就完美的解决了这一点比如char类型刚好一个字节存8位
按下一次按键后LEDNum从0000 0000加加后变为0000 0001取反1111 1110给P2口刚好第一个灯亮而且LEDNum的值不会因为赋给P2而变成P2的值还是 0000 0001加一0000 0010 取反 1111 1101 给P2,刚好点亮第二个灯依次循环实现了用灯表示二进制
#include REGX52.Hvoid Delay(unsigned int xms)
{unsigned char i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}void main()
{unsigned char LEDNum0; while(1){if(P3_10){Delay(20);while(P3_10);Delay(20);LEDNum;P2~ LEDNum;}}
} 1.4.两个独立按键控制LED移位左移右移 方法一
0000 0001 0x010
0000 0010 0x011
0000 0100 0x012
0000 1000 0x013
..............
0 1 2 3 4定义为LEDNum,每按一下加一加到7LEDNum回到0加个if语句。ifLEDNum8),LEDNum0,因为LEDNum7时,继续执行i,
P2口应该与上面写的是反的再取反操作。
代码如下
#include REGX52.Hunsigned char LEDNum;void Delay(unsigned int xms)
{unsigned char i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}void main()
{while(1){if(P3_10){Delay(20);while(P3_10);Delay(20);if(LEDNum8) LEDNum0;P2~(0x01LEDNum);LEDNum;}if(P3_00)//??????{Delay(20);while(P3_00);Delay(20);if(LEDNum0)//???????LEDNum7;elseLEDNum--;P2~(0x01LEDNum);}}
}
注意:LEDNum是无符号型最大值 255LEDNum--的话减到0再减一的话变成255这就是越界。所以减到0我们重新让他变为7
方法二 每按一次独立按键P2的数值变化如下
P2: 1111 1111 上电时, 我们用左移操作时最低位是不是补0我们在或上0x01,补成1 1111 1110 按一次按键 P2左移1位 ,此时P21111 1110 1111 1101 按两次按键 P2左移1位后或上0000 0001 1111 1011 按三次按键 P2左移1位后或上0000 0001 ...............
#include REGX52.H
void Delay(unsigned int xms)
{unsigned char i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}void main()
{ P20xFE;while(1){if(P3_10){Delay(20);while(P3_10);Delay(20);P2P21|0x01;if(P20xFF){P20xFE;}}if(P3_00){Delay(20);while(P3_00);Delay(20);P2P21|0x80;if(P20xFF){P20x7F;}}}
}
1.5一个独立按键控制流水灯方向 代码如下
方法一一个代码编程所有
#include REGX52.H
#include INTRINS.H //导入头文件
unsigned char LEDNum;
unsigned int count;
void Delay1ms(unsigned int xms) //11.0592MHz //延时函数
{unsigned char i, j;while (xms--){i 2;j 199;do{while (--j);} while (--i);}
}void main()
{while(1){if(P3_10){Delay1ms(20);while(P3_10);Delay1ms(20); //软件消抖P20xFE;Delay1ms(500);LEDNum 0xFE;while(1){while(count 0) //当count为0时进入此循环{LEDNum _crol_(LEDNum,1);P2 LEDNum;Delay1ms(500);//1if(P3_10){Delay1ms(20);while(P3_10);Delay1ms(20);count 1; //再次按下K1改变count值使进入逻辑右移}}while(count 1) //当count为1时进入此循环{LEDNum _cror_(LEDNum,1);P2 LEDNum;Delay1ms(500);if(P3_10){Delay1ms(20);while(P3_10);Delay1ms(20);count 0; //再次按下K1改变count值使进入逻辑左移}}} }}
}
方法2模块化编程
后面我们专门写一期怎么模块化编程下面针对这个题进行一次模块化编程涉及内容有中断定时器后面所以讲到了会一一再解释这里的所有代码的具体含义。
main.c
#include REGX52.H
#include Timer0.h
#include Key.h
#include INTRINS.Hunsigned char KeyNum,LEDMode;void main()
{P20xFE;Timer0Init();while(1){KeyNumKey(); //获取独立按键键码if(KeyNum!0) //如果按键按下{//if(KeyNum1) //如果K1按键按下//{LEDMode; //模式切换if(LEDMode2)LEDMode0;//}}}
}void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值T0Count; //T0Count计次对中断频率进行分频if(T0Count500)//分频500次500ms{T0Count0;if(LEDMode0) //模式判断P2_crol_(P2,1); //LED输出 //_crol_循环左移if(LEDMode1)P2_cror_(P2,1);//_cror_循环右移}
}
Timer0.c
#include REGX52.H/*** brief 定时器0初始化1毫秒12.000MHz* param 无* retval 无*/
void Timer0Init(void)
{TMOD 0xF0; //设置定时器模式TMOD | 0x01; //设置定时器模式TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值TF0 0; //清除TF0标志TR0 1; //定时器0开始计时ET01;EA1;PT00;
}/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值T0Count;if(T0Count1000){T0Count0;}
}
*/
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__void Timer0Init(void);#endif
Key.c
#include REGX52.H
#include Delay.h/*** brief 获取独立按键键码* param 无* retval 按下按键的键码范围0~4无按键按下时返回值为0*/
unsigned char Key()
{unsigned char KeyNumber0;if(P3_10){Delay(20);while(P3_10);Delay(20);KeyNumber1;}if(P3_00){Delay(20);while(P3_00);Delay(20);KeyNumber2;}if(P3_20){Delay(20);while(P3_20);Delay(20);KeyNumber3;}if(P3_30){Delay(20);while(P3_30);Delay(20);KeyNumber4;}return KeyNumber;
}
Key.h
#ifndef __KEY_H__
#define __KEY_H__unsigned char Key();#endif
Delay.c
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i 2;j 239;do{while (--j);} while (--i);}
}
Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__void Delay(unsigned int xms);#endif