Advertisement
Guest User

Untitled

a guest
Apr 21st, 2014
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.97 KB | None | 0 0
  1. #include "derivative.h"
  2. #include "ADC.h"
  3. #include <HD44780.h>
  4. #include <ltoaz.h>
  5. #include "PWM.h"
  6.  
  7. unsigned char adcczas;
  8. static short int offsetIt;
  9. unsigned char flagaUAR=0;
  10.  
  11. float stalaK = 10.0;
  12.  
  13.  
  14. char ADC_init(void)
  15. {
  16. SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; //sygnał zegarowy na przetwornik analogowo cyfrowy
  17. SIM_SCGC5 |=SIM_SCGC5_PORTB_MASK; //zmienimy 3 wejscia ADC na piny portuB p0,p1,p2
  18. PORTB_PCR(0)= PORT_PCR_MUX(0); //kanal nr 8 ADC
  19. PORTB_PCR(1)= PORT_PCR_MUX(0); //kanal nr 9 ADC
  20. PORTB_PCR(2)= PORT_PCR_MUX(0); //kanal nr 12 ADC
  21. ADC0_SC1A = 0x1F; // moduł ADC0 wyłączony aktualnie
  22.  
  23. ADC0_CFG1 |= ADC_CFG1_ADICLK(1) | // (Bus clock)/2 = 12 MHz
  24. ADC_CFG1_MODE(2) | // Rozdzielczość = 10-bit
  25. ADC_CFG1_ADLSMP_MASK | // Długi czas próbkowania
  26. ADC_CFG1_ADIV(2); // (Input clock)/4 = 3 MHz
  27. ADC0_SC2 &= ~(1<<ADC_SC2_ADTRG_SHIFT );// Konwersja wyzwalana programowo -> wstawiamy ADTRG =0
  28.  
  29. ADC0_SC3 |= ADC_SC3_AVGE_MASK | // Sprzętowe uśrednianie próbek
  30. ADC_SC3_AVGS(3); //liczba próbek do usredniania = 32
  31.  
  32. ADC0_SC3 |= ADC_SC3_CAL_MASK; // Start sekwencji kalibracji
  33. while(ADC0_SC3 & ADC_SC3_CAL_MASK); // Oczekiwanie na zakończenie kalibracji
  34. if (ADC0_SC3 & ADC_SC3_CALF_MASK){ // Sprawdzenie wyniku kalibracji
  35. ADC0_SC3 |= ADC_SC3_CALF_MASK; // Zerowanie flagi CALF
  36. return -1; // Jeśli konwersja zakończona błędem
  37. }
  38.  
  39. return 0;
  40.  
  41. }
  42.  
  43. int ADC_pomiar(unsigned char kanal)
  44. {
  45.  
  46. ADC0_SC1A = ADC_SC1_ADCH(kanal); //wybranie kanalu do pomiaru
  47.  
  48. while(!(ADC0_SC1A & ADC_SC1_COCO_MASK));// Oczekiwanie na zakończenie konwersji
  49.  
  50. return (int) ADC0_RA;
  51.  
  52. }
  53.  
  54. void obslugaADC (void)
  55. {
  56. unsigned char calk;
  57. short int pomiar,wynik,reszta;
  58.  
  59. short int moment;
  60.  
  61.  
  62. char pradIt[8]="It=",napiecie[11]="Ut=",momentM[8]="M=";
  63. char *buff = napiecie+3;
  64. char *buff1 = pradIt+3;
  65. char *buff2 = momentM+2;
  66. static obiektLCD LCDnapiecie,LCDpradtwornika,LCDmoment;
  67. if(adcczas==200) //5x na sekunde pomiar
  68. {
  69. /*
  70. * CZĘŚĆ PROGRAMU ODPOWIEDZIALNA ZA OBLICZENIE/PRZELICZENIE NAPIECIA
  71. */
  72. adcczas=0;
  73.  
  74.  
  75. pomiar=ADC_pomiar(8);
  76. wynik= ((long)(pomiar*3300*2))>>10; //wynik w mV, vref =3.3V, blad na plytce, w rev E zostal poprawiony
  77. //mnozymy x2 aby skompensowac wplyw dzielnik 1/2 na pomiar -> zakres 0-6,6V
  78. calk=wynik/1000;
  79. reszta=wynik%1000;
  80.  
  81.  
  82. buff = ltoaz(calk,buff,10,0);
  83. *buff++='.';
  84. buff = ltoaz(reszta,buff,10,3);
  85. *buff++='V';
  86. *buff='\0';
  87. bRAM(napiecie,0,2,&LCDnapiecie);
  88.  
  89. /*
  90. * CZĘŚĆ PROGRAMU ODPOWIEDZIALNA ZA OBLICZENIE/PRZELICZENIE PRĄDU TWORNIKA
  91. */
  92. pomiar=ADC_pomiar(9)-offsetIt;
  93. if(pomiar<0)pomiar=0;
  94.  
  95. wynik= ((long)(pomiar*3300))>>10;
  96.  
  97. wynik = wynik* (37/27); //przemnazam przez odwrotnosc stalej enkodera
  98. //100mV/A sensivity czujnika dla zakresu 20A, napiecie dla 20A ->4,5V
  99. calk=wynik/100; //liczba całkowita
  100. reszta=wynik%100; //reszta, rozdzielczosc 0,1A tylko,szumy w tym układzie wynoszą 11mV/A
  101.  
  102. buff1 = ltoaz(calk,buff1,10,0);
  103. *buff1++='.';
  104. buff1 = ltoaz(reszta,buff1,10,2);
  105. *buff1++='A';
  106. *buff1='\0';
  107. bRAM(pradIt,0,3,&LCDpradtwornika);
  108.  
  109. /*
  110. * CZĘŚĆ PROGRAMU ODPOWIEDZIALNA ZA OBLICZENIE/PRZELICZENIE MOMENTU
  111. */
  112.  
  113. moment=wynik*stalaK; //przeliczenie momentu, wynik zawiera aktualna wartosc pomiaru ADC
  114.  
  115. calk = moment/100; //moment czesc calkowita
  116. reszta = moment%100; //moment reszta
  117. buff2 = ltoaz(calk,buff2,10,0);
  118. *buff2++='.';
  119. buff2 = ltoaz(reszta,buff2,10,1);
  120. *buff2++='N';
  121. *buff2++='m';
  122. *buff2='\0';
  123. bRAM(momentM,0,4,&LCDmoment);
  124.  
  125. }
  126. }
  127.  
  128. void kalibczujnik(void)
  129. {
  130. /*
  131. * URUCHAMIAJ TO JAKO OSTATNIE ABY NAPIECIE NA WYJSCIU CZUJNIKA MOGLO SIE USTABILIZOWAĆ
  132. */
  133. int kalibracja[10],srednia=0;
  134. unsigned char i;
  135.  
  136. for(i=0;i<10;i++)
  137. {
  138. kalibracja[i]=ADC_pomiar(9);
  139. srednia=srednia+kalibracja[i];
  140. }
  141. offsetIt =srednia/10;
  142.  
  143. }
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151. void regulatorPID (Type_Def_PID *x)
  152. {
  153. /*
  154. * u(t) =kp*e(t) + kp*Td*[e(t)-e(t-1)]/Tp + (kp*Ts/Ti)*(e(0)+e(1)+e(2)+...+e(t))
  155. */
  156.  
  157.  
  158. if(flagaPID&&flagaUAR)
  159.  
  160. {
  161.  
  162. flagaPID=0;
  163. float I;
  164. short int D;
  165.  
  166. x->uchybakt = x->wartzadana-ADC_pomiar(9) ;
  167.  
  168.  
  169. D= x->uchybakt - x->uchybpop;
  170. I= x->uchybakt * x->Ts + x->calkapop;
  171.  
  172. x->wartwyjsc =(short int) (x->kp * x->uchybakt + (x->kp * x->Td * D)/x->Ts + ((x->kp * x->Ts)/(x->Ti)) * I);
  173.  
  174. if((x->wartwyjsc)>2400) x->wartwyjsc=2400;
  175. if((x->wartwyjsc)<0)x->wartwyjsc=0;
  176.  
  177. x->uchybpop = x->uchybakt;
  178. x->calkapop = I;
  179.  
  180. cnt = x->wartwyjsc;
  181.  
  182.  
  183.  
  184. }
  185.  
  186.  
  187. }
  188.  
  189. void obslugaPID (Type_Def_PID *x)
  190. {
  191. static obiektLCD LCDmomentUAR;
  192. static char momentUAR[10]="M=";
  193. char *buff= momentUAR+2;
  194. unsigned char reszta,calk;
  195. int temp;
  196.  
  197. /*
  198. * 564,75 - > wartosc dla pradu I=0 plynacego w obwodzie
  199. * 572 -> przyjmiemy taka wartosc za punkt odniesienia 0
  200. */
  201.  
  202.  
  203.  
  204.  
  205. if(flagaUAR)
  206. {
  207.  
  208. if(!(GPIOD_PDIR & (1<<5))) x->wartzadana+=2; // przycisk odpowiadajacy za zwiekszanie
  209. if(x->wartzadana>1023) x->wartzadana=1023;
  210.  
  211. if(!(GPIOD_PDIR & (1<<0))) x->wartzadana-=2;
  212. if(x->wartzadana<572) x->wartzadana=572;
  213.  
  214.  
  215.  
  216. temp = ((long)(3300*(572-x->wartzadana)))>>10; //wartosc przeliczeniowa posrednia w mV
  217.  
  218. calk = (temp*stalaK)/100; //czesc calkowita momentu nastawionego
  219. reszta=(unsigned char)(temp*stalaK)%10; //badz uwazny tutaj!!! mozliwa poprawka !! //reszta z momentu nastawionego
  220.  
  221.  
  222.  
  223. buff=ltoaz(calk,buff,10,0);
  224. *buff++='.';
  225. buff=ltoaz(reszta,buff,10,1);
  226. *buff++='N';
  227. *buff++='m';
  228. *buff='\0';
  229. bRAM(momentUAR,11,4,&LCDmomentUAR); //dopisz opoznienie do obslugi klawiszy
  230.  
  231. }
  232.  
  233. regulatorPID(&PID);
  234.  
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement