再见——电脑鼠 Atmega128

学了一年的电脑鼠基本收获不多,也不能说少,至少看了眼界。

挺羡慕之后参见的同学可以有只完好的Micro Mouse,而不用担心电机坏了,红外坏了。

电脑鼠报废主要在红外吧,只能直走,不能避障。庆幸结课时要求不高,能顺利转几圈。

总之,作为软件部分:

快速PWM基本会用;

UART正常;

PID算法,P算法凑数吧;

红外发射接受会写,但硬件不能用;

遗憾;


代码留作纪念;

//ICC-AVR application builder : 2015/11/21 星期六 13:30:53
// Target : M128
// Crystal: 24.0000Mhz

#include <iom128v.h>
#include <macros.h>
#include "uart.h" 
#include "motor.h"

unsigned char adc_num;
unsigned char adc_ready;
unsigned char adc_data[7];
unsigned char adc_data_temp[7];

//void delay_ms(int t); 

void port_init(void)
{
	PORTA = 0x00;
	DDRA  = 0x00;
	PORTB = 0xF8;
	DDRB  = 0xF8;
	PORTC = 0x00;
	DDRC  = 0xFF;
	PORTD = 0x00;
	DDRD  = 0x00;
	PORTE = 0x00;
	DDRE  = 0x00;
	PORTF = 0x00;
	DDRF  = 0x00;
	PORTG = 0x00;
	DDRG  = 0x00;
}


//ADC initialize
// Conversion time: 69uS
void adc_init(void)
{
	ADCSRA = 0x00; //disable adc
	ADMUX = 0x00; //select adc input 0
	ACSR  = 0x80;
	ADCSRA = 0xCF;
	ADMUX = 0x60; //select adc input 0
	
	adc_num=0x00;
	adc_ready=0x00;
}

#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
	unsigned char tmp;
   	adc_data_temp[adc_num]=ADCH;
	adc_num++;
	PORTC=0x01<<adc_num;
	ADMUX++;
	if(adc_num==0x06 )
	{
		for( tmp = 0x00; tmp <0x06; tmp++ )
	    {
//	       	adc_data[tmp]=0x88;
	       	adc_data[tmp]=adc_data_temp[tmp];
		}
		adc_ready=0x01;  // 数据准备OK,申请标志位
		adc_num=0x00;
		ADMUX &= 0xF8 ;
	}
	else
		ADCSRA|=1<<(ADSC);		// 启动ADC 单次循环采样
 //conversion complete, read value (int) using...
}

void adc_read(void)
{
	ADCSRA|=1<<(ADSC);
} 
void adc_put()
{
	char k;
	Putdata(0xDD);
	for(k=0;k<7;k++)
	{
		Putdata(adc_data[k]);
		adc_data[k]=0x00;
	}
}
//call this routine to initialize all peripherals
void init_devices(void)
{
	//stop errant interrupts until set up
	CLI(); //disable all interrupts
	XDIV  = 0x00; //xtal divider
	XMCRA = 0x00; //external memory
	port_init();
	timer0_init();
	timer1_init();
	timer2_init();
	timer3_init(); 
	uart1_init();
	adc_init(); 
	MCUCR = 0x00;
	EICRA = 0x00; //extended ext ints
	EICRB = 0x00; //extended ext ints
	EIMSK = 0x00;
	TIMSK = 0x41; //timer interrupt sources
	ETIMSK = 0x04; //extended timer interrupt sources
	SEI(); //re-enable interrupts
 	//all peripherals are now initialized
}

int i=0,j;
unsigned char v=0;
void main(void)
{
 	init_devices();
 	motor_init();
	v=0x04;
	forward(0x20);
	delay_ms(500); 

 while(1)
 {
 	//这部分应该放在adc转换完成中断里
	 //由于红外管损坏仅能随便写 
	 while(adc_ready==0x01)
	 {
		adc_ready=0x00;
		if(adc_data[3]>=0x20&&adc_data[4]>=0x20)
		{
			if(adc_data[3]>=0x35)
				turn_left(v);
			else
				turn_right(v);
		}
		else
			forward(v);
	//	adc_put();
	 }
	 adc_read();
	 delay_ms(10);
 }

 //insert your functional code here...
}



//motor.h
// 最大速度0x1A; 采样周期越小速度越快, 
unsigned char Lcon,Rcon,Lspeed,Rspeed;
int Lptmp,Ltmp,Rptmp,Rtmp;

void motor_message(void)
{
	Putdata(0xFF);
	Putdata(Lcon);
	Putdata(Lspeed);
	Putdata(OCR1AL);
	Putdata(0xAA);
	Putdata(Rcon);
	Putdata(Rspeed);
	Putdata(OCR1BL);
}

void pid_left(void)
{
	Lcon=TCNT2;
	TCNT2=0;
	Ltmp=(Lspeed-Lcon);
	Lptmp+=Ltmp;
	if(Lptmp<0) Lptmp=0x00;
	if(Lptmp>0xFF) Lptmp=0xFF;
	OCR1AL=Lptmp;
}

void motor_left(unsigned char v)
{
	Lspeed=v;
}

void pid_right(void)
{
	Rcon=TCNT3L;
	TCNT3L=0;
	Rtmp=(Rspeed-Rcon)*8;
	Rptmp+=Rtmp;	
	if(Rptmp<0x00) Rptmp=0x00;
	if(Rptmp>0xFF) Rptmp=0xFF;
	OCR1BL=Rptmp;
}

void motor_right(unsigned char v)
{
	Rspeed=v;
//	Putdata(0x2B);
}

void turn_left(unsigned char v)
{
	motor_right(0x1A);
	motor_left(v); 
	delay_ms(10);
	motor_right(v); 
} 

void turn_right(unsigned char v)
{
	motor_left(0x1A);
	motor_right(v);
	delay_ms(10);
	motor_right(v);
} 

void forward(unsigned char v)
{
	motor_left(v);
	motor_right(v);
}

//TIMER0 initialize - prescale:8
// WGM: PWM Fast
// desired value: 1Hz
// actual value: 11718.750Hz (100.0%)
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 ASSR  = 0x00; //set async mode
 TCNT0 = 0x01; //set count
 OCR0  = 0xFF;
 TCCR0 = 0x6A; //start timer
}

unsigned int count=0,temp1=0;
unsigned char temp2;
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
  //reload counter value
 count++;
 if(count>=8)
 {
 	temp1++;
	if(temp1>=150)
	{
	//	Putdata(0xBB);
	//	Putdata(0xBB);
	//	Putdata(0xBB);
//		motor_message();
		adc_put();
		temp1=0;
	}
 //	 delay_ms(500); 
 //	Putdata(0xF0);
 //	Putdata(TCNT3L);
	 pid_right();
 	 pid_left();
	  count=0;
//	motor_message();
 }
 TCNT0 = 0x01;
}

//TIMER1 initialize - prescale:8
// WGM: 5) PWM 8bit fast, TOP=0x00FF
// desired value: 1Hz
// actual value: 11718.750Hz (100.0%)
void timer1_init(void)
{
	TCCR1B = 0x00; //stop
	TCNT1H = 0xFF; //setup
	TCNT1L = 0x01;
	OCR1AH = 0x00;
	OCR1AL = 0xFF;
	OCR1BH = 0x00;
	OCR1BL = 0xFF;
	OCR1CH = 0x00;
	OCR1CL = 0xFF;
	ICR1H  = 0x00;
	ICR1L  = 0xFF;
	TCCR1A = 0xA9;
	TCCR1B = 0x0A; //start Timer
}

//TIMER2 initialize - prescale:Stop
// WGM: Normal
// desired value: 1Hz
// actual value: Out of range
void timer2_init(void)
{
	TCCR2 = 0x00; //stop
	TCNT2 = 0x00 /*INVALID SETTING*/; //setup
	OCR2  = 0x00 /*INVALID SETTING*/;
	TCCR2 = 0x07; //start
}

#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
	TCNT2 = 0x00 /*INVALID SETTING*/; //reload counter value
}

//TIMER3 initialize - prescale:Stop
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Hz
// actual value: Out of range
void timer3_init(void)
{
	TCCR3B = 0x00; //stop
	TCNT3H = 0x00 /*INVALID SETTING*/; //setup
	TCNT3L = 0x00 /*INVALID SETTING*/;
	OCR3AH = 0x00 /*INVALID SETTING*/;
	OCR3AL = 0x00 /*INVALID SETTING*/;
	OCR3BH = 0x00 /*INVALID SETTING*/;
	OCR3BL = 0x00 /*INVALID SETTING*/;
	OCR3CH = 0x00 /*INVALID SETTING*/;
	OCR3CL = 0x00 /*INVALID SETTING*/;
	ICR3H  = 0x00 /*INVALID SETTING*/;
	ICR3L  = 0x00 /*INVALID SETTING*/;
	TCCR3A = 0x00;
	TCCR3B = 0x07; //start Timer
}

#pragma interrupt_handler timer3_ovf_isr:iv_TIM3_OVF
void timer3_ovf_isr(void)
{
	//TIMER3 has overflowed
	TCNT3H = 0x00 /*INVALID SETTING*/; //reload counter high value
	TCNT3L = 0x00 /*INVALID SETTING*/; //reload counter low value
	Putdata(0x33);
}
void motor_init(void)
{
	OCR1A=0x00;
	OCR1B=0x00;
	OCR1C=0x00;
	OCR0=0x00;
	Lcon=0x00;
	Lspeed=0x00;
	Lptmp=0x00;
	Ltmp=0x00;
	Rcon=0x00;
	Rspeed=0x00;
	Rptmp=0x00;
	Rtmp=0x00;
}

//uart.h
void delay_us(int t)
{	int i;
	while(t--); 
	for(i=0;i<34;i++);
}
void delay_ms(int t) //延迟ms
{
	int i,j;
	for(i=0;i<t;i++) 
	  for(j=0;j<3400;j++); 
}
//UART1 initialize
// desired baud rate:115200
// actual baud rate:115385 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart1_init(void)
{
 UCSR1B = 0x00; //disable while setting baud rate
 UCSR1A = 0x00;
 UCSR1C = 0x06;	//设置传输位数8位 
 UBRR1L = 0x0C; //set baud rate lo
 UBRR1H = 0x00; //set baud rate hi
 UCSR1B = 0x98;	//发送使能\接收中断使能\接受使能 
}

void Putdata(unsigned char g_Dat)									// 串口写函数 g_Dat:往串口写的数据
{
	while (!(UCSR1A & (BIT(UDRE1))));						// 等待传送结束	等待发送缓冲区空
	UDR1 = g_Dat;
}

unsigned char get_data[7],shou;
unsigned char data_ready,data_count=0; 
#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
void uart1_rx_isr(void)
{
	get_data[data_count++]=UDR1;
//	motor_left(get_data[data_count-1]);
	if(data_count>=1)
	{
		data_ready=1;
		data_count=0;
	//	Putdata(0x2B);
	}
	
 //uart has received a character in UDR
}



以下图片版权归邱哥所有,请勿擅自使用!






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值