Advertisement
k_vychodilova

MIKROPC

Nov 8th, 2018
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. /*
  2. * Ukazkovy program pro Programovani mikropocitacu
  3. * Casovac TPM, generovani PWM.
  4. * Program ukazuje rizeni jasu LED s vyuzitim casovace.
  5. * Cervena LED na FRDM-KL25Z meni jas od 0 do 100% pomoci hardwarove
  6. * generovaneho PWM casovacem TPM2 s frekvenci 100 Hz.
  7. *
  8. * POZOR: v nastaveni projektu > compiler > preprocesor musi byt CLOCK_SETUP=1
  9. * aby byl CPU clock 48 MHz!
  10. *
  11. * Uzitecne informace:
  12. * Pomoci casovace muzeme ridit LED RGB primo na FRDM-KL25Z desce,
  13. * LED LD1 az LD3 na vyvojovem kitu nejsou napojeny na kanaly casovace.
  14. *
  15. * B18 - Red LED - TPM2 kanal 0 (ALT3)
  16. * B19 - Green LED - TPM2 kanal 1 (ALT3)
  17. * D1 - Blue LED - TPM0 kanal 1 (ALT4)
  18. *
  19. */
  20.  
  21. #include "MKL25Z4.h"
  22. #include "stdbool.h"
  23. #include <stdio.h>
  24. #include "drv_gpio.h"
  25. #include "drv_lcd.h"
  26.  
  27. // Cislo kanalu TPM2 na kterem generujeme PWM
  28. // 0 - RED LED
  29. // 1 - GREEN LED
  30. #define PWM_CHANNEL (0)
  31.  
  32. #define SWITCH_PRESSED (1)
  33. #define SWITCH_NOT_PRESSED (0)
  34.  
  35.  
  36. // Cislo pinu, na kterem generujeme PWM
  37. // POZOR: musi byt synchronni s PWM_CHANNEL!
  38. #define PWM_PINNUMBER (18)
  39.  
  40. void delay(void);
  41. int switch1_read(void);
  42. int switch2_read(void);
  43. void delay_debounce(void);
  44.  
  45. int main(void)
  46. {
  47. //Tlacitka
  48. // inicializace pinu pro tlacitko
  49. pinMode(SW1, INPUT_PULLUP);
  50. pinMode(SW2, INPUT_PULLUP);
  51.  
  52. int sw_state1;
  53. int sw_state2;
  54.  
  55. // inicializace ovladace GPIO
  56. GPIO_Initialize();
  57.  
  58. //LCD
  59. LCD_initialize();
  60. LCD_clear();
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67. // Kolik tiku casovace odpovida 1% sirky pulsu.
  68. // Nastaveno na spravnou hodnotu nize pri nastaveni casovace
  69. uint32_t ticksPerPercent = 1;
  70.  
  71.  
  72. // Povolit clock pro TPM0, tpm2
  73. SIM->SCGC6 |= SIM_SCGC6_TPM2_MASK;
  74.  
  75.  
  76. // Nastavit zdroj hodin pro casovac TPM (sdileno vsemi moduly TPM)
  77. // Dostupne zdroje hodinoveho signalu zavisi na CLOCK_SETUP
  78. // Pro CLOCK_SETUP = 1 nebo 4 je mozno pouzit OSCERCLK (8 MHz)
  79. // Pro CLOCK_SETUP = 0 (vychozi v novem projektu) PLLFLLCLK (20.97152 MHz)
  80. // Mozne hodnoty:
  81. // 0 - clock vypnut
  82. // 1 - MCGFLLCLK nebo MCGFLLCLK/2
  83. // 2 - OSCERCLK
  84. // 3 - MCGIRCLK (interni generator, 32 kHz nebo 4 MHz)
  85. // !!! Pozor pri zapisu do SOPT2 nespolehat na to, ze oba bity
  86. // pole TPMSRC jsou vynulovany, nestaci SOPT2[TPMSRC] |= nova_hodnota;
  87. // je nutno nejprve vynulovat a pak "ORovat" novou hodnotu.
  88. SIM->SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK;
  89. SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2);
  90.  
  91.  
  92. // Nastavit casovac
  93. // Pole PS (prescale) muze byt zmeneno pouze, kdyz je
  94. // citac casovace zakazan (counter disabled), tj. pokud SC[CMOD] = 0
  95. // ...nejprve zakazat counter
  96. TPM2->SC = TPM_SC_CMOD(0);
  97.  
  98. // ...pockat az se zmena projevi (acknowledged in the LPTPM clock domain)
  99. while (TPM2->SC & TPM_SC_CMOD_MASK )
  100. ;
  101.  
  102. //
  103. // ... pri zakazanem citaci provest nastaveni
  104. //
  105. // Nastavime PWM s pulsy zarovnanymi na zacatek periody (edge aligned).
  106. // Protoze LED sviti pri log. 0 na pinu, pouzijeme low-true pulses,
  107. // tj. puls bude hodnota log. 0 a "klid" mezi pulsy bude log. 1.
  108. // Doba do preteceni citace urcuje periodu PWM.
  109. // Pozadujeme periodu 100 Hz, tedy doba do preteceni je 0.01 s (10 ms):
  110. // Modulo = (0.01 * 8000000)/Prescale = 80000/8 = 10000
  111. // Modulo bude 10 000, coz je 100% sirky pulsu (perioda PWM)
  112. // Tedy 1% = 100 "tiku" casovace.
  113. TPM2->CNT = 0; // manual doporucuje vynulovat citac pred zapisem modulo
  114. TPM2->MOD = 10000;
  115.  
  116. // Nastavime kolik je tiku casovace na 1% sirky pulsu pro lepsi
  117. // citelnost zbytku programu
  118. ticksPerPercent = 100;
  119.  
  120. // Nastavit rezim casovace na PWM edge aligned, low true pulses
  121. TPM2->CONTROLS[PWM_CHANNEL].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK);
  122.  
  123. // Nastavit pin na PWM vystup
  124. // ... povolit hodinovy signal pro port pinu
  125. SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
  126. // ...Kanal casovace je funkce pinu 3 (ALT3)
  127. PORTB->PCR[PWM_PINNUMBER] = PORT_PCR_MUX(3);
  128.  
  129.  
  130. // Zapiseme pocatecni hodnotu duty, napr. na 10%
  131. //0% pro ukol navic
  132. TPM2->CONTROLS[PWM_CHANNEL].CnV = 0 * ticksPerPercent;
  133.  
  134.  
  135. // Nastavime casovac a spustime citani zapisem nenulove delicky (prescale)
  136. // TPM_SC_PS(3): 3 je hodnota pole PS pro nastaveni delicky na 8
  137. TPM2->SC = ( TPM_SC_CMOD(1) | TPM_SC_PS(3) );
  138.  
  139.  
  140. // Budeme plynule menit duty od 0 do 100%
  141. uint32_t dutyInPercent = 0;
  142. //bool directionUp = true;
  143. while(1)
  144. {
  145. /* Zapis nove sirky pulsu do registru casovace
  146. TPM2->CONTROLS[PWM_CHANNEL].CnV = dutyInPercent * ticksPerPercent;
  147.  
  148. if ( dutyInPercent == 0 ) {
  149. directionUp = true;
  150. }
  151.  
  152. if ( dutyInPercent == 100 ) {
  153. directionUp = false;
  154. }
  155.  
  156. if ( directionUp )
  157. dutyInPercent++;
  158. else
  159. dutyInPercent--;
  160.  
  161. delay();*/
  162. sw_state1 = switch1_read();
  163. if(sw_state1 == SWITCH_PRESSED)
  164. {
  165. pinMode(LED_RED,OUTPUT);
  166. //Zapis nove sirky pulsu do registru casovace
  167. TPM2->CONTROLS[PWM_CHANNEL].CnV = dutyInPercent * ticksPerPercent;
  168. char str[10];
  169. sprintf(str, "%d", dutyInPercent);
  170. LCD_set_cursor(1,1);
  171. if(dutyInPercent<100){
  172. dutyInPercent=dutyInPercent+10;
  173. LCD_puts(str);
  174. }
  175. else
  176. dutyInPercent== 0;
  177.  
  178.  
  179. }
  180. sw_state2 = switch2_read();
  181. if(sw_state2 == SWITCH_PRESSED)
  182. {
  183. pinMode(LED_GREEN,OUTPUT);
  184. //Zapis nove sirky pulsu do registru casovace
  185. TPM2->CONTROLS[PWM_CHANNEL].CnV = dutyInPercent * ticksPerPercent;
  186. char str[10];
  187. sprintf(str, "%d", dutyInPercent);
  188. LCD_set_cursor(2,1);
  189. if(dutyInPercent<100){
  190. dutyInPercent=dutyInPercent+10;
  191. LCD_puts(str);
  192. }
  193. else
  194. dutyInPercent==0;
  195. }
  196.  
  197.  
  198. delay();
  199.  
  200. }
  201.  
  202.  
  203.  
  204. /* Never leave main */
  205. return 0;
  206. }
  207.  
  208. /* delay
  209. Jednoducha cekaci funkce - busy wait
  210. */
  211. void delay(void)
  212. {
  213. unsigned long n = 1000000L;
  214. while ( n-- )
  215. ;
  216. }
  217.  
  218.  
  219. int switch1_read(void)
  220. {
  221. int switch_state1 = SWITCH_NOT_PRESSED;
  222. if ( pinRead(SW1) == LOW )
  223. {
  224. // tlacitko je stisknuto
  225.  
  226. // debounce = wait
  227. unsigned long n = 200000L;
  228. while ( n-- )
  229. ;
  230.  
  231. // znovu zkontrolovat stav tlacitka
  232. if ( pinRead(SW1) == LOW )
  233. {
  234. switch_state1 = SWITCH_PRESSED;
  235. }
  236. }
  237. // vratime stav tlacitka
  238. return switch_state1;
  239. }
  240.  
  241. int switch2_read(void)
  242. {
  243. int switch_state2 = SWITCH_NOT_PRESSED;
  244. if ( pinRead(SW2) == LOW )
  245. {
  246. // tlacitko je stisknuto
  247.  
  248. // debounce = wait
  249. unsigned long n = 200000L;
  250. while ( n-- )
  251. ;
  252.  
  253. // znovu zkontrolovat stav tlacitka
  254. if ( pinRead(SW2) == LOW )
  255. {
  256. switch_state2 = SWITCH_PRESSED;
  257. }
  258. }
  259. // vratime stav tlacitka
  260. return switch_state2;
  261. }
  262.  
  263.  
  264.  
  265.  
  266. ////////////////////////////////////////////////////////////////////////////////
  267. // EOF
  268. ////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement