51单片机阶段性测试使单片机所有LED小灯频闪3次,3次后使LED小灯从左向右按照顺序亮起,最后一个LED小灯亮起后所有LED小灯长亮3秒,3秒后往返流水灯三次,三次后所有LED小灯熄灭3秒,3秒后中间两个LED小灯长亮一秒,一秒后从两个长亮的LED小灯向左右两边依次亮起,每亮起一个后面亮起的LED小灯熄灭。完成之前动作后LED小灯从左向右开始亮起,到达最右边后依次返回,所有小灯频闪三次结束。
需要金沙滩51板子的吗
【请采纳,谢谢!】以下是一个简单的程序,可以实现题目描述的功能,假设51单片机的开发环境是Keil C:
#include <reg52.h>
#include <intrins.h>
#define LED_PORT P0
void delay(int ms) {
int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 125; j++) {
_nop_();
}
}
}
void flash_all_leds() {
int i;
for (i = 0; i < 3; i++) {
LED_PORT = 0xff;
delay(500);
LED_PORT = 0x00;
delay(500);
}
}
void light_up_from_left_to_right() {
int i;
for (i = 0; i < 8; i++) {
LED_PORT = ~(0xff << i);
delay(500);
}
delay(3000);
}
void light_up_from_right_to_left() {
int i;
for (i = 7; i >= 0; i--) {
LED_PORT = ~(0xff >> i);
delay(500);
}
delay(3000);
}
void flow_lights() {
int i, j;
for (i = 0; i < 3; i++) {
LED_PORT = 0x81;
for (j = 0; j < 7; j++) {
LED_PORT = (LED_PORT << 1) | 0x01;
delay(100);
}
for (j = 0; j < 7; j++) {
LED_PORT = (LED_PORT >> 1) | 0x80;
delay(100);
}
}
}
void light_up_middle_two() {
LED_PORT = 0x18;
delay(1000);
}
void light_up_from_middle_to_edges() {
int i;
for (i = 1; i < 4; i++) {
LED_PORT = ~(0x18 << i) & ~(0x18 >> i);
delay(200);
LED_PORT = ~(0x18 << i) & ~(0x18 >> i) & ~(0x10 >> i);
delay(200);
}
LED_PORT = 0x00;
}
void main() {
int i;
while (1) {
flash_all_leds();
light_up_from_left_to_right();
light_up_from_right_to_left();
flow_lights();
LED_PORT = 0x00;
delay(3000);
light_up_middle_two();
light_up_from_middle_to_edges();
LED_PORT = 0x00;
delay(3000);
for (i = 0; i < 3; i++) {
light_up_from_left_to_right();
light_up_from_right_to_left();
}
}
}
这段代码使用了单片机的计时器来实现延时功能,使用了位运算来控制LED小灯的亮灭。你可以根据自己的需要对程序进行修改和优化。
以下是一种可能的51单片机程序实现:
#include <reg51.h> // 引入单片机头文件
// 定义控制LED小灯亮灭的函数
void light(int num) {
switch (num) {
case 1: P1 = 0x7F; break; // 0111 1111,第1个灯亮,其余灯灭
case 2: P1 = 0xBF; break; // 1011 1111,第2个灯亮,其余灯灭
case 3: P1 = 0xDF; break; // 1101 1111,第3个灯亮,其余灯灭
case 4: P1 = 0xEF; break; // 1110 1111,第4个灯亮,其余灯灭
case 5: P1 = 0xF7; break; // 1111 0111,第5个灯亮,其余灯灭
case 6: P1 = 0xFB; break; // 1111 1011,第6个灯亮,其余灯灭
case 7: P1 = 0xFD; break; // 1111 1101,第7个灯亮,其余灯灭
case 8: P1 = 0xFE; break; // 1111 1110,第8个灯亮,其余灯灭
default: P1 = 0xFF; break; // 所有灯灭
}
}
// 定义LED小灯频闪的函数
void blink() {
for (int i = 0; i < 3; i++) { // 闪3次
P1 = 0x00; // 所有灯灭
delay(500); // 延时0.5秒
P1 = 0xFF; // 所有灯亮
delay(500); // 延时0.5秒
}
}
// 定义LED小灯从左向右按照顺序亮起的函数
void from_left_to_right() {
for (int i = 1; i <= 8; i++) {
light(i);
delay(500); // 延时0.5秒
}
}
// 定义所有LED小灯长亮的函数
void all_on() {
light(8);
delay(3000); // 延时3秒
}
// 定义往返流水灯的函数
void shuttle() {
for (int i = 0; i < 3; i++) { // 往返3次
for (int j = 1; j <= 7; j++) { // 从左向右流水
light(j);
delay(200); // 延时0.2秒
}
for (int j = 7; j >= 1; j--) { // 从右向左流水
light(j);
delay(200); // 延时0.2秒
}
}
}
// 定义所有LED小灯熄灭的函数
#include <reg52.h> //包含头文件
#include <intrins.h>
//宏定义
#define led P2 //宏定义P2口
//使用typedef关键字
//类型重命名
typedef unsigned char uchar;
typedef unsigned int uint;
//函数声明
void delay(uint i); //延时函数
//主函数
void main()
{
//定义for循环计数变量i
uchar i;
while(1)
{
//利用左移循环函数实现循环点亮led小灯
for(i = 0; i < 8; i++)
{
led = _crol_(0xfe,i); //点亮led小灯
delay(50000); //延迟一会
}
}
}
//函数定义
//延时函数
void delay(uint i)
{
while(i--);
}
操作解析:
需要用到包含在intrins.h的头文件中的循环左移和循环右移函数:
unsigned char _cror_ (unsigned char, unsigned char); //循环左移函数
unsigned char _crol_ (unsigned char, unsigned char); //循环右移函数
其中第一个参数为需要循环左移(或循环右移)的16进制数,第二个参数为需要循环左移(或循环右移)的位数。
循环左移(或循环右移),循环就是相应的高位(或低位)会依次循环补到相应的低位或高位),这样的话,就无需取反,即可达到点亮下一个小灯的操作数。例如:
_cror_(0xfe,1); //即将十六进制0xfe循环左移一位
该过程为:
循环右移刚好与之相反
_crol_(0x7f,1); //即将十六进制0x7f循环右移一位
若一次移位多位的话,根据以上过程举一反三即可。