extern char getchar(void);So soll also ein einzelnes Zeichen empfangen und gesendet werden. Außerdem wird noch eine Init-Funktion für den UART gebraucht. Die Funktion UART0_Timer1 habe ich aus den Nuvoton-Beispielprojekten übernommen und in der Schreibweise angepasst. Darin stecken anscheinend einige kleinere Abweichungen vom normalen 8051. Dagegen sehen getchar und putchar ganz traditionell aus. Diese beiden grundlegenden Funktionen sollen hier zunächst einmal ohne die stdio.h verwendet werden. Der Controller soll jedes Byte, das er empfängt, unverändert wieder zurücksenden.
extern void putchar(char);
#include <N76E003.h>
//#include <stdio.h>
void InitUART0_Timer1(long Baudrate);
char getchar(void);
void putchar(char);
void delay(void);
void main(void)
{
unsigned char n;
P0M1=0;P0M2=0;P1M1=0;P1M1=0;
InitUART0_Timer1(9600);
while (1)
{
n= getchar();
putchar(n);
}
}
void InitUART0_Timer1(long Baudrate) //T1M = 1, SMOD = 1
{
SCON = 0x50; //UART0 Mode1,REN=1,TI=1
TMOD |= 0x20; //Timer1 Mode2
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++);
}
#include <N76E003.h>
#include <stdio.h>
void InitUART0_Timer1(long Baudrate);
char getchar(void);
void putchar(char);
void delay(void);
void main(void)
{
int n;
P0M1=0;P0M2=0;P1M1=0;P1M1=0;
InitUART0_Timer1(9600);
printf ("UART0, 9600 Baud\r\n");
n=0;
while (1)
{
n++;
printf("N = %d\r\n", n);
delay();
}
}
Der AD-Wandler hat eine Auflösung von 12 bit und bis zu acht Eingänge. Ein neunter Eingang führt auf die interne Bandgap-Referenz von 1,2 V. Leider kann diese Spannung nicht als Referenz des AD-Wandlers genutzt werden, sondern man kann sie nur messen. Zusätzlich kann man den bei der Produktion gemessenen Wert aus dem ROM lesen. Weil man dann die Referenz genau kennt, lässt dich rückwärts die genaue Betriebsspannung VDD berechnen.
Für
eine Messung muss man mit
ADCCON1=1; den AD-Wandler einschalten und mit ADCCON0=Input; den
Eingang
auswählen. Dann wird der Wandler mit ADCS = 1 gestartet und mit
while(ADCF ==
0); das Ende der Messung abgewartet. Danach steht das Ergebnis in
ADCRH
und ADCRL bereit.
Zuerst wurde ADC0 abgefragt. Der Pin liegt an P1.7. Leider liegen die
Eingänge
nicht in einer Reihe, sondern sind überall verteilt. Ich habe alle Pins
als
quasi-bidirektionale Ports stehen gelassen. damit haben sie einen
internen
Pullup nach VDD. Im Leerlauf wurde daher an ADC0 eine Spannung von 3 V
gemessen, genauer 2998 mV. Dann habe ich eine gelbe LED mit internem
Vorwiderstand von 1 k gegen Masse angeschlossen. Die Spannung sank auf
2030 mV.
Die hohe Auflösung von ca. 1 mV ist schon eine feine Sache. In dieser
Beziehung
ist der N76E003 sogar einem ATmega überlegen.
#include <N76E003.h>
#include <stdio.h>
void InitUART0_Timer1(long Baudrate);
char getchar(void);
void putchar(char);
void delay(void);
void main(void)
{
int n;
float u;
P0M1=0;P0M2=0;P1M1=0;P1M1=0;
InitUART0_Timer1(9600);
ADCCON1=1; //ADC on
printf ("ADC 12 Bit, 9600 Baud\r\n");
n=0;
while (1)
{
ADCCON0 = 0; //ADC0 = P17
//ADCCON0 = 8; //ADC8 = Uref 1,2 V
ADCS = 1; // ADC start trig signal
while(ADCF == 0);
n=ADCRH;
n=16 * n+ ADCRL;
printf ("\r\n ADC = %d",n);
u = n * 3000.0 / 4095.0;
n = u;
printf ("\r\n U = %d mV",n);
delay();
}
}
while (1)
{
//ADCCON0 = 0; //ADC0 = P17
ADCCON0 = 8; //ADC8 = Uref 1,2 V
ADCS = 1; // ADC start trig signal
while(ADCF == 0);
n=ADCRH;
n=16 * n+ ADCRL;
printf ("\r\n ADC = %d",n);
u = n * 3000.0 / 4095.0;
n = u;
printf ("\r\n U = %d mV",n);
delay();
}