MSP430 + LED 7 segmentos
Autor: Marco Antônio | Publicado: 2014-10-08T14:04:00-07:00

Para implementar um contador usando mais de um bloco de LED de 7 segmentos é necessário multiplexar o sinal (ligar um bloco por vez), todavia usando-se frequência tal que não seja perceptível ao olhos o "liga/desliga"



Depois de implementar o circuito na protoboard basta rodar o programa abaixo
** Para o caso apresentado, foram utilizados blocos de LED 7Segmentos de anodo comum, o que significa que o MSP fornecerá o GND, assim sendo, quando o MSP fornecer sinal ALTO o led desliga e quando fornecer sinal BAIXO o led acende.

Tutorial em vídeo - https://www.youtube.com/watch?v=ATGpmncioA8
Veja funcionando - https://www.youtube.com/watch?v=JGgaYKlFPNA

_________________________________________________

/*IMPLEMENTAR UM CRONOMETRO COM LED DE 7 SEGMENTOS USANDO O TIMER0_A
*/
#include "io430.h"

int unidade = 0;
int dezena = 0;
int centena = 0;

void main (void)
{
&nbsp; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
&nbsp; BCSCTL1 = CALBC1_1MHZ;&nbsp; //ajusta o DCO para 1MHz
&nbsp; DCOCTL = CALDCO_1MHZ;&nbsp;&nbsp; //ajusta o DCO para 1MHz
&nbsp; P1DIR |= 0x7F;&nbsp; //seta output direction para os bits 0,1,2,3,4,5,6
&nbsp; P2DIR |= 0x07;&nbsp; //seta output direction para os bits 0,1,2
&nbsp; P2OUT |= 0x07;&nbsp; //apaga com sinal alto
&nbsp; P1OUT |= 0x7F;&nbsp; //apaga com sinal alto

/* TESTE DOS LEDS E DOS NÚMEROS EM CADA BLOCO DE LED DE 7 SEGMENTOS
//P2.0 OUT&nbsp; 
&nbsp; P2OUT |= 0x07; 
&nbsp; P2OUT &amp;= ~0x01; 
&nbsp; //0
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x3F; 
&nbsp; //1
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x06;
&nbsp; //2
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x5B; 
&nbsp; //3
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x4F; 
&nbsp; //4
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x66; 
&nbsp; //5
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x6D; 
&nbsp; //6
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0x7D;
&nbsp; //7
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x07; 
&nbsp; //8
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0xFF; 
&nbsp; //9
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0xEF; 

&nbsp; 
//P2.1 OUT
&nbsp; P2OUT |= 0x07; 
&nbsp; P2OUT &amp;= ~0x02; 
&nbsp; //0
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x3F;
&nbsp; //1
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0x06; 
&nbsp; //2
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x5B; 
&nbsp; //3
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x4F; 
&nbsp; //4
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x66; 
&nbsp; //5
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x6D; 
&nbsp; //6
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x7D; 
&nbsp; //7
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x07;&nbsp; 
&nbsp; //8
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0xFF; 
&nbsp; //9
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0xEF; 

//P2.2 OUT
&nbsp; P2OUT |= 0x07;&nbsp; 
&nbsp; P2OUT &amp;= ~0x04; 
&nbsp; //0
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x3F; 
&nbsp; //1
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x06;&nbsp; 
&nbsp; //2
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x5B; 
&nbsp; //3
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x4F;&nbsp; 
&nbsp; //4
&nbsp; P1OUT |= 0x7F;&nbsp; 
&nbsp; P1OUT &amp;= ~0x66;&nbsp; 
&nbsp; //5
&nbsp; P1OUT |= 0x7F; 
&nbsp; P1OUT &amp;= ~0x6D; 
&nbsp; //6
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0x7D;
&nbsp; //7
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0x07;
&nbsp; //8
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0xFF;
&nbsp; //9
&nbsp; P1OUT |= 0x7F;
&nbsp; P1OUT &amp;= ~0xEF;
*/

&nbsp; 
//Setup do timer
&nbsp; TA0CTL = TASSEL_2 + ID_2 + MC_1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*TASSEL (timer_A clock source select) seleciona a fonte do timer, 2=0x10 que indica SMCLK
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID (input divider) 0=0x00(/1) &gt; 1=0x01(/2) &gt; 2=0x10(/4) &gt; 3=0x11(/8)&nbsp;&nbsp;&nbsp; --&gt;QUANTO MAIOR O NUMERO MAIS DEMORA PARA CHEGAR NO VALOR MAXIMO (PISCA MAIS LENTO)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MC (mode control) 0=0x00(stop) &gt; 1=0x01(up) &gt; 2=0x10(continuous) &gt; 3=0x11(up/down)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UP(periodo diferente de 0xFFFF) conta até o valor armazenado no registrador TACCR0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e seta a flag CCIFG no registrador TACCTL0 quando atinge o valor de comparação no registrador TACCR0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e seta a flag TAIFG no registrador TACTL quando o timer passa do valor armazenado no registrador TACCR0 para 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CONTINUOUS seta flag TAIFG no registrador TACTL quando zera a contagem 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UP/DOWN timer conta até TACCR0 e depois decrementa até zero (grafico triangular)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; seta flag CCIFG em DOIS MOMENTOS: quando atinge o valor de TACCR0 ou volta para zero
*/
&nbsp;&nbsp;&nbsp; 
&nbsp; TA0CCTL0 = CCIE; //(capture/compare interrupt enable) habilita a interrupção pela flag CCIFG
&nbsp; TA0CCR0 = 0x61A8;
&nbsp; TA0CCTL0 &amp;= ~CCIFG; //limpa flag de interrupção

//Habilita interrupção
&nbsp; __bis_SR_register(GIE); //habilita interrupção
&nbsp; //__enable_interrupt(); //outra forma de habilitar interrupção

&nbsp; 
//MULTIPLEXAÇÃO
for (;;) //loop infinito
{
&nbsp; switch (unidade) {
&nbsp; case 0:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 1:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x06;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 2:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x5B;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 3:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x4F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 4:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x66;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 5:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x6D;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 6:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x7D;
&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp; 
&nbsp; case 7:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x07;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 8:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xFF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 9:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xEF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 10:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; unidade = 0;
&nbsp;&nbsp;&nbsp; dezena++;
&nbsp;&nbsp;&nbsp; break;
&nbsp; }
&nbsp; P2OUT &amp;= ~0x04; //acende o led da unidade
&nbsp; 
&nbsp; switch (dezena) {
&nbsp; case 0:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 1:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x06;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 2:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x5B;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 3:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x4F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 4:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x66;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 5:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x6D;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 6:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x7D;
&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp; 
&nbsp; case 7:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x07;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 8:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xFF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 9:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xEF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 10:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; dezena = 0;
&nbsp;&nbsp;&nbsp; centena++;
&nbsp;&nbsp;&nbsp; break;
&nbsp; }
&nbsp; P2OUT &amp;= ~0x02; //acende o led da dezena

&nbsp; switch (centena) {
&nbsp; case 0:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 1:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x06;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 2:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x5B;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 3:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x4F;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 4:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x66;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 5:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x6D;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 6:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x7D;
&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp; 
&nbsp; case 7:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x07;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 8:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xFF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 9:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0xEF;
&nbsp;&nbsp;&nbsp; break;
&nbsp; case 10:
&nbsp;&nbsp;&nbsp; P1OUT |= 0xFF;
&nbsp;&nbsp;&nbsp; P2OUT |= 0x07;
&nbsp;&nbsp;&nbsp; P1OUT &amp;= ~0x3F;
&nbsp;&nbsp;&nbsp; centena = 0;
&nbsp;&nbsp;&nbsp; break;
&nbsp; }
&nbsp; P2OUT &amp;= ~0x01; //acende o led da centena

}
}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void interrupt_timer(void)
{
&nbsp; unidade++;
&nbsp; TA0CCTL0 &amp;= ~CCIFG; //limpa flag de interrupção
}
____________________________________________________________________