⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camel.c

📁 一个出口非洲的骑骆驼机器人的控制程序。采用工业手机模块作为通讯模块;AVR单片机作为控制中心;工业用马达作为骆驼机器人驱动动力。通过控制中心通过AT指令集连接通讯模块
💻 C
📖 第 1 页 / 共 2 页
字号:
//ICC-AVR application builder : 2008-8-15 14:27:08
// Target : M16
// Crystal: 12.0000Mhz
//

/*=============================================================================================================================================================================================================
20080815WB	建立一个骆驼机器人骑手程序
20080815CNL	修改了王斌的程序。
20080815_1CNL	去掉了密码模块
20080815_3CNL	能够正常编译的程序
20081017_1CNL  	修改程序为GSM模块的程序。


=================================================================================================================================================================================================*/
#define vuchar volatile unsigned char 
#define vuint volatile unsigned int 
#define uchar unsigned char 
#define uint unsigned int 

#include <avr/io.h>
#include <avr/interrupt.h>
#define clear_interrupt()		cli() 	//禁止所有中断b
#define set_interrupt()			sei()	//开全局中断

vuchar uartTemp;


#define statusLedOn()		(PORTC &= ~(1<<4))
#define statusLedOff()		(PORTC |= (1<<4)) 

//按键输入端口利用PA口的PA3-PA6口,PA3口最为低位,PA6口为高位
#define keyPress()	((PIND&0x10)==0x10)
uchar keyLevel=0;		//按键控制信号断口电平标记
uchar KeyFlag=0;		 //按键按下标志位
uchar KeyNum=0;			//按下的按键编号

//#define key0() 	((PINC&0X0F)==0x00)
#define key1() 	((PINC&0X0F)==0x01)
#define key2() 	((PINC&0X0F)==0x02)
#define key3() 	((PINC&0X0F)==0x03)
#define key4() 	((PINC&0X0F)==0x04)
#define key5() 	((PINC&0X0F)==0x05)
#define key6() 	((PINC&0X0F)==0x06)
#define key7() 	((PINC&0X0F)==0x07)
#define key8() 	((PINC&0X0F)==0x08)
#define key9() 	((PINC&0X0F)==0x09)
#define key10() ((PINC&0X0F)==0x0A)
#define key11() ((PINC&0X0F)==0x0B)
#define key12() ((PINC&0X0F)==0x0C)

//马达控制定义
uchar MotorCounter=0;							//电机脉宽寄存器
uchar motortime=0;
#define motortime1	2							//电机控制信号从高到低的转折时间
#define motortime2	4							//电机控制信号的波形周期
#define MotorStart() (PORTD=PORTD|(1<<5))  
#define MotorStop()  (PORTD=PORTD&~(1<<5))    	//用PC口的PC0口为电机的控制端口


//声音模块定义
#define speakerSetPlay()		(PORTB&=~(1<<2))
#define speakerResetPlay()		(PORTB|=(1<<2))
#define speakerSetREC()			(PORTB&=~(1<<1))
#define speakerResetREC()		(PORTB|=(1<<1))
//#define speakerBusyReceive()	(PINB&(1<<1))
#define speak_Sound1()			(PORTB=	(((PORTB&~(1<<3))&~(1<<4))&~(1<<5)))
#define speak_Sound2()			(PORTB= (((PORTB|(1<<3))&~(1<<4))&~(1<<5)))
#define speak_Sound3()			(PORTB= (((PORTB&~(1<<3))|(1<<4))&~(1<<5)))
#define speak_Sound4()			(PORTB= (((PORTB|(1<<3))|(1<<4))&~(1<<5)))
#define speak_Sound5()			(PORTB= (((PORTB&~(1<<3))&~(1<<4))|(1<<5)))
#define speak_Sound6()			(PORTB= (((PORTB|(1<<3))&~(1<<4))|(1<<5)))
#define speak_Sound7()			(PORTB=	(((PORTB&~(1<<3))|(1<<4))|(1<<5)))
#define speak_Sound8()			(PORTB=	(((PORTB|(1<<3))|(1<<4))|(1<<5)))
volatile uchar speakerPlayInitSet=0;			//喇叭初始设置标志
volatile uchar speakerRecInitSet=0;
volatile uchar speakerTimes = 0;			//声音触发次数
volatile uint speakerRecTemp = 0;			//延时计数
volatile uint speakerPlayTemp=0;
volatile uchar speakerBusy=0;   			//正在播放,忙信号
volatile uchar speakerPlayflag=0;
volatile uchar speakerRecflag=0;
#define speaker_first		0
#define speaker_Enable		1
#define speaker_Set			2
#define speaker_Reset		3



//手机模块相关定义
vuchar GSMTimerCounter=0;	//时钟计数器
#define GSMPressOn()	(PORTC=PORTC|(1<<5))       	//模拟摘机开通,使用PA7端口
#define GSMPressOff()	(PORTC=PORTC&(~(1<<5)))    	//模拟摘机关闭,使用PA7端口
vuchar GSMtemp=0;
uchar GSMReceiveTemp[100];
uchar GSMATConnectTest[4]={'A','T','\r','\n'};			//AT通讯测试
uchar GSMATConnectOk[4]={'O','K','\r','\n'};			//正常接听
uchar GSMATAcceceptMode[8]={'A','T','S','0','=','3','\r','\n'};	//接听模式设置
uchar GSMATOnLineTest[9]={'A','T','+','C','P','A','S','\r','\n'};	//接听模式设置
vuchar GSMTalkingFlag=0;					//是否是通话状态
vuchar GSMTalkingCounter=0;					//通话状态检测定时器
#define GSMTalkingYes   1
#define GSMTalkingNo   	0

/////////////////////////////////////////////////////////
void SpeakerPlay(void)
{
	if(speakerPlayInitSet==0)
	{
		if(speakerPlayflag==speaker_first)
		{
			speakerResetPlay();
			speakerPlayflag=speaker_Enable;
			speakerPlayTemp=0;
		}
		else if(speakerPlayflag==speaker_Enable)
		{
			
			speakerPlayTemp++;
			if(speakerPlayTemp<20)
			{
				speakerSetPlay();
			}
			else
			{
				speakerResetPlay();
				speakerPlayflag=speaker_first;
				speakerPlayInitSet=1;
			}		
		}
	}
}


void SpeakerRec(void)
{
	if(speakerRecInitSet==0)
	{
		if(speakerRecflag==speaker_first)
		{
			speakerResetREC();
			speakerRecflag=speaker_Enable;
			speakerRecTemp=0;
		}
		else if(speakerRecflag==speaker_Enable)
		{
			speakerRecTemp++;
			if(speakerRecTemp<20)
			{
				speakerSetREC();
			}
			else
			{
				speakerResetREC();
				speakerRecflag=speaker_first;
				speakerRecInitSet=1;
			}		
		}
	}
}

void checkKey(void)
{
	//在可以检测的状态下,假如键盘状态有电平输出
	if((keyLevel==0)&&keyPress())
	{
		//修改电平状态,直到客户放开按钮
		keyLevel=1;
		
		if(key1())                    
			{
				KeyFlag=1;KeyNum=1;
			}
		else if(key2())
			{
				KeyFlag=1;KeyNum=2;
			}
		else if(key3())
			{
				KeyFlag=1;KeyNum=3;
			}
		else if(key4())
			{
				KeyFlag=1;KeyNum=4;
			}
		else if(key5())
			{
				KeyFlag=1;KeyNum=5;
			}
		else if(key6())
			{
				KeyFlag=1;KeyNum=6;
			}
		else if(key7())
			{
				KeyFlag=1;KeyNum=7;
			}
		else if(key8())
			{
				KeyFlag=1;KeyNum=8;
			}
		else if(key9())
			{
				KeyFlag=1;KeyNum=9;
			}		
		else if(key10())
			{
				KeyFlag=1;KeyNum=10;
			}
		else if(key11())
			{
				KeyFlag=1;KeyNum=11; 
			}
		else if(key12())
			{
				KeyFlag=1;KeyNum=12; 
			}		
	}

	//没有状态输出
	else if(keyPress()==0)
	{
		keyLevel=0;
	}
    
}


