Hallo!
Ich möchte in meinem Progamm zu Testzwecken die Funktion sprintf() verwenden. Jedoch habe ich auf dem tiny2313 nur 2K Programmspeicher zur Verfügung, und nach Einbau von sprintf() wird diese Grenze gesprengt und der Compiler verweigert den Dienst.
Ich poste einfach mal meinen ganzen Code. Vielleicht hat ja irgend jemand noch eine Idee, wie ich das Programm kleiner bekomme, ohne Funktionalität einbüßen zu müssen. Mir fällt da leider nichts mehr ein.
Ich bin sicher, dass man für die Konvertierung von int nach char[] auch andere Wege als sprintf() gehen könnte, aber es geht mir eher um die Optimierung des restlichen Codes. Schließlich ist das Programm ohne sprintf() schon bei ca. 1800 Bytes. Das ist zuviel und müsste doch irgendwie verkleinert werden können.
Die Compiler-Option zur Optimierung ist natürlich eingestellt ("-0s", habe alle ausprobiert).
Falls sich jemand wirklich die Qual antut, den kompletten Code nach Möglichkeiten zu durchforsten, dann VIELEN, VIELEN DANK!
Code:
#ifndef F_CPU
#define F_CPU 4000000
#endif
#ifndef UART_BAUD_RATE
#define UART_BAUD_RATE 9600
#endif
//
#include <avr/io.h>
#include <avr/eeprom.h>
#include <stdio.h>
#include <util/delay.h>
/*
#include <avr/interrupt.h>
#include <stdint.h>
#include <stdbool.h>
*/
//
//PROTOTYPEN
void myWait(unsigned int iX);
unsigned int myPot2(unsigned int iExp);
void USART_init(unsigned int baud);
void USART_transmit(unsigned char cData);
void USART_transmit_str(char *cStr);
void long_delay_ms( unsigned long ms );
/***************/
int main(void) {
/***************/
unsigned short int i = 0;
/*
unsigned short int iBin = 0;
unsigned int iWait = 12000;
unsigned int iIncr = 100;
unsigned int iWaitMax = 8000;
unsigned int iWaitMin = 2000;
bool bWaitGoesDown = true;
bool bDirIsLeft = true;
unsigned int iEEPROM_index = 0;
*/
char *cUSART_inp = NULL;
unsigned short int iUSART_inp = 0;
unsigned long iTest=0;
unsigned char cZahl[3] = {0};
//
DDRB = 0xff; //Port B Pins als Ausgänge definieren
PORTB = 0xff;
//DDRD = 0x00; //Port D Pins als Eingänge definieren. Wohl nicht notwendig, da die Bits standardmäßig sowieso 0 sind
//
USART_init(UART_BAUD_RATE);
//
for(;;) {
//
if( iTest++ % 500 == 0 ) {
USART_transmit('.');
}
//
if( UCSRA & (1<<RXC) ) { //Zeichen werden empfangen und im char-array gespeichert
cUSART_inp = (char *)realloc( cUSART_inp , (++iUSART_inp) * sizeof(char) );
cUSART_inp[iUSART_inp-1] = UDR;
}
//
if( !(PIND & (1<<PIND2)) && iUSART_inp>0) { //SW0 gedrückt
for(i=0;i<iUSART_inp;i++) {
eeprom_write_byte(i,cUSART_inp[i]); //char-array (cUSART_inp) in EEPROM speichern
}
//
free(cUSART_inp); //char-array löschen, aber nicht den Index iUSART_inp, da dieser
cUSART_inp = NULL; //beim Zurücklesen gebraucht wird.
//
USART_transmit_str(" SAVED ");
long_delay_ms(200); //wartet 1 Sek, nicht 200 MSek... warum auch immer...
}
//
if( !(PIND & (1<<PIND3)) && iUSART_inp>0) { //SW1 gedrückt
cUSART_inp = (char *)realloc( cUSART_inp , (iUSART_inp) * sizeof(char) );
//
sprintf(cZahl,"%i",iUSART_inp);
USART_transmit_str("iUSART_inp: " + *cZahl);
//
for(i=0;i<iUSART_inp;i++) {
cUSART_inp[i] = eeprom_read_byte(i); //Inhalt des EEPROMs rurück in das char-array schreiben
}
//
USART_transmit_str(cUSART_inp);
//
free(cUSART_inp); //string wurde auf Terminal ausgegeben, daher char-array
cUSART_inp = NULL; //und Index zurücksetzen
iUSART_inp = 0;
}
//
//
// Hier folgen ein Lauflicht und diverse Möglichkeiten, dieses zu beeinflussen.
// Zum Testen von USART- und EEPROM-Funktionen ist dieser Teil auskommentiert.
//
/*
// SW0:
while( !(PIND & (1 << PIND2)) ) {
;// Lauflicht anhalten, wenn SW0 gedrückt ist
}
//
// SW1:
if( !(PIND & (1 << PIND3)) ) { //Laufrichtung ändern, wenn SW1 gedrückt wird
if( bDirIsLeft ) {
bDirIsLeft = false;
iBin = 8;
}else {
bDirIsLeft = true;
iBin = 0;
}
myWait(1000);
}
//
// SW2:
while( !(PIND & (1 << PIND4)) ) { //perfektes Disco-Licht auf SW2 !
PORTB = 0x00;
myWait(2500);
PORTB = 0xff;
myWait(2500);
}
//
// SW3:
if( !(PIND & (1 << PIND5)) ) { //auf SW3 soll per USART ans Terminal gesendet werden
//
USART_transmit('U');
USART_transmit('S');
USART_transmit('A');
USART_transmit('R');
USART_transmit('T');
USART_transmit(' ');
USART_transmit('T');
USART_transmit('E');
USART_transmit('S');
USART_transmit('T');
}
//
if( bDirIsLeft ) { //hier wird die LED verschoben, abhängig von der Laufrichtung
PORTB = 0xff - myPot2(iBin++);
if( iBin==8 ) {
iBin=0;
}
}else {
PORTB = 0xff - myPot2(--iBin);
if( iBin==0 ) {
iBin=8;
}
}
//
myWait(iWait);
//
if( bWaitGoesDown ) {
if( iWait < iWaitMin+500 ) {
iIncr = 20;
}
if( iWait > iWaitMin ) {
iWait -= iIncr;
}else {
bWaitGoesDown=false;
}
}else {
if( iWait > iWaitMin ) {
iIncr = 100;
}
if( iWait < iWaitMax ) {
iWait += iIncr;
}else {
bWaitGoesDown=true;
}
}
*/
}
//
return 0;
}
/***************/
unsigned int myPot2(unsigned int iExp) { //potenziert die Basis 2 mit dem Exponenten iExp
/***************/
unsigned short int i,iErg;
iErg = 1;
for(i=0;i<iExp;i++) {
iErg = iErg * 2;
}
return iErg;
}
/***************/
void long_delay_ms( volatile unsigned long ms ) {
/***************/
while( ms-- )
_delay_ms( 1 );
}
/***************/
void USART_init(unsigned int baud) { //nochmal genau ansehen und schöner formulieren!
/***************/
/*
UBRRH = (unsigned char)(baud>>8); //Baudrate setzen
UBRRL = (unsigned char)baud; //
//
UCSRB = (1<<RXEN)|(1<<TXEN); //Receiver und Transmitter aktivieren
//
UCSRC = (1<<USBS)|(3<<UCSZ0); //8 Datenbits, 2 Stopbits (?)
*/
UCSRA=0x00;
//UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x17;
//
UCSRB = (1<<RXEN)|(1<<TXEN); //Receiver und Transmitter aktivieren
}
/***************/
void USART_transmit(unsigned char cData) {
/***************/
while( !(UCSRA & (1<<UDRE)) ) {
;//warten, bis der transmit buffer leer ist, so dass wieder übertragen werden kann
}
UDR = cData;
}
/***************/
void USART_transmit_str(char *cStr) {
/***************/
while(*cStr) {
USART_transmit(*cStr++);
}
}
Lesezeichen