Configure o PWM do MSP430

PWM do MSP430

Antes de iniciarmos esse tópico vamos abordar brevemente algumas características do famoso microcontrolador da Texas Instruments, o MSP430.

O significado da sigla MSP vem do inglês Mixed Signal Processor (Processador de Sinais Mistos). É um microcontrolador de arquitetura RISC de 16 bits e que ganhou fama devido ao seu baixo custo e principalmente seu baixo consumo de energia.

Hoje mostrarei como configurar o PWM em um MSP430 através de dois exemplos. O primeiro é bem simples e o resultado é um duty cycle fixo, onde conseguimos mudar apenas no código. Já o segundo aumentamos o duty cycle através de uma tecla. O hardware utilizado é uma placa da Texas Instruments, a Launchpad EXP430G2 (Figura 1) com o microcontrolador MSP430G2231. O compilador utilizado foi o CCS (Code Composer Studio), que pode ser baixado no próprio site da Texas Instruments. Para implementar o PWM no MSP430 vamos utilizar o periférico Timer0_A.

PWM do MSP430 - Launchpad EXP430G2
Figura 1 – Placa de Desenvolvimento Launchpad EXP430G2

Exemplo de PWM

Vamos ao primeiro exemplo:

/*
 * MSP430 PWM I
 * AUTOR: LUIZ FERNANDO PALARMINI
 * EXEMPLO DE PWM: CONFIGURANDO O DUTY CYCLE
 */

#include <msp430.h> 

int main(void) {

	//##########################################//
	//####  CONFIGURAÇÃO DO WATCHDOG TIMER  ####//
	//##########################################//

	WDTCTL = WDTPW | WDTHOLD;		//WATCHDOG TIMER PARADO

	//##########################################//
	//#######  CONFIGURAÇÃO DO CLOCK  ##########//
	//##########################################//

	DCOCTL = 0;             		//
	BCSCTL1 = CALBC1_1MHZ;  		//CONFIGURA CLOCK EM 1 MHZ
	DCOCTL = CALDCO_1MHZ;   		//

	//##########################################//
	//##########  DECLARAÇÃO DE I/Os  ##########//
	//##########################################//

	P1DIR |= 0x40;			//P1.6 IMPLEMENTADO COMO SAÍDA
	P1SEL |= 0x40;			//CONFIGURANDO P1.6 COMO PERIFÉRICO TA0.1

	//##########################################//
	//#######  CONFIGURAÇÃO DO TIMER0_A  #######//
	//##########################################//

	TACCR0 = 1000;			//PERÍODO DO PWM
	TACCTL1 = OUTMOD_7;		//MODO DE SAÍDA DO TIMER0_A: RESET/SET
	TACCR1 = 100;			//DUTY CYCLE DO PWM EM 10%
	TACTL = TASSEL_2 + MC_1;	//TASSEL_2 -> CLOCK SOURCE: MCLK	MC_1 ->					 	                //TIMER COM CONTAGEM PROGRESSIVA DE 0 ATÉ TACCR1

	_BIS_SR(CPUOFF);		//DESLIGA A CPU PARA ECONOMIZAR CONSUMO (LPM0)

	return 0;

}

Entendendo o código

WDTCTL = WDTPW | WDTHOLD;		//WATCHDOG TIMER PARADO

Nessa linha desabilito o Watchdog Timer.

DCOCTL = 0;             		//
BCSCTL1 = CALBC1_1MHZ;  		//CONFIGURA CLOCK EM 1 MHZ
DCOCTL = CALDCO_1MHZ;   		//

Aqui configuramos o clock interno do microcontrolador para 1 MHz através do gerador de clock DCO (Digitally Controlled Oscilator – Oscilador Controlado Digitalmente).

P1DIR |= 0x40;			//P1.6 IMPLEMENTADO COMO SAÍDA
P1SEL |= 0x40;			//CONFIGURANDO P1.6 COMO PERIFÉRICO TA0.1

Registradores de I/Os, P1DIR selecionamos se o pino será entrada (nível lógico baixo) ou saída (nível lógico alto). P1SEL, nesse registrador informamos se o pino terá função alternativa (no nosso caso, periférico Timer A) ou será I/O.

TACCR0 = 1000;			//PERÍODO DO PWM
TACCTL1 = OUTMOD_7;		//MODO DE SAÍDA DO TIMER0_A: RESET/SET
TACCR1 = 100;			//DUTY CYCLE DO PWM EM 10%
TACTL = TASSEL_2 + MC_1;	//TASSEL_2 -> CLOCK SOURCE: MCLK MC_1 ->			         
                                //TIMER COM CONTAGEM PROGRESSIVA DE 0 ATÉ TACCR1

Nesse trecho estamos configurando o período do PWM através do registrador TACCR0. Com o valor 1000 estamos informando ao Timer que conte até esse valor. Uma das funções do registrador TACCTL1 é controlar o comportamento das saídas físicas conectadas ao timer, existindo no total 8 modalidades diferentes. Para o PWM utilizaremos somente os modos 3 e 7 (OUTMOD_3 – PWM ativo em nível lógico baixo, OUTMOD_7 – PWM ativo em nível lógico alto). O registrador TACCR1 será o nosso duty cycle do PWM. Como configuramos o clock do MSP430 em 1MHz teremos um período de 1KHz devido ao valor 1000 armazenado em TACCR0 e o duty cycle será 10% devido ao valor 100 armazenado em TACCR1. No registrador TACTL informamos que o clock source do microcontrolador será MCLK (Tassel_2) e o modo de operação do timer será progressivo de 0 até o valor armazenado em TACCR0.

_BIS_SR(CPUOFF);	//DESLIGA A CPU PARA ECONOMIZAR CONSUMO (LPM0)

Nessa linha de código, entramos em modo de economia de energia LPM0, desligando a CPU.

Agora o segundo exemplo:

/*
 * MSP430 PWM II
 * AUTOR: LUIZ FERNANDO PALARMINI
 * EXEMPLO DE PWM: CONTROLANDO O DUTY CYCLE ATRAVÉS DE BOTÃO
 */

#include <msp430.h> 

int main(void) {

	//##########################################//
	//####  CONFIGURAÇÃO DO WATCHDOG TIMER  ####//
	//##########################################//

	WDTCTL = WDTPW | WDTHOLD;		//WATCHDOG TIMER PARADO

	//##########################################//
	//#######  CONFIGURAÇÃO DO CLOCK  ##########//
	//##########################################//

	DCOCTL = 0;             		//
	BCSCTL1 = CALBC1_1MHZ;  		//CONFIGURA CLOCK EM 1 MHZ
	DCOCTL = CALDCO_1MHZ;   		//

	//##########################################//
	//##########  DECLARAÇÃO DE I/Os  ##########//
	//##########################################//

	P1DIR |= 0x40;			//P1.6 IMPLEMENTADO COMO SAÍDA
	P1SEL |= 0x40;			//CONFIGURANDO P1.6 COMO PERIFÉRICO TA0.1
	P1DIR &= ~0x08;			//P1.3 IMPLEMENTADO COMO ENTRADA
	P1IE  |= 0X08; 			//HABILITA INTERRUPÇÃO EM P1.3
	P1IFG &= ~0X08; 		//LIMPA FLAG DE INTERRUPÇÃO DO PINO P1.3
	P1REN |= 0X08;			//HABILITA RESISTOR INTERNO EM P1.3
	P1OUT |= 0X08;			//RESISTOR DE PULL-UP EM P1.3
	P1IES ^= 0x08;                  //BORDA DE SUBIDA/DESCIDA DO PINO P1.3


	//##########################################//
	//#######  CONFIGURAÇÃO DO TIMER0_A  #######//
	//##########################################//

	TACCR0 = 1000;			//PERÍODO DO PWM
	TACCTL1 = OUTMOD_7;		//MODO DE SAÍDA DO TIMER0_A: RESET/SET
	TACCR1 = 100;			//DUTY CYCLE DO PWM EM 10%
	TACTL = TASSEL_2 + MC_1;        //TASSEL_2 -> CLOCK SOURCE: MCLK	MC_1 ->					                        //TIMER COM CONTAGEM PROGRESSIVA DE 0 ATÉ TACCR1

	//_BIS_SR(CPUOFF);	        //DESLIGA A CPU PARA ECONOMIZAR CONSUMO (LPM0)


	__enable_interrupt();	       //HABILITA INTERRUPÇÕES

	while(1);
}


//##########################################//
//############  INTERRUPÇÕES  ##############//
//##########################################//

#pragma vector = TIMER0_A0_VECTOR
__interrupt void timer_int(void){

	TACCTL1 &= ~CCIFG;

}

#pragma vector = PORT1_VECTOR
__interrupt void port_int(void){

	if (P1IN & 0x08) {
		TACCR1 = (TACCR1 + 10)%100;	//AUMENTA EM 10% O DUTY CYCLE DO PWM
	}

	P1IFG &= ~0x08;		//LIMPA FLAG DE INTERRUPÇÃO DO PINO P1.3

}

Vamos agora analisar o que há de novo no código

P1IE  |= 0X08; 			//HABILITA INTERRUPÇÃO EM P1.3
P1IFG &= ~0X08; 		//LIMPA FLAG DE INTERRUPÇÃO DO PINO P1.3
P1REN |= 0X08;			//HABILITA RESISTOR INTERNO EM P1.3
P1OUT |= 0X08;			//RESISTOR DE PULL-UP EM P1.3
P1IES ^= 0x08;                  //BORDA DE SUBIDA/DESCIDA DO PINO P1.3

Aqui temos Registradores de I/O. P1IE é responsável por habilitar interrupção nos ports, P1IFG é a flag de interrupção dos ports, P1REN habilita resistor interno dos ports e em P1OUT estamos configurando resistor de pull-up.

__enable_interrupt();			//HABILITA INTERRUPÇÕES

Esta é uma função intrínseca que habilita as interrupções do MSP430.

#pragma vector = TIMER0_A0_VECTOR
__interrupt void timer_int(void){

	 TACCTL1 &= ~CCIFG;
}

Aqui limpamos a flag de estouro do timer.

#pragma vector = PORT1_VECTOR
__interrupt void port_int(void){

    if (P1IN & 0x08) {
        TACCR1 = (TACCR1 + 10)%100;	//AUMENTA EM 10% O DUTY CYCLE DO PWM
    }

    P1IFG &= ~0x08;			//LIMPA FLAG DE INTERRUPÇÃO DO PINO P1.3

}

Nesse código tratamos a interrupção dos ports, toda vez que o botão que está ligado em P1.3 é pressionado, aumenta o duty cycle do PWM em 10% e limpa a flag de interrupção do pino P1.3.

Segue abaixo (figura 2) as formas de ondas geradas no pino P1.6:

PWM do MSP430 - Formas de ondas monitoradas por osciloscópio no pino P1.6
Figura 2: Formas de ondas monitoradas por osciloscópio no pino P1.6

Espero que com esse conteúdo vocês tenham aprendido como configurar o PWM no MSP430 e não deixem de aprofundar mais o conhecimento mudando os valores dos registradores, usando outras opções de configurações e implementando ainda mais os códigos.

Fiquem á vontade para críticas e sugestões.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
7 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Felipe Xavier
Felipe Xavier
15/11/2016 11:48

Luiz, boa tarde. gostei da aplicação. Estou trabalhando em cima de inversores CC/CA, mas tenho dificuldades de configurar o tempo dos pulsos e um mcu atende com precisão. Vou tentar implementar um inversor CC/CA, utilizando pelo menos 14 bits (quero reservar 2 bits para controle), 7 para pulsos que gerarão o semi ciclo modificado e mais 7 pulsos que gerarão o outro semi ciclo modificado. E através de drivers e mosfets, aplicar o sinal em um trafo com tape central positivo. Os mosfets conduzirão conforme forem acionados e assim, cada pulso terá uma tensão média conduzindo num sentido e também… Leia mais »

Henrique Dezidério
Henrique Dezidério
14/10/2016 10:50

Só gostaria que me explicasse o que significa aquelas diretivas #pragma
Obrigado

Luiz Fernando Palarmini
Luiz Fernando Palarmini
Reply to  Henrique Dezidério
06/11/2016 22:25

Boa noite Henrique, a diretiva #pragma vector serve para informar ao compilador que o código abaixo dela deve ser tratado como interrupção.

Henrique Dezidério
Henrique Dezidério
Reply to  Luiz Fernando Palarmini
07/11/2016 17:21

Ok, obrigado

Haroldo Amaral
Haroldo Amaral
05/05/2016 01:15

Parabéns pelo artigo Luiz!

Luiz Fernando Palarmini
Luiz Fernando Palarmini
Reply to  Haroldo Amaral
25/05/2016 20:42

Obrigado Haroldo! Valeu pelas dicas também, rsrs.

Pedro Patrício
Pedro Patrício
Reply to  Luiz Fernando Palarmini
29/12/2016 15:20

Olá Luiz Fernando, estou a trabalhar na comunicação serial entre duas msp430 com o compilador code compuser, e não consigo fazer as linhas de comando para as referidas placas se comunicarem, se poder espero que me deia uma ajuda.
pemat21@hotmail.com

Home » Software » Configure o PWM do MSP430

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: