Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*****************************************************************************
- ***** *****
- ***** Name: addons.c *****
- ***** Some addons for MSP430 device, including: *****
- ***** * clock LFXT1, ACLK and MCLK initialization *****
- ***** * ports (buzer, status led, keys) initialization *****
- ***** * passive delay functions based on timerA *****
- ***** !! NOTE: !! ***** *****
- ***** !! To use passive delay functions (based on TimerA) !! *****
- ***** !! You need to set ACLK to exactly 1 MHz !! *****
- ***** !! and MAKE SURE not to use TimerA in other function. !! *****
- ***** !! Otherwise, this functions can perform undesired !! *****
- ***** !! operations !! *****
- ***** !! !! *****
- *****************************************************************************/
- #include "stdio.h"
- #include "stdlib.h"
- #include "addons.h"
- #include <msp430.h>
- #include<msp430x14x.h>
- #define _100us 100 //
- #define _10us 10 //
- /* Active delay x CPU cycles (original from display.c) */
- void activeDelay (unsigned int a) {
- int k;
- for (k=0 ; k != a; ++k) {
- _NOP();
- _NOP();
- _NOP();
- _NOP();
- }
- }
- /* Active delay x 100 us (original from display.c) */
- void activeDelayx100us(unsigned char b) {
- int j;
- for (j=0; j!=b; ++j) activeDelay(_100us);
- }
- /* Active delay x 1ms (original from display.c) */
- void activeDelayx1ms(unsigned int d) {
- unsigned int j, k;
- for(j=0; j != d; ++j) {
- for(k=0; k != 4000; ++k) _NOP();
- }
- }
- /* Odczekanie (bierne) przedziału czasu z zakresu 1-1000 µs
- * Z wykorzystaniem Timera A
- * Przerwania muszą być odblokowane oraz ACLK=1MHz */
- void __Delayx1us(unsigned short t_us) {
- TACTL = TASSEL0 + MC_1; // TimerA: source - ACLK(1MHz), up mode
- CCR0 = t_us; // TimerA: count up to t_us
- CCTL0 = CCIE; // TimerA: interrupt enable
- _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
- }
- /* Odczekanie (bierne) przedziału czasu z zakresu 1-500 ms
- * Rzeczywiście odmierzany czas:
- * t'_ms = 1.024 * t_ms (nieco dłuższy)
- *
- * Z wykorzystaniem Timera A
- * Przerwania muszą być odblokowane oraz ACLK=1MHz */
- void __Delayx1ms(unsigned short t_ms) {
- if (t_ms > 500) t_ms = 500;
- TACTL = TASSEL0 + MC_1 + ID_3; // TimerA: source - ACLK(1MHz), up mode, divider-8
- CCR0 = t_ms << 7; // TimerA: count up to 128*t_ms
- CCTL0 = CCIE; // TimerA: interrupt enable
- _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
- }
- /* Odczekanie dłuższego czasu: 4 - 130000 ms
- * Oscylator LFXT1 ustawiany w trybie niskiej częstotliwości 32768 Hz
- * ACLK przetaktowywany na 32768/8 = 4096 Hz
- * TimerA divider 8 --> f_TimerA = 512 Hz
- * Rzeczywiście odmierzany czas:
- * t'_ms = 0,977 * t_ms = 1/1,024 * t_ms (nieco krótszy)
- * t_ms=1024 ms is real 1000ms
- void __Delayx1ms_long(unsigned short t_ms) {
- if (t_ms > 16380) t_ms = 16380;
- if (t_ms < 4) t_ms = 4;
- unsigned char diva0 = BCSCTL1 & DIVA0;
- unsigned char diva1 = BCSCTL1 & DIVA1;
- //Change clock configuration
- TACTL = TASSEL0 + MC_1 + ID_3; // TimerA: source - ACLK(1MHz), up mode, divider-8
- CCR0 = t_ms >> 2; // TimerA: count up to 0.5*t_ms
- BCSCTL1 &= ~XTS; // LFXT1 in low frequency 32768Hz
- do // wait in loop until crystal is stable
- IFG1 &= ~OFIFG;
- while (IFG1 & OFIFG);
- BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 4096Hz
- BCSCTL1 |= DIVA1; //
- //Start TimerA, and sleep
- CCTL0 = CCIE; // TimerA: interrupt enable
- STATUS_LED_ON;
- _BIS_SR(CPUOFF); // wyłączenie procesora i MCLK
- STATUS_LED_OFF;
- //Restore clock configuration
- BCSCTL1 |= XTS; // LFXT1 in high frequency 8MHz
- do // wait in loop until crystal is stable
- IFG1 &= ~OFIFG;
- while (IFG1 & OFIFG);
- STATUS_LED_ON;
- BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 1MHz
- BCSCTL1 |= DIVA1; //
- BCSCTL1 &= ~DIVA0; // restore ACLK divider
- BCSCTL1 &= ~DIVA1; //
- BCSCTL1 |= (diva0|diva1); //
- STATUS_LED_OFF;
- }*/
- /* Przerwanie TimerA włącza procesor po czasie określonym w użytej funkcji __Delayx1us() lub __Delayx1ms() */
- #pragma vector=TIMERA0_VECTOR
- __interrupt void Timer_A (void)
- {
- _BIC_SR_IRQ(CPUOFF); // włącz procesor
- CCTL0 &= ~CCIE; // TimerA: interrupt disable
- }
- /* Inicjalizacja portów klawiszy, diod, styczników i buzera */
- void InitPorts2() {
- P4DIR &= ~0x10; // Ustawienie bitu P4.4 na 0 (tryb wejsciowy) B1 key
- P4DIR &= ~0x20; // Ustawienie bitu P4.5 na 0 (tryb wejsciowy) B2 key
- P4DIR &= ~0x40; // Ustawienie bitu P4.6 na 0 (tryb wejsciowy) B3 key
- P4DIR &= ~0x80; // Ustawienie bitu P4.7 na 0 (tryb wejsciowy) B4 key
- P4DIR |= BIT2; // Ustawienie bitu P4.2 na 1 (tryb wyjsciowy) BUZER
- BUZ_OFF; // Wyłącz buzer jeśli włączony
- P2DIR |= 0x02; // Ustawienie bitu P2.1 na 1 (tryb wyjsciowy) STATUS_LED
- P2OUT &= ~0x02; // Zgas diode STATUS_LED jesli zapalona
- P1DIR |= 0x20; // Ustawienie bitu P1.5 na 1 (tryb wyjsciowy) REL_1
- P1OUT &= ~0x20; // Wylacz stycznik REL_1 i powiazana z nim diode
- P1DIR |= 0x40; // Ustawienie bitu P1.6 na 1 (tryb wyjsciowy) REL_2
- P1OUT &= ~0x40; // Wylacz stycznik REL_2 i powiazana z nim diode
- }
- /* INICJALIZACJA OSCYLATORÓW I ZEGARÓW
- * Ostatecznie pracuje tylko oscylator LFXT1, który zasila ACLK (f_ACLK) i MCLK (f_MCLK)
- * Oscylator DCO i zegar SMCLK są wyłączane */
- void InitOsc2(unsigned char f_MCLK, unsigned char f_ACLK) {
- BCSCTL1 |= XTS; // oscylator LFXT1 w trybie wysokiej częstotliwości (8MHz)
- _BIC_SR(OSCOFF); // włączenie oscylatora LFXT1
- unsigned char i;
- do {
- IFG1 &= ~OFIFG; // wyczyszczenie flagi OFIFG rejestru IFG1
- for (i = 0xFF; i != 0; i--);// odczekanie
- }
- while (IFG1 & OFIFG); // czekaj dopóki flaga błędu oscylatora jest ustawiona
- switch (f_ACLK) {
- case 4:
- BCSCTL1 |= DIVA0; // ACLK = LFXT1/2 = 4MHz
- BCSCTL1 &= ~DIVA1; //
- break;
- case 2:
- BCSCTL1 &= ~DIVA0; // ACLK = LFXT1/4 = 2MHz
- BCSCTL1 |= DIVA1; //
- break;
- case 1:
- BCSCTL1 |= DIVA0; // ACLK = LFXT1/8 = 1MHz
- BCSCTL1 |= DIVA1; //
- break;
- case 8 :
- default:
- BCSCTL1 &= ~DIVA0; // ACLK = LFXT1/1 = 8MHz
- BCSCTL1 &= ~DIVA1; //
- break;
- };
- switch (f_MCLK) {
- case 4:
- BCSCTL2 |= DIVM0; // MCLK = LFXT1/2 = 4MHz
- BCSCTL2 &= ~DIVM1; //
- break;
- case 2:
- BCSCTL2 &= ~DIVM0; // MCLK = LFXT1/4 = 2MHz
- BCSCTL2 |= DIVM1; //
- break;
- case 1:
- BCSCTL2 |= DIVM0; // MCLK = LFXT1/8 = 1MHz
- BCSCTL2 |= DIVM1; //
- break;
- case 8 :
- default:
- BCSCTL2 &= ~DIVM0; // MCLK = LFXT1/1 = 8MHz
- BCSCTL2 &= ~DIVM1; //
- break;
- };
- BCSCTL2 |= SELM0 | SELM1; // MCLK taktowany z LFXT1
- for (i = 0xFF; i != 0; i--); // odczekanie
- _BIS_SR(SCG0); // wyłączenie oscylatora DCO
- _BIS_SR(SCG1); // wyłączenie zegara SMCLK
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement