quarta-feira, 15 de fevereiro de 2017

Recursos especiais do PIC (parte 2)

Como prometido, continuo aqui com o último post sobre alguns módulos dos PICs. Lembrando novamente que estamos falando sobre o PIC18F2550/4550 mas isto se aplica a todos que tiverem. Confiram sempre o datasheet do seu microcontrolador para conferir o nome e função dos registradores.

Fail-Safe Clock Monitor

No último post da série, falamos sobre o WDT e como ele pode nos ajudar quando o PIC "trava", mas e a causa deste travamento? Um estouro de pilha? Uma operação ilegal? Uma flutuação de tensão? Ruído na alimentação? Bem, em todos estes casos com certeza o WDT irá atuar e se for algo transiente, o PIC retoma à operação normal. Mas e se ele travou porque houve uma falha no seu Oscilador externo? Se deu defeito no capacitor ou no cristal do circuito de clock? Aí entra o FSCM pra salvar o dia.
 Segundo o datasheet, "O Fail-Safe Clock Monitor (FSCM) permite ao microcontrolador continuar a operar na eventual falha do oscilador externo ao mudar automaticamente o clock do dispositivo para o bloco oscilador interno". Ao detectar uma falha no oscilador externo, o PIC gera uma interrupção (OSCFIF), muda o clock para o interno e limpa o WDT. Com a interrupção você pode optar por dois caminhos: entrar em um dos estados de gerenciamento de energia do PIC ou escolher a próxima fonte de clock.
No programa, tudo que envolver tempo terá que ser ajustado para o novo clock interno, ou você pode usar um cristal sempre da mesma frequência do clock interno escolhida (eu trabalharia com 8MHz).
Para ativar este recurso, primeiro configure o registrador OSCCON selecionando o clock desejado em caso de falha e as interrupções (INTCON). Ative a interrupção pelo bit OSCFIE e a monitore pelo bit OSCFIF. Lembre-se de ativar o bit de configuração FCMEN (CONFIG1H).

Two-Speed Start-up

 Este é o mais simples de todo: ative o bit de configuração IESO (CONFIG1H). Em modos de oscilador que usem um cristal (XT, HS, XTPLL e HSPLL), este recurso permite o microcontrolador rodar no clock interno até que o clock do cristal esteja estável. O sugerido é apenas que a primeira coisa que seu programa deve fazer é configurar o clock interno (escolher a velocidade) através do OSCCON. Assim que o clock do cristal estiver pronto, automaticamente o PIC muda sua fonte de clock para ele. É uma boa alternativa para o Power-Up Timer.

High/Low Voltage Detector

 Este é o tipo de recurso que você quer ter ativado caso esteja alimentando seu circuito com bateria ou fontes que estejam sujeitas a flutuações de tensão. Este módulo é basicamente um comparador de tensão com sua referência ajustável. Quando a tensão no pino RA5 (HLVDIN) ficar acima ou abaixo do nível configurado, é gerada uma interrupção (HLVDIF). Este módulo é configurado pelo registrador HLVDCON. Importante ressaltar que cada vez que você ativa este módulo, ele leva um tempo para estabilizar, e para isto, há um bit que informa quando ele está pronto (IRVST). Segundo o datasheet, para usar ele você deve prosseguir da seguinte forma:
1. Desabilite o módulo limpando o bit HLVDEN (HLVDCON<4>).
2. Escreva o valor aos bits HLVDL3:HLVDL0 que selecionam a tensão de disparo do HLVD desejada.
3. Arme o bit VDIRMAG para detectar uma tensão acima (VDIRMAG=1) ou abaixo (VDIRMAG=0) da tensão de disparo.
4. Habilite o módulo HLVD armando o bit HLVDEN.
5. Limpe a bandeira de interrupção do HLVD, HLVDIF
(PIR2<2>), que pode ter sido armada por uma interrupção anterior.
6. Habilite a interrupção do HLVD, se desejado, armando os bits HLVDIE e GIE/GIEH (PIE2<2> and INTCON<7>). Uma interrução não será gerada até o bit IRVST estar armado.
E pronto! O HLVD estará aí pra te ajudar a saber se uma tensão está abaixo ou acima de um valor desejado. Isto é muito útil pra monitorar a tensão da bateria que alimenta seu circuito, por exemplo.


