__xdata unsigned char dat[500];Allerdings wird dieses Array an das Ende des Programms angehängt. Die genaue Adresse ist nur mühsam zu erkunden. Mit einem Offset kann ich dann tatsächlich auf eine bestimmte Adresse zugreifen. Besser wäre es, wenn ich das Array gleich an einen gewünschten Ort setzen könnte. Es ist mir allerdings nicht gelungen, herauszufinden, ob und wie das geht.
__code unsigned char arom[] = {0x99};
void AromErase (unsigned int Addr)
{
//Erase APROM DATAFLASH page
IAPAL = (Addr&0xff);
IAPAH = (Addr>>8)&0xff;
IAPFD = 0xFF;
TA=0xAA;TA=0x55;CHPCON|=0x01; //set_IAPEN
TA=0xAA;TA=0x55;IAPUEN|=0x01; //set_APUEN;
IAPCN = 0x22;
TA=0xAA;TA=0x55;IAPTRG|=0x01; // set_IAPGO;
TA=0xAA;TA=0x55;IAPUEN&=~0x01; //clr_APUEN;
TA=0xAA;TA=0x55;CHPCON&=~0x01; //clr_IAPEN;
}
void AromWrite (unsigned int Addr, unsigned char Dat)
{
TA=0xAA;TA=0x55;CHPCON|=0x01; //set_IAPEN
TA=0xAA;TA=0x55;IAPUEN|=0x01; //set_APUEN;
IAPCN = 0x21; //Write AROM
IAPAL = (Addr&0xff);
IAPAH = (Addr>>8)&0xff;
IAPFD = Dat;
TA=0xAA;TA=0x55;IAPTRG|=0x01; // set_IAPGO;
TA=0xAA;TA=0x55;IAPUEN&=~0x01; //clr_APUEN;
TA=0xAA;TA=0x55;CHPCON&=~0x01; //clr_IAPEN;
}
unsigned char AromRead(unsigned int Addr)
{
unsigned char Dat;
TA=0xAA;TA=0x55;CHPCON|=0x01; //set_IAPEN
TA=0xAA;TA=0x55;IAPUEN|=0x01; //set_APUEN;
IAPCN = 0x00; //read_AROM
IAPAL = (Addr&0xff);
IAPAH = (Addr>>8)&0xff;
TA=0xAA;TA=0x55;IAPTRG|=0x01; // set_IAPGO;
Dat = IAPFD;
TA=0xAA;TA=0x55;CHPCON&=~0x01; //clr_IAPEN
return Dat;
}
unsigned char UID_BYTE(unsigned char Addr)
{
unsigned char Dat;
TA=0xAA;TA=0x55;CHPCON|=0x01; //set_IAPEN
IAPAL = Addr;
IAPAH = 0x00;
IAPCN = 0x04; //read_UID
TA=0xAA;TA=0x55;IAPTRG|=0x01; // set_IAPGO;
Dat = IAPFD;
TA=0xAA;TA=0x55;CHPCON&=~0x01; //clr_IAPEN
return Dat;
}
void Timer0_Delay1ms(long ms)
{
CKCON &= ~4; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
TR0 = 1; //Start Timer0
while (ms != 0)
{
TL0 = 0xCA; //65536-1334 =64202
TH0 = 0xFA;
while (TF0 != 1); //Check Timer0 Time-Out Flag
TF0=0;
ms --;
}
TR0=0; //Stop Timer0
}
void InitUART0_Timer1(long Baudrate) //T1M = 1, SMOD = 1
{
SCON = 0x50; //UART0 Mode1,REN=1,TI=1
TMOD |= 0x20; //Timer1 Mode1
PCON |= 128; //SMOD = 1 UART0 Double Rate Enable
CKCON |=16; //set_T1M
T3CON &= ~64; //BRCK = 0 Serial port 0 baud rate clock source = Timer1
TH1 = 256 - (1000000/Baudrate+1); /*16 MHz */
TR1 = 1;
TI = 1; //For printf
}
char getchar(void)
{
char c;
while (!RI);
c = SBUF;
RI = 0;
return (c);
}
void putchar(char c)
{
while (!TI);
TI = 0;
SBUF = c;
}
void delay(void)
{
int i,j;
for(i=0;i<0xff;i++)
for(j=0;j<0xff;j++);
}
void Timer0_Delay1ms(long ms)
{
CKCON &= ~4; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
TR0 = 1; //Start Timer0
while (ms != 0)
{
TL0 = 0xCA; //65536-1334 =64202
TH0 = 0xFA;
while (TF0 != 1); //Check Timer0 Time-Out Flag
TF0=0;
ms --;
}
TR0=0; //Stop Timer0
}
...
while (1)
{
printf ("x \r\n");
Timer0_Delay1ms(1000);
}
Der Datenlogger
#include <N76E003.h>Um die Bedienung möglichst einfach zu halten, wurde folgender Ablauf festgelegt: Zuerst werden 1280 Daten ausgelesen. Dann folgt eine Wartezeit von einer Minute, sodass man die Daten mit einem Reset beliebig oft auslesen kann. Lässt man die Minute verstreichen, beginnt eine neue Messung. Das Programm löscht zunächst den verwendeten Datenbereich. Dann werden mit dem AD-Wandler 1280 Werte im Abstand von jeweils einer Sekunde erfasst und im ARM gespeichert. Die Datenmenge und die Intervallzeit lassen sich leicht für die jeweilige Anwendung anpassen.
#include <stdio.h>
unsigned char AromRead(unsigned int Addr);
void AromWrite (unsigned int Addr, unsigned char Dat);
void AromErase (unsigned int Addr);
unsigned char UID_BYTE(unsigned char Addr);
void InitUART0_Timer1(long Baudrate);
char getchar(void);
void putchar(char);
void delay(void);
void Timer0_Delay1ms(long ms);
void main(void)
{
unsigned int i;
unsigned int Addr;
unsigned char dat;
P0M1=0;P0M2=0;P1M1=0x80;P1M2=0;
InitUART0_Timer1(9600);
ADCCON1=1; //ADC on
for(i=0;i<1280;i++) //Auslesen
{
printf ("\n %d",AromRead(0x0A00+i));
}
Timer0_Delay1ms(60000); //1 min warten
Addr = 0x0A00;
for(i=0;i<10;i++) //10 Blöcke löschen
{
AromErase (Addr);
Addr = Addr+128;
}
for(i=0;i<1280;i++) //Messen und speichern
{
ADCCON0 = 0; //ADC0 = P17
ADCS = 1;
while(ADCF == 0);
dat=ADCRH;
AromWrite (0x0A00+i,dat);
Timer0_Delay1ms(100);
}
while(1);
}