wkrug
16.02.2016, 15:29
Hallo,
ich möchte die Interruptroutinen eines ATMEGA 328P als Assembler Files generieren.
Ich habe dazu AVR-GCC 4.3.3.
Ich hab dazu folgenden Quelltext geschrieben:
main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include "asm.S"
// Declare your global variables here
volatile uint8_t asmtable = 0;
volatile uint8_t maintable = 0;
//************* Test Working Tables *************
// Registersatz 0, Die Tabellen müssen in der Hauptschleife erzeugt werden
volatile uint8_t pwmport0[13] = {0,1,2,3,4,5,6,7,8,9,10,11,0xFF}; //Reihenfolge und Endemarker
volatile uint16_t pwmtime0[13] = {11,12,13,14,15,16,17,18,19,20,21,22,0}; //PWM Abschaltezeitpunkte
//Zu setzende / löschende Bits auf Port B
volatile uint8_t pwmportb0[13] = {
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
//Zu setzende Bits auf Port C
//Zu setzende / löschende Bits auf Port C
volatile uint8_t pwmportc0[13] = {
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000
};
//Registersatz 1
volatile uint8_t pwmport1[13] = {0,1,2,3,4,5,6,7,8,9,10,11,0xFF};
volatile uint16_t pwmtime1[13] = {21,22,23,24,25,26,27,28,29,30,31,32,0};
//Zu setzende / löschende Bits auf Port B
volatile uint8_t pwmportb1[13] = {
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
//Zu setzende Bits auf Port C
//Zu setzende / löschende Bits auf Port C
volatile uint8_t pwmportc1[13] = {
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000
};
//*****************End of Test Working Tables *************
// External Interrupt 0 service routine
ISR (INT0_vect)
{
uint8_t uc_buffer;
uc_buffer=EICRA;
if((uc_buffer&0b00000011)>0)
{
asm volatile ("nop"); //War die steigende Flanke
}
else
{
asm volatile ("nop"); //War die fallende Flanke
}
EICRA^=0b00000011;
asm volatile ("nop");
asm volatile ("nop");
// Place your code here
}
//Timer 0 Comparematch A Interrupt 5ms generierung
/*ISR (TIMER0_COMPA_vect)
{
asm volatile (
"nop\n\t"
"nop\n\t"
);
}
*/
//Timer 1 Comparematch A Interrupt PWM generierung
/*ISR (TIMER1_COMPA_vect)
{
//asm volatile ("nop");
asm volatile (
"push r16\n\t"
"push r16\n\t"
"nop\n\t"
"pop r16\n\t"
"pop r16"
);
}
*/
//Hauptschleife
int main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
//#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
/*#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif */
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 19,531 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 5,0688 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x62;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 312,500 kHz
// Mode: Fast PWM top=0x03FF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 3,2768 ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (1<<OCIE1A) | (0<<TOIE1);
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (1<<ISC00);
EIMSK=(0<<INT1) | (1<<INT0);
EIFR=(0<<INTF1) | (1<<INTF0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
// USART initialization
// USART disabled
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);
// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// Global enable interrupts
sei();
while (1)
{
PORTB|=(1<<PB4);
asm volatile ("nop");
PORTB&=(~(1<<PB4));
asm volatile ("nop");
// Place your code here
}
return 0;}
Das zugehörige asm.S File ist:
.global TIMER0_COMPA_vect
TIMER0_COMPA_vect:
push r16
nop
pop r16
reti
.global TIMER1_COMPA_vect
TIMER1_COMPA_vect:
push r16
push r16
nop
pop r16
pop r16
reti
Lt. Beschreibung soll das so funktionieren.
Bei mir wird aber immer der Fehler:
In file included from main.c:4:
asm.S:1: error: expected identifier or '(' before '.' token
Eine Funktion ist natürlich noch nicht gegeben, aber compilieren sollte sich der Code eigentlich lassen.
Hat da jemand eine Idee?
ich möchte die Interruptroutinen eines ATMEGA 328P als Assembler Files generieren.
Ich habe dazu AVR-GCC 4.3.3.
Ich hab dazu folgenden Quelltext geschrieben:
main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include "asm.S"
// Declare your global variables here
volatile uint8_t asmtable = 0;
volatile uint8_t maintable = 0;
//************* Test Working Tables *************
// Registersatz 0, Die Tabellen müssen in der Hauptschleife erzeugt werden
volatile uint8_t pwmport0[13] = {0,1,2,3,4,5,6,7,8,9,10,11,0xFF}; //Reihenfolge und Endemarker
volatile uint16_t pwmtime0[13] = {11,12,13,14,15,16,17,18,19,20,21,22,0}; //PWM Abschaltezeitpunkte
//Zu setzende / löschende Bits auf Port B
volatile uint8_t pwmportb0[13] = {
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
//Zu setzende Bits auf Port C
//Zu setzende / löschende Bits auf Port C
volatile uint8_t pwmportc0[13] = {
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000
};
//Registersatz 1
volatile uint8_t pwmport1[13] = {0,1,2,3,4,5,6,7,8,9,10,11,0xFF};
volatile uint16_t pwmtime1[13] = {21,22,23,24,25,26,27,28,29,30,31,32,0};
//Zu setzende / löschende Bits auf Port B
volatile uint8_t pwmportb1[13] = {
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
//Zu setzende Bits auf Port C
//Zu setzende / löschende Bits auf Port C
volatile uint8_t pwmportc1[13] = {
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111111,
0b00111110,
0b00111100,
0b00111000,
0b00110000,
0b00100000,
0b00000000
};
//*****************End of Test Working Tables *************
// External Interrupt 0 service routine
ISR (INT0_vect)
{
uint8_t uc_buffer;
uc_buffer=EICRA;
if((uc_buffer&0b00000011)>0)
{
asm volatile ("nop"); //War die steigende Flanke
}
else
{
asm volatile ("nop"); //War die fallende Flanke
}
EICRA^=0b00000011;
asm volatile ("nop");
asm volatile ("nop");
// Place your code here
}
//Timer 0 Comparematch A Interrupt 5ms generierung
/*ISR (TIMER0_COMPA_vect)
{
asm volatile (
"nop\n\t"
"nop\n\t"
);
}
*/
//Timer 1 Comparematch A Interrupt PWM generierung
/*ISR (TIMER1_COMPA_vect)
{
//asm volatile ("nop");
asm volatile (
"push r16\n\t"
"push r16\n\t"
"nop\n\t"
"pop r16\n\t"
"pop r16"
);
}
*/
//Hauptschleife
int main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
//#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
/*#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif */
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 19,531 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 5,0688 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x62;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 312,500 kHz
// Mode: Fast PWM top=0x03FF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 3,2768 ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (1<<OCIE1A) | (0<<TOIE1);
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (1<<ISC00);
EIMSK=(0<<INT1) | (1<<INT0);
EIFR=(0<<INTF1) | (1<<INTF0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
// USART initialization
// USART disabled
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);
// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// Global enable interrupts
sei();
while (1)
{
PORTB|=(1<<PB4);
asm volatile ("nop");
PORTB&=(~(1<<PB4));
asm volatile ("nop");
// Place your code here
}
return 0;}
Das zugehörige asm.S File ist:
.global TIMER0_COMPA_vect
TIMER0_COMPA_vect:
push r16
nop
pop r16
reti
.global TIMER1_COMPA_vect
TIMER1_COMPA_vect:
push r16
push r16
nop
pop r16
pop r16
reti
Lt. Beschreibung soll das so funktionieren.
Bei mir wird aber immer der Fehler:
In file included from main.c:4:
asm.S:1: error: expected identifier or '(' before '.' token
Eine Funktion ist natürlich noch nicht gegeben, aber compilieren sollte sich der Code eigentlich lassen.
Hat da jemand eine Idee?