Estes eram os últimos módulos que faltavam eu comentar. Sei que ficou parecendo estar tudo por cima mas a ideia era apresentar os módulos pra que vocês saibam da existência deles. Recomendo e muito lerem o datasheet para entenderem como eles funcionam e para como usá-los da melhor forma nos seus projetos. Tire sempre o máximo proveito do microcontrolador que você comprou!

As aparências enganam (algorítimos de ordenação)

Ordenar de forma crescente ou decrescente um sequência de dados na memória de um microcontrolador ou em uma memória externa pode ser necessário uma hora, ainda mais se for usar a busca binária, ou pelo simples fato de você querer dados ordenados. Mas como fazer isto?
Procurando no Google por "sorting algorithms", achei uma página bem interessante que permite visualizar de forma gráfica o que acontece em cada algorítimo. Fui pesquisar como cada um funciona e, buscando o mais simples de programar, acabei no Bubble sorting. Após programar ele com sucesso no PC, resolvi escrever ele e rodar no PIC18F2550. Pra minha surpresa, quando fui organizar uma memória de 512 bytes (4Kbits), esta tarefa foi executada de forma absurdamente lenta (cerca de 10 minutos pra finalizar). Resolvi escrever outro, mas não fui procurar na internet (até procurei o Quick sort mas fiquei com preguiça por dar muito trabalho haha): resolvi pensar. Desenvolvi um algorítimo, mas depois descobri que era exatamente o Selection Sort. Desta vez, o mesmo trabalho que o Bubble levou 10 minutos, em cerca de 3 o Selection fez. "Ora, mas na página lá em cima ele se mostrava bem mais lento. O que houve?" Bem, vou deixar vcs curiosos pela resposta por enquanto. Agora vou mostrar como cada algorítimo realmente trabalha e mostrar os códigos pro PIC que fiz.


Bubble Sorting

Bem simples de programar, o Bubble Sorting consiste em trocar duplas de dados se n+1 > n (sendo n o índice do vetor). Vamos usar de exemplo um vetor de cinco posições com os números 1, 7, 3, 5 e 2. Observe a imagem abaixo que mostra uma iteração apenas (leia como um gibi):


Na próxima iteração, o algorítimo veria que 1 < 3, e portanto não os trocaria de lugar; 3 < 5 mesma coisa, até que por fim chega em 5 > 2, ou seja, trocaria ambos de lugar. Se os números forem iguais, ele não faz nada. O programa precisa repetir isto até todos estarem ordenados.
Abaixo segue um pseudocódigo como exemplo:




Selection Sorting

Tão simples de programar quanto o Bubble, este método surpreendeu ao se mostrar significantemente mais ágil com memórias externas. Este consiste em buscar e "pegar" os menores valores encontrados no vetor e os colocar na ordem crescente, fazendo isso cada vez avançando a partir do último número ordenado. A imagem abaixo exemplifica como isto deve ser feito:


Veja que quando os números forem iguais nada é feito. Creio que este método seja o mais intuitivo (mais próximo do que faríamos como pessoas). Tudo é feito em uma única "passada" pelo vetor.
Aqui segue o pseudocódigo:




Mas e a velocidade?

OK, matando sua curiosidade vamos lá: e a velocidade? A página e vídeos que demonstravam o funcionamento dos algorítimos estavam todos errados? Bem, sim e não.
O problema destes exemplos em animação ou vídeo é considerar que o tempo de leitura e escrita da memória e de comparação sejam todos iguais, mas sabemos que não é verdade. O PIC leva muito mais tempo lendo ou escrevendo uma memória do que simplesmente comparando dois valores da sua RAM. Em uma memória 24C64, por exemplo, a escrita leva cerca de 5 ms a mais do que a leitura, portanto, o algorítimo que menos escrever ganhará vantagem, e em um vetor enorme isto se torna muito relevante, como no exemplo que dei em que o Selection levou cerca de um terço do tempo do Bubble. Ainda mais, o algorítimo que menos escrever aumentará a vida útil da memória. Por isso devemos tomar cuidado com comparações fora do contexto, não só nestes algorítimos mas em qualquer outro. Precisamos pensar muito maior do que as coisas que nos são mostradas. Trago este caso pra que vocês reflitam como é importante considerar os diversos fatores em um programa e escolher métodos conforme a realidade com a qual está trabalhando.