smokesea 发表于 2012-11-8 00:06:21

Atmega最简系统+8个LED效果闪烁

本帖最后由 smokesea 于 2012-11-8 00:24 编辑

代码就开源吧,本就是给儿子的模型车准备的.代码个人而言还是非常满意的,因为灯的效果是可以随时进行调整和组织的.并且,如果只调整标准效果的话简单调整数组即可.
就算是开发更多的效果需要添加的代码也很少.
这次亲身体验了"ATMega8L最小系统"后,感觉可以玩儿的东西更多了.
关键是太便宜了,哈哈.
视频等审核通过后就放上来,效果很赞的哦.
视频链接http://player.youku.com/player.php/sid/XNDcyMzA3MjA0/v.swf





int ERR = 0;

//所有灯默认关闭
#define ACTION_TYPE_STAND           -1//标准动作 ACTION的影响范围,ACTION的亮度,ACTION持续时间
#define ACTION_TYPE_LOOP        -2//想要重复的ACTION的ID 想要重复的次数,第三个参数意思是当前已经重复了几次 >0表示重复的次数,<=0表示永远循环
#define ACTION_TYPE_ACTION_END-4//每个Action的结束标记
//独立的特效类型
#define ACTION_TYPE_ACTION_ROLLING -5 //跑马灯
#define ACTION_TYPE_ACTION_MID_2_SIDE -6 //从中间向两边点亮
#define ACTION_TYPE_ACTION_SIDE_2_MID -7 //从两边向中间点亮


//定义ACTION的控制范围 >0的就表示单个灯的表现
#define ACTION_ORDER_ALL         -11//所有灯
#define ACTION_ORDER_ODD           -12 //奇数灯
#define ACTION_ORDER_EVEN        -13 //偶数灯

//定义ACTION的类型 >0表示指定亮度
#define ACTION_LIGHT_HIGH-111 //灯亮度最大
#define ACTION_LIGHT_MID   -123 //灯亮度剧中
#define ACTION_LIGHT_LOW   -124 //灯关闭

//定义ACTION的持续时间
#define ACTION_KEEP_LONG200
#define ACTION_KEEP_SHORT100
#define ACTION_KEEP_ZERO   0 //等待为0,只为控制某些灯

//ACTION列表,最多容纳255个action,当action开始play时将每个ACTIONTYPE的索引记录到这里
int action_index = 0;
int action_list;
//ACTION的明细,一行是一组
int action_detail[]={
                //所有灯亮起
                ACTION_TYPE_STAND,ACTION_ORDER_ALL,ACTION_LIGHT_HIGH,ACTION_KEEP_SHORT,ACTION_TYPE_ACTION_END,
                //所有灯降低亮度
                ACTION_TYPE_STAND,ACTION_ORDER_ALL,ACTION_LIGHT_LOW,ACTION_KEEP_SHORT,ACTION_TYPE_ACTION_END,
                //从0开始重复
                ACTION_TYPE_LOOP,0,2,0/*重复了几次*/,ACTION_TYPE_ACTION_END,
               
                //奇数灯高亮
                ACTION_TYPE_STAND,ACTION_ORDER_EVEN,ACTION_LIGHT_LOW,ACTION_KEEP_ZERO,ACTION_TYPE_ACTION_END,
                ACTION_TYPE_STAND,ACTION_ORDER_ODD,ACTION_LIGHT_HIGH,ACTION_KEEP_LONG,ACTION_TYPE_ACTION_END,
               
                //偶数灯高亮
                ACTION_TYPE_STAND,ACTION_ORDER_ODD,ACTION_LIGHT_LOW,ACTION_KEEP_ZERO,ACTION_TYPE_ACTION_END,
                ACTION_TYPE_STAND,ACTION_ORDER_EVEN,ACTION_LIGHT_HIGH,ACTION_KEEP_LONG,ACTION_TYPE_ACTION_END,
                //从2行开始重复
                ACTION_TYPE_LOOP,-4,2,0/*重复了几次*/,ACTION_TYPE_ACTION_END,

                //跑马灯
                ACTION_TYPE_ACTION_ROLLING,4/*循环总次数*/,ACTION_TYPE_ACTION_END,
               
                //从中间向两边点亮
                ACTION_TYPE_ACTION_MID_2_SIDE,ACTION_TYPE_ACTION_END,
                //从两边向两边点亮
                ACTION_TYPE_ACTION_SIDE_2_MID,ACTION_TYPE_ACTION_END,
                //从-2行开始重复
                ACTION_TYPE_LOOP,-2,2,0/*重复了几次*/,ACTION_TYPE_ACTION_END,
                //跑马灯
                ACTION_TYPE_ACTION_ROLLING,2/*循环总次数*/,ACTION_TYPE_ACTION_END,
//奇数灯高亮
                ACTION_TYPE_STAND,ACTION_ORDER_EVEN,ACTION_LIGHT_LOW,ACTION_KEEP_ZERO,ACTION_TYPE_ACTION_END,
                ACTION_TYPE_STAND,ACTION_ORDER_ODD,ACTION_LIGHT_HIGH,ACTION_KEEP_LONG,ACTION_TYPE_ACTION_END,
               
                //偶数灯高亮
                ACTION_TYPE_STAND,ACTION_ORDER_ODD,ACTION_LIGHT_LOW,ACTION_KEEP_ZERO,ACTION_TYPE_ACTION_END,
                ACTION_TYPE_STAND,ACTION_ORDER_EVEN,ACTION_LIGHT_HIGH,ACTION_KEEP_LONG,ACTION_TYPE_ACTION_END,
//从-2行开始重复
                ACTION_TYPE_LOOP,-2,2,0/*重复了几次*/,ACTION_TYPE_ACTION_END,
                //从0开始重复
                ACTION_TYPE_LOOP,0,2,0/*重复了几次*/,ACTION_TYPE_ACTION_END
               
        };



