Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.26 KB | None | 0 0
  1. /*****************************************************************************
  2. ***** *****
  3. ***** Name: addons.c *****
  4. ***** Some addons for MSP430 device, including: *****
  5. ***** * clock LFXT1, ACLK and MCLK initialization *****
  6. ***** * ports (buzer, status led, keys) initialization *****
  7. ***** * passive delay functions based on timerA *****
  8. ***** !! NOTE: !! ***** *****
  9. ***** !! To use passive delay functions (based on TimerA) !! *****
  10. ***** !! You need to set ACLK to exactly 1 MHz !! *****
  11. ***** !! and MAKE SURE not to use TimerA in other function. !! *****
  12. ***** !! Otherwise, this functions can perform undesired !! *****
  13. ***** !! operations !! *****
  14. ***** !! !! *****
  15. *****************************************************************************/
  16. #include "stdio.h"
  17. #include "stdlib.h"
  18. #include "addons.h"
  19. #include <msp430.h>
  20. #include<msp430x14x.h>
  21.  
  22. #define _100us 100 //
  23. #define _10us 10 //
  24.  
  25. /* Active delay x CPU cycles (original from display.c) */
  26. void activeDelay (unsigned int a) {
  27. int k;
  28. for (k=0 ; k != a; ++k) {
  29. _NOP();
  30. _NOP();
  31. _NOP();
  32. _NOP();
  33. }
  34. }
  35.  
  36. /* Active delay x 100 us (original from display.c) */
  37. void activeDelayx100us(unsigned char b) {
  38. int j;
  39. for (j=0; j!=b; ++j) activeDelay(_100us);
  40. }
  41.  
  42. /* Active delay x 1ms (original from display.c) */
  43. void activeDelayx1ms(unsigned int d) {
  44. unsigned int j, k;
  45. for(j=0; j != d; ++j) {
  46. for(k=0; k != 4000; ++k) _NOP();
  47. }
  48. }
  49.  
  50. /* Odczekanie (bierne) przedziału czasu z zakresu 1-1000 µs
  51. * Z wykorzystaniem Timera A
  52. * Przerwania muszą być odblokowane oraz ACLK=1MHz */
  53. void __Delayx1us(unsigned short t_us) {
  54. TACTL = TASSEL0 + MC_1; // TimerA: source - ACLK(1MHz), up mode
  55. CCR0 = t_us; // TimerA: count up to t_us
  56. CCTL0 = CCIE; // TimerA: interrupt enable
  57. _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
  58. }
  59.  
  60. /* Odczekanie (bierne) przedziału czasu z zakresu 1-500 ms
  61. * Rzeczywiście odmierzany czas:
  62. * t'_ms = 1.024 * t_ms (nieco dłuższy)
  63. *
  64. * Z wykorzystaniem Timera A
  65. * Przerwania muszą być odblokowane oraz ACLK=1MHz */
  66. void __Delayx1ms(unsigned short t_ms) {
  67. if (t_ms > 500) t_ms = 500;
  68. TACTL = TASSEL0 + MC_1 + ID_3; // TimerA: source - ACLK(1MHz), up mode, divider-8
  69. CCR0 = t_ms << 7; // TimerA: count up to 128*t_ms
  70. CCTL0 = CCIE; // TimerA: interrupt enable
  71. _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
  72. }
  73.  
  74. /* Odczekanie dłuższego czasu: 4 - 130000 ms
  75. * Oscylator LFXT1 ustawiany w trybie niskiej częstotliwości 32768 Hz
  76. * ACLK przetaktowywany na 32768/8 = 4096 Hz
  77. * TimerA divider 8 --> f_TimerA = 512 Hz
  78. * Rzeczywiście odmierzany czas:
  79. * t'_ms = 0,977 * t_ms = 1/1,024 * t_ms (nieco krótszy)
  80. * t_ms=1024 ms is real 1000ms
  81. void __Delayx1ms_long(unsigned short t_ms) {
  82. if (t_ms > 16380) t_ms = 16380;
  83. if (t_ms < 4) t_ms = 4;
  84. unsigned char diva0 = BCSCTL1 & DIVA0;
  85. unsigned char diva1 = BCSCTL1 & DIVA1;
  86.  
  87. //Change clock configuration
  88. TACTL = TASSEL0 + MC_1 + ID_3; // TimerA: source - ACLK(1MHz), up mode, divider-8
  89. CCR0 = t_ms >> 2; // TimerA: count up to 0.5*t_ms
  90.  
  91. BCSCTL1 &= ~XTS; // LFXT1 in low frequency 32768Hz
  92. do // wait in loop until crystal is stable
  93. IFG1 &= ~OFIFG;
  94. while (IFG1 & OFIFG);
  95. BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 4096Hz
  96. BCSCTL1 |= DIVA1; //
  97.  
  98. //Start TimerA, and sleep
  99. CCTL0 = CCIE; // TimerA: interrupt enable
  100. STATUS_LED_ON;
  101. _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
  102. STATUS_LED_OFF;
  103. //Restore clock configuration
  104. BCSCTL1 |= XTS; // LFXT1 in high frequency 8MHz
  105. do // wait in loop until crystal is stable
  106. IFG1 &= ~OFIFG;
  107. while (IFG1 & OFIFG);
  108. STATUS_LED_ON;
  109. BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 1MHz
  110. BCSCTL1 |= DIVA1; //
  111. BCSCTL1 &= ~DIVA0; // restore ACLK divider
  112. BCSCTL1 &= ~DIVA1; //
  113. BCSCTL1 |= (diva0|diva1); //
  114. STATUS_LED_OFF;
  115. }*/
  116.  
  117. /* Przerwanie TimerA włącza procesor po czasie określonym w użytej funkcji __Delayx1us() lub __Delayx1ms() */
  118.  
  119. #pragma vector=TIMERA0_VECTOR
  120. __interrupt void Timer_A (void)
  121. {
  122. _BIC_SR_IRQ(CPUOFF); // włącz procesor
  123. CCTL0 &= ~CCIE; // TimerA: interrupt disable
  124. }
  125.  
  126. /* Inicjalizacja portów klawiszy, diod, styczników i buzera */
  127. void InitPorts2() {
  128. P4DIR &= ~0x10; // Ustawienie bitu P4.4 na 0 (tryb wejsciowy) B1 key
  129. P4DIR &= ~0x20; // Ustawienie bitu P4.5 na 0 (tryb wejsciowy) B2 key
  130. P4DIR &= ~0x40; // Ustawienie bitu P4.6 na 0 (tryb wejsciowy) B3 key
  131. P4DIR &= ~0x80; // Ustawienie bitu P4.7 na 0 (tryb wejsciowy) B4 key
  132. P4DIR |= BIT2; // Ustawienie bitu P4.2 na 1 (tryb wyjsciowy) BUZER
  133. BUZ_OFF; // Wyłącz buzer jeśli włączony
  134. P2DIR |= 0x02; // Ustawienie bitu P2.1 na 1 (tryb wyjsciowy) STATUS_LED
  135. P2OUT &= ~0x02; // Zgas diode STATUS_LED jesli zapalona
  136. P1DIR |= 0x20; // Ustawienie bitu P1.5 na 1 (tryb wyjsciowy) REL_1
  137. P1OUT &= ~0x20; // Wylacz stycznik REL_1 i powiazana z nim diode
  138. P1DIR |= 0x40; // Ustawienie bitu P1.6 na 1 (tryb wyjsciowy) REL_2
  139. P1OUT &= ~0x40; // Wylacz stycznik REL_2 i powiazana z nim diode
  140. }
  141.  
  142. /* INICJALIZACJA OSCYLATORÓW I ZEGARÓW
  143. * Ostatecznie pracuje tylko oscylator LFXT1, który zasila ACLK (f_ACLK) i MCLK (f_MCLK)
  144. * Oscylator DCO i zegar SMCLK są wyłączane */
  145. void InitOsc2(unsigned char f_MCLK, unsigned char f_ACLK) {
  146. BCSCTL1 |= XTS; // oscylator LFXT1 w trybie wysokiej częstotliwości (8MHz)
  147. _BIC_SR(OSCOFF); // włączenie oscylatora LFXT1
  148.  
  149. unsigned char i;
  150. do {
  151. IFG1 &= ~OFIFG; // wyczyszczenie flagi OFIFG rejestru IFG1
  152. for (i = 0xFF; i != 0; i--);// odczekanie
  153. }
  154. while (IFG1 & OFIFG); // czekaj dopóki flaga błędu oscylatora jest ustawiona
  155. switch (f_ACLK) {
  156. case 4:
  157. BCSCTL1 |= DIVA0; // ACLK = LFXT1/2 = 4MHz
  158. BCSCTL1 &= ~DIVA1; //
  159. break;
  160. case 2:
  161. BCSCTL1 &= ~DIVA0; // ACLK = LFXT1/4 = 2MHz
  162. BCSCTL1 |= DIVA1; //
  163. break;
  164. case 1:
  165. BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 1MHz
  166. BCSCTL1 |= DIVA1; //
  167. break;
  168. case 8 :
  169. default:
  170. BCSCTL1 &= ~DIVA0; // ACLK = LFXT1/1 = 8MHz
  171. BCSCTL1 &= ~DIVA1; //
  172. break;
  173. };
  174.  
  175. switch (f_MCLK) {
  176. case 4:
  177. BCSCTL2 |= DIVM0; // MCLK = LFXT1/2 = 4MHz
  178. BCSCTL2 &= ~DIVM1; //
  179. break;
  180. case 2:
  181. BCSCTL2 &= ~DIVM0; // MCLK = LFXT1/4 = 2MHz
  182. BCSCTL2 |= DIVM1; //
  183. break;
  184. case 1:
  185. BCSCTL2 |= DIVM0; // MCLK = LFXT1/8 = 1MHz
  186. BCSCTL2 |= DIVM1; //
  187. break;
  188. case 8 :
  189. default:
  190. BCSCTL2 &= ~DIVM0; // MCLK = LFXT1/1 = 8MHz
  191. BCSCTL2 &= ~DIVM1; //
  192. break;
  193. };
  194.  
  195. BCSCTL2 |= SELM0 | SELM1; // MCLK taktowany z LFXT1
  196. for (i = 0xFF; i != 0; i--); // odczekanie
  197. _BIS_SR(SCG0); // wyłączenie oscylatora DCO
  198. _BIS_SR(SCG1); // wyłączenie zegara SMCLK
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement