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

📄 00atmega8.c

📁 AVR嵌入式舵机驱动程序 用串口设置舵机转动的角度
💻 C
字号:
#include <iom8v.h>
#include <macros.h>
#define PWM1 3
/////////////////////////////////////////////////////////////////////////////
const char adr = 0x00;//地址
const unsigned char a_init0=125,a_init1=88,a_init2=5,a_init3=171;
char emp = 0;		   	 														 //表示定时器可更新数据
char state = 0;																	 //表示串口接受到新数据
char cnt=0;
char flag=1,flag2=1;
unsigned char deg_0=0,deg_1=0,deg_2=0,angel2=211;
char angle0_l=0xDC,angle0_h= 0x05,angle1_l=0xDC,angle1_h= 0x05;//用于改变脉宽
int angle;
/////////////////////////////////////////////////////////////////////////////
void init_feet(void)
{
 int temp;
 		////////////////////////////////
			//舵机0
				temp = a_init0;
				angle = (temp *11)+380;
   	   			angle0_l = angle;
   	   			angle0_h = angle>>8;
			////////////////////////////////
			//舵机1
				temp = a_init1;
				angle = (temp *11)+500;
				angle1_l = angle;
   	   			angle1_h = angle>>8;
			//////////////////////////////////
			//舵机2
				temp = a_init2;
				angel2=239-(temp/3);//255-(temp/3+16)	
				flag2=1;
}
////////////////////////////////////////////////////
void init_feet_2(void)
{
 int temp;
 		////////////////////////////////
			//舵机0
				temp = a_init0;
				angle = (temp *11)+380;
   	   			angle0_l = angle;
   	   			angle0_h = angle>>8;
			////////////////////////////////
			//舵机1
				temp = a_init1;
				angle = (temp *11)+500;
				angle1_l = angle;
   	   			angle1_h = angle>>8;
			//////////////////////////////////
			//舵机2
				temp = a_init2+a_init3;
				angel2=239-(temp/3);//255-(temp/3+16)	
				flag2=0;
}
////////////////////////////////////////////////////
static void io_init(void)//
{

	PORTB = 0xFF;
 	DDRB  = 0x0E;
 	PORTC = 0x7F; 												  					 //m103 output only
 	DDRC  = 0x00;
 	PORTD = 0x7F;
 	DDRD  = 0xFF;
//	wdt_enable(WDTO_15MS);
//	ACSR = 0x80;
}
////////////////////////////////////////////////////
//软件生成波形,低电平15ms,扩展出一路舵机,在INTERRUPT(SIG_OVERFLOW0)中置端口pb3为高电平
//发现即使周期改变,高电平长度正确也可控制舵机
void timer0_init(void)
{
	TCCR0 = 0x00;
	TCNT0 = 0X8A;
	TCCR0 = 0x05;//1024
}
////////////////////////////////////////////////////
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
	if(flag==1)
	{
		PORTB|=(1<<3);
		TCCR0 = 0x00;
		TCNT0 = angel2;		
		flag=0;
		TCCR0 = 0x04;//256分频

	}
	else
	{
		PORTB^=(1<<3);
		TCCR0 = 0x00;
		TCNT0 = 0X8A;		
		flag=1;
		TCCR0 = 0x05;

	}
}
////////////////////////////////////////////////////////////
//脉宽为1.5ms。
void timer1_init(void)
{	 TCCR1B = 0x00; 	  	  														 //stop
 	 
 	 TCNT1H = 0x00; 																//setup
 	 TCNT1L = 0x00;
 
 	 OCR1AL = 0xDC;
 	 OCR1AH = 0x05;//1500
 	 OCR1BH = 0x05;
 	 OCR1BL = 0xDC;//1500
 
 	 ICR1H  = 0x4E;
 	 ICR1L  = 0x20;//20000
 
 	 TCCR1A = 0xA2;//COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
				   //1		0		1		0      0	0	   1	0
 	 TCCR1B = 0x1A;//ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10																//start Timer
}				   //0      0     0   1     1    0     1    0     8分频
////////////////////////////////////////////////////////////////////////////
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
	 OCR1AH = angle0_h;
 	 OCR1AL = angle0_l;
	 OCR1BH = angle1_h;
 	 OCR1BL = angle1_l;
 	 emp = 1; 		   		  	//设置空标志,允许进行角度换算。
}
/////////////////////////////////////////////////////////////////////
void uart0_init(void)//char size: 8 bit
{
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00; //MPCM
 UCSRC = 0x8E; //URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
			   //1       0     0    0    1    1     1    0
 UBRRL = 0x33; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x90; //RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8
			   //1       0     0     1    0    0     0    0
}
/////////////////////////////////////////////
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
	unsigned char  resh,temp;
 	PORTD = PORTD^0x20;		 					//第5位led
 	temp = UDR;
	if(temp==0xFF)
			init_feet();
	if(temp==0xFE)
			init_feet_2();
	if(temp==adr)
	{
	 state=1;
	 cnt=1;
	 }
	 else if(state==1)
	 {
	  if(cnt==1)
	  {
	  	deg_0 = temp;
		cnt=2;
		}
		else if(cnt==2)
		{
		 deg_1 = temp;
		 cnt=3;
		 }
		 else if(cnt==3)
		 {
		  deg_2 = temp;
		  cnt = 0;
		  state = 2;
		  }
		}
}
/////////////////////////////////////////////////////////////////

void init_devices(void)
{
 	CLI(); 																		
 	timer1_init();
 	uart0_init();
  	timer0_init();
  	MCUCR = 0x00;
 	GICR  = 0x00;
 	TIMSK = 0x05; 																//timer interrupt sources
 	SEI(); 																				
}
//////////////////////////////////////////////////////////////////////////////
int main(void)
{
	
	unsigned int ii=0;
	int temp=0;
	io_init();
	init_devices();
	for(ii=0;ii;ii++);	
	init_feet();															//启动后延时6ms
	while(1)
	{
		// TODO: Add your code here
		if(emp == 1 && state == 2)   	   			  			 			  		//换算可以进行
   		{	//舵机0,1,2的换算	
			////////////////////////////////
			//舵机0
				temp = deg_0 +a_init0-128;
				angle = (temp *11)+380;
   	   			angle0_l = angle;
   	   			angle0_h = angle>>8;
			////////////////////////////////
			//舵机1
				temp = deg_1 +a_init1-128;
				angle = (temp *11)+500;
				angle1_l = angle;
   	   			angle1_h = angle>>8;
			//////////////////////////////////
			//舵机2
				if(flag2==1)
					temp = deg_2 +a_init2-128;
				else
					temp = deg_2 +a_init3+a_init2-128;
				angel2=239-(temp/3);//255-(temp/3+16)	
				PORTD = PORTD^0x40;    
   	  	
			emp = 0;
			state = 0;
		}												//第6位
	}
}

⌨️ 快捷键说明

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