int leds[]={2,3,4,5,6,7,8,9};
int led_count = 8;


int action_detail_index = 0;

int set_led_light(int pin, int light)
{
        if(light > 0)
        {
                return light;
        }
       
        if(light == ACTION_LIGHT_HIGH)
        {
                digitalWrite(pin,HIGH);
        }else if(light = ACTION_LIGHT_LOW)
        {
                digitalWrite(pin,LOW);
        }
}

void action_play()
{
        int ac = sizeof(action_detail)/sizeof(int);
        for(int i = action_detail_index; i < ac; i++)
        {
                if(action_detail == ACTION_TYPE_STAND)
                {
                        parser_action_stand();
                        return ;
                }else if(action_detail == ACTION_TYPE_LOOP)
                {
                        parser_action_loop();
                        return ;
                }else if(action_detail == ACTION_TYPE_ACTION_ROLLING)
                {
                        parser_action_rolling();
                }
                else if(action_detail == ACTION_TYPE_ACTION_MID_2_SIDE)
                {
                        parser_action_mid_2_side();
                }
                else if(action_detail == ACTION_TYPE_ACTION_SIDE_2_MID)
                {
                        parser_action_side_2_mid();
                }
        }
        action_detail_index = 0;
        action_index = 0;
        //全部播放完毕,清除loop类型的计数
        int act_idx = 0;
        for(int i = 0 ; i < 255; i++)
        {
                if(action_list==-1)
                {
                        break;
                }
                act_idx = action_list;
                if(action_detail == ACTION_TYPE_LOOP)
                {
                        action_detail = 0;
                }
        }
}
//解析标准事件
void parser_action_stand()
{
        action_list = action_detail_index;
        int order = action_detail;
        int light = action_detail;
        int _delay = action_detail;
        int end = action_detail;
        if(end != ACTION_TYPE_ACTION_END)
        {
                Serial.print("action_detail_index");
                Serial.println(action_detail_index);
                ERR = 1;
                return ;
        }
        //设置索引
        action_detail_index+=5;
        action_index++;
       
        if(order == ACTION_ORDER_ALL)
        {
                for(int i = 0; i < led_count;i++)
                {
                        set_led_light(leds,light);
                }
               
        }else if(order == ACTION_ORDER_ODD )
        {
                for(int i = 0; i < led_count;i++)
                {
                        if(i%2==1)
                        {
                                set_led_light(leds,light);
                        }
                }
               
        }else if(order == ACTION_ORDER_EVEN)
        {
                for(int i = 0; i < led_count;i++)
                {
                        if(i%2==0)
                        {
                                set_led_light(leds,light);
                        }
                }
        }
        if(delay>0)
        {
                delay(_delay);
        }
}

//解析循环事件
void parser_action_loop()
{
        action_list = action_detail_index;
        int act_idx = action_detail;
        int loop_count = action_detail;
        int count = action_detail;
        int end = action_detail;
        if(end != ACTION_TYPE_ACTION_END)
        {
                ERR = 2;
                return ;
        }
        //永远重复
        if(loop_count <=0)
        {
                action_detail_index=0;
                action_index=0;
                return ;
        }
        count++;
        action_detail=count;
        //当前循环的次数>规定次数了,继续往下走
        if(count > loop_count)
        {
                //设置索引
                action_detail_index+=5;
                action_index++;
        }else
        {
                if(act_idx >= 0)
                {
                        action_index=act_idx;
                }else
                {
                        action_index+=act_idx;
                        if(action_index < 0)
                        {
                                action_detail_index = 0;
                        }
                }
                action_detail_index = action_list;
        }
       
}

//解析跑马灯
void parser_action_rolling()
{
        action_list = action_detail_index;
       
        int loop = action_detail;
        int end = action_detail;
        if(end != ACTION_TYPE_ACTION_END)
        {
                ERR = 3;
                return ;
        }
        for(int i = 0 ; i < led_count;i++)
        {
                set_led_light(leds, ACTION_LIGHT_LOW);
        }
        delay(10);
        //奇数从左向右,偶数从右向左
        for(int l = 0 ; l < loop; l++)
        {
                if(l %2 == 1)
                {
                       
                        for(int i = 0 ; i < led_count ; i++)
                        {
                                set_led_light(leds,ACTION_LIGHT_HIGH);
                               
                                delay(50);
                        }
                        for(int i = 0 ; i < led_count ; i++)
                        {
                                set_led_light(leds,ACTION_LIGHT_LOW);
                                delay(50);
                        }
                }else
                {
                        for(int i = led_count -1 ; i >= 0 ; i--)
                        {
                                set_led_light(leds,ACTION_LIGHT_HIGH);
                                delay(50);
                        }
                        for(int i = led_count - 1 ; i >= 0 ; i--)
                        {
                                set_led_light(leds,ACTION_LIGHT_LOW);
                                delay(50);
                        }
                }
        }
        action_detail_index+=3;
        action_index++;
}

