Quelltext /~heha/enas/Convac-Ätzer/Firmware-190517.zip/Analog.cpp

/* Projekt Convac-Ätzer
   Zugriff auf analoge Karte
   Henrik Haftmann, 161128
   
   Beim Controller ist angeschlossen, siehe
   http://www.tu-chemnitz.de/~heha/enas/Convac-Ätzer/Eagle.zip/
   
 */

#include "Convac.h"
#include <avr/pgmspace.h>
#include <util/delay.h>

// channel=0..8: A/D-Wandler, zuerst 12 Bit, dann 8 Bit
// channel=9..17: D/A-Wandler, zuerst 14 Bit, dann 8 Bit
// channel=18..20: Zähler (keine Ahnung wie)
int ANALOG::getIo(byte channel) {
 if (!channel) {	// AD574
  BUS::setXaddr(0);
#if 1
  BUS::ioWrite(BUS::BA_ANALOG|7,0);	// A/D-Wandlung auslösen (40 µs)
  _delay_us(40);
#endif
  channel=BUS::ioRead(BUS::BA_ANALOG|7);	// High-Byte lesen
  BUS::setXaddr(1);
  word r=((word)channel<<8|BUS::ioRead(BUS::BA_ANALOG|7))>>4;	// Low-Nibble
  return r+ios.adc12-2048;
 }
 if (--channel<8) {	// AD7828
  BUS::setXaddr(channel);
  byte r=BUS::ioRead(BUS::BA_ANALOG|1);		// Byte lesen
  return r+ios.adc8[channel]&0xFF;
 }
 if (!(channel-=8)) return ios.dac14;	// AD7534
 if (--channel<8) return ios.dac8[channel];	// AD7228
 return 0;		// Zähler (unbekannt)
}

void ANALOG::setIo(byte channel, int value) {
// if (value==-32768) return;	// NaN
 if (!channel) {		// AD574
#if 0
  BUS::setXaddr(0);	// A0=0: 12-bit-Umsetzung (nicht 8 Bit)
  BUS::ioWrite(BUS::BA_ANALOG|7,0);	// A/D-Wandlung auslösen (40 µs)
#endif
  ios.adc12=value;
 }else if (--channel<8) {	// AD7828: nichts tun
  ios.adc8[channel]=value;
 }else if (!(channel-=8)) {	// AD7534
//  if (value>0x1FFF) value=0x1FFF;
//  if (value<-0x2000) value=-0x2000;	// begrenzen
  ios.dac14=value;
//  value&=0x3FFF;		// sicherheitshalber
  value=(value^0x1FFF)&0x3FFF;
/* Dieser D/A-Wandler gibt folgendens aus (Anschlüsse e18-c18):
 * value	gewandelt	Spannung
 * 0x1FFF	0x0000		+10 V
 * 0x1000	0x0FFF		+5 V
 * 0x0000	0x1FFF		0 V
 * 0xFFFF	0x2000		-1 mV
 * 0xF000	0x2FFF		-5 V
 * 0xE000	0x3FFF		-10 V
 */
  BUS::setXaddr(1);
  BUS::ioWrite(BUS::BA_ANALOG|4,value>>8);	// High-Byte (6 Bits) laden
  BUS::setXaddr(2);
  BUS::ioWrite(BUS::BA_ANALOG|4,value);	// Low-Byte laden
  BUS::setXaddr(3);
  BUS::ioWrite(BUS::BA_ANALOG|4,0);	// analog ausgeben
 }else if (--channel<8) {	// AD7228
  ios.dac8[channel]=value;
  BUS::setXaddr(channel);	// Sub-Kanal adressieren
  BUS::ioWrite(BUS::BA_ANALOG|2,value);	// analog ausgeben
 }
}

char ANALOG::getBits(byte channel) {
 if (!channel) return -12;	// negativ für "vorzeichenbehaftet"
 if (--channel<8) return 8;
 if (!(channel-=8)) return -14;	// auch dieser ist vorzeichenbehaftet
 if (--channel<8) return 8;
 return 0;
}

int ANALOG::getMin(byte channel) {
 char bits=getBits(channel);
 if (bits>=0) return 0;		// vorzeichenlos
 return -(1U<<~bits);		// "-12" wird zu "-2048"
}
 
int ANALOG::getMax(byte channel) {
 char bits=getBits(channel);
 if (bits<0) bits=~bits;	// bits = -bits-1
 return (1U<<bits)-1;
}

void ANALOG::getPin(byte channel) {	// Hier: Nur den „Pluspol“
 byte start;
 if (!channel) start=22;
 else if (--channel<8) start=10;
 else if (!(channel-=8)) start=18;
 else if (--channel<8) start=4;
 else{
  sbuf[0]='-';		// Anschluss für Zähler unbekannt
  sbuf[1]=0;
  return;
 }
 mkeca(start,channel);	// bspw. Reihe 4-6-8 für 8-bit-D/A-Wandler AD7228
}

// Ausgänge setzen
void ANALOG::initOutputs() {
 setIo(9,ios.dac14);
 for (byte i=0; i<8; i++) setIo(10+i,ios.dac8[i]);
}

ANALOG::ios_t ANALOG::ios;

ANALOG::scale_t ANALOG::scale[21]={
//	scale	offset	nk	unit[7]		gemessen 170314
 /*0*/	{1550,	0,	1,	"U/min"},	// A/D-Wert = -18 bei -109 U/min
 /*1*/	{1000,	0,	2,	"V"},
 /*2*/	{1000,	0,	2,	"V"},
 /*3*/	{1000,	0,	2,	"V"},
 /*4*/	{1000,	0,	2,	"V"},
 /*5*/	{1000,	0,	2,	"V"},
 /*6*/	{1000,	0,	2,	"V"},
 /*7*/	{1000,	0,	2,	"V"},
 /*8*/	{1000,	0,	2,	"V"},
 /*9*/	{-2790,	0,	1,	"U/min"},	// -109 U/min bei D/A-Wert = 100
 /*10*/	{1000,	0,	2,	"V"},
 /*11*/	{1000,	0,	2,	"V"},
 /*12*/	{1000,	0,	2,	"V"},
 /*13*/	{1000,	0,	2,	"V"},
 /*14*/	{1000,	0,	2,	"V"},
 /*15*/	{1000,	0,	2,	"V"},
 /*16*/	{1000,	0,	2,	"V"},
 /*17*/	{1000,	0,	2,	"V"},
 /*18*/	{256,	0,	2,	"Hz"},
 /*19*/	{256,	0,	2,	"Hz"},
 /*20*/	{256,	0,	2,	"Hz"}};

