📄 sl3010_3.c
字号:
/*******************************************/
/* 广州天河双龙电子公司 */
/* http://www.sl.com.cn */
/* 020-85510191,87578852,87578872 */
/* nikko@sl.com.cn */
/*******************************************/
//遥控器没有按键或者 pd3,pd2,pd1,pd0 短路块全部不接上,全为高电平
//机器人运行霓虹灯程序。
//将 pd0 接低电平,pd3,pd2,pd1 保持高电平,只连接pd0的短路块
// 或按下遥控器<A>(保持 0.5s) 进入遥控机器人运行环境
//将 pd1 接低电平,pd3,pd2,pd0 保持高电平,只连接pd1的短路块
// 或按下遥控器<B>(保持 0.5s) 寻迹机器人,探测白底黑线,沿黑线行进
//将 pd2 接低电平,pd3,pd1,pd0 保持高电平,只连接pd2的短路块
// 或按下遥控器<C>(保持 0.5s) 机器人避障碍、避悬崖行进
//将 pd3 接低电平,pd2,pd1,pd0 保持高电平,只连接pd3的短路块
// 或按下遥控器<D>(保持 0.5s) 机器人按程序设定路线行走,走四方形,同时演奏音乐
//程序等待声控起动运行。
//将 sl3010.c 文件拷贝到 icc avr 安装目录的<include>文件夹
//sl3010.c 是sl3010机器人板的子函数库
//程序中调用此文件后 #include <sl3010.c>
//可直接调用里面的函数和变量
#include <io8515v.h>
#include <macros.h>
#include <sl3010.c>
#include <eeprom.h>
#define xuanya_delayms 300
#define cny_delayms 50
#define light_delay 100
/* 音乐数据 */
/* 四分之一拍为0x10, 二分之一拍为0x20, 一拍为0x40*/
/* 低1-1 2-2 3-3 4-4 5-5 6-6 7-7 */
/* 中1-8 2-9 3-A 4-B 5-C 6-D 7-E */
/* 高1-F*/
#pragma data:eeprom
unsigned char sound[]={
//走进新时代
0x68,0x26,0x25,0x23,0x22,0x13,0x12,0x41,0x41,0x41,0x23,0x25,
0x28,0x48,0x28,0x29,0x2a,0x29,0x26,0x45,0x45,0x45,0x45,0x68,
0x29,0x29,0x28,0x26,0x25,0x46,0x46,0x46,0x25,0x26,0x29,0x43,
0x25,0x22,0x23,0x22,0x21,0x42,0x42,0x42,0x42,0x63,0x25,0x26,
0x25,0x26,0x25,0x23,0x22,0x13,0x12,0x41,0x23,0x25,0x28,0x28,
0x28,0x28,0x29,0x2a,0x2a,0x29,0x46,0x46,0x46,0x46,0x46,0x29,
0x2a,0x28,0x28,0x26,0x25,0x26,0x26,0x25,0x43,0x43,0x22,0x42,
0x26,0x25,0x23,0x22,0x13,0x12,0x41,0x41,0x41,0x41,
0x00,0x00
};
#pragma data:data
/* 音阶表 */
const unsigned int TONETABLE[15]={DO,RE,MI,FA,SO,LA,TI,DO_H,
RE_H,MI_H,FA_H,SO_H,LA_H,TI_H,DO_HH};
/* 音阶重装常数 */
unsigned int toneconst;
unsigned int sound_add=0;
unsigned int delay_time1,delay_time2,led_delayms=600;
unsigned char temp,temp1;
unsigned char pa,pb,pc,pd,remote_in,timers,cny_in,cny_times,rst_time,cds,pd_select,remote_select;
unsigned char gzsl,t0_times;
const unsigned char led_data[]=
{//设置LED广告灯数据表
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,
0x00,0x18,0x3c,0x7e,0xff,0x7e,0x3c,0x18,
0x00,0x18,0x3c,0x7e,0xff,0x7e,0x3c,0x18,
0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x8f,0xc7,0xe3,0xf1,
0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x8f,0xc7,0xe3,0xf1,
0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,
0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,
0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,
0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x0a,0x0a
};
//TIMER0 initialisation - prescale:1024
// desired value: 25mSec
// actual value: 24.960mSec (0.2%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop timer
TCNT0 = 0x3D; //set count value
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:8
void timer0_ovf_isr(void)
{
TCNT0 = 0x3D; //reload counter value
t0_times++;
if(gzsl == 0x88)
{
if(t0_times == 10)
{
timers++;
t0_times = 0;
}
}
if(gzsl == 0x11)
{
if(t0_times == delay_time1) //delay_time1*25ms
{
t0_times = 0;
gzsl = 0x22;
forward();
}
}
if(gzsl == 0x22)
{
if(t0_times == delay_time2) //delay_time2*25ms
{
t0_times = 0;
gzsl = 0x11;
turn_right();
}
}
}
void stop_timer0()
{
CLI();
TCCR0 = 0x00;//停止timer0
MCUCR = 0x00;
GIMSK = 0x00;
TIMSK = 0x00;
SEI();
}
/*******************************************/
/* 电子音乐演示程序 */
/*******************************************/
//使用说明:音乐输出端口:PORTC.0,音乐数据存放
//于AT90S8515 的EEPROM存贮器中。
// 可以用并口下载软件写入新的音乐文件
//PA口为音乐灯,当不同的音乐节奏,点亮不同的灯。
#pragma interrupt_handler timer1_ovf_isr:iv_TIMER1_OVF
void timer1_ovf_isr(void)
{
TCNT1=toneconst;
PORTC^=1;
}
void music_car(void)
{
TCCR1A = 0x00;
TCCR1B =(1<<CS11);//8分频
temp1=EEPROMread((int)&sound[sound_add]);
while(temp1!=0)
{
temp=temp1;
temp&=0x0f;
/*
//PA口为音乐灯
if(temp==1 || temp==2 || temp==3 || temp==4){PORTA = 0xfe;}
if(temp==5 || temp==6){PORTA = 0xfc;}
if(temp==7 || temp==8 ){PORTA = 0xf8;}
if(temp==9){PORTA = 0xf0;}
if(temp==10){PORTA = 0xe0;}
if(temp==11){PORTA = 0xc0;}
if(temp==12){PORTA = 0x80;}
if(temp==13 || temp==14 || temp==15){PORTA = 0x00;}
*/
if(temp!=0)
{
TIMSK|=(1<<TOIE1);//根据SOUNDTABLE中数据的低四位选择音调频率
temp--;
toneconst=TONETABLE[temp];
TCNT1=toneconst;
}
temp=temp1;
temp>>=4;
temp&=0x0f;
delay_ms(temp*129);//根据SOUNDTABLE中数据的高四位*5后,为音调持续时间
TIMSK&=~(1<<TOIE1);
sound_add++;
temp1=EEPROMread((int)&sound[sound_add]);
}
delay_ms(1000);
}
// 电机驱动信号 led灯指示电机状态
//PORTD = 0xA0;//前行//1010 0000 //PORTA = 0xC3;//1100,0011
//PORTD = 0x90;//左转//1001 0000快速左转//PORTA = 0x33;//0011,0011
//PORTD = 0x80;//左转//1000 0000慢速左转//PORTA = 0xF3;//1111,0011
//PORTD = 0x60;//右转//0110 0000快速右转//PORTA = 0xCC;//1100,1100
//PORTD = 0x20;//右转//0010 0000慢速右转//PORTA = 0xCF;//1100,1111
//PORTD = 0x50;//后退//0101 0000 //PORTA = 0x3C;//0011,1100
//PC3声控启动
// 用PD7~PD4来作为电机驱动端
void xuanya_car(void)
{
PORTA = 0xa5;//1010,0101
work_status = 0x20;//置对应的工作状态标志
mic_startup(); //等待声控启动
while(1)
{//左(pc7) 中(pc6) 右(pc5)
sw_touch(); //检测轻触开关
pc = PINC & 0x10;
if(pc == 0x00)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
pc = PINC & 0xE0;
if(pc == 0x40)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
if(pc == 0x80)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
if(pc == 0x20)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
if(pc == 0xc0)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
if(pc == 0x60)
{//后退//左转
backward();//后退
delay_ms(xuanya_delayms);
turn_right();//左转
delay_ms(xuanya_delayms/2);
}
if(pc == 0xE0)
{
//刹车 //led灯为流水灯
stop();
PORTA = 0x3C;
delay_ms(xuanya_delayms);
PORTA = 0xC3;
delay_ms(xuanya_delayms);
}
else
{
forward();//前行
}
}
}
void remote_car()
{//遥控车程序
port_init();//调用端口初始化函数
work_status = 0x60;//置对应的工作状态标志
remote_rst:
PORTA = 0x0F;
mic_startup();//等待声控启动函数
while(1)
{
sw_touch();//检测轻触开关
remote_in = PINB & 0x0F;
switch (remote_in)
{//检测遥控器是否有键按下
case 0x00:
forward(); //前行
rst_time=0;
break;
case 0x04: // < A >
turn_right(); //右转
rst_time=0;
break;
case 0x02: // < B >
backward(); //后退
rst_time=0;
break;
case 0x08: // < C >
stop(); //停止运动
rst_time++;
break;
case 0x01: // < D >
turn_left(); //左转
rst_time=0;
break;
}
delay_ms(200);
if(rst_time == 50)
{//当按住< C > 键的持续时间超过10S,遥控机器人复位,等待声控重起运行
rst_time=0;
goto remote_rst;
}
}
}
//自走车 机器人走四方形路线,遥控器调节行走路线
void auto_car()
{
port_init();//PA,PB,PC,PD 初始化
work_status = 0x51;//置对应的工作状态标志
PORTA = 0x44;//0100,0100
delay_time1=22; //转弯时间 22*25ms = 550ms
delay_time2=48; //前行时间 48*25ms = 1200ms
mic_startup();//等待声控启动
gzsl=0x11;t0_times=0;
CLI(); //disable all interrupts
timer0_init();
MCUCR = 0x00;
GIMSK = 0x00;
TIMSK|=(1<<TOIE0);
SEI(); //re-enable interrupts
forward(); //前行
delay_ms(200);
while(1)
{
music_car();
}
}
//cny_car 探测白底黑线,沿着黑线运动
void cny_car()
{
port_init(); //PA,PB,PC,PD 初始化
PORTA = 0xc3; //1100,0011
cny_car_start:
mic_startup(); //等待声控启动
while(1)
{
sw_touch();
cny_in = PINC & 0xe0;
if(cny_in == 0x00 || cny_in == 0x40 || cny_in == 0xa0)
{//前行
forward(); //前行
cny_times = 0x00;
}
if(cny_in == 0x20 || cny_in == 0x60)
{//慢速右转
turn_right_s(); //慢速右转
delay_ms(cny_delayms);
cny_times = 0x00;
}
if(cny_in == 0x80 || cny_in == 0xc0)
{//慢速左转
turn_left_s(); //慢速左转
delay_ms(cny_delayms);
cny_times = 0x00;
}
if(cny_in == 0xe0)
{//前行--探测多次都为 0xe0 ,停止运行
forward();
cny_times++;
delay_ms(10);
if(cny_times == 0x64)
{
stop(); //停止运动//熄灭指示灯
goto cny_car_start;
}
}
}
}
void main()
{
port_init(); //PA,PB,PC,PD 初始化
work_status = 0x67; //置对应的工作状态标志
gzsl=0x88;timers=0;
PORTA = 0x7e;
CLI(); //disable all interrupts
timer0_init();
MCUCR = 0x00;
GIMSK = 0x00;
TIMSK|=(1<<TOIE0);
SEI(); //re-enable interrupts
while(1)
{
gzsl=0x88;
pa = led_data[timers];
if(pa==0x0a){timers=0;}
PORTA = pa;
/******************************************************/
pd_select = PIND & 0x01;
if(pd_select == 0x00)//pd0=0,其它为高电平
{
while(1)
{
delay_ms(500);//消除抖动
pd_select = PIND & 0x0f;
if(pd_select == 0x0e)//pd0=0,其它为高电平
{
stop_timer0();
remote_car();//运行遥控车程序
}
else
break;
}
}
pd_select = PIND & 0x02;
if(pd_select == 0x00)//pd1=0,其它为高电平
{
while(1)
{
delay_ms(500);//消除抖动
pd_select = PIND & 0x0f;
if(pd_select == 0x0d)//pd1=0,其它为高电平
{
stop_timer0();
cny_car();//寻迹机器人,探测白底黑线,沿黑线行进
}
else
break;
}
}
pd_select = PIND & 0x04;
if(pd_select == 0x00)//pd2=0,其它为高电平
{
while(1)
{
delay_ms(500);//消除抖动
pd_select = PIND & 0x0f;
if(pd_select == 0x0b)//pd2=0,其它为高电平
{
stop_timer0();
xuanya_car();//机器人避障碍、避悬崖行进
}
else
break;
}
}
pd_select = PIND & 0x08;
if(pd_select == 0x00)//pd3=0,其它为高电平
{
while(1)
{
delay_ms(500);//消除抖动
pd_select = PIND & 0x0f;
if(pd_select == 0x07)//pd3=0,其它为高电平
{
stop_timer0();
auto_car(); //机器人按程序设定路线行走
}
else
break;
}
}
/********************************************************/
remote_select = PINB & 0x0f;//检测遥控器是否有键按下
if(remote_select == 0x04)// A
{
while(1)
{
delay_ms(500);//消除抖动
remote_select = PINB & 0x0f;
if(remote_select == 0x04)// A
{
stop_timer0();
remote_car();//运行遥控车程序
}
else
break;
}
}
if(remote_select == 0x02)// B
{
while(1)
{
delay_ms(500);//消除抖动
remote_select = PINB & 0x0f;
if(remote_select == 0x02)// B
{
stop_timer0();
cny_car();//寻迹机器人,探测白底黑线,沿黑线行进
}
else
break;
}
}
if(remote_select == 0x08)// C
{
while(1)
{
delay_ms(500);//消除抖动
remote_select = PINB & 0x0f;
if(remote_select == 0x08)// C
{
stop_timer0();
xuanya_car();//机器人避障碍、避悬崖行进
}
else
break;
}
}
if(remote_select == 0x01)// D
{
while(1)
{
delay_ms(500);//消除抖动
remote_select = PINB & 0x0f;
if(remote_select == 0x01)// D
{
stop_timer0();
auto_car();//机器人按程序设定路线行走
}
else
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -