EmbeddedRelated.com
Forums

sdcc, 8051/8031 in C

Started by Lukas July 24, 2005
I've bought some time ago 8051 learning kit with monitor in ROM and 8k
external ram starting at 0x8000h, where programs in intel hex format are
load to external RAM via RS232
if i want to start this program i have to press 0 and type address 8000
(where the program is), then the program is running
Now i have a problem, i trying many things to make it come working like i
want, but i didn't make it.
Below i've pasted code. I want to run any of interrupts (1 or/and 3). In
belowe code it doesn't work, why?
Could someone show me my mistake which i doing? Perhaps I forgot about
someting or make it in wrong order?
Running this code i get nothng on LED display, if i remove lines from TMOD
to TR0 it will display a 0 on first LED display. Otherwise it will wont work
:( why?


#include "8051.h"

//adresses where are LED display
xdata at 0x4000 unsigned char liczba;
xdata at 0x4001 unsigned char wyswietlacz;

//digits definition
#define c0 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20
#define c1 0x02 | 0x04
#define c2 0x01 | 0x02 | 0x40 | 0x10 | 0x08
#define c3 0x01 | 0x02 | 0x40 | 0x04 | 0x08
#define c4 0x20 | 0x40 | 0x02 | 0x04
#define c5 0x01 | 0x20 | 0x40 | 0x04 | 0x08
#define c6 0x01 | 0x20 | 0x40 | 0x04 | 0x08 | 0x10
#define c7 0x01 | 0x02 | 0x04
#define c8 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40
#define c9 0x01 | 0x20 | 0x40 | 0x02 | 0x04 | 0x08 | 0x047
#define kr 0x80

char tab[11]={c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,kr};
unsigned char zn,cnt;

void obsluga(void) interrupt 1; //handle of int T0
void obslug2(void) interrupt 3; //handle of int T1

void main(void)
 {
 cnt = 0; //setting starting LED segment
 zn = 0; //setting starting digit
 TMOD = 17; //T0 & T1 16bit

 //seting timers T1 i T0
 TH1 = 0x80;
 TL1 = 0;
 TH0 = 0;
 TL0 = 0;
 //***

 ET1 = ET0 = EA = 1; //accept int from T0, T1 and globally
 TR1 = 1; // 1 starting timer T1 - 0 stopping
 TR0 = 1; // 1 starting timer T0 - 0 stopping


 while(1) //loop to infinitive
 {
 wyswietlacz = cnt; //which LED to activate
liczba = tab[zn];  //which digit to display
 liczba = 0; //turn off digit

 }
 }

void obsluga(void) interrupt 1
 {

 TR0 = 0; //stop timer T0
 TH0 = 0; //set older bits
 TL0 = 0; //set younger bits
 zn++; //change on next
 if (zn>9) zn=0;
 TR0 = 1; //starts timer T0
 }

void obslug2(void) interrupt 3
 {
 TR1 = 0; //stop timer T1
 cnt++; //change display on which will by digit displayed

 TH1 = 0x80; //set timet
 TL1 = 0; //set timet
 TR1 = 1; //starts timer T1
 }




Lukas wrote:
> I've bought some time ago 8051 learning kit with monitor in ROM and 8k > external ram starting at 0x8000h, where programs in intel hex format are > load to external RAM via RS232 > if i want to start this program i have to press 0 and type address 8000 > (where the program is), then the program is running > Now i have a problem, i trying many things to make it come working like i > want, but i didn't make it. > Below i've pasted code. I want to run any of interrupts (1 or/and 3). In > belowe code it doesn't work, why? > Could someone show me my mistake which i doing? Perhaps I forgot about > someting or make it in wrong order? > Running this code i get nothng on LED display, if i remove lines from TMOD > to TR0 it will display a 0 on first LED display. Otherwise it will wont work > :( why? > > > #include "8051.h" > > //adresses where are LED display > xdata at 0x4000 unsigned char liczba; > xdata at 0x4001 unsigned char wyswietlacz; > > //digits definition > #define c0 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 > #define c1 0x02 | 0x04 > #define c2 0x01 | 0x02 | 0x40 | 0x10 | 0x08 > #define c3 0x01 | 0x02 | 0x40 | 0x04 | 0x08 > #define c4 0x20 | 0x40 | 0x02 | 0x04 > #define c5 0x01 | 0x20 | 0x40 | 0x04 | 0x08 > #define c6 0x01 | 0x20 | 0x40 | 0x04 | 0x08 | 0x10 > #define c7 0x01 | 0x02 | 0x04 > #define c8 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 > #define c9 0x01 | 0x20 | 0x40 | 0x02 | 0x04 | 0x08 | 0x047 > #define kr 0x80 > > char tab[11]={c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,kr}; > unsigned char zn,cnt; > > void obsluga(void) interrupt 1; //handle of int T0 > void obslug2(void) interrupt 3; //handle of int T1 > > void main(void) > { > cnt = 0; //setting starting LED segment > zn = 0; //setting starting digit > TMOD = 17; //T0 & T1 16bit > > //seting timers T1 i T0 > TH1 = 0x80; > TL1 = 0; > TH0 = 0; > TL0 = 0; > //*** > > ET1 = ET0 = EA = 1; //accept int from T0, T1 and globally > TR1 = 1; // 1 starting timer T1 - 0 stopping > TR0 = 1; // 1 starting timer T0 - 0 stopping > > > while(1) //loop to infinitive > { > wyswietlacz = cnt; //which LED to activate
-
> liczba = tab[zn]; //which digit to display > liczba = 0; //turn off digit
Could you explain how these two instructions work? Is there a specific protocol, why do you write a 0 just after the digit?
> } > } > > void obsluga(void) interrupt 1 > { > > TR0 = 0; //stop timer T0 > TH0 = 0; //set older bits > TL0 = 0; //set younger bits > zn++; //change on next > if (zn>9) zn=0; > TR0 = 1; //starts timer T0 > } > > void obslug2(void) interrupt 3 > { > TR1 = 0; //stop timer T1 > cnt++; //change display on which will by digit displayed > > TH1 = 0x80; //set timet > TL1 = 0; //set timet > TR1 = 1; //starts timer T1 > }
Uzytkownik "Lanarcam" <lanarcam1@yahoo.fr> napisal w wiadomosci
news:1122215949.286600.24830@g49g2000cwa.googlegroups.com...
> > > Lukas wrote: > > I've bought some time ago 8051 learning kit with monitor in ROM and 8k > > external ram starting at 0x8000h, where programs in intel hex format are > > load to external RAM via RS232 > > if i want to start this program i have to press 0 and type address 8000 > > (where the program is), then the program is running > > Now i have a problem, i trying many things to make it come working like
i
> > want, but i didn't make it. > > Below i've pasted code. I want to run any of interrupts (1 or/and 3). In > > belowe code it doesn't work, why? > > Could someone show me my mistake which i doing? Perhaps I forgot about > > someting or make it in wrong order? > > Running this code i get nothng on LED display, if i remove lines from
TMOD
> > to TR0 it will display a 0 on first LED display. Otherwise it will wont
work
> > :( why? > > > > > > #include "8051.h" > > > > //adresses where are LED display > > xdata at 0x4000 unsigned char liczba; > > xdata at 0x4001 unsigned char wyswietlacz; > > > > //digits definition > > #define c0 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 > > #define c1 0x02 | 0x04 > > #define c2 0x01 | 0x02 | 0x40 | 0x10 | 0x08 > > #define c3 0x01 | 0x02 | 0x40 | 0x04 | 0x08 > > #define c4 0x20 | 0x40 | 0x02 | 0x04 > > #define c5 0x01 | 0x20 | 0x40 | 0x04 | 0x08 > > #define c6 0x01 | 0x20 | 0x40 | 0x04 | 0x08 | 0x10 > > #define c7 0x01 | 0x02 | 0x04 > > #define c8 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 > > #define c9 0x01 | 0x20 | 0x40 | 0x02 | 0x04 | 0x08 | 0x047 > > #define kr 0x80 > > > > char tab[11]={c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,kr}; > > unsigned char zn,cnt; > > > > void obsluga(void) interrupt 1; //handle of int T0 > > void obslug2(void) interrupt 3; //handle of int T1 > > > > void main(void) > > { > > cnt = 0; //setting starting LED segment > > zn = 0; //setting starting digit > > TMOD = 17; //T0 & T1 16bit > > > > //seting timers T1 i T0 > > TH1 = 0x80; > > TL1 = 0; > > TH0 = 0; > > TL0 = 0; > > //*** > > > > ET1 = ET0 = EA = 1; //accept int from T0, T1 and globally > > TR1 = 1; // 1 starting timer T1 - 0 stopping > > TR0 = 1; // 1 starting timer T0 - 0 stopping > > > > > > while(1) //loop to infinitive > > { > > wyswietlacz = cnt; //which LED to activate > > - > > liczba = tab[zn]; //which digit to display > > liczba = 0; //turn off digit > > Could you explain how these two instructions work? > Is there a specific protocol, why do you write > a 0 just after the digit?
this is for turn off the display i know that this is done badly but i'll correct this when the iterrupts will work first i have to clear all LEDs display 2nd i have to write a digit wich i wat to display then show the nr of diplay on wich it should aper
> > > } > > } > > > > void obsluga(void) interrupt 1 > > { > > > > TR0 = 0; //stop timer T0 > > TH0 = 0; //set older bits > > TL0 = 0; //set younger bits > > zn++; //change on next > > if (zn>9) zn=0; > > TR0 = 1; //starts timer T0 > > } > > > > void obslug2(void) interrupt 3 > > { > > TR1 = 0; //stop timer T1 > > cnt++; //change display on which will by digit displayed > > > > TH1 = 0x80; //set timet > > TL1 = 0; //set timet > > TR1 = 1; //starts timer T1 > > } >
I was using 8051s before I move to AVR.

Anyway, I'm not sure, do interrupt 1 IS Timer0 overflow interrupt (or
interrupt 3 IS Timer1overflow interrupt) ?  Usually I get that wrong
(so my interrupt handler handles wrong interrupt).

Another mistake that I usually had is forgetting not to activated
global/timer overflow interrupt. I see that you have done it, so
there's no mistakes.

Probably you need to read your monitor's firmware documentation.

Some monitors use timer overflow interrupt as switching task timer
tick. So it can switch from user program to monitors program. It's
quite normal in embedded OS.

If I may suggest, you should try bare development boards (where it has
no monitor firmware in it). You'll get much more experience and fun =D