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

📄 xunxiandongzuo8.c

📁 mega8 对电机控制。采用mega8对电机控制。然后再用mega16 来控制mega8
💻 C
字号:
//ICC-AVR application builder : 2005-12-22 22:30:20
// Target : M8
// Crystal: 8.0000Mhz
#include <iom8v.h>
#include <macros.h>

#include "Main8.h"


#include "L_PID.c"
#include "Slave_SPI.c"
#include "TIMEDELAY8.C"


void port_init(void)
{
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC =  0x00; //m103 output only
 DDRC  = 0x00;
 PORTD =  0x00;
 DDRD  = 0x00;
 
 PORTB |= 0x02;	//OC1A output ,high level
 DDRB |= 0x02;	
 
 PORTC &= ~0x02;
 DDRC |= 0x02;
 
 PORTC |= 0x08;	//PC3 输出,控制电机方向,1->正转,0->反转 0000 1000
 DDRC |= 0x38; //PC4,PC5输出
 
 PORTD |= 0X0C;		//INT0,INT1设置为输入,PD2,PD3 
 DDRD  &= ~0X0C;	
 
 PORTD &=~0x80;	//PD7置低 
 DDRD |= 0x80;	
 
 PORTD &=~0x40;//PD6置低
 DDRD |= 0x40;	
 
 PORTD |= 0x10;	//T0设为带上拉输入,码盘脉冲输入
 DDRD &= ~0x10; 
}

//TIMER0 initialize - prescale:falling edge
void timer0_init(void)
{
 TCCR0 = 0x00; //stopvv
 TCNT0 = 0x00 /*INVALID SETTING*/; //set count
 TCCR0 = 0x06; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
	num_H++;			//低字节逸溢出,高字节加一
}

//TIMER1 initialize - prescale:1
// WGM: 7) PWM 10bit fast, TOP=0x03FF
// desired value: 7.813KHz
// actual value:  7.813KHz (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xFC; //setup
 TCNT1L = 0x01;
 OCR1AH = 0x00;		//初始占空比为0,停机
 OCR1AL = 0x00;
 OCR1BH = 0x00;
 OCR1BL = 0x00;
 ICR1H  = 0x03;
 ICR1L  = 0xFF;
 TCCR1A = 0xC3;		//OC1A输出PWM波形
 TCCR1B = 0x09; //start Timer
}


/*INT0下降沿触发,	INT1上升沿触发,
INT0触发时方向电平为1,表正转,INT1触发时方向电平为0,表正转,*/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
 	//external interupt on INT0		Dir GO_AHEAD-> GO_BACK, 存贮并清零
 	unsigned int temp_int = 0x0000;
 	unsigned char temp_char = 0x00;
 	
 	temp_char = TCNT0;		//读取脉冲计数低字节
 	TCNT0=0;
 	
 	temp_int = num_H;		//读取脉冲计数高字节
 	num_H = 0;
 	
 	temp_int <<=8;			//计算脉冲数
 	temp_int += temp_char;
 	
	Num_Speed += temp_int;		//累计脉冲数
}


#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
 	//external interupt on INT0		//Dir GO_BACK -> GO_AHEAD, 存贮并清零
 	unsigned int temp_int = 0x0000;
 	unsigned char temp_char = 0x00;
 	
 	temp_char = TCNT0;		//读取脉冲计数低字节
 	TCNT0=0;
 	
 	temp_int = num_H;		//读取脉冲计数高字节
 	num_H = 0;
 	
 	temp_int <<=8;			//计算脉冲数
 	temp_int += temp_char;
 	
	Num_Speed -= temp_int;		//累计脉冲数	
}


//TIMER2 initialize - prescale:1024
// WGM: Normal
// desired value: 20mSec
// actual value: 19.968mSec (0.2%)
void timer2_init(void)
{
 TCCR2 = 0x00; //stop
 TCNT2 = 0x64; //setup
 
 TCCR2 = 0x07; //start
}

/*						定时进行PID运算				*/
#define Dir ( (PIND)&(1<<2) )		//方向输入,“非零”为GO_AHEAD,“0”为GO_BACK

#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
	unsigned int temp_int = 0x0000;
 	unsigned char temp_char = 0x00;
	signed int temp_sint=0;

 	TCNT2 = 0x64; //reload counter value
	
 	SEI();
	
	temp_char = TCNT0;		//读取脉冲计数低字节
 	TCNT0=0;
 	
 	temp_int = num_H;		//读取脉冲计数高字节
 	num_H = 0;
 	
 	temp_int <<=8;			//计算脉冲数
 	temp_int += temp_char;
	
	if(Dir)				//计数累加
		Num_Speed += temp_int;
	else
		Num_Speed -= temp_int;
	
	L_sPID.vi_FeedBack = Num_Speed;	//储存当前速速值
	
	/**************************************/
	switch( PID_choice )
	{
		case SPEED_SET :
		{ 
			temp_sint = v_PIDCalc ( &L_sPID);
			break;
		}
		case DISTANCE_SET : 
		{
			temp_sint = s_PIDCalc( &L_sPID );
			break;
		}
	}
	//temp_sint = v_PIDCalc ( &L_sPID);
	Num_Speed = 0;
	
	send_PWM( temp_sint );	//调节PWM的占空比	
	
}

/*pwm脉宽调节*/
void send_PWM(signed int num_pwm)
{
	if( num_pwm >= 0 )
		now_dir = GO_AHEAD;
	else
		now_dir = GO_BACK;
		
	if( now_dir == GO_AHEAD )	//判断正反转
	{				
		//now_dir=GO_AHEAD,正向,	
		if(pre_dir != now_dir)	//pre_dir!=now_dir,换成正向,								
		{	
			PORTC |= 0x08;	//PC3->1,转向变为正		
			pre_dir = now_dir; 	//重载pre_dir	
		}
		
		OCR1A = num_pwm;	//重载OCR1A	
		
		TCNT1H = 0x03; //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
 		TCNT1L = 0xF0;
	}
	else
	{				
		//now_dir=GO_BACK,负方向,							
		if(pre_dir != now_dir)	//pre_dir!=now_dir,换成负向
		{		
			PORTC &= ~0x08;	//PC3->0,转向变为负												
			pre_dir = now_dir; 	//重载pre_dr						
		}
		
		OCR1A = 0 - num_pwm;	//赋负转占空比	
			
		TCNT1H = 0x03; //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
 		TCNT1L = 0xF0;
	}	
}

void free_stop (void)			//立即停机
{
	now_dir = GO_STOP;
	pre_dir = GO_STOP;
	
	PORTC |= 0x08;	//正向输出占空比为零。
	OCR1A = 0x0000;	//使占空比为0
	
	TCNT1H = 0x03;  //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
 	TCNT1L = 0xF0;
		
	PID_choice = 0xFF;	
} 

//call this routine to initialize all peripherals
void init_devices(void)			  
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();
 timer1_init();
 timer2_init();
 //init_7279();
 spi_init();
  L_PIDInit();

 MCUCR = 0x0E; //INT0 下降沿触发,INT1上升沿触发,INT0 为高电平时表电机正转
 GICR  = 0xC0; 
 TIMSK = 0x41; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void main()
{
	unsigned char i ;
	unsigned long temp_long = 0;
	init_devices();
	//TCCR2 = 0x07;
	//PID_choice = SPEED_SET;//选择PID方式
	//L_sPID.vi_Ref= 300; //给定参考速度
	//delay_s(2);
	//L_sPID.vi_Ref= -300;
	while (1)
	{

	}
}

⌨️ 快捷键说明

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