Skocz do zawartości

Robot z silnikami krokowymi Atmega32 optymalizacja kodu


Pomocna odpowiedź

@SzymonT ciężko tutaj o pomoc, bo nie napisałeś co to za robot, co ma robić i jakie dokładnie masz problemy, a kod nie ma praktycznie żadnych komentarzy. Jeśli temat jest nadal aktualny to na pewno przydałoby się więcej szczegółów 😉

  • 3 tygodnie później...

Udało się zoptymalizować kod.
Wygląda lepiej niż pointy do funkcji
Obsługa znaków z bluetooth też wygląda lepiej.

#define F_CPU 7372800L
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE ((F_CPU / (USART_BAUDRATE * 16UL)) - 1)

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

volatile bool flagx = true, flagy = true;
volatile uint8_t Lx = 127, Ly = 127;
volatile uint8_t DirPx = 0, DirPy = 0;
volatile uint16_t ile = 65536 - 28;

volatile uint8_t idx = 0, idy = 0;
#define BUF_SIZE 16

volatile char rx_buf[BUF_SIZE];
volatile uint8_t rx_pos = 0;

volatile char letter;
volatile int number;

#define YA1_PORT PORTC
#define YA1_BIT  PC5
#define YA2_PORT PORTD
#define YA2_BIT  PD6
#define YB1_PORT PORTC
#define YB1_BIT  PC3
#define YB2_PORT PORTC
#define YB2_BIT  PC2

#define XA1_PORT PORTD
#define XA1_BIT  PD5
#define XA2_PORT PORTD
#define XA2_BIT  PD4
#define XB1_PORT PORTC
#define XB1_BIT  PC0
#define XB2_PORT PORTC
#define XB2_BIT  PC1

static inline void Xset_pin(volatile uint8_t* port, uint8_t bit, uint8_t val){
	if(val) *port |=  (1<<bit);
	else    *port &= ~(1<<bit);
}

void Ystep_set(uint8_t a1,uint8_t a2,uint8_t b1,uint8_t b2){
	Xset_pin(&YA1_PORT, YA1_BIT, a1);
	Xset_pin(&YA2_PORT, YA2_BIT, a2);
	Xset_pin(&YB1_PORT, YB1_BIT, b1);
	Xset_pin(&YB2_PORT, YB2_BIT, b2);
}

void Xstep_set(uint8_t a1,uint8_t a2,uint8_t b1,uint8_t b2){
	Xset_pin(&XA1_PORT, XA1_BIT, a1);
	Xset_pin(&XA2_PORT, XA2_BIT, a2);
	Xset_pin(&XB1_PORT, XB1_BIT, b1);
	Xset_pin(&XB2_PORT, XB2_BIT, b2);
}

const uint8_t Xseq_full[4][4] = {
	{1,0, 1,0},
	{0,1, 1,0},
	{0,1, 0,1},
	{1,0, 0,1},
};

ISR(TIMER1_OVF_vect) {
	Xstep_set(Xseq_full[idx][0],Xseq_full[idx][1],Xseq_full[idx][2],Xseq_full[idx][3]);

	if(DirPx){
		idx++; if(idx>=4) idx=0;
		}else{
		if(idx==0) idx=3; else idx--;
		}
	TCNT1 = ile;
}

ISR(TIMER2_COMP_vect) {
	Ystep_set(Xseq_full[idy][0],Xseq_full[idy][1],Xseq_full[idy][2],Xseq_full[idy][3]);

	if(!DirPy){
		idy++; if(idy>=4) idy=0;
		}else{
		if(idy==0) idy=3; else idy--;
	}
}

// ------------------ Inicjalizacja USART ------------------
void usart_init(void) {
	UBRRH = (BAUD_PRESCALE >> 8);
	UBRRL = BAUD_PRESCALE;
	UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);
	UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
}

// ------------------ Drobna funkcja opó?nienia ------------------
void wait_us(int us) {
	for (int i = 0; i < us; i++) {
		_delay_us(1);
	}
}

// ------------------ Przerwanie USART ------------------
ISR(USART_RXC_vect)
{
	char c = UDR;
	while (!(UCSRA & (1<<UDRE))) { }
	UDR = c;
	if (c == '\n' || c == '\r')
	{
		rx_buf[rx_pos] = '\0';
		letter = rx_buf[0];
		number = atoi((const char*)&rx_buf[2]);
		rx_pos = 0;

		switch(letter)
		{
			case 'x':
			Lx = number;
			break;

			case 'y':
			Ly = number;
			break;

			case 'l':
			Lx = 127;
			break;

			case 'p':
			Ly = 127;
			break;

			case 'w':
			Ly=127;
			Lx=127;

			PORTC &= ~(1<<PC0);
			PORTC &= ~(1<<PC1);
			PORTD &= ~(1<<PD5);
			PORTD &= ~(1<<PD4);

			PORTC &= ~(1<<PC3);
			PORTC &= ~(1<<PC2);
			PORTD &= ~(1<<PD6);
			PORTC &= ~(1<<PC5);
			break;

			default:
			break;
		}
	}
	else
	{
		if (rx_pos < BUF_SIZE - 1)
		{
			rx_buf[rx_pos] = c;
			rx_pos++;
		}
	}
}
// ------------------ Funkcja glówna ------------------
int main(void) {
	// Ustawienia portów
	PORTD = 0x02;
	DDRD |= (1<<PD4) | (1<<PD5) | (1<<PD6);
	DDRC |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC5);

	usart_init();

	TCCR1A = 0;
	TCCR1B = (1<<CS11) | (1<<CS10);
	TCCR2 = (1<<CS22) | (1<<CS20) | (1<<WGM21);
	TIMSK |= (1<<OCIE2) | (1<<TOIE1);

	OCR2 = 28;  //1-17.4us
	TCNT1 = ile;

	sei(); // global interrupt
	TIMSK&=~(1<<TOIE1);
	TIMSK&=~(1<<OCIE2);
	uint8_t yL=127,xL=127;
	for(;;) {
		// Obsluga X
		if(xL!=Lx)
		{
			xL=Lx;
			if(xL!=127)
			{
				if(xL<127)
				{
					DirPx=1;
					ile=65536-2*(154-(127-xL));
				}
				else if(xL>127)
				{
					DirPx=0;
					ile=65536-2*(154-(-1*(127-xL)));
				}
				if(flagx==true)
				{
					TIMSK|=1<<TOIE1;
					flagx=false;
				}
			}
			else
			{
				TIMSK&=~(1<<TOIE1);
				flagx=true;
			}
		}
		// Obsluga y
		if(yL!=Ly)
		{
			yL=Ly;
			if(yL!=127)
			{
				if(yL<127)
				{
					DirPy=1;
					OCR2=154-(127-yL);
				}
				else if(yL>127)
				{
					DirPy=0;
					OCR2=154-(-1*(127-yL));
				}

				if(flagy==true)
				{
					TIMSK|=1<<OCIE2;
					flagy=false;
				}
			}
			else
			{
				TIMSK&=~(1<<OCIE2);
				flagy=true;
			}
		}
	}
}

 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...