//数据发送程序
#define sendBufferSize 100
vuchar sendBuffer[sendBufferSize];		//发送临时寄存器
vuchar sendBufferReader=0;		//发送数据读个数
vuchar sendBufferCounter=0;		//发送数据个数
SIGNAL(SIG_UART_TRANS)
{
	//UDR = 0x55;
	
	if(--sendBufferCounter)
	{
		UDR=sendBuffer[++sendBufferReader];
	}
	else 
	{
		sendBufferReader=0;
	}
}

//发送程序,参数为要发送的字符指针以及要发送的字符数量
void sendData(uchar *sendPtr,uchar sendCounter)
{
	uchar sendTemp=0;
	sendBufferCounter=sendCounter;
	sendBufferReader=0;
	for(sendTemp=0;sendTemp<sendCounter;sendTemp++)
	{
		sendBuffer[sendTemp]=*(sendPtr+sendTemp);
	}
	UDR = sendBuffer[sendBufferReader];
}


//数据接收程序
#define receiveBufferSize 100
vuchar receiveBuffer[receiveBufferSize];
vuchar receiveBufferWriter=0;
vuchar receiveBufferCounter=0;
SIGNAL(SIG_UART_RECV)
{
		receiveBuffer[receiveBufferCounter++]=UDR;
   	if (receiveBufferCounter >= receiveBufferSize) receiveBufferCounter=0;
}


//接收程序,参数为要放置数据的地址,最大的接收量
void receiveData(uchar *receivePtr,uchar receiveCounter)
{
	uchar receiveTemp=0;
	while(receiveBufferWriter!=receiveBufferCounter)
	{
		*(receivePtr+receiveTemp)=receiveBuffer[receiveBufferWriter];
		receiveTemp++;
		if(receiveTemp>=receiveCounter)
			{break;}
		receiveBufferWriter++;
		if (receiveBufferWriter >= receiveBufferSize) 
			{receiveBufferWriter=0;}
	}
}


SIGNAL(SIG_OVERFLOW1)
{
	 //TIMER1 has overflowed
	TCNT1H = 0xCF;
	TCNT1L = 0x2C;//初始值


	//手机时钟计数器	
	 GSMTimerCounter++;
	//通话检测定时器
	GSMTalkingCounter++;

	/*
	//声音控制程序
	if(VoiceCounter>0)
    { 
	  VoiceTime++;
	  if(VoiceTime<VoiceTime1)                //VoiceTime1是脉冲从高电平到低电平的转折点
		{
		   SpeakerSignalUp();
		}
	   else if(VoiceTime<VoiceTime2)          // VoiceTime2是脉冲周期
		{
			SpeakerSignalDown();
		}
		else 
		{
			VoiceTime=0;
			VoiceCounter--;
		}
	}
	*/
	
	//马达控制程序
	if(MotorCounter>0)
	{ 
		motortime++;
		if(motortime<motortime1)                 //motortime1是电机开启到关闭的时间点
		{
			MotorStart();
		}
		 else if(motortime<motortime2)           // motortime2是时间周期
		{
			MotorStop();
		}
		else 
		{
			motortime=0;
			MotorCounter--;
		}
	}
	
}


//按键按一下机器人甩一甩鞭子
void hit1(void)
{  
    MotorCounter=5;                // 计数值确定甩鞭子的时间长短
} 


//按键按一下机器人甩几下鞭子
void hit2(void)
{  
    MotorCounter=20;               // 计数值确定甩鞭子的时间长短
}

//放出录音芯片内声音,按一下键放一次声
void voice1(void)
{  
    //VoiceCounter=1;
    speak_Sound1();
}

//放出远程控制人员的语音信号
void voice3(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -