vklaffehn
30.07.2011, 21:16
Moin, ich bins mal wieder :-)
Da es mittlerweile einen Treiber für meinen USBTinyISP für 64bit gibt, hab ich mal AVRStudio 4.18 und WinAVR 2010 auf meinem Rechner installiert. Nun habe ich da ein kleines Problem :
Ich habe von meinem MiniPanoBot ein Programm für den Tiny2313, das bisher wunderbar tat, was es sollte. Nun habe ich gerade einen kleinen Fehler behoben (an 2 Stellen für die Berechnung der Anzahl Schritte pro ° eine 69 durch eine 67 ersetzt, sonst nichts!!) und nun geht mal wieder was nicht. Alerdings habe ich das selbe Phänomen auch bei meiner aktuellen Schaltung festgestellt. In der Motoransteuerung gibt es eine Beschleunigungsrampe, die über eine feste Anzahl Schritte geht. Dafür benutze ich die Variable 'ramp', die ich also 'volatile int ramp=400' global definiert habe. Dies hat wunderbar geklappt, aber nun nicht mehr.... Bei meinem neuen Projekt ging es erst, als ich die Variable direkt in der Funktion deklariert habe, vorher schien die Varible entweder '0' oder irgendetwas undefiniertes kleines zu sein. Leider weiß ich nicht mehr, mit welcher WinAVR Version ich das vorher kompiliert hatte, allerdings haben zwei Versuche mit einer 2009er und einer 2008er Version das witzige Ergebnis geliefert, dass das Programm nicht mehr in das FlashROM passte.... hat einer eine schlaue Idee, ob es da einen Bug gibt oder verstehe ich da was falsch? Meines erachtens ist doch eine volatile Variable quasi sowas wie eine globale Variable?
Mal mein Code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "uart.h"
#include <avr/interrupt.h>
#include <stdint.h>
//#include <avr/pgmspace.h>
#define UART_BAUD_RATE 250000
#define m_delay 1500
volatile uint16_t motor1=0;
volatile uint16_t motor2=0;
//absolute direction in degree (-180 to 180, -90 to 90)
volatile int16_t xpos = 0;
volatile int16_t ypos = 0;
//#define speed 400
volatile int8_t speed = 40;
volatile int ramp = 400;
//const unsigned char step[4]={5,9,10,6};
const unsigned char halfstep[8]={5,1,9,8,10,2,6,4};
//const unsigned char halfstep[8]={0b00001010,0b00001000,0b00001001,0b00000001,0b00 000010,0b00000110,0b00000100,0b00000101};
void init()
{
DDRA = 0b00000011;
DDRB = 0b11111111;
DDRD = 0b00000000;
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
}
void _vdelay_us(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_us(10);
}
}
void _vdelay_ms(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_ms(1);
}
}
void step_x(int dir)
{
motor1 = motor1 + dir;
PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
_vdelay_us(speed);
}
void step_y(int dir)
{
motor2 = motor2 + dir;
PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
_vdelay_us(speed);
}
void turn_x(int steps)
{
int cnt;
// int ramp = 400;
int rf=4;
int shortramp=0;
char m=0;
m = motor1;
if (abs(steps)<(ramp*2))
{
shortramp=ramp-(abs(steps)/2);
ramp= abs(steps)/2;
}
else
shortramp=0;
PORTA |= (1<<0);
if (steps>0)
{
for (cnt=0;cnt<=steps;cnt++)
{
step_x(1);
// ramp start/stop
if (cnt<ramp) //start
{
_vdelay_us((ramp-cnt+shortramp)*rf);
}
if (cnt>(steps-ramp)) //stop
{
_vdelay_us((cnt-(steps-ramp-shortramp))*rf);
}
}
}
else
if (steps<0)
{
for (cnt=0;cnt>=steps;cnt--)
{
step_x(-1);
// ramp start/stop
if (abs(cnt)<ramp) //start
{
_vdelay_us((ramp-abs(cnt)+shortramp)*rf);
}
if (abs(cnt)>(abs(steps)-ramp)) //stop
{
_vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
}
}
}
motor1 += steps;
PORTA&=~(1<<0); //motor disable
}
void turn_y(int steps)
{
int cnt;
// int ramp = 400;
int rf=4;
int shortramp=0;
char m=0;
m = motor2;
if (abs(steps)<(ramp*2))
{
shortramp=ramp-(abs(steps)/2);
ramp= abs(steps)/2;
}
else
shortramp=0;
PORTA |= (1<<1);
if (steps>0)
{
for (cnt=0;cnt<=steps;cnt++)
{
step_y(1);
// ramp start/stop
if (cnt<ramp) //start
{
_vdelay_us((ramp-cnt+shortramp)*rf);
}
if (cnt>(steps-ramp)) //stop
{
_vdelay_us((cnt-(steps-ramp-shortramp))*rf);
}
}
}
else
if (steps<0)
{
for (cnt=0;cnt>=steps;cnt--)
{
step_y(-1);
// ramp start/stop
if (abs(cnt)<ramp) //start
{
_vdelay_us((ramp-abs(cnt)+shortramp)*rf);
}
if (abs(cnt)>(abs(steps)-ramp)) //stop
{
_vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
}
}
}
motor2 += steps;
PORTA&=~(1<<1); //motor disable
}
void turn_deg_x(int16_t deg)
{
turn_x(deg*67);
}
void turn_deg_y(int16_t deg)
{
turn_y(deg*67);
}
unsigned char serialin(void)
{
unsigned int c;
c = uart_getc();
while ( c & UART_NO_DATA )
c = uart_getc();
return c;
}
void remote_move()
{
int16_t x,y;
x=serialin()+(serialin()<<8);
y=serialin()+(serialin()<<8);
turn_deg_x(x-(xpos));
turn_deg_y(y-(ypos));
xpos = x;
ypos = y;
uart_putc(0);
}
void remote(void)
{
unsigned int c;
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
//uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
//uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
//uart_puts_P("Buffer overflow error: ");
}
//doing commands
switch(c)
{
case 1:
remote_move();
break;
}
}
}
int main(void)
{
init();
while (1)
{
remote();
}
}
MfG
Volker
Da es mittlerweile einen Treiber für meinen USBTinyISP für 64bit gibt, hab ich mal AVRStudio 4.18 und WinAVR 2010 auf meinem Rechner installiert. Nun habe ich da ein kleines Problem :
Ich habe von meinem MiniPanoBot ein Programm für den Tiny2313, das bisher wunderbar tat, was es sollte. Nun habe ich gerade einen kleinen Fehler behoben (an 2 Stellen für die Berechnung der Anzahl Schritte pro ° eine 69 durch eine 67 ersetzt, sonst nichts!!) und nun geht mal wieder was nicht. Alerdings habe ich das selbe Phänomen auch bei meiner aktuellen Schaltung festgestellt. In der Motoransteuerung gibt es eine Beschleunigungsrampe, die über eine feste Anzahl Schritte geht. Dafür benutze ich die Variable 'ramp', die ich also 'volatile int ramp=400' global definiert habe. Dies hat wunderbar geklappt, aber nun nicht mehr.... Bei meinem neuen Projekt ging es erst, als ich die Variable direkt in der Funktion deklariert habe, vorher schien die Varible entweder '0' oder irgendetwas undefiniertes kleines zu sein. Leider weiß ich nicht mehr, mit welcher WinAVR Version ich das vorher kompiliert hatte, allerdings haben zwei Versuche mit einer 2009er und einer 2008er Version das witzige Ergebnis geliefert, dass das Programm nicht mehr in das FlashROM passte.... hat einer eine schlaue Idee, ob es da einen Bug gibt oder verstehe ich da was falsch? Meines erachtens ist doch eine volatile Variable quasi sowas wie eine globale Variable?
Mal mein Code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "uart.h"
#include <avr/interrupt.h>
#include <stdint.h>
//#include <avr/pgmspace.h>
#define UART_BAUD_RATE 250000
#define m_delay 1500
volatile uint16_t motor1=0;
volatile uint16_t motor2=0;
//absolute direction in degree (-180 to 180, -90 to 90)
volatile int16_t xpos = 0;
volatile int16_t ypos = 0;
//#define speed 400
volatile int8_t speed = 40;
volatile int ramp = 400;
//const unsigned char step[4]={5,9,10,6};
const unsigned char halfstep[8]={5,1,9,8,10,2,6,4};
//const unsigned char halfstep[8]={0b00001010,0b00001000,0b00001001,0b00000001,0b00 000010,0b00000110,0b00000100,0b00000101};
void init()
{
DDRA = 0b00000011;
DDRB = 0b11111111;
DDRD = 0b00000000;
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
}
void _vdelay_us(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_us(10);
}
}
void _vdelay_ms(int delay)
{
int cnt;
for (cnt=0;cnt<delay;cnt++)
{
_delay_ms(1);
}
}
void step_x(int dir)
{
motor1 = motor1 + dir;
PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
_vdelay_us(speed);
}
void step_y(int dir)
{
motor2 = motor2 + dir;
PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
_vdelay_us(speed);
}
void turn_x(int steps)
{
int cnt;
// int ramp = 400;
int rf=4;
int shortramp=0;
char m=0;
m = motor1;
if (abs(steps)<(ramp*2))
{
shortramp=ramp-(abs(steps)/2);
ramp= abs(steps)/2;
}
else
shortramp=0;
PORTA |= (1<<0);
if (steps>0)
{
for (cnt=0;cnt<=steps;cnt++)
{
step_x(1);
// ramp start/stop
if (cnt<ramp) //start
{
_vdelay_us((ramp-cnt+shortramp)*rf);
}
if (cnt>(steps-ramp)) //stop
{
_vdelay_us((cnt-(steps-ramp-shortramp))*rf);
}
}
}
else
if (steps<0)
{
for (cnt=0;cnt>=steps;cnt--)
{
step_x(-1);
// ramp start/stop
if (abs(cnt)<ramp) //start
{
_vdelay_us((ramp-abs(cnt)+shortramp)*rf);
}
if (abs(cnt)>(abs(steps)-ramp)) //stop
{
_vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
}
}
}
motor1 += steps;
PORTA&=~(1<<0); //motor disable
}
void turn_y(int steps)
{
int cnt;
// int ramp = 400;
int rf=4;
int shortramp=0;
char m=0;
m = motor2;
if (abs(steps)<(ramp*2))
{
shortramp=ramp-(abs(steps)/2);
ramp= abs(steps)/2;
}
else
shortramp=0;
PORTA |= (1<<1);
if (steps>0)
{
for (cnt=0;cnt<=steps;cnt++)
{
step_y(1);
// ramp start/stop
if (cnt<ramp) //start
{
_vdelay_us((ramp-cnt+shortramp)*rf);
}
if (cnt>(steps-ramp)) //stop
{
_vdelay_us((cnt-(steps-ramp-shortramp))*rf);
}
}
}
else
if (steps<0)
{
for (cnt=0;cnt>=steps;cnt--)
{
step_y(-1);
// ramp start/stop
if (abs(cnt)<ramp) //start
{
_vdelay_us((ramp-abs(cnt)+shortramp)*rf);
}
if (abs(cnt)>(abs(steps)-ramp)) //stop
{
_vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
}
}
}
motor2 += steps;
PORTA&=~(1<<1); //motor disable
}
void turn_deg_x(int16_t deg)
{
turn_x(deg*67);
}
void turn_deg_y(int16_t deg)
{
turn_y(deg*67);
}
unsigned char serialin(void)
{
unsigned int c;
c = uart_getc();
while ( c & UART_NO_DATA )
c = uart_getc();
return c;
}
void remote_move()
{
int16_t x,y;
x=serialin()+(serialin()<<8);
y=serialin()+(serialin()<<8);
turn_deg_x(x-(xpos));
turn_deg_y(y-(ypos));
xpos = x;
ypos = y;
uart_putc(0);
}
void remote(void)
{
unsigned int c;
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
//uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
//uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
//uart_puts_P("Buffer overflow error: ");
}
//doing commands
switch(c)
{
case 1:
remote_move();
break;
}
}
}
int main(void)
{
init();
while (1)
{
remote();
}
}
MfG
Volker