Advertisement
k_vychodilova

MIKRO_UTB

Nov 14th, 2018
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.22 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. int switch3_read(void);
  44. void delay_debounce(void);
  45.  
  46. int main(void)
  47. {
  48.     //Tlacitka
  49.     // inicializace pinu pro tlacitko
  50.     pinMode(SW1, INPUT_PULLUP);
  51.     pinMode(SW2, INPUT_PULLUP);
  52.     pinMode(SW3, INPUT_PULLUP);
  53.  
  54.  
  55.     int sw_state1;
  56.     int sw_state2;
  57.     int sw_state3;
  58.  
  59.     // inicializace ovladace GPIO
  60.     GPIO_Initialize();
  61.  
  62.     //LCD
  63.     LCD_initialize();
  64.     LCD_clear();
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.     // Kolik tiku casovace odpovida 1% sirky pulsu.
  72.     // Nastaveno na spravnou hodnotu nize pri nastaveni casovace
  73.     uint32_t ticksPerPercent = 1;
  74.  
  75.  
  76.     // Povolit clock pro TPM0, tpm2
  77.     SIM->SCGC6 |= SIM_SCGC6_TPM2_MASK;
  78.  
  79.  
  80.     // Nastavit zdroj hodin pro casovac TPM (sdileno vsemi moduly TPM)
  81.     // Dostupne zdroje hodinoveho signalu zavisi na CLOCK_SETUP
  82.     // Pro CLOCK_SETUP = 1 nebo 4 je mozno pouzit OSCERCLK (8 MHz)
  83.     // Pro CLOCK_SETUP = 0 (vychozi v novem projektu) PLLFLLCLK (20.97152 MHz)
  84.     // Mozne hodnoty:
  85.     // 0 - clock vypnut
  86.     // 1 - MCGFLLCLK nebo MCGFLLCLK/2
  87.     // 2 - OSCERCLK
  88.     // 3 - MCGIRCLK  (interni generator, 32 kHz nebo 4 MHz)
  89.     // !!! Pozor pri zapisu do SOPT2 nespolehat na to, ze oba bity
  90.     // pole TPMSRC jsou vynulovany, nestaci SOPT2[TPMSRC] |= nova_hodnota;
  91.     // je nutno nejprve vynulovat a pak "ORovat" novou hodnotu.
  92.     SIM->SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK;
  93.     SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2);
  94.  
  95.  
  96.     // Nastavit casovac
  97.     // Pole PS (prescale) muze byt zmeneno pouze, kdyz je
  98.     // citac casovace zakazan (counter disabled), tj. pokud SC[CMOD] = 0
  99.     // ...nejprve zakazat counter
  100.     TPM2->SC = TPM_SC_CMOD(0);
  101.  
  102.     // ...pockat az se zmena projevi (acknowledged in the LPTPM clock domain)
  103.     while (TPM2->SC & TPM_SC_CMOD_MASK )
  104.         ;
  105.  
  106.     //
  107.     // ... pri zakazanem citaci provest nastaveni
  108.     //
  109.     // Nastavime PWM s pulsy zarovnanymi na zacatek periody (edge aligned).
  110.     // Protoze LED sviti pri log. 0 na pinu, pouzijeme low-true pulses,
  111.     // tj. puls bude hodnota log. 0 a "klid" mezi pulsy bude log. 1.
  112.     // Doba do preteceni citace urcuje periodu PWM.
  113.     // Pozadujeme periodu 100 Hz, tedy doba do preteceni je 0.01 s (10 ms):
  114.     // Modulo = (0.01 * 8000000)/Prescale = 80000/8 = 10000
  115.     // Modulo bude 10 000, coz je 100% sirky pulsu (perioda PWM)
  116.     // Tedy 1% = 100 "tiku" casovace.
  117.     TPM2->CNT = 0;  // manual doporucuje vynulovat citac pred zapisem modulo
  118.     TPM2->MOD = 10000;
  119.  
  120.     // Nastavime kolik je tiku casovace na 1% sirky pulsu pro lepsi
  121.     // citelnost zbytku programu
  122.     ticksPerPercent = 100;
  123.  
  124.     // Nastavit rezim casovace na PWM edge aligned, low true pulses
  125.     TPM2->CONTROLS[PWM_CHANNEL].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK);
  126.  
  127.     // Nastavit pin na PWM vystup
  128.     // ... povolit hodinovy signal pro port pinu
  129.     SIM->SCGC5 |=  SIM_SCGC5_PORTB_MASK;
  130.     SIM->SCGC5 |=  SIM_SCGC5_PORTD_MASK;
  131.  
  132.     // ...Kanal casovace je funkce pinu 3 (ALT3)
  133.     PORTB->PCR[PWM_PINNUMBER] = PORT_PCR_MUX(3);
  134.     PORTD->PCR[PWM_PINNUMBER] = PORT_PCR_MUX(3);
  135.  
  136.  
  137.  
  138.     // Zapiseme pocatecni hodnotu duty, napr. na 10%
  139.     //0% pro ukol navic
  140.     TPM2->CONTROLS[PWM_CHANNEL].CnV = 0 * ticksPerPercent;
  141.     TPM0->CONTROLS[PWM_CHANNEL].CnV = 0 * ticksPerPercent;
  142.  
  143.  
  144.  
  145.     // Nastavime casovac a spustime citani zapisem nenulove delicky (prescale)
  146.     // TPM_SC_PS(3): 3 je hodnota pole PS pro nastaveni delicky na 8
  147.     TPM2->SC = ( TPM_SC_CMOD(1) | TPM_SC_PS(3) );
  148.     TPM0->SC = ( TPM_SC_CMOD(1) | TPM_SC_PS(3) );
  149.  
  150.  
  151.  
  152.     // Budeme plynule menit duty od 0 do 100%
  153.     uint32_t dutyInPercent1 = 0;
  154.     uint32_t dutyInPercent2 = 0;
  155.     uint32_t dutyInPercent3 = 0;
  156.  
  157.  
  158.     //bool directionUp = true;
  159.     while(1)
  160.     {
  161.         /* Zapis nove sirky pulsu do registru casovace
  162.         TPM2->CONTROLS[PWM_CHANNEL].CnV = dutyInPercent1 * ticksPerPercent;
  163.         TPM2->CONTROLS[PWM_CHANNEL1].CnV = dutyInPercent2 * ticksPerPercent;
  164.         TPM0->CONTROLS[PWM_CHANNEL2].CnV = dutyInPercent3 * ticksPerPercent;
  165. char str[10];
  166. if ( sw_state1 == SWITCH_PRESSED) {,   
  167. pinMode(LED_RED,OUTPUT);
  168. dutyInPercent1+=10;
  169.     sprintf(str, "%d", dutyInPercent1);
  170.     LCD_set_cursor(1,1);
  171.     LCD_puts(str);
  172.     if ( dutyInPercent1 == 100 ) {
  173.         dutyInPercent1 = 0;
  174.     }
  175. }
  176. if ( sw_state2 == SWITCH_PRESSED) {
  177. pinMode(LED_GREEN,OUTPUT);
  178. dutyInPercent2+=10;
  179. sprintf(str, "%d", dutyInPercent2);
  180. LCD_set_cursor(2,1);
  181. LCD_puts(str);
  182.  
  183.         if ( dutyInPercent2 == 100 ) {
  184.             dutyInPercent2 = 0;
  185.         }
  186. }
  187. if ( ( sw_state3 == SWITCH_PRESSED) {,                      dutyInPercent3+=10;
  188. sprintf(str, "%d", dutyInPercent3);
  189. LCD_set_cursor(3,1);
  190.  
  191. LCD_puts(str);
  192.         if ( dutyInPercent3 == 100 ) {
  193.             dutyInPercent3 = 0;
  194.         }
  195. delay();
  196. }               }
  197.             else
  198.             dutyInPercent==0;
  199.         }
  200.  
  201.  
  202.         delay();
  203.  
  204.     }
  205.  
  206.     /* Never leave main */
  207.     return 0;}
  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. int switch3_read(void)
  263. {
  264.     int switch_state3 = SWITCH_NOT_PRESSED;
  265.     if ( pinRead(SW3) == LOW )
  266.     {
  267.         // tlacitko je stisknuto
  268.  
  269.         // debounce = wait
  270.         unsigned long n = 200000L;
  271.             while ( n-- )
  272.                 ;
  273.  
  274.         // znovu zkontrolovat stav tlacitka
  275.         if ( pinRead(SW3) == LOW )
  276.         {
  277.             switch_state3 = SWITCH_PRESSED;
  278.         }
  279.     }
  280.     // vratime stav tlacitka
  281.     return switch_state2;
  282. }
  283.  
  284.  
  285.  
  286.  
  287.  
  288. ////////////////////////////////////////////////////////////////////////////////
  289. // EOF
  290. ////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement