单片机彩灯移动实验_学习单片机技术怎样才算入门

我在学习单片机时,刚入门编写程序的课程就是控制流水灯,流水灯之所以被我们广泛的学习是因为流水灯的实例在我们日常生活中随处可见,便于引起我们学习者的兴趣。比如流水彩灯、彩色灯条、圣诞树彩灯、渐亮渐灭呼吸灯、水滴流水灯等等。毫不夸张的说如果我们初学单片机编程的小伙伴,能够熟练的控制这些流水灯的发光样式,那么你的单片机技术就已经入门了,也就是说你已经学会了80%的单片机技术。为了帮助刚学单片机的小伙伴们进一步掌握流水灯的控制方法,下面给出三个实例供大家参考。

实例一:左右循环移动流水灯

07ca05dbf50910655da9568a97923291.png

控制流水灯效果图

ef6359ba669af1bb5e7502b7f8fe627f.png

电路原理图

8d7f5993a9d04748f87bc3d042d71066.png

电路仿真图

#include

#define uchar unsigned char

#define uint unsigned int

#define LED P2 //8个LED接口

uchar code led_mod_1[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //LED从左到右点亮

uchar code led_mod_2[8] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //LED从右到左点亮

void delay_ms(uint n) //延时函数,单位时间为1ms左右

{

uint i;

uchar j;

for(i=0;i

for(j=0;j<110;j++);

}

void led_display(uchar *led_mod) //向LED接口输出8种状态

{

uchar i;

for(i=0;i<8;i++)

{

LED = *(led_mod+i); //指针指向地址

delay_ms(700);

}

}

void main( )//主函数

{

while(1)

{

led_display(led_mod_1); //将led_mod_1数组的每个数据输到LED接口上

led_display(led_mod_2); //将led_mod_2数组的每个数据输到LED接口上

}

}

实例二:多花样流水灯程序的编写

8374b7c50f4437583f06276e192e35c4.png

亮灯效果

1a82d1982a6cae0772e838ebe0a392fe.png

电路原理图

99f2ae96f1275ab9c1427ec2cb341443.png

电路仿真图

#include

#define uchar unsigned char

#define uint unsigned int

#define LED P2 //8个LED接口

#define KEY P1 //按键接口

sbit INDICATOR = P3^3; //指示灯接口

uchar code led_mod_1[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //LED从左到右点亮

uchar code led_mod_2[8] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //LED从右到左点亮

uchar code led_mod_3[8] = {0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; //从左到右依次点亮

uchar code led_mod_4[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; //从右到左依次点亮

uchar code led_mod_5[4] = {0xe7,0xc3,0x81,0x00}; //中间两个向傍边点亮

bit led_mod_select; //LED流水灯模式切换标志,0:手动切换:1:自动切换

uchar time = 50; //计时时间,计时time*10ms

uchar mod_count = 0; //模式计数

uchar output_count = 0; //状态输到LED接口计数

void delay_ms(uint n) //延时函数,单位时间为1ms左右

{

uint i;

uchar j;

for(i=0;i

for(j=0;j<110;j++);

}

void led_output(uchar *led_out,uchar num,uchar *num_count,uchar *led_mod) //向LED接口输出8种状态

{

LED = *(led_out+*num_count);

(*num_count)++;

if(*num_count>=num)

{

*num_count = 0;

if(led_mod_select) //自动切换模式

{

(*led_mod)++; //切换到下一个模式

}

}

}

uchar key_scan() //按键扫描

{

uchar key_val;

KEY = 0xff;

if((KEY&0x07)!=0x07)

{

KEY = 0xff;

delay_ms(10); //按键消抖

if((KEY&0x07)!=0x07)

{

key_val = KEY;

key_val = key_val&0x07; //按键只接低3位I/O口,需要屏蔽高5位I/O口

while((KEY&0x07)!=0x07) //按键是否释放

KEY = 0xff;

return key_val;

//返回按键值

}

}

return 0; //无按键按下

}

void key_function() //按键功能(三个按键功能)

{

uchar val;

val = key_scan();

switch(val)

{

case 0x06:

if(led_mod_select==0)

{

mod_count --;

output_count = 0;

}

break;

case 0x05:

if(led_mod_select==0)

{

mod_count ++;

output_count = 0;

}

break;

case 0x03:

led_mod_select = ~led_mod_select; //选择手动/自动模式

INDICATOR = led_mod_select;

output_count = 0;

mod_count = 0;

break;

default:break;

}

}

void main_init() //初始化

{

led_mod_select = 1; //LED流水灯自动切换

TMOD = 0x01; //初始化定时器寄存器

TH0 = (0xffff-10000)/256; //10ms的计时值初值

TL0 = (0xffff-10000)%256;

IE = 0x82;

TR0 = 1; //进定时器中断

}

void main() //主函数

{

main_init();

while(1)

{

key_function();

}

}

void led_display() interrupt 1

{

static uchar time_count = 0; //时间计数,单位时间为10ms

TH0 = (0xffff-10000)/256; //重装10ms的计时值

TL0 = (0xffff-10000)%256;

time_count++;

if(time_count>=time)

{

time_count = 0;

switch(mod_count)

{

case 0: led_output(led_mod_1,8,&output_count,&mod_count); break;

case 1: led_output(led_mod_2,8,&output_count,&mod_count); break;

case 2: led_output(led_mod_3,8,&output_count,&mod_count); break;

case 3: led_output(led_mod_4,8,&output_count,&mod_count); break;

case 4: led_output(led_mod_5,4,&output_count,&mod_count); break;

default: mod_count = 0; break;

}

}

实例三:按键可控流水灯的控制

831459b5a6b398d35a1637c6cc1f90f8.png

通过按键控制流水灯亮灯方式

7694923ec4e79da437d3a9a95beb3a39.png

电路原理图

1fe25f93eb938bdcd433f42c04103593.png

仿真图

#include

#define uchar unsigned char

#define uint unsigned int

#define LED P0 //8个LED接口

#define KEY P1 //按键接口

sbit INDICATOR = P3^3; //指示灯接口

uchar code led_mod_1[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //LED从左到右点亮

uchar code led_mod_2[8] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //LED从右到左点亮

uchar code led_mod_3[8] = {0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; //从左到右依次点亮

uchar code led_mod_4[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; //从右到左依次点亮

uchar code led_mod_5[4] = {0xe7,0xc3,0x81,0x00}; //中间两个向傍边点亮

//uchar code led_mod_6[8] = {}; //产生堆积的效果

bit led_mod_select; //LED流水灯模式切换标志,0:手动切换:1:自动切换

uchar time = 50; //计时时间,计时time*10ms

uchar mod_count = 0; //模式计数

uchar output_count = 0; //状态输到LED接口计数

bit stop; //停止/运行标志,0:运行;1:停止

bit suspend; //暂停/继续标志,0:继续;1:暂停

void delay_ms(uint n) //延时函数,单位时间为1ms左右

{

uint i;

uchar j;

for(i=0;i

for(j=0;j<110;j++);

}

void led_output(uchar *led_out,uchar num,uchar *num_count,uchar *led_mod) //向LED接口输出8种状态

{

LED = *(led_out+*num_count);

(*num_count)++;

if(*num_count>=num)

{

*num_count = 0;

if(led_mod_select) //自动切换模式

{

(*led_mod)++; //切换到下一个模式

}

}

}

uchar key_scan( )//按键扫描

{

uchar key_val;

KEY = 0xff;

if(KEY!=0xff)

{

KEY = 0xff;

delay_ms(10); //按键消抖

if(KEY!=0xff)

{

key_val = KEY;

key_val = key_val&0x07; //按键只接低3位I/O口,需要屏蔽高5位I/O口

while(KEY!=0xff) //按键是否释放

KEY = 0xff;

return key_val;//返回按键值

}

}

return 0; //无按键按下

}

void key_function() //按键功能

{

uchar val;

val = key_scan();

switch(val)

{

case 0xfe: //上一个模式

if((0==stop)&&(0==suspend)) //处于运行和继续的状态

{

if(led_mod_select==0)

{

mod_count --;

output_count = 0;

}

}

break;

case 0xfd: //下一个模式

if((0==stop)&&(0==suspend))

{

if(led_mod_select==0)

{

mod_count ++;

output_count = 0;

}

}

break;

case 0xfb: //模式切换

if((0==stop)&&(0==suspend))

{

led_mod_select = ~led_mod_select;

INDICATOR = led_mod_select;

output_count = 0;

mod_count = 0;

}

break;

case 0xf7: //时间加

if((0==stop)&&(0==suspend))

{

time = time+10;

if(time>=100)

{

time = 100;

}

}

break;

case 0xef: //时间减

if((0==stop)&&(0==suspend))

{

if(time<10)

{

time = 10;

}

time = time-10;

}

break;

case 0xdf: //暂停/继续

if(0==stop)

{

suspend = ~suspend;

if(suspend)

{

TR0 = 0;

}

else

{

TR0 = 1;

}

}

break;

case 0xbf: //停止/开始

stop = ~stop;

if(stop)

{

TR0 = 0; //定时器停止计数

LED = 0xff; //初始化变量

led_mod_select = 1;

suspend = 0;

INDICATOR = led_mod_select;

led_mod_select = 1; //LED流水灯自动切换

time = 50; //计时时间,计时time*10ms

mod_count = 0; //模式计数从0开始

output_count = 0; //数组的第一个状态

}

else

{

TR0 = 1; //定时器开始计数

}

break;

case 0x7f:

break;

default:break;

}

}

void main_init() //主函数初始化

{

led_mod_select = 1; //LED流水灯自动切换

TMOD = 0x01; //初始化定时器寄存器

TH0 = (0xffff-10000)/256; //10ms的计时值初值

TL0 = (0xffff-10000)%256;

IE = 0x82;

TR0 = 1;

}

void main() //主函数

{

main_init();

while(1)

{

key_function();

}

}

void led_display() interrupt 1

{

static uchar time_count = 0; //时间计数,单位时间为10ms

TH0 = (0xffff-10000)/256; //重装10ms的计时值

TL0 = (0xffff-10000)%256;

time_count++;

if(time_count>=time)

{

time_count = 0;

switch(mod_count)

{

case 0: led_output(led_mod_1,8,&output_count,&mod_count); break;

case 1: led_output(led_mod_2,8,&output_count,&mod_count); break;

case 2: led_output(led_mod_3,8,&output_count,&mod_count); break;

case 3: led_output(led_mod_4,8,&output_count,&mod_count); break;

case 4: led_output(led_mod_5,4,&output_count,&mod_count); break;

default: mod_count = 0; break;

}

}

}

以上仅举例了三种流水灯的编写方法,希望能对刚学单片机的小伙伴们有所帮助。我们学习单片机技术就是要通过实践才能对电路知识有更深的理解,对电路参数的计算才能有新的认识。在程序的编写上提高了我们程序块之间的连接能力。在软件方面熟悉了编程软件Keilc51、单片机仿真软件P roteus的使用,提高了我们软件的编写,调试能力。

喜欢的话欢迎转载、有问题可以留言互动!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值