Hallo,
Ik heb nu een tijdje zitten overwegen om c te gaan gebruiken omdat ik nu met linux werk (ik heb nog wel een dualboot windows) maar daarom lijkt het me beter om c te gaan gebruiken, alleen deze taal lijkt me veel moeilijker.
Is c beter als bascom ?, en weet iemand een paar makkelijke beginners tutorials ?
Op 30 januari 2010 00:07:07 schreef avr-linux:
alleen deze taal lijkt me veel moeilijker.
De instap voor C is hoger.
Is c beter als bascom ?
Er is geen 'beter als dan', elke programmeertaal heeft zijn plaats en doelgroep.
Op 30 januari 2010 00:07:07 schreef avr-linux:
...... en weet iemand een paar makkelijke beginners tutorials ?
Sinds enkele weken heb ik het boek van Wim Dolman: "Micro controllers en de taal C".
Voor mij een heel leerzaam boek. C wordt duidelijk uitgelegd. En vooral de combinatie C en AVR maakt praktisch heel toepasbaar.
http://mic.dolman-wim.nl/index.html (..nee, ik heb geen aandelen)
En hier staat ie nog een keer + nog veel meer.
http://www.circuitsonline.net/forum/view/66299/1/mikroc+tutorial
Oke ik heb nu voor c gekozen maar nu heb ik al gelijk een probleem.
Namelijk ik weet dus nog niks van c en nu wil ik eerst de programmer onder linux testen.
klopt deze code :
#include <avr/io.h>
#include <util/delay.h>
// knipperende LED op PORTA.0 (PA0)
int main()
{
// PA0 als output
DDRB = (1 << PB0);
// oneindige lus
while(1)
{
// 0.5 sec delay
_delay_ms(500);
// PA0 hoog niveau
PORTB |= (1 << PB0);
// 0.5 sec delay
_delay_ms(500);
// PA0 laag niveau
PORTB &= ~(1 << PB0);
}
return 0;
}
Ik heb een led aangesloten op PB0
en hoe maak ik een hex bestand hiervan ?
[Bericht gewijzigd door avr-linux op (26%)]
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Plaats dit in een bestand met de naam "Makefile"
# Makefile voor een ATmega8
MCU=atmega8
CC=avr-gcc
OBJCOPY=avr-objcopy
TARGET=m8
# optimize for size:
CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues --save-temps
all: Main.hex
Main.hex : Main.out
$(OBJCOPY) -R .eeprom -O ihex Main.out Main.hex
Main.out : Main.o
$(CC) $(CFLAGS) -o Main.out -Wl,-Map,Main.map Main.o
Main.o : Main.c
$(CC) $(CFLAGS) -c Main.c
load:
avrdude -y -p $(TARGET) -c dapa -e -U flash:w:Main.hex
# Zet de programmeer/erase counter op 0
initcnt:
avrdude -p $(TARGET) -c dapa -Y 0
# Enable full-swing xtal-oscillator (CKOPT)
fullswing:
avrdude -p $(TARGET) -c dapa -U hfuse:w:0xc9:m
# Nuttige fuse byte settings:
# BODLEVEL BODEN SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0
# 1 1 1 0 0 0 0 1 originele setting, interne osc. 1MHz
# 0 0 0 0 0 0 0 1 interne osc. 1MHz, BOD enabled
# 0 0 0 0 0 0 1 0 interne osc. 2MHz, BOD enabled
# 0 0 0 0 0 0 1 1 interne osc. 4MHz, BOD enabled
# 0 0 0 0 0 1 0 0 interne osc. 8MHz, BOD enabled
# 0 0 0 1 1 1 1 0 kristal, BOD enabled
readfuse:
avrdude -p $(TARGET) -c dapa -U lfuse:r:ATmega8.lfuse:h
avrdude -p $(TARGET) -c dapa -U hfuse:r:ATmega8.hfuse:h
# use internal RC oscillator 1 Mhz, BOD enabled
wrfuse1mhz:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0x01:m
# use internal RC oscillator 2 Mhz, BOD enabled
wrfuse2mhz:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0x02:m
# use internal RC oscillator 4 Mhz, BOD enabled
wrfuse4mhz:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0x03:m
# use internal RC oscillator 8 Mhz, BOD enabled
wrfuse8mhz:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0x04:m
# use external 3-8 Mhz crystal
wrfusecrystalslow:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0xee:m
# use external 8 - 16Mhz full-swing crystal, BOD enabled
wrfusecrystal:
avrdude -p $(TARGET) -c dapa -U lfuse:w:0x1e:m
clean:
rm -f *.o *.map *.out *.hex *~ *.i *.s
good:
indent -kr *.c
rm -f *.o *.out *.map *~ *.hex *.i *.s
check:
avr-size -d Main.out
tags:
rm -f *.o *.out *.map *~ *.hex *.i *.s
etags *.c *.h
Vervang "Main" telkens door de naam van je programma.
Nu hoef je enkel "make clean all load" in te tikken, en als het goed is, gaat de LED aan het knipperen.
Let ook op de warnings. Je kan er al eentje verwachten omdat je de systeemklok (F_CPU) niet hebt opgegeven aan het begin van je code.
Bedankt, maar ik gebruik een atmega88 en mysmartusb.
En als ik avr-gcc blink.c in de terminal type dan krijg ik de volgende error :
sudo avr-gcc blink.c
In bestand ingevoegd vanuit blink.c:2:
/usr/lib/gcc/avr/4.3.3/../../../avr/include/avr/io.h:313:6: let op: #warning "device type not defined"
In bestand ingevoegd vanuit blink.c:3:
/usr/lib/gcc/avr/4.3.3/../../../avr/include/util/delay.h:90:3: let op: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
blink.c: In functie ‘main’:
blink.c:6: fout: ‘DDRB’ undeclared (first use in this function)
blink.c:6: fout: (Each undeclared identifier is reported only once
blink.c:6: fout: for each function it appears in.)
blink.c:6: fout: ‘PB0’ undeclared (first use in this function)
blink.c:8: fout: ‘PORTB’ undeclared (first use in this function)
Wat is er mis ?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
sudo avr-gcc blink.c
avr-gcc heeft er het raden naar, voor welk type AVR hij moet compileren. Weet dus ook niet hoe hij "PORTB" moet vertalen. Zie Makefile hierboven...
Tja ik heb nu van alles geprobeerd ik heb nu de volgende bestanden gekregen :
blink.c <- orgineel
blink.c~
blink.o
Wat kan ik hier mee ?
EDIT:
Haha, laat maar het werkt al 
[Bericht gewijzigd door avr-linux op (13%)]
Ik ben nu dus een beetje test programmatjes aan het maken maar het wil dus steeds niet lukken nu ben ik er achter gekomen dat de delay functie niet werkt ...
Ik krijg deze fout :
/usr/lib/gcc/avr/4.3.3/../../../avr/include/util/delay.h:90:3: let op: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
wat kan ik hier aan doen ?
EDIT sorry weer te vroeg iets gevraag, ik heb de make file van pros aan gepast en nu werkt het allemaal perfect.
Dankje pros
[Bericht gewijzigd door avr-linux op (15%)]
Ik zit nu weer met een probleem ik heb nu een led display in elkaar gesoldeerd, alleen de leds een voor een uit zetten werkt niet.
Ik gebruik daar deze code voor :
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 255; /* onderste rij minnen*/
DDRD = 255;
while(1)
{
PORTB |= (1<<PB7);
_delay_ms(100);
PORTB &= ~(1<<PB7);
}
return 0;
}
Alleen er gaat wel een rij leds aan maar ze gaan niet meer uit hoe kan dat ?
[Bericht gewijzigd door avr-linux op (27%)]
ben je geen delay vergeten? Als je een 1
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 255; /* onderste rij minnen*/
DDRD = 255;
while(1)
{
PORTB |= (1<<PB7);
_delay_ms(100);
PORTB &= ~(1<<PB7);
_delay_ms(100);
}
return 0;
}
of
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 255; /* onderste rij minnen*/
DDRD = 255;
while(1)
{
PINB |= (1<<PB7);
_delay_ms(100);
}
return 0;
}
is het zelfde. Zie datasheet atmega88.
Nog een vraagje.
Ik heb nu dus aardig wat leds om aan te sturen maar hoe kan ik elke led een symbool geven.
Dus bij voorbeeld als ik led1 aan type dat dan PB0 en PB7 aan gaan ?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Bedoel je define's? Zoiets, dus:
#define led1_aan PORTB |= _BV(PB0) | _BV(PB7)
// Wat verder...
led1_aan;
Precies zoals hij aangeeft.
Wat je ook kan doen:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define LED1 PB7
int main(void) {
DDRB = 0xFF; /* onderste rij minnen*/
DDRD = 0xFF;
while(1)
{
PORTB |= (1<<LED1);
_delay_ms(100);
PORTB &= ~(1<<LED1);
_delay_ms(100);
}
return 0;
}
Of voorbeeld van pros:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define led1_aan PORTB |= (1<<PB7)
#define led1_uit PORTB &= ~(1<<PB7)
int main(void) {
DDRB = 0xFF; /* onderste rij minnen*/
DDRD = 0xFF;
while(1)
{
led1_aan;
_delay_ms(100);
led1_uit;
_delay_ms(100);
}
return 0;
}
Ik heb nu dit maar dat werkt niet :
#define F_CPU 8000000UL
#define led1_aan PORTB |= (0<<PB0) |= (1<<PB7)
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 255;
DDRD = 255;
while(1) {
led1_aan;
}
return 0;
}
Als ik led 1 aan wil zetten dan moet ik PB0 sinken en PB7 hoog maken.
Hoe kan ik dat doen in die define regel ?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
wel, precies zoals het er staat. De define plaats je helemaal aan het begin van je code. In de rest van je programma kan je dan "led1_aan;" intikken ipv "PORTB |= _BV(PB0) | _BV(PB7);"
Let wel op met define's. De preprocessor doet niet steeds wat jij denkt dat hij zal doen. Je kan zien wat hij er van bakt met de magische woorden
avr-cpp jouwprogramma.c | more
Je kan meerdere regels code in een define plaatsen. Zo:
#define F_CPU 8000000UL
#define led1_aan PORTB &= ~(1<<PB0); \
PORTB |= (1<<PB7)
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 255;
DDRD = 255;
while(1) {
led1_aan;
}
return 0;
}
De preprocessor weet dan dat beide regels tot dezelfde define behoren.