Neste post, vamos explicar como funciona programa exemplo que faz piscar o led embutido na placa e também compreender um pouco mais sobre operações de tempo na marra. Abaixo vemos o programa exemplo codificado em linguagem C, já que não há um display na placa para escrever “Hello World”, há um led para informar que o micro está respondendo e com este led iremos programar, por enquanto.
#include "msp430.h"
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Pára o watchdog
P1DIR |= 0x01; // Seta Porta 1 como saída
volatile unsigned int i; // Volatile para que o compilador não
// tenha que otimizar erroneamente no assembly
for (;;) // Inicia loop infinito
{
P1OUT ^= 0x01; // Alterna P1 usando X-OR*
for (i=0;i<10000;i++); // Gasto decremental de tempo por software
}
}
Podemos perceber que a alteração da variável P1OUT é feita usando uma operação de *XOR, conhecida como Exclusive OR, comparação lógica que resulta em 1 se compara valores diferentes:
Valor A | 0 | 0 | 1 | 1 |
Valor B | 0 | 1 | 0 | 1 |
A XOR B | 0 | 1 | 1 | 0 |
No exemplo estamos fazendo uma XOR com o valor 1. Então cada vez que essa operação for executada o valor de P1OUT será trocado.
Tomando de base o mesmo programa, vamos modificá-lo para testar o dispositivo. Vamos tentar modificar intuitivamente (tentativa e erro) o tempo que o led fica acesso através do delay gerado pela função for.
void main(void)
{
volatile unsigned long int i; // unsigned long int pode receber até 4*10^6
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= 0x01;
for(;;)
{
P1OUT ^= 0x01;
for (i=0;i<100000;i++); // Delay incremental maior
}
}
A variável i foi modificada para long pois queriamos testar o maior tempo possível. Fazendo uma análise dos valores empíricos, obteve-se um tempo médio experimental entre uma piscada e outra de 1,70 segundos (i=100000).
Dobrando-se o valor final de i (200000) obtivemos o tempo de 2,8 segundos e quando fizemos o teste dividindo o valor final de i pela metade (50000) resultou em 1,05 segundos. Fazendo a relação entre os tempos e valores de i obtivemos as seguintes proporções:
led [μs] | 2,80 | 1,70 | 1,05 |
for [loop] | 200.000,00 | 100.000,00 | 50.000,00 |
T [μs/loop] | 1,40E-05 | 1,70E-05 | 2,10E-05 |
T = 1,7 10-5 segundos (17μs)
.
.
Fazendo uma avaliação do gráfico, depreendemos que o tempo médio do período T é de 1,16(μs), e um loop com i de 0 a 0 teria 0,5(s).
Percebemos que existe uma grande diferença entre os tempos para cada situação. Isso se deve ao overhead de instruções, que é constante e impacta mais os tempos menores e principalmente aos erros de medida.
Com isso podemos fazer uma conta aproximada:
Supondo que queremos um tempo de 60(s) ou 1 minuto.
Então o código para o led piscar a cada 1 minuto deverá ser:
void main(void)
{
volatile unsigned long int i;
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= 0x01;
for(;;)
{
P1OUT ^= 0x01;
for (i=0;i<3529411;i++); // Delay de 60s
}
}
Com essas informações podemos criar uma primeira função que cria um delay de t (ms):
void tempo (unsigned long int t)
{
unsigned long int i;
unsigned long int max;
if (t < t_max) //t_max é o maximo que t pode ter sem estourar {
max = t*58823; // max = t_desejado/t_ciclo
for (i=0;i<max;i++); // Delay de 60s
}
}
No próximo post estaremos aprendendo mais sobe as bibliotecas básicas do MSP e criaremos a nossa própria biblioteca.
Até semana que vem!
Nenhum comentário:
Postar um comentário