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: 0 Mitglieder und 6 Gäste