嵌入式学习--江协51单片机day1
今天学习了led灯的相关操作以及独立按键对于led灯的控制。
led灯的相关操作
led灯的相关操作包括点亮,闪烁,流水灯以及流水灯plus
点亮
开发板的led灯是低电平有效,也就是当我们设置0时亮,1时灭。
P2是开发板的led灯模块的8位接口,在编程是使用两位十六进制表示,记作0x**
例如P2=1111 1110,记作P2=0xFE(注意大小写是有区别的)
这里是对led灯模块的整体操作,对于某个灯的操作为P2_0=0等,对于某个灯就只有一位了
闪烁
开发板运行程序速度极快,所以我们一般将程序放入死循环中,同时对于操作进行delay
#include <REGX52.H>
#include<INTRINS.H>
void Delay500ms() //@12.000MHz
{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){P2=0xFE;Delay500ms();P2=0xFF;Delay500ms();}
}
流水灯以及plus
实现流水灯,就是控制led灯挨个亮即可
#include <REGX52.H>
#include<INTRINS.H>
void Delay500ms() //@12.000MHz
{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){P2=0xFE;//1111 1110Delay500ms();P2=0xFD;//1111 1101Delay500ms();P2=0xFB;//1111 1011Delay500ms();P2=0xF7;//1111 0111Delay500ms();P2=0xEF;//1110 1111Delay500ms();P2=0xDF;//1101 1111Delay500ms();P2=0xBF;//1011 1111Delay500ms();P2=0x7F;//0111 1111Delay500ms();}
}
对于delay函数,我们不能对于不同的时间延迟就创建不同的函数,我们需要传递进参数,这样出现了plus
#include <REGX52.H>
#include<INTRINS.H>
void Delay1ms(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms=xms-1;}}void main()
{while(1){P2=0xFE;//1111 1110Delay1ms(100);P2=0xFD;//1111 1101Delay1ms(100);P2=0xFB;//1111 1011Delay1ms(100);P2=0xF7;//1111 0111Delay1ms(100);P2=0xEF;//1110 1111Delay1ms(100);P2=0xDF;//1101 1111Delay1ms(100);P2=0xBF;//1011 1111Delay1ms(100);P2=0x7F;//0111 1111Delay1ms(100);}}
独立按键对led灯的控制
开发板设置的是k1是P3_0,k2是P3_1不要弄混了
控制led灯的点亮
这里开始对led的某个灯进行操作
#include <REGX52.H>
void main()
{
// P2=0xFE;while(1){if(P3_1==0||P3_0==0){P2_0=0;}else{P2_0=1;}}
}
控制led灯的状态
上述只是控制了led灯的点亮,但是对于led灯的开关,由于金属按钮的震动的特性,我们需要编写特定的程序过滤掉震动,我们采取delay的方式。以后对于独立按键基本就是这样的框架
#include <REGX52.H>
void Delay(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_1==0){Delay(20);while(P3_1==0);//若是依然处于按下的状态就不断循环Delay(20);//已经松开手,改变灯的状态P2_0=~P2_0;}}
}
控制led灯显示二进制
c51中的数据类型与c中的有差别,可以搜一下。
显示二进制显然是对于led这个模块的整体进行操作。是否能对P2直接操作?P2默认是1111 1111
这样是全灭的,无法满足,如果让它自增(当溢出时就变成0000 0000),我们能发现恰好和我们想要的结果相反。那么是否能够通过取反获得结果?实践后发现也不行。
我们可以通过变量来完成操作,注意变量的声明要在主函数的开始就声明(尝试不放在开头会报错)
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}}void main()
{unsigned char LEDNum=0;while(1){if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);//p2 1111 1111//P2++;//溢出变0000 0000LEDNum++;P2=~LEDNum;}}
}
可能有人会疑问,LEDNum超了8位怎么办?其实没有关系,后面八位永远都是0000 0000~1111 1111。
控制led灯移位
还是对led灯模块进行操作。移位是补0,所以我们采用先移位后取反来得到结果。思考得到是对0000 0001进行移位。这里我们实现了k1led灯左移,k2led灯右移。
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}}void main()
{unsigned char LEDNum=0;P2=~0x01;while(1){if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);LEDNum++;if(LEDNum==8)LEDNum=0;P2=~(0x01<<LEDNum);}if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);if(LEDNum==0)LEDNum=7;elseLEDNum--;P2=~(0x01<<LEDNum);}}
}
这就是day1的学习内容,欢迎大家学习和指正