Build error: expected 'asm' or '__attribute__' before 'char'

Koupil jsem si tuto knihu Burkhard Mann C PRO MIKROKONTROLÉRY-ANSI-C a pomocí AVRStudia4 AVR-GCC to zkouším se učit ale v příkladu Příklad 1.2: teto knihy jsem narazil

#include <stdio.h> //pro použití funkce printf() //pro použitou platformu MCU
#include <avr/pgmspace.h> //pro použití výstupní funkce AVR fprintf_P()
flash char Txt1] = "Ahoj C\n"; //text, který bude udržován jen v pamìti FLASH
char Txt2]= "konec"; //text, který se bude kopírovat do RAM
{ char Alpha[27]; //pro 26 písmen a 0 jako koncový znak
char I; //pro jednotlivá písmena abecedy
unsigned char i; //jako index pro pole Alpha]
for(I='A', i=0; I<'Z'; ++I, ++i) // zavádìní jednotlivých písmen do pole (array)
printf_P(Txt1); // výstup s textem v pamìti FLASH
printf("%\n", Alpha); // výstup s textem v RAM
printf(Txt2); }

a vygeneruje toto:

Build started 28.9.2010 at 15:05:49
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT prvni.o -MF dep/prvni.o.d  -c  ../prvni.c
../prvni.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'char'
../prvni.c:5: error: expected identifier or '(' before '{' token
make: *** [prvni.o] Error 1
Build failed with 2 errors and 0 warnings...

kde může být chyba? díky za trpělivost.

:arrow_right: administrator: přejmenováno z "Příklad z knihy"

Ten kód asi nebude určenej pro GCC. Na třetím řádku překladač nezná “flash”. Na GCC se používají klíčová slova PROGMEM a potom funkce pro práci s Flash určené. Podrobnější info je v manuálu GCC.

C nebylo původně navrženo pro harvardskou architekturu a v ANSI C tedy není pro přístup do paměti programu žádný standardizovaný postup. Výrobce každého překladače si to tedy lepí po svém.

Zdravím
Tak jak se pracuje s pamětí flash?nějaký malý příklad by by moc pomohl já vím ty mi odkazuješ na manuál GCC ale přesto mohl bys mi jako začátečníkovi pomoc se v tom trochu z orientovat díky moc

Pro práci s flash pamětí se používá knihovna <avr/pgmspace.h>.

K deklaraci hodnot, jejichž hodnota je uložena ve flash se používá PROGMEM.
(Tyto deklarace samozřejmě nelze měnit, prostě slouží k tomu,
aby jsi nezahltil SRAMku)

Př.:

const int Vyska PROGMEM = 172; //Výška v cm const char Jmeno] PROGMEM ="Dežo"; //Jméno oběti ...

Aby však ještě nebylo všemu dost, tak tyto hodnoty NELZE číst klasickými funkcemi.
Ty právě pracují pouze se SRAM pamětí.
Musíš znovu použít funkce z knihovny <avr/pgmspace.h>.

Př.:

if ( strcmp_P( "Johan", Jmeno) == 0) Dat_prachy;
if ( pgm_read_word_near(Vyska) > "153") Dat_vypoved;

Suma sumárum.
Práci s flash pamětí sice využívám, ale jen pro texty (rozuměj “chybové hlášky”) :smiley:
a pro tabulky hodnot.
Samostatné hodnoty typu char, int, atd. nemá cenu takto zpracovávat
protože se u nich výsledný efekt (uvolnění kapacity SRAM) neobjeví,
jelikož je stejně musíš nakonec to SRAMky dostat.

Meloun: ten kus kódu není celej co?
Předpokládám, že by to mělo chodit na tvém zapojení s LCD. Potom ovšem takovýto kousek kódu nemůže v žádném případě pracovat. Printf() vytiskne zadaný text na standardní výstup. u PC je to konzole pokud není stream přesměrován. Co je to u mcu? Nikde tam nastavení streamu nemáš. Vzhledem k tomu, že to rozhodně sám používat nebudu, nehodlám tomu věnovat úsilí abych tuhle žravou a zbytečnnou funkci rozchodil.
Následující kus kódu sice jde přeložit, ale rozhodně nepředpokládám, že by fungoval.[code]#include <stdio.h>
#include <avr/pgmspace.h> //pro použití výstupní funkce AVR fprintf_P()

char text] PROGMEM = “Ahoj C\n”; //text, který bude udržován jen v pamiti FLASH

void main(void)
{
char buff] = “yg”;
printf_P(text); // výstup s textem v pamiti FLASH
printf("%s\n", buff); // výstup s textem v RAM
for(;;);
}[/code]

Spíš upravím tvůj předchozí program, co psal na LCD. Nevím, jesli ten, co jsem ti dával na fórum funguje, ale dopíšu to do něj. Vzhledem k tomu, že to stejně nemám na čem vyzkoušet, bude to na tobě.

Něco jsem slepil, vyzkoušej a uvidíme. Nejsem si jistej, jesli tam ten pointer do pgm_space (jméno pole je pointer) můžu takhle přímo zasadit jako parametr funkce, nebo jesli nebude potřeba některé z maker(PGM_P).
Řešením by samozřejmě bylo zkopírovat text do SRAM a pak vypsat, ale zaplnění ram jsem se chtěl vyhnout, tak jsem to zkusil takto.
Doplnil jsem tam funkci “void LCD_flash_string(char str])”, která by se měla o vypsání textu z flash postarat.

Pro ostatní, kterým se nechce do zdrojáku:

[code]//globální prom.
char text] PROGMEM = “Ahoj C\n”; //text, který bude udržován jen v pamiti FLASH

// volání v main
LCD_flash_string(text);

// funkce samotná
void LCD_flash_string(char str])
{
unsigned char x = 0;
char znak = pgm_read_byte(&(str[x++]));
while(znak != ‘\0’)
{
_delay_ms(1);
LCD_send_char(znak);
znak = pgm_read_byte(&(str[x++]));
}
}[/code]

edit: chyba :slight_smile: pracuju na ní…
edit: tak snad teď
main.c (2.49 KB)

Ten soubor “main.c"který si tady pověsil tak se přeložil v pořádku natáhl jsem ho do atmegy8 bohužel mi to nefunguje, mě to chodí jen z"LCD.h” knihovnou nevím sice proč ale je to tak uvítal bych toto cestu která nemusí mít tuto knihovnu “LCD.h” ze kterou výsledný překlad je podstatně větší ale nedaří se mi to rozchodit. díky za trpělivost

Dej mi sem funkční kód z toho vlákna, kde ti nakonec displej chodil. Se podívám po rozdílech, snad tam uvidím, jesli je chyba jako obvykle mezi mojí klávesnicí a židlí, nebo byl nefunkční už ten upravovanej zdroják.

Tak jsem si pohrával a dal jsem do všech _delay_ms(10) ve tvém "main.h"a světe div se když jsem natáhl do atmegy8 a funguje to až do té doby něž vypnu napájení když to opět zapnu tak se zobrazí na 1 sekundu celý první řádek pak to zmizí nic méně tady pověsím ten program který mě funguje konkrétně ty soubory které jsou zvýrazněny díky za trpělivost.
screen.JPG
LCD_Test.zip (74 KB)

Trochu po lopatě:

  1. Abychom mohli ovládat LCD displej (nebo jinou periférii), potřebujeme k tomu knihovnu.

  2. Každá knihovna má dva soubory, “.h" a ".c” .
    Např knihovna pro LCD se skládá ze souborů “lcd.h” a “lcd.c”.

Soubor “lcd.h” obsahuje za prvé různé definice (#define…), za druhé deklarace funkcí (prototypy funkcí), např:
void lcd_putc(char c);

V souboru “lcd.c” je potom kód funkcí, deklarovaných v souboru “lcd.h”, např:
void lcd_putc(char c)
{
write_data©;
}

  1. Soubor “lcd.c” přidáme v AvrStudiu do Source Files.
    Soubor “*.h” vložíme (#include “lcd.h”)

Takže i když bys to uvítal, tak bez toho lcd.h to asi nepůjde.
Ostatně není pravda, že “s lcd.h je kód podstatně větší”.
Tvoje (Fleuryho) knihovna zabírá asi 430 bajtů, což jistě není moc.
Nejvíc v tvém kódu (LCD_test.c) zabírá funkce sprintf().

Kód, který napsal Piityy se dá zjednodušit, protože Fleuryho knihovna už obsahuje funkci pro zobrazení flash stringu.

[code]#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include “lcd.h”

//definuj stringy ve FLASH
const char menu1] PROGMEM = “MENU1”;
const char menu2] PROGMEM = “MENU2”;
const char menu3] PROGMEM = “MENU3”;
const char menu4] PROGMEM = “MENU4”;
const char menu5] PROGMEM = “MENU5”;

