Quelltext /~heha/ewa/Kram/Solarpaneel.zip/C-Programm/analog.c

/*
Projekt: Photovoltaik-Präsentation "solar" mit MSP430
Detail: Analog-Digital-Umsetzung (ADU_Xxx),
	Digital-Analog-Umsetzung (DAU_Xxx),
	Relais (Rel_Xxx)

060803	erstellt
*/
#include "solar.h"

/* Hardware-Anschluss:
 P6.0 = Kanal AD0: Spannung Solarzelle
 P6.1 = Kanal AD1: Strom Solarzelle
 P6.2 = Kanal AD2: Spannung Last
 P6.3 = Kanal AD3: Strom Last
 P6.4 = Kanal AD4: Spannung Akku
 P6.5 = Kanal AD5: Strom Akku
 P6.6 = D/A-Wandler Kanal0: Stromsenke Solarzelle (Kennlinienaufnahme)
 
 P3.0 = Relais0 = Solarstromsteuerung - Kennlinienaufnahme
 P3.1 = Relais1 = Last vom Laderegler direkt zur Solarzelle schalten
 P6.7 = Relais2 = Solarzelle1 -> Solarzelle2 umschalten
  ACHTUNG: Hardware-Konstruktionsfehler (falls Laderegler blöd):
   Relais1 muss bei drohender Tiefentladung des Akkus anziehen!
   Bei ausgeschalteter Schaltung droht dennoch Tiefentladung!
   Ggf. Kontakte (Öffner und Schließer) tauschen und Software anpassen!
 */

/************************************************************************
 * Analog-Digital-Konverter
 ************************************************************************/
static int AD_Buf[N_AVG*N_CH];
// Irgendwie hat GCC ein Problem mit zweidimensionalen Arrays!

void ADU_Init(void){
 P6DIR=0x80;	// REL2 = Ausgang, alles andere Eingang
 P6SEL=0x3F;	// 6 A/D-Wandler, 1 D/A-Wandler; REL2
 P3DIR|=0x03;
 ADC12CTL1=SHS0|SHP|ADC12DIV2|ADC12DIV1|ADC12DIV0|ADC12SSEL1|CONSEQ1|CONSEQ0;
 ADC12CTL0=0xFF00|MSC|REF2_5V|REFON|ADC12ON;
 ADC12MCTL0=0x00;	// 0 = Kanal AD0: Spannung Solarzelle
 ADC12MCTL1=0x01;	// 1 = Kanal AD1: Strom Solarzelle
 ADC12MCTL2=0x02;	// 2 = Kanal AD2: Spannung Last
 ADC12MCTL3=0x03;	// 3 = Kanal AD3: Strom Last
 ADC12MCTL4=0x04;	// 4 = Kanal AD4: Spannung Akku
 ADC12MCTL5=0x05;	// 5 = Kanal AD5: Strom Akku
 ADC12MCTL6=0x08;	// 6 = Referenzspannung (Bezug für Akku-Strom)
 ADC12MCTL7=0x9A;	// 7 = Temperatur MSP430 und Sequenz-Ende
 ADC12CTL0|=ENC/*|ADC12SC*/;
 DMA0SA=(unsigned)&ADC12MEM[0];	// ADC12MEM[0]..ADC12MEM[7]
 DMA0DA=(unsigned)&AD_Buf[0];	// beginnend mit erster Kopie
 DMA0SZ=N_CH;		// 8 Words = 1 Block
 DMACTL0|=0x0006;	// DMA0-Trigger ist A/D-Wandler
 DMA0CTL=0x5F14;	// Blocktransfer, Quelle und Ziel Auto-Inkrement,
 			// wortweise, DMA aktiviert, Interrupt aktiviert
}

// DMA-Interrupt: Nach 8 A/D-Wandlungen und Transfer zum Puffer
// zum nächsten Puffer weiterschalten
interrupt(DACDMA_VECTOR) DMA_Complete(void) {
 int *a=(int*)DMA0DA;
 a+=N_CH;	// nächster Block
 if (a==&AD_Buf[N_AVG*N_CH]) {
// Test-Ausgang toggeln
//  P3OUT^=0x04;
  a=&AD_Buf[0];	// am Ende zurück zum Anfang
 }
 DMA0DA=(unsigned)a;
 DMA0CTL&=~DMAIFG;	// muss gelöscht werden!
// Ansonsten hätte die ISR über 3 DMA-Kanäle und den D/A-Wandler
// keine Chance herauszufinden, wer der Verursacher war.
}

// Summe aus N_AVG A/D-Wandlungen beschaffen
int ADU_Get(int Kanal) {
 int i,ret=0, *p;
 for (i=0, p=AD_Buf+Kanal; i<N_AVG; i++,p+=N_CH) ret+=*p;
 return ret;
}

/************************************************************************
 * Digital-Analog-Konverter
 ************************************************************************/
void DAU_Init(void){
 DAC12_0CTL=DAC12AMP1;
 DAC12_0CTL=DAC12AMP1|DAC12CALON;	// Kalibrierung starten
}

// DAU_Put ist Makro
// DAU_Get ist Makro

static volatile BYTE*const Addrs[]={&P3OUT,&P3OUT,&P6OUT};
static          BYTE const Masks[]={  0x01,  0x02,  0x80};

/************************************************************************
 * Relais
 * what=0: REL0 = Solarstromsteuerung - Kennlinienaufnahme
 * what=1: REL1 = Last vom Laderegler direkt zur Solarzelle schalten
 * what=2: REL2 = Solarzelle1 -> Solarzelle2 umschalten
 ************************************************************************/
void Rel_SetState(INT what, bool state){
 if ((unsigned)what>=sizeof(Masks))return;
 if (state) *(Addrs[what])|= Masks[what];
 else       *(Addrs[what])&=~Masks[what];
}

bool Rel_GetState(INT what) {
 if ((unsigned)what>=sizeof(Masks))return false;
 return *(Addrs[what])&Masks[what];
}
Vorgefundene Kodierung: ANSI (CP1252)4
Umlaute falsch? - Datei sei ANSI-kodiert (CP1252)