O modelo específico que vamos usar é o MSP430G2231 que possui 2K de memória Flash, 128 bytes de Ram e 10 pinos de E/S digital. Os 2K de Flash, em uma arquitetura Von-Neuman, permitem colocar facilmente a nossa matriz de caracteres. Já os 128 bytes de Ram impedem de manter uma imagem da tela na memória.
Hardware
Como a Launchpad trabalha com 3,6V vamos abusar ligeiramente o display e conectá-lo diretamente. Vamos usar a USI (Universal Serial Interface) para gerar os sinais DIN e SCK, os demais sinais serão gerados por E/S digital. Ficamos portanto com as seguintes conexões entre o display e a Launchpad:
- Vcc -> Vcc
- Gnd -> Gnd
- SCE -> P1.4
- RST -> P1.0
- D/C -> P1.1
- DIN -> P1.6
- SCK -> P1.5
- LED -> Vcc através de um resistor de 100R
Para sofisticar um pouco, vamos colocar duas imagens e uma barra indicando a leitura de temperatura feita pelo sensor interno do MSP430. O software foi feito usando o compilador IAR.
Como de costume, a parte mais complicada é iniciar corretamente os periféricos:
- O watchdog precisa ser desligado (ou reiniciado periodicamente), já que é ativado no reset.
- As entradas e saídas digitais precisam ter a direção programa, o resto das configurações podem ficar nos valores de reset.
- A USI é bastante flexível, o que significa que tem vários registradores de configuração. Em primeiro lugar, precisamos acionar os pinos de SDO e SCLK, selecionar operação SPI master, habilitar a saída e deixar a operação suspensa.Isto é feito no registrador USICTL0.
- O registrador USICTL1 deve ser programado com zero, para ativar o modo SPI.
- O clock para a USI foi programado para SMCLK/8 no registrador USICKCTL.
- A contagem de bits (USICNT) é iniciada com zero e a operação da USI é liberada no USICTL0.
- Embora o MSP430G2231 possa gerar internamente um clock de até 16MHz, vamos trabalhar com 1MHz que é o valor calibrado na fábrica.
- A programação do ADC para leitura da temperatura foi copiada do exemplo da Texas.
- Para fazer a leitura periodicamente vamos usar o TimerA, alimentado pela base de tempo de 12KHz do MSP430.
void IniciaHw (void) { // Programa entradas e saídas digitais P1SEL = 0; P1DIR = PIN_SCE | PIN_RESET | PIN_DC | PIN_SDIN | PIN_SCLK; P1OUT = PIN_SCE; // Programa a USI USICTL0 = USIPE6 | USIPE5 | USIMST | USIOE | USISWRST ; USICTL1 = 0; USICKCTL = USIDIV_2 | USISSEL_2; // Clock = SMCLK/8 = 1/16 MHZ = 62,5 KHz, ativo low USICNT = 0; USICTL0 &= ~USISWRST; // retira o reset do LCD P1OUT = PIN_SCE | PIN_RESET; // Ligar o DCO, vamos trotar a 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; BCSCTL2 = 0; // Configura o ADC para ler o sensor de temperatura ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; // Configura ACLK p/ 6 KHz BCSCTL1 |= DIVA_1; // ACLK/2 BCSCTL3 |= LFXT1S_2; // ACLK = VLO / 2 }Feita a programação da USI, para enviar um byte basta colocá-lo em USISRL e carregar 8 em USICNT. A USI se encarrega de gerar o clock e deslocar os bits. O fim da transmissão é sinalizado pelo bit USIIFG no registrador USICTL1.
// Envia um byte para o controlador do display // dc: LCD_CMD ou LCD_DAT // data: byte a enviar void LcdWrite(byte dc, byte data) { // Seleciona dado ou comando if (dc == LCD_DAT) P1OUT |= PIN_DC; else P1OUT &= ~PIN_DC; // Seleciona o display P1OUT &= ~PIN_SCE; // Envia o byte USICTL0 |= USIOE; USISRL = data; USICNT = 8; while ((USICTL1 & USIIFG) == 0) ; // Desliga a seleção P1OUT |= PIN_SCE; }A leitura da temperatura é feita disparando a conversão e deixando o processador parado (low power mode 0) enquanto ela é concluída. A instrução __bis_SR_register liga (coloca em 1) bits do registrador de status (SR). No caso são ligados os bits que param o processador e habilita interrupções. Quando uma interrupção ocorre, este valor do SR é salvo na pilha e o processador é acordado. A rotina de interrupção usa a instrução __bic_SR_register_on_exit para limpar (colocar em 0) bits da cópia do SR que está na pilha. Quando a rotina retorna, é restaurado o SR alterado, o que no caso significa que o processador estará novamente rodando.
// Faz uma leitura de temperatura void LeTemperatura (void) { ADC10CTL0 |= ENC + ADC10SC; __bis_SR_register(CPUOFF + GIE); // dorme em LPM0 até concluir leitura temperatura = ADC10MEM; } // Trata interrupção do ADC #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Retorna ao modo ativo }No lado do timer, é usado o modo de "contagem para cima", onde ele conta de 0 até o valor escrito em TACCR0. Ao atingir o valor, uma interrupção é gerada. Novamente é usado o recurso de economia de energia; neste caso paramos mais partes do MSP430 usando o low power mode 3.
// Dorme por 200 mseg void Dorme (void) { TACCR0 = 1200; // 200 ms TACTL = TASSEL_1 | MC_1 | TAIE; // ACLK, Up mode. __bis_SR_register(LPM3_bits + GIE); // dorme em LPM3 até timer interromper } // Trata interrupção do timer // Timer A0 interrupt service routine #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A (void) { TACTL = TASSEL_1; // Para o timer __bic_SR_register_on_exit(LPM3_bits); // Retorna ao modo ativo }O nosso programa principal fica assim:
int main( void ) { // Desliga Watchdog WDTCTL = WDTPW + WDTSSEL + WDTHOLD; // Inicia o hardware IniciaHw(); LcdInitialise(); // Mostra a nossa tela inicial LcdClear(); LcdWriteString ("DQSoft", 0, 3); LcdWriteImg (invasor1, 30, 16, 11, 8); LcdWriteImg (invasor2, 51, 16, 8, 8); // Loop principal for (;;) { Dorme (); LeTemperatura (); LcdBarraHoriz(0, 40, LCD_DX, 0); LcdBarraHoriz(0, 40, (int) (temperatura >> 4), 1); } }O projeto completo está nos arquivos do blog (veja lá no alto à direita) no arquivo Nokia5110_MSP430.zip.
4 comentários:
Bom dia
Qual sua versão do IAR?
Pois não consigo abrir na minha versão (4,2)
Eu teria como modificar para poder abrir?
Acho que usei a 5.30. Não tenho certeza se 4.2 suporta o MSP430G que é usado na Launchpad. De qualquer forma, o jeito é criar um novo workspace / projeto com a sua versão, acertar a configuração para a Launchpad e incluir os meus fontes. Outra opção é baixar a versão atual do site da IAR (http://supp.iar.com/Download/SW/?item=EW430-KS4).
Ola..Boa Noite..Gostaria de Saber se este projeto com o MSP430..TEM video..? Obrigada!!
Não fiz nenhum vídeo deste projeto com o MSP430. O mais próximo foi um vídeo do display ligado a um Arduino: http://www.youtube.com/watch?feature=player_embedded&v=xO05Rs3qrdo
Postar um comentário