/* Analoge Karte, Schaltung (Netzliste)
	Pin	Netz		(Pin	Netz)
IC1 74HCT04 6 Inverter	Hier: Quarzoszillator 4,194 MHz
IC2 74HCT08 4 AND-Gatter
	4	X0(20)	Subadresse
	5	X0(20)
	6	x0
	7(gnd)	00
	8	a1
	9	X1(19)	Subadresse
	10	X1(19)
	14(5p)	5P
IC3 74HCT138
	1(A0)	A0
	2(A1)	A1
	3(A2)	A2
	4(!E1)	!IOSTB(7)
	5(!E2)	!SEL(9)
	6(E3)	5P
	15	!Y0	IC6-1,19	so 'ne Art ID lesen (hier 0x30)
	14	!Y1	Auswahl 8-bit-A/D-Wandler	
	13	!Y2	Auswahl 8-bit-D/A-Wandler
	12	!Y3	IC5-11 (Ausgangslatch, wofür??)
	11	!Y4	Auswahl 14-bit-D/A-Wandler
	10	!Y5	Auswahl Zählerchip
	9(!y6)	nc	
	7	!Y7	Auswahl 12-bit-A/D-Wandler
	8(gnd)	00
	16(5p)	5P
IC4 74HCT245 Datenbustreiber (Puffer)
	Pin	Bus		Pin	intern
	1	!WR(8)
	19	!SEL(9)
	18	D0		2	d0
	17	D1		3	d1
	16	D2		4	d2
	15	D3		5	d3
	14	D4		6	d4
	13	D5		7	d5
	12	D6		8	d6
	11	D7		9	d7
IC5 74HCT374 (Flipflops = Ausgaberegister)
	1(!oe)	00
	18	d0		19
	3	d1		2	IC9-12
	17	d2		16
	4	d3		5
	14	d4		15
	7	d5		6
	13	d6		12
	8	d7		9
	10(gnd)	00
	11(clk)	Y3
	20(ucc)	5P

IC6 74HCT244 (zum Rücklesen)
	Pin	intern		Pin
	1,19	!Y0
	3	d0		17	GND
	18	d1		2	GND
	5	d2		15	GND
	16	d3		4	GND
	7	d4		13	Pin hochgebogen, Ucc
	14	d5		6	Pin hochgebogen, Ucc
	9	d6		11	GND
	12	d7		8	GND

IC7 74HCT4020	14-bit-Binärzähler
IC8 74HCT393	2 4-bit-Binärzähler
IC9 74HCT132 4 NAND-Gatter mit Schmitt-Trigger
IC10 S360B114 Zähler-ASIC
	27	d0
	2	d1
	3	d2
	4	d3
	6	d4
	10	d5
	12	d6
	13	d7
	20	!Y5
IC11 ADC574 12-bit-A/D-Wandler (sukzessive Approximation 40 µs)
	1	5P
	2(data mode) GND	8-Bit-Bus
	3(!CS)	!Y7
	4(BA)	x0		Byte-Auswahl über Subadresse
	5(rc)	!WR(8)		Konvertierungsstart durch Schreibzugriff
	6(ce)	an 100k an 5P
	7(15p)
	8(10p ref out)
	9(agnd)	GND
	10(reference input)
	11(15n)
	12(bipolar offset)
	13(10V span input)
	14(20V span input)
	15(dgnd)GND
	16	d4
	17	d5
	18	d6
	19	d7
	20	d0
	21	d1
	22	d2
	23	d3
	24	d4
	25	d5
	26	d6
	27	d7
	28(sts)	nc
IC12 AD7534 14-bit-D/A-Wandler, kann nur Schreibzugriffe
	1(uref)
	2(rfb)
	3(iout)
	4(agnd)	GND
	5(agnd)	GND
	6(dgnd)	GND
	7(d7)	d7
	8(d6)	d6
	9(d5)	d5
	10(d4)	d4
	11(d3)	d3
	12(d2)	d2
	13(d1)	d1
	14(d0)	d0
	15(a1)	x1	01=High-Byte laden, 10=Low-Byte laden
	16(a0)	x0	11=DAC aktualisieren
	17(!wr)	!Y4
	18(!cs)	!Y4
	19(udd)
	20(uss)
IC13 LT1019
	1(nc)	nc		8(nc)
	2(in)	15P(31)		7(nc)
	3(temp)			6(out)	ref+
	4(gnd)	00		5(trim)
IC14 AD7828 8 8-bit-A/D-Wandler (2,4 µs)
	12(!rd)	!Y1
	13(int)	nc
	14(gnd)	00
	16(ref+)ref+	LT1019 Pin 6
	17(rdy)	nc	erfordert 2,4 µs Zugriffszeit (= Buszyklus)
	18(!cs)	!Y1
	8(d0)	d0
	9	d1
	10	d2
	11	d3
	19	d4
	20	d5
	21	d6
	22(d7)	d7
	23(a2)	X2(18)	Subadresse
	24(a1)	x1
	25(a0)	x0
	26	5P
IC15 REF01
IC16 AD7228 8 8-bit-D/A-Wandler
	13(d7)	d7
	14	d6
	15	d5
	16	d4
	17	d3
	18	d2
	19	d1
	20(d0)	d0
	21(!wr)	!Y2
	22(a2)	X2(18)
	23(a1)	x1
	24(a0)	x0
IC17 MC3486
IC18 LF351
IC19 REF01
IC20 OP200
 */
Vorgefundene Kodierung: UTF-80