vasonline hat geschrieben:Hi PetriK,
I have found the reference design & installed the code on my PC.
Kannst du einen Link abgeben?
Viele Grüße
vasonline hat geschrieben:Hi PetriK,
I have found the reference design & installed the code on my PC.







#include <htc.h>
__CONFIG (FOSC_HS & WDTE_OFF);         // Instellen PIC 16F716 Externe Oscillator Kristal en Watchdog af momenteel. Kan ook met GUI -> Configure -> Configuration bits
#define _XTAL_FREQ 16000000           // 16Mhz kristal op de PIC/GTI.
// Functies
void CheckVolt(void);
void CheckGrid(void);
void DoeMPP(void);
void StartOp(void);
void ADCInit(void);
void Show(void);
void PWMInit(void);
unsigned char ADCLees(unsigned char ch);
// Variabelen
unsigned char LeesVolt;
unsigned char VoltOk;
void main()
{
StartOp();
ADCInit();
PWMInit();
Show();
 
for (;;)
   {
   CheckVolt();
   DoeMPP();
   }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void StartOp(){
   TRISA=0b11111111; // declare porta als input  RA0-RA3
   TRISB=0b00000000; // declare portb als output  RB0->RB7
}
void DoeMPP(){
   if (VoltOk == 1)
      {
      RB1=0;    // Groene LED
      __delay_ms(200); 
      RB2=0;   // Rode LED
      __delay_ms(200); 
      RB1=1;    // Groene LED
      __delay_ms(200); 
      RB2=1;   // Rode LED
      }
   else 
      {
      RB2=1;   //Rode LED
      RB1=0;    // Groene LED
      __delay_ms(2000);
      }
}
void CheckVolt(){
   LeesVolt= ADCLees(1);   //RA1 Lezen
   //        ACD = Binair 76543210. Max 255, min 0 (byte 0b00000000)
   //      53 = 1.05V = 10.5V
   //      150 = 2.95V = 28V   
   if (LeesVolt >= 53 & LeesVolt <= 150 )
      {
      VoltOk=1;   
      }
   else
   {
      VoltOk=0;
   }
}
void Show() {
   RB1=1;    // Groene LED AAN
   RB2=1;   // Rode LED AAN
   __delay_ms(4000);        // wachten bij het opstarten.
   RB4=1;   // Shutdown UCC AAN.
}
void PWMInit(){
   // Datasheet p. 49. Na te kijken.
   CCP1CON = 0b00111100 ;
}
void ADCInit(){
   //         76543210
   ADCON0 = 0b10000000; // P.43 van de datasheet. Fosc/32
   ADCON1 = 0b00000000; // P.44 van de datasheet: Referentievoltage van Vdd gebruiken (5V) RA0->RA3 allemaal analoog.
}
unsigned char ADCLees(unsigned char ch)         //Fuctie om ADC te lezen: RA0-RA4 Zie datasheet voor CHS waarden
{
   if(ch>4) return 0;  // Ongeldige invoer: Tusssen 0 en 4
      switch(ch){
      case 0: CHS2=0b0;CHS1=0b0;CHS0=0b0;   //RA0
         break;
      case 1: CHS2=0b0;CHS1=0b0;CHS0=0b1;   //RA1
         break;
      case 2: CHS2=0b0;CHS1=0b1;CHS0=0b0;   //RA2
         break;
      case 3: CHS2=0b0;CHS1=0b1;CHS0=0b1;   //RA3
         break;
      case 4: CHS2=0b1;CHS1=0b0;CHS0=0b0;   //RA4
         break;
   }
   ADON=1;  // ADC Module aanzetten
   __delay_us(5); // Wachten tot de condensator geladen is. P43 datasheet
   GO_DONE=1;  //Start conversie
         while(GO_DONE); // Wachten op de het meetresultaat. GO_DONE gaat terug op nul als de pic klaar is met meten.
      
   ADON=0;  //switch off adc
   return ADRES;
}







#include <htc.h>
__CONFIG (FOSC_HS & WDTE_OFF);         // Instellen PIC 16F716 Externe Oscillator Kristal en Watchdog af momenteel. Kan ook met GUI -> Configure -> Configuration bits
#define _XTAL_FREQ 16000000           // 16Mhz kristal op de PIC/GTI.
// Functies
void CheckVolt(void);
void NetInit(void);
void DoeMPP(void);
void StartOp(void);
void ADCInit(void);
void Show(void);
void PWMInit(void);
unsigned char ADCLees(unsigned char ch);
// Variabelen
unsigned char LeesVolt;
unsigned char VoltOk;
unsigned char LeesGrid;
unsigned char GridOk;
unsigned char PwmAan;
unsigned char PulsBreedte;
unsigned char GridVorigeWaarde;
unsigned char GridPeriodeTeller;
// #define PulsBreedte  1      //Breedte van de puls, te vermenigvuldigen met de basissinus.
// 'Sinustabelle' voor de modulatie van de pulsbreedte // Gebaseerd op GTI_LCD_EE.c // Based on GTI_LCD_EE.c
const unsigned int Sine[100] = {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                             10,  20,  30,  40,  50,  60,  70,  80,  89,  99,
                            108, 117, 126, 135, 143, 152, 160, 167, 175, 182,
                            189, 196, 202, 208, 214, 219, 224, 229, 233, 237,
                            240, 243, 246, 249, 251, 252, 253, 254, 255, 255,
                            255, 255, 254, 253, 252, 251, 249, 246, 243, 240,
                            237, 233, 229, 224, 219, 214, 208, 202, 196, 189, 
                            182, 175, 167, 160, 152, 143, 135, 126, 117, 108,
                             99,  89,  80,  70,  60,  50,  40,  30,  20,  10,
                              0,   0,   0,   0,   0,   0,   0,   0,   0,   0 };
unsigned char SineIndex = 0;        // sine table index, 0..100    
void main()
{
StartOp();
Show();
ADCInit();
NetInit();
PWMInit();
 
for (;;)
   {
   CheckVolt();
   DoeMPP();
   }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void StartOp(){
   //    XX  XX  XX  RA4 RA3 RA2 RA1 RA0
   TRISA=0b11111111; // declare porta als input  RA0-RA3
   //    RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
   TRISB=0b00101000; // opgeven portb als output  RB0->RB2, RB4-RB7. RB5 input = NET. RB3 input omdat bij output de PWM start na de PWMInit().
   GIE=1;        //Enable Global Interrupt
   PEIE=1;      //Enable Peripal Interrupts   The PIR registers contain the interrupt flags for the “peripheral” interrupt sources, which include: The ADC, UART, CCP, USB, TMR3, TMR2, TMR1, and TMR0 modules.
}
// Main Interrupt Service Routine (ISR)
void interrupt isr(void){
   if (TMR2IF == 1) {
         CCPR1L = ( PulsBreedte * Sine[SineIndex++]) /255 ;    // Installeer de volgende pulsbreedte uit de sinus constante * PulsBreedte. Delen door 255 om te kunnen varieëren (255 stappen, 8 bits)
         if(SineIndex == 100) SineIndex = 0;        // reset index at end-of-period.    
      TMR2IF = 0;          // clear TMR2 interrupt flag  Om TMR2 interrupt vlag actief te zetten.
   }
   
   if (TMR1IF == 1) {
      //RB4 = 0;
      GridVorigeWaarde = LeesGrid;
      LeesGrid = RB5;       // Lees de huidige waarde van de netinvoer op RB5 (digitale puls) in.
       if (GridVorigeWaarde > LeesGrid) {
      // 1 vs 0  ---___
      GridOk = 1;
      GridPeriodeTeller = 0;      // Begin van een nieuwe lage periode.
      RB4 = 1;                  // Controle
      }
       if (GridVorigeWaarde < LeesGrid) {
      // 0 vs 1  ___---
      GridOk = 1;
      GridPeriodeTeller = 0;      // Begin van een nieuwe hoge periode.
      RB4 = 0;               // Controle
      }
   
      if (GridVorigeWaarde == LeesGrid) {
      // 0 vs 0 ______ of 1 vs 1 ------
      // Tellen of het niet langer dan 10ms duurt, want anders hebben we geen grid (!) Dan onmiddelijk uitschakelen.
      // Anders Ok. 100µs * 10 = 1ms * 10 = 10 ms = 1 puls ? Proefondervindelijk op 55 gezet. = Ok!
   
      GridPeriodeTeller++;
         if (GridPeriodeTeller > 55) {
         GridOk = 0;
         RB4 = 0; // UCC shutdown // Controle      
         GridPeriodeTeller = 0;
          }
      }
      TMR1IF = 0;          // Wis de TMR1 interuupt vlag. Om de TMR1 interrupt vlag terug actief te zetten.
         TMR1L = 112;         // Timer1 LSB register terug instellen. Deze onthoud dit niet na een succesvolle timer overflow. (16  bit teller, deel 2, 8 bit)
         TMR1H = 254;         // Timer1 MSB register. Deze onthoud dit niet na een succesvolle timer overflow.  (16 bit teller, deel 1, 8 bit)   
   }
}
void DoeMPP(){
   if (VoltOk == 1)
      {
        TRISB3 = 0;  // Zet RA3 als output (PWM aan)
      RB1=0;    // Groene LED
      __delay_ms(200); 
      RB2=0;   // Rode LED
      __delay_ms(200); 
      RB1=1;    // Groene LED
      __delay_ms(200); 
      RB2=1;   // Rode LED
       PulsBreedte++;         // Pulsbreedte verhogen (hier moet een echte mmp tracker komen)
      }
   else 
      {
        PulsBreedte = 0;  // Pulsbreedte af.
         TRISB3 = 1;  // Zet RA3 als input (PWM volledig uit)
      RB2=1;   //Rode LED
      RB1=0;    // Groene LED
      __delay_ms(2000);
      }
}
void CheckVolt(){ 
   LeesVolt= ADCLees(1);   //RA1 Lezen
   //        ACD = Binair 76543210. Max 255, min 0 (byte 0b00000000)
   //      53 = 1.05V = 10.5V
   //      150 = 2.95V = 28V   
   if (LeesVolt >= 53 & LeesVolt <= 150 )
      {
      VoltOk=1;   
      }
   else
   {
      VoltOk=0;
   }
}
void NetInit() {         // Na te kijken.
   // **** Timer 1 ***, Elke 100µS
   TMR1L = 112;         // preset for timer1 LSB register  (16  bit teller, deel 2, 8 bit)
   TMR1H = 254;         //preset for timer1 MSB register  (16 bit teller, deel 1, 8 bit)
   TMR1CS = 0;            // Teller mode. Interne klok.
   TMR1IF = 0;            // Timer1, op nul zetteb. Deze komt op 1 van zodra CCPR1(L) = TMR1.
   TMR1ON = 1;            // Timer1 aan.
   TMR1IE = 1;            // Timer1 interrupt aan.
}
void Show() {
   RB1=1;    // Groene LED AAN
   RB2=1;   // Rode LED AAN
   __delay_ms(4000);        // wachten bij het opstarten.
   RB4=1;   // Shutdown UCC AAN.
}
void PWMInit(){
   // *** PWM gedeelte van de CCP module ***
   PR2 = 250-1;              // PWM Periode 250 x prescale 4 = 1000 instruct cycles    
   CCP1CON = 0b00001100;     // '00------' unimplemented bits    
                             // '--00----'   DC1B1:DC1B0 duty cycle bits    
                             // '----1100' active hi PWM mode P1A B C en D actief, we hebben alleen A nodig. Aan te passen? Zie datasheet.
   // CCPR1L = 0b00001111;      // De PWM duty cyclus. De 2 andere bits zijn te vinden in CCP1CON: bit DC1B1 & DC1B0.
   TMR2IF = 0;             // TMR2IF wissen, op nul zetten. Deze komt op 1 van zodra PR2 = TMR2. (één PWM puls)
   TMR2IE = 1;             // Timer2 interrupt aan.
   T2CON = 0b00000101;       // '0-------' unimplemented bit    
                             // '-0000---' TOUTPS<3:0>, postscale 1    
                             // '-----1--' TMR2ON, turn Timer 2 on    
                             // '------01' T2CKPS<1:0>, prescale 4
   PulsBreedte = 0;
   
}
                                                                                                                 
void ADCInit(){
   //         76543210
   ADCON0 = 0b10000000; // P.43 van de datasheet. Fosc/32
   ADCON1 = 0b00000000; // P.44 van de datasheet: Referentievoltage van Vdd gebruiken (5V) RA0->RA3 allemaal analoog.
}
unsigned char ADCLees(unsigned char ch)         //Fuctie om ADC te lezen: RA0-RA4 Zie datasheet voor CHS waarden
{
   if(ch>4) return 0;  // Ongeldige invoer: Tusssen 0 en 4
      switch(ch){
      case 0: CHS2=0b0;CHS1=0b0;CHS0=0b0;   //RA0
         break;
      case 1: CHS2=0b0;CHS1=0b0;CHS0=0b1;   //RA1
         break;
      case 2: CHS2=0b0;CHS1=0b1;CHS0=0b0;   //RA2
         break;
      case 3: CHS2=0b0;CHS1=0b1;CHS0=0b1;   //RA3
         break;
      case 4: CHS2=0b1;CHS1=0b0;CHS0=0b0;   //RA4
         break;
   }
   ADON=1;  // ADC Module aanzetten
   __delay_us(5); // Wachten tot de condensator geladen is. P43 datasheet
   GO_DONE=1;  //Start conversie
         while(GO_DONE); // Wachten op de het meetresultaat. GO_DONE gaat terug op nul als de pic klaar is met meten.
      
   ADON=0;  //switch off adc
   return ADRES;
}


Zurück zu Elektronik für Windkraftanlagen
Mitglieder in diesem Forum: Bing [Bot] und 1 Gast