int main()
{

lcd_init(LCD_DISP_ON );

for(;:wink:
{
//zobraz string “menu1”
lcd_clrscr(); // vymaž displej
lcd_puts_p(menu1); // zobraz string umístěný ve FLASH
_delay_ms(1000);
}
}
[/code]

Ten main, co jsem sem dal je z jinýho vlákna - obsluha je tam bez knihovny (napsaná ručně). Využívá pouze vestavěné funkce GCC pro práci s flash. Jen to asi nefachá. Nemám to na čem vyzkoušet…
Snad tvůj kód pojede.

Zdravím
Ten příklad co uveřejnil AB mě funguje taky se asi musím spokojit že to bez té knihovny “LCD.h” nepůjde.
Další věc kterou chci prozkoumat práci uart bohužel atmega8 má právě RXD je na pinu PD0 na něm mám připojen signál displeje RS a signál TXD je na pinu PD1 na něm je signál R/W z toho vyplývá zásadní otázka jestli tyto signály mohu přesunout třeba někam na port C?
další otázka jak to udělat aby jsem mohl k pinu portu C tlačítko?
díky za trpělivost.

Můžeš. Je třeba v lcd.h přepsat definice daných signálů.
Co je za problém s tlačítkem? Prostě ho tam připoj (obvykle mezi pin a zem, odpor mezi pin a Vcc nebo se místo něj aktivuje pullup v procesoru).
Není mi moc jasný, jak chceš něco dělat s uartem, když nevíš jak připojit tlačítko (a předpokládám, že ani ho obsloužit). Opisováním příkladů z knížky se to vážně nenaučíš.

To není potřeba přepnout jako u PIC v registru tris ? a ve kterém registru se aktivuje ten pullup rezistor a jak se zjišťuje logický stav pinu v C ? to jsou pro tebe absurdní otázky ale pro mě který začínal u "konkurence =PIC " z seriálu článků z KTE magazínu pak s knihy “Moderní učebnice programování PIC 1,2” nebo jakou knihu si mám pořídit ve které najdu odpovědi na tyto otázky? díky za trpělivost

Piny u avr jsou defaultně po resetu nastaveny jako vstupní a to je to, co pro tlačítko potřebuješ - chceš číst jeho stav. Když je v DDR registru příslušného portu “0”, pin je vstupní. Stav pinu se čte z registru PINx. Zde je nutné také znát logické funkce a jejich zápis v C.
Když je pin jako vstupní a do registru PORTx zapíšeš “1”, aktivuje se pull-up.

[code]DDRC &= ~(1<<PC1); // vynulovani bitu 1 v DDRC, pin je vstup
PORTC |= 1<<PC1; // nastaveni bitu 1 v PORTC,
// jelikoz je pin vstupni, aktivuje se pull-up

// tlacitko je mezi PC1 a GND
if(!(PINC & (1<<PC1)))
{
// tlacitko stisknuto, na pinu je “0”

//nejaky kod, treba rozsvitit ledku

}
else
{
// tlacitko nestisknuto

// nejaky kod, treba zhasnout ledku

}[/code]
Co se týká knížek, zkus se nejdřív podívat tady na fóru, jesli některá nebude do začátku rozumná, osobně jsem je nezkoumal.

edit: tak jsem trochu koukal, ale většina jich předpokládá alespoň zaklady práce s mcu, nebo začínají s asm. Tak nížka, kterou máš ty, má podle obsahu rozumnej popis jazyka, ale chybějí tam příklady opravdu do začátku.

Zdravím
Potřeboval bych napsat do prvků pole[40] do paměti flash výsledky násobku
x=1;
for i = 0 to 40
x=x*2;
pole(i)=x;
next
ten příklad píši to v basicu jen pro představu to
asi nepůjde? díky za trpělivost

To rozhodně nepujde, flash je jen pro čtení (až na výjimky, ale to bych teď neřešil).

Zdravím
Mám takový problém

for (i = 0; i < 255 ; i++)

tento kód zvyšuje i = 1 po 1 se zvyšuje až 255 jak to upravit aby to odečítalo to znamená i=255 na i=0? díky za trpělivost.

for (i = 255; i > 0 ; i–)
Tohle však půjde jen do 1 (nejmenší číslo použitelné uvnitř cyklu je 1). Jesli to potřebuješ až do 0, musí být výpočet prováděn uvnitř cyklu.
for(i=255; i>0; )
{
i–;
// dalsi prikazy
}

Kdybys to totiž napsal for (i = 255; i >= 0 ; i–), vytvořil bys nekonečnej cyklus - když odečteš od 0 jedničku, v unsigned char z toho vznikne 255 a cykl by jel dál.

Zdravím
Za první co to za upozornění? sice to mohu dát přeložit ale překlad je nepřesný warning: suggest parentheses around assignment used as truth value
za druhé mám tady ten úryvek kódu

 for (i = 0; i < 255 ; i++){
  if(!(PINC & (1<<PC3))) //když tento řádek za komentuji
  obsah* = 0x01; 
  else                          // tento taky a do slova v nutím logickou 1 
  {obsah*= 0x00;}    // tento taky pořád obdobný výsledek 

ve kterém chci aby na základě logické úrovně na vstupním pinu PC3 se zapsala na aktuální pozici pole “obsah” buď logická “1” nebo “0”

a za třetí

char buffer [8];
int main()
 lcd_init(LCD_DISP_ON );
    
    for (i=0; i <255;i++){
	
   sprintf (buffer, "%d",obsah*);
   lcd_puts(buffer);
    _delay_ms(1000);
   }
   } 

aby se mi to vypisovaly ty logické úrovně na displej bohužel se tak neděje vypisuji se tam hodnoty "10000000100000000"atd.díky za trpělivost***