Dag iedereen,
Ik ben net begonnen met mc's en als oefening probeer ik met een tiny2313 een 7 segment teller met 2 segmenten te maken.
in men code probeer ik een waarde af te ronden, maar AVRstudio geeft een error als ik wil compilen. Heeft iemand een idee wat ik verkeerd doe?
segment2 = floor (count/10);
segment1 = count - segment2;
dit is men volledige code
/*
verbindngen 7segment:
a->PD5
b->PD4
c->PD1
d->PD2
e->PD3
f->PD6
g->PD7
DP->PD0
*/
#include <avr/io.h>
#include <util/delay.h>
#define SEVEN_SEGMENT_PORT PORTB
#define SEVEN_SEGMENT_DDR DDRB
void SevenSegment(uint8_t n,uint8_t dp)
{
/*
This function writes a digit given by n to the display
the decimal point is displayed if dp=1
Note:
n must be less than 9
*/
if(n<10)
{
switch (n)
{
case 0:
SEVEN_SEGMENT_PORT=0b01111110;
break;
case 1:
SEVEN_SEGMENT_PORT=0b00010010;
break;
case 2:
SEVEN_SEGMENT_PORT=0b10111100;
break;
case 3:
SEVEN_SEGMENT_PORT=0b10110110;
break;
case 4:
SEVEN_SEGMENT_PORT=0b11010010;
break;
case 5:
SEVEN_SEGMENT_PORT=0b11100110;
break;
case 6:
SEVEN_SEGMENT_PORT=0b11101110;
break;
case 7:
SEVEN_SEGMENT_PORT=0b01110010;
break;
case 8:
SEVEN_SEGMENT_PORT=0b11111110;
break;
case 9:
SEVEN_SEGMENT_PORT=0b11110110;
break;
case 10:
SEVEN_SEGMENT_PORT=0b00011110;
break;
case 11:
SEVEN_SEGMENT_PORT=0b10001110;
break;
case 12:
SEVEN_SEGMENT_PORT=0b00000010;
break;
case 13:
SEVEN_SEGMENT_PORT=0b10001010;
break;
case 14:
SEVEN_SEGMENT_PORT=0b11001100;
break;
}
if(dp)
{
//if decimal point should be displayed
//make 0th bit Low
SEVEN_SEGMENT_PORT&=0b11111110;
}
}
else
{
//This symbol on display tells that n was greater than 9
//so display can't handle it
SEVEN_SEGMENT_PORT=0b11111101;
}
}
void main()
{
int count;
int segment1;
int segment2;
SEVEN_SEGMENT_DDR=0xFF; //All output
SEVEN_SEGMENT_PORT=0x00; //All segments off
count=0;
// oneindige lus
while(1)
{
segment2 = floor (count/10);
segment1 = count - segment2;
SevenSegment(count,0);
// PB0 hoog niveau (decimal point)
PORTB |= (1 << PB0);
// teller +1
count++;
// 0.5 sec delay
_delay_ms(500);
// PB0 laag niveau
PORTB &= ~(1 << PB0);
if(count==100)
{
count=0;
}
// 0.5 sec delay
_delay_ms(500);
}
}alvast bedankt
RobHoi
42
Wat was de foutmelding?
Edit: misschien moet je math.h includen
[Bericht gewijzigd door RobHoi op (48%)]
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
floor() is een functie die met floats werkt. Niet aan te bevelen voor een µC, dus.
Je kan het ook zo doen:
unsigned char getal; // Max 99!
unsigned char tientallen = 0;
while (getal > 9) {
tientallen++;
getal -= 10;
}
// getal bevat nu de eenheden
Dat neemt enkele regels meer in beslag, maar de uiteindelijke code zal heel wat kleiner zijn.
Daarnaast kan je beter een opzoek-tabel gebruiken om te weten welke segmenten moeten oplichten.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Progger
GMT+1
het resultaat van een deling mag je niet in een integer opslaan.
en dus heeft de TS netjes de Floor functie gebruikt, wat kennelijk ook niet werkt.
beter is het om de div en mod functies te gebruiken (de mod functie heet inderdaad % in C)
en dan met 2 variabelen werken, zoals pros zegt.
p.s. waarom heb je 14 cases als je n maar tot 9 gaat?
Op 14 mei 2010 16:36:15 schreef Progger:
het resultaat van een deling mag je niet in een integer opslaan.
En waarom dan niet? Je moet alleen weten wat er gebeurt.
Op 14 mei 2010 16:35:48 schreef pros:
Jouw code neemt 10 bytes extra in beslag...
Maar ik bespaar 10 toetsaanslagen 
[Bericht gewijzigd door JoWi op (29%)]
eagle987
Eerst waren het atomen, dan waren het protonen, neutronen, elektronen, nog later waren het quarks en nu blijken het snaren te zijn...
if(n<10)
{...
case 10:
SEVEN_SEGMENT_PORT=0b00011110;
break;
case 11:
SEVEN_SEGMENT_PORT=0b10001110;
break;
...
}
lijkt me niet echt nuttig..
int count;
count=0;mag je gerust vervangen door:
int count = 0;int segment2;
segment2 = floor (count/10);Vervang deze integer eens in een float of double variabele, dan zou het moeten werken.
Bedankt voor de tips iedereen
Ik heb het als volgt opgelost
int count = 0;
int tientallen;
int eenheden;
SEVEN_SEGMENT_DDR=0xFF;
SEVEN_SEGMENT_PORT=0x00;
while(1)
{
tientallen = count / 10;
tientallen = tientallen % 10;
eenheden = count - (10*tientallen);p.s. waarom heb je 14 cases als je n maar tot 9 gaat?
Dat zijn nog restanten van één van mijn probeersels. Er komen nog stukken code bij en er gaan ook nog stukken uit.
Hoe accuraat is de interne timer van de tiny2313 trouwens. Ik heb in men project settings de frequentie op 10Mhz gezet, maar men teller wijkt per seconde toch nog een paar tienden af.
volledige code
/*
verbindngen 7segment:
a->PD5
b->PD4
c->PD1
d->PD2
e->PD3
f->PD6
g->PD7
DP->PD0
*/
#include <avr/io.h>
#include <util/delay.h>
#define SEVEN_SEGMENT_PORT PORTB
#define SEVEN_SEGMENT_DDR DDRB
void SevenSegment(uint8_t n,uint8_t dp)
{
/*
This function writes a digit given by n to the display
the decimal point is displayed if dp=1
Note:
n must be less than 9
*/
if(n<10)
{
switch (n)
{
case 0:
SEVEN_SEGMENT_PORT=0b01111110;
break;
case 1:
SEVEN_SEGMENT_PORT=0b00010010;
break;
case 2:
SEVEN_SEGMENT_PORT=0b10111100;
break;
case 3:
SEVEN_SEGMENT_PORT=0b10110110;
break;
case 4:
SEVEN_SEGMENT_PORT=0b11010010;
break;
case 5:
SEVEN_SEGMENT_PORT=0b11100110;
break;
case 6:
SEVEN_SEGMENT_PORT=0b11101110;
break;
case 7:
SEVEN_SEGMENT_PORT=0b01110010;
break;
case 8:
SEVEN_SEGMENT_PORT=0b11111110;
break;
case 9:
SEVEN_SEGMENT_PORT=0b11110110;
break;
case 10:
SEVEN_SEGMENT_PORT=0b00011110;
break;
case 11:
SEVEN_SEGMENT_PORT=0b10001110;
break;
case 12:
SEVEN_SEGMENT_PORT=0b00000010;
break;
case 13:
SEVEN_SEGMENT_PORT=0b10001010;
break;
case 14:
SEVEN_SEGMENT_PORT=0b11001100;
break;
}
if(dp)
{
//if decimal point should be displayed
//make 0th bit Low
SEVEN_SEGMENT_PORT&=0b11111110;
}
}
else
{
//This symbol on display tells that n was greater than 9
//so display can't handle it
SEVEN_SEGMENT_PORT=0b11111101;
}
}
void main()
{
int count = 0;
int tientallen;
int eenheden;
SEVEN_SEGMENT_DDR=0xFF; //All output
SEVEN_SEGMENT_PORT=0x00; //All segments off ;
// oneindige lus
while(1)
{
tientallen = count / 10;
tientallen = tientallen % 10;
eenheden = count - (10*tientallen);
SevenSegment(eenheden,0);
// PB0 hoog niveau (decimal point)
PORTB |= (1 << PB0);
// teller +1
count++;
// 0.5 sec delay
_delay_ms(500);
// PB0 laag niveau
PORTB &= ~(1 << PB0);
if(count==100)
{
count=0;
}
// 0.5 sec delay
_delay_ms(500);
}
}Op 14 mei 2010 17:58:31 schreef retro man:
tientallen = count / 10; tientallen = tientallen % 10; eenheden = count - (10*tientallen);
Moet dus zijn:
tientallen = count / 10;
eenheden = count % 10;
Je tweede regel doet niks (aannemende dat het getal < 100 is)
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Hoe accuraat is de interne timer van de tiny2313 trouwens.
Met de interne R/C-oscillator is dat allesbehalve accuraat. Maar als je een extern kristal gebruikt, ziet het er al heel wat beter uit.
Ik heb in men project settings de frequentie op 10Mhz gezet.
Hoe heb je dat gedaan?
Nog een tip voor die segmenten. Ik doe dat meestal zo:
#define seg_a _BV(PB7)
#define seg_b _BV(PB5)
#define seg_c _BV(PB3)
#define seg_d _BV(PB0)
#define seg_e _BV(PB2)
#define seg_f _BV(PB6)
#define seg_g _BV(PB4)
#define seg_dp _BV(PB1)
#define NUL 0xFF & ~(seg_a | seg_b | seg_c | seg_d | seg_e | seg_f)
#define EEN 0xFF & ~(seg_b | seg_c)
#define TWEE 0xFF & ~(seg_a | seg_b | seg_d | seg_e | seg_g)
#define DRIE 0xFF & ~(seg_a | seg_b | seg_c | seg_d | seg_g)
#define VIER 0xFF & ~(seg_b | seg_c | seg_f | seg_g)
#define VIJF 0xFF & ~(seg_a | seg_c | seg_d | seg_f | seg_g)
#define ZES 0xFF & ~(seg_a | seg_c | seg_d | seg_e | seg_f | seg_g)
#define ZEVEN 0xFF & ~(seg_a | seg_b | seg_c)
#define ACHT 0xFF & ~(seg_a | seg_b | seg_c | seg_d | seg_e | seg_f | seg_g)
#define NEGEN 0xFF & ~(seg_a | seg_b | seg_c | seg_d | seg_f | seg_g)
unsigned char CIJFERS[] = { NUL, EEN, TWEE, DRIE, VIER, VIJF, ZES, ZEVEN, ACHT, NEGEN};
// Voorbeeld
unsigned char x = 5;
PORTB = CIJFERS[x];
In dit geval gaat het om common-anode displays, waarbij de segmenten een laag niveau moeten krijgen om op te lichten. Voor common-kathode displays laat je die "0xFF & ~" weg.
En "_BV(PBx) kan je vervangen door "(1 << PBx)", als je dat wenst.