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);
}
:funk::funk::funk::funk::funk::funk:线好多 这次亲身体验了"ATMega8L最小系统"后,感觉可以玩儿的东西更多了.
关键是太便宜了
同感啊,8L的低电压用纽扣电池应该可以带动,可以做很多小型应用:lol 8L的低电压用纽扣电池应该可以带动+1,支持的就是这个!哈哈! 玩具车是12v的电池盒,找了一个贴片的ASM1117来稳压到5v,焊接的时候可把我整惨了。中午买个焊台去 smokesea 发表于 2012-11-8 11:23 static/image/common/back.gif
玩具车是12v的电池盒,找了一个贴片的ASM1117来稳压到5v,焊接的时候可把我整惨了。中午买个焊台去
为了个玩具买个焊台:dizzy:是因为静电? ttyp 发表于 2012-11-8 12:31 static/image/common/back.gif
为了个玩具买个焊台是因为静电?
是带机械臂的那种,焊小东西太费劲了,没事瞎玩儿呗,就是个业余爱好:D 加点pwm吧 Malc 发表于 2012-11-8 18:17 static/image/common/back.gif
加点pwm吧
ATMega8只有两个pwm,所以没有使用 smokesea 发表于 2012-11-8 18:26 static/image/common/back.gif
ATMega8只有两个pwm,所以没有使用
软件pwm,要多少有多少 {:soso_e179:} Malc 发表于 2012-11-8 18:44 static/image/common/back.gif
软件pwm,要多少有多少
太慢了,8L有点吃不消 {:soso_e136:}代码好长,跑马灯那么长的呢 效果不错,哈哈 真心看不懂这个写程序的方式
能告诉我这样的程序是用的什么原理写出来的吗?
页:
[1]
2