Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenos días.
Estoy intentanto hace un pequeño programilla en C para el micro de Atmel Attiny 26.
Utilizo el compilador que suministra el propio Atmel, el AVR Studio 4.18. Bien, este es el código:
#include "stdio.h"
#include "interrupt.h"
#include "tn26def.inc"
unsigned char PB3_ant = 0;
unsigned char flanco = 0;
unsigned char regula = 1;
unsigned char incremento = 0;
unsigned int contaje = 0;
unsigned int segundero = 0;
// Tratamiento interrupción timer1
ISR(OVF1addr) {
contaje = contaje + 1;
if (contaje == 976)
{
segundero = segundero + 1;
contaje = 0;
}
}
// Programa principal
void main ()
{
while (1)
{
DDRB = 0x00; // set PB3 as input
if ((PORTB & 1<< PINB3) && (PB3_ant==0)) // Detectar flanco ascendente para inicio
{
flanco = 1;
TCNT1 = 0x00;
TCCR1B = 0x01; //Define preescalado (CPU/16384) y arranca Timer1).
PB3_ant = (PORTB & 1<<PINB3);
}
else PB3_ant = (PORTB & 1<<PINB3);
while (flanco == 1) //Inicio regulación
{
if (regula == 1)
{
if (segundero == 22)
{
incremento = incremento + 1;
DDRA = 0xFF; // set PORTA as output
PORTA = incremento;// turn on pullup resistor for PORTA
}
if (segundero == 5400)
{
incremento = 0xff;
DDRA = 0xFF; // set PORTA as output
PORTA = incremento;// turn on pullup resistor for PORTA
regula = 2;
}
}
if (regula == 2)
{
if (segundero == 36000)
{
regula = 3;
segundero = 0;
incremento = 0xFF;
}
}
if (regula == 3)
{
if (segundero == 22)
{
incremento = incremento - 1;
DDRA = 0xFF; // set PORTA as output
PORTA = incremento;// turn on pullup resistor for PORTA
}
if (segundero == 5400)
{
incremento = 0;
DDRA = 0xFF; // set PORTA as output
PORTA = incremento;// turn on pullup resistor for PORTA
regula = 1;
segundero = 0;
}
}
DDRB |= (0<<PB3); // set PB3 as input
if((PORTB3 & 0<< PINB3) && (PB3_ant==1)) // Detectar flanco descendente para fin
{
flanco = 0;
TCNT1 = 0x00;
segundero = 0;
TCCR1A = 0x00; // Para timer1.
incremento = 0;
regula = 1;
PB3_ant = (PORTB & 1<<PINB3);
}
else PB3_ant = (PORTB & 1<<PINB3);
PB3_ant = (PORTB & 1<<PINB3);
SEI();
TIMSK |= 1 << TOIE1;
CLI();
}
PB3_ant = (PORTB & 1<<PINB3); //PB3_ant <- PB3
}
}
El problema me surge con la sentencia: #include <tn26def.inc>, cuyo contenido es (lo he acortado un poco para que no se haga muy extenso):
/***************************************************************************
* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y *
*
* Number :AVR000
* File Name :"tiny26def.inc"
* Title :Register/Bit Definitions for the ATtiny26
* Date :April 16th, 2002
* Version :1.00
* Support E-mail :support@atmel.no
* Target MCU :ATtiny26
*
* DESCRIPTION
* When including this file in the assembly program file, all I/O register
* names and I/O register bit names appearing in the data book can be used.
* In addition, the six registers forming the three data pointers X, Y and
* Z have been assigned names XL - ZH. Highest RAM address for Internal
* SRAM is also defined
*
* The Register names are represented by their hexadecimal address.
*
* The Register Bit names are represented by their bit number (0-7).
*
* Please observe the difference in using the bit names with instructions
* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
* (skip if bit in register set/cleared). The following example illustrates
* this:
*
* in r16,PORTB ;read PORTB latch
* sbr r16,(1<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#)
* out PORTB,r16 ;output to PORTB
*
* in r16,TIFR ;read the Timer Interrupt Flag Register
* sbrc r16,TOV0 ;test the overflow flag (use bit#)
* rjmp TOV0_is_set ;jump if set
* ... ;otherwise do something else
************************************************************************/
;** Specify Device
.device ATtiny26
;** I/O Register Definitions
equ SREG =$3F
equ SP =$3D
equ GIMSK =$3B
equ GIFR =$3A
equ TIMSK =$39
equ TIFR =$38
equ MCUCR =$35
equ MCUSR =$34
equ TCCR0 =$33
efine TCNT0 =$32
equ OSCCAL =$31
equ TCCR1A =$30
equ TCCR1B =$2F
equ TCNT1 =$2E
equ OCR1A =$2D
equ OCR1B =$2C
equ OCR1C =$2B
equ PLLCSR =$29
equ WDTCR =$21
.equ EEAR =$1E
.equ EEDR =$1D
.equ EECR =$1C
.equ PORTA =$1B
.equ DDRA =$1A
.equ PINA =$19
.equ PORTB =$18
.equ DDRB =$17
.equ PINB =$16
.equ USIDR =$0F
.equ USISR =$0E
.equ USICR =$0D
.equ ACSR =$08
.equ ADMUX =$07
.equ ADCSR =$06
.equ ADCH =$05
.equ ADCL =$04
;** Bit Definitions
;** GIMSK **
.equ INT0 =6
.equ PCIE1 =5
.equ PCIE0 =4
;** GIFR
.equ INTF0 =6
.equ PCIF =5
;** TIMSK **
.equ OCIE1A =6
.equ OCIE1B =5
.equ TOIE1 =2
.equ TOIE0 =1
;** TIFR ******
.equ OCF1A =6
.equ OCF1B =5
.equ TOV1 =2
.equ TOV0 =1
.equ INT0addr =$001 ;External Interrupt0 Vector Address
.equ IOPINSaddr =$002 ;Pin change interrupt
.equ OC1Aaddr =$003 ;Output Compare1A Interrupt Vector Address
.equ OC1Baddr =$004 ;Output Compare1B Interrupt Vector Address
.equ OVF1addr =$005 ;Overflow1 Interrupt Vector Address
.equ OVF0addr =$006 ;Overflow0 Interrupt Vector Address
.equ USI_STARTaddr =$007 ;Universal Seria Bus Start Interrupt Address
.equ USI_OVFaddr =$008 ;Universal Seria Bus Overflow Interrupt Address
.equ ERDYaddr =$009 ;EEPROM Ready Interrupt Vector Address
.equ ACIaddr =$00A ;Analog Comparator Interrupt Vector Address
.equ ADCCaddr =$00B ;ADC conversion complete Interrupt Vector Address */
Por lo que podeis ver son "etiquetas" para digamos programar más cómodamente, y por lo que veo son sentencias propias del lenguaje ensamblador. El caso es que al compilar el programa me da multitud de errores del tipo:
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:45:12: error: invalid suffix "A" on integer constant
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:46: error: stray '$' in program
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:47: error: stray '$' in program
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:48: error: stray '$' in program
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:49: error: stray '$' in program
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:50: error: stray '$' in program
D:PROGRAMASAVR_TOOLSAvrStudio4..AvrAssemblerAppnotes/tn26def.inc:51: error: stray '$' in program
con lo que entiendo que este tipo de sentencias no le gustan. He probado a modificar este archivo (guardándolo con otro nombre), con cosas como: sustituir los "equ" por "#define", borrando el símbolo "$" etc etc y he conseguido que se compile sin errores. Pero claro, me aparecen otro tipo de "errores" casualmente cuando hago referencia a alguna de las etiquetas como por ejemplo:
.
DDRB = 0x00; // set PB3 as input
con el error:
../principal.c:34: error: 'DDRB' undeclared (first use in this function)
En fin, alguien que me pueda orientar un poco, ¿es correcto lo que estoy haciendo incluyendo ese archivo de definiciones?, debería de ser un archivo digamos "tn26def.c" o algo así.
Muchas gracias.
Hola:
Estas intentando '#incluir' un archivo de cabecera o definiciones de ensamblador en un programa de C (GNU-GCC del WinAVR, que se integra en el AVRStudio, aunque no sea parte de el). Aunque nunca he trabajado con el ATTiny, me imagino que en realidad no tienes que añadir ningún include específico. Con:
#include <avr/io.h>
y el correcto setup del makefile debería bastarte. Si no voy equivocado, al definir el procesador en el makefile, el <avr/io.h> te incluye las definiciones necesarias pertinentes según el procesador que hayas elegido, facilitando mucho la migración de un micro a otro. Para añadir otras librerías estándar, puedes usar:
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
Buenas.
Muchas gracias Beamspot, resisando el <io.h> he visto a su vez otro archivoi .h con las definiciones para el micro en cuestión. Y nada, ha sido definir el micro al comienzo del programa y todos los errores han desaparecido.
Saludos!
De nada. Gracias a tí por finalizar el hilo explicando que la solución te ha funcionado.