//解析从中间向两边点亮
void parser_action_mid_2_side()
{
        action_list = action_detail_index;
        int _end = action_detail;
        if(_end != ACTION_TYPE_ACTION_END)
        {
                ERR = 4;
                return ;
        }
        for(int i = 0 ; i < led_count;i++)
        {
                set_led_light(leds, ACTION_LIGHT_LOW);
        }
        delay(10);
        //从中间向两边点亮
        int mid = led_count / 2;
        for(int l = 0 ; l < led_count / 2; l++)
        {
                set_led_light(leds, ACTION_LIGHT_HIGH);
                set_led_light(leds , ACTION_LIGHT_HIGH);
                delay(100);
        }
        action_detail_index+=2;
        action_index++;
}

//解析从两边向中间点亮
void parser_action_side_2_mid()
{
        action_list = action_detail_index;
        int _end = action_detail;
        if(_end != ACTION_TYPE_ACTION_END)
        {
                ERR = 5;
                return ;
        }
        for(int i = 0 ; i < led_count;i++)
        {
                set_led_light(leds, ACTION_LIGHT_LOW);
        }
        delay(10);
        //从中间向两边点亮
        int mid = led_count / 2;
        for(int l = 0 ; l < led_count / 2; l++)
        {
                set_led_light(leds , ACTION_LIGHT_HIGH);
                set_led_light(leds , ACTION_LIGHT_HIGH);
                delay(100);
        }
        action_detail_index+=2;
        action_index++;
}


void setup()
{
for(int i = 2 ; i < 10; i++)
{
    pinMode(i,OUTPUT);
    digitalWrite(i,LOW);
}
for(int i = 0 ; i < 255; i++)
{
          action_list=-1;
}
Serial.begin(9600);
}

void loop()
{
        if(ERR != 0)
        {
                delay(1000);
                Serial.print("Error");
                Serial.println(ERR);
                return ;
        }
action_play();
delay(8);
}




小猪会轮滑 发表于 2012-11-8 08:26:07

:funk::funk::funk::funk::funk::funk:线好多

ttyp 发表于 2012-11-8 08:44:43

这次亲身体验了"ATMega8L最小系统"后,感觉可以玩儿的东西更多了.
关键是太便宜了


同感啊,8L的低电压用纽扣电池应该可以带动,可以做很多小型应用:lol

Randy 发表于 2012-11-8 09:19:13

8L的低电压用纽扣电池应该可以带动+1,支持的就是这个!哈哈!

smokesea 发表于 2012-11-8 11:23:32

玩具车是12v的电池盒,找了一个贴片的ASM1117来稳压到5v,焊接的时候可把我整惨了。中午买个焊台去

ttyp 发表于 2012-11-8 12:31:03

smokesea 发表于 2012-11-8 11:23 static/image/common/back.gif
玩具车是12v的电池盒,找了一个贴片的ASM1117来稳压到5v,焊接的时候可把我整惨了。中午买个焊台去

为了个玩具买个焊台:dizzy:是因为静电?

smokesea 发表于 2012-11-8 14:32:10

ttyp 发表于 2012-11-8 12:31 static/image/common/back.gif
为了个玩具买个焊台是因为静电?

是带机械臂的那种,焊小东西太费劲了,没事瞎玩儿呗,就是个业余爱好:D

Malc 发表于 2012-11-8 18:17:39

加点pwm吧

smokesea 发表于 2012-11-8 18:26:36

Malc 发表于 2012-11-8 18:17 static/image/common/back.gif
加点pwm吧

ATMega8只有两个pwm,所以没有使用

Malc 发表于 2012-11-8 18:44:56

smokesea 发表于 2012-11-8 18:26 static/image/common/back.gif
ATMega8只有两个pwm,所以没有使用

软件pwm,要多少有多少

韋編弎絕 发表于 2012-11-8 22:05:01

{:soso_e179:}

smokesea 发表于 2012-11-9 10:06:59

Malc 发表于 2012-11-8 18:44 static/image/common/back.gif
软件pwm,要多少有多少

太慢了,8L有点吃不消

Ansifa 发表于 2012-12-17 00:53:39

{:soso_e136:}代码好长,跑马灯那么长的呢

Ansifa 发表于 2012-12-17 00:54:43

效果不错,哈哈

vp110 发表于 2012-12-21 12:57:22

真心看不懂这个写程序的方式

能告诉我这样的程序是用的什么原理写出来的吗?
页: [1] 2
查看完整版本: Atmega最简系统+8个LED效果闪烁