É
notável o aumento de fabricantes produzindo microcontroladores equipados
com núcleos ARM que, por sua vez, estão cada vez mais próximos de se
tornarem padrão de mercado. Para os fabricantes, fornecer
microcontroladores rápidos, eficientes e baratos se tornou uma questão
de sobrevivência o que, naturalmente, faz com que invistam cada vez mais
em pesquisa e desenvolvimento.
Edriano Carlos de Araújo
Os µCs Kinetis
Atualmente
podemos encontrar microcontroladores repletos de periféricos, cada vez
mais rápidos e baratos, o que não ocorria no passado. Seguindo esta
tendência de mercado, a Freescale Semicondutores lançou a sua mais
recente família de microcontroladores Kinetis que, segundo a sua própria
definição, é “the gateway to the most scalable portfólio of ARM® MCUs
in the industry”.
O Kinetis possui dois módulos DAC de 12 bits que podem ser alocados para um pino de saída, entrada do módulo comparador, conversor digital-analógico, amplificador operacional ou para outros periféricos. Conforme descrito anteriormente, os periféricos presentes nesta família de microcontroladores não estão simplesmente isolados no sistema executando funções simples, mas sim fazendo parte de um sofisticado e complexo conjunto de features que devolve ao programador a capacidade de inovar e fazer a diferença, pois devido à grande quantidade de possibilidades oferecidas pelo microcontrolador, o sucesso e a qualidade do produto sendo desenvolvido estão diretamente ligados, à capacidade do profissional. Partindo deste princípio, será proposta uma situação-problema simples que possa ser desenvolvida de maneira fácil e prática, mas que proporcione ao leitor ferramentas suficientes para o entendimento deste periférico. Não serão abordados neste artigo a transferência por DMA e a geração de interrupções, ficando estes para uma segunda parte. Para o desenvolvimento destas tarefas utilizaremos o Kit de desenvolvimento KiwikStik (figura 1).
O módulo DAC
A figura 2 mostra um diagrama de blocos do módulo DAC. Suas principais features são:
• Tensão de saída em passos de 1/4096 Vin;
• Vin “tensão de entrada” selecionável entre duas fontes distintas;
• Operação estática do módulo em modos STOP e WAIT;
• Buffer de 16 palavras com níveis máximo e mínimo selecionáveis, capazes de gerar interrupções;
• E suporte a DMA.
Situação-problema
Utilizando
o módulo DAC do Kinetis, gerar uma forma de onda senoidal de 5 kHz,
analisando o impacto no uso da CPU e dos recursos aplicados no projeto.
Proposta A
Nesta
primeira solução, o módulo será configurado de maneira simples sem
considerar o buffer de 16 palavras, ou qualquer outra característica
avançada do DAC, utilizando o periférico como um módulo isolado muito
semelhante à maioria dos DACs presentes em microcontroladores mais
antigos. É importante salientar que durante o desenvolvimento deste
artigo, o Reference Manual do Kinetis K40 já estava em 1731 páginas e
aumentando com o tempo, pois, como em toda família nova, ajustes são
feitos de tempos em tempos. Portanto, mesmo lendo este artigo, é de suma
importância se ter o Reference Manual próximo. Também é importante
entender que devido à grande quantidade de registradores contidos nesta
família de microcontroladores apenas iremos inicializar os registradores
que afetam diretamente o nosso desenvolvimento, deixando os demais em
sua condição de RESET.
Primeiro passo
Configurar o módulo. Para um melhor entendimento será utilizado como base o exemplo contido no CD que acompanha o livro (box 1):
• Configurar o clock para o periférico. Neste caso, o clock é habilitado setando o BIT 12 do registrador SIM_SCGC2;
• Se, por algum motivo, o clock do módulo não seja habilitado, uma
interrupção por Hard fault será gerada, portanto é muito importante que o
clock do módulo seja habilitado (figura 3a);
• Zerar o conteúdo dos registradores de controle. Este passo não é
obrigatório, pois, em sua grande maioria os registradores “nascem do
Reset” em zero (figura 3b, 3c e 3d);
• Configurar os registradores de controle (tabela 1).
Segundo passo
Configurar
uma interrupção de tempo responsável pela atualização do mesmo e criar
uma sub-rotina para atualizar o valor de saída do DAC. Lembrando que,
neste caso, apenas o primeiro registrador do buffer será utilizado:
•
Rotina responsável por atualizar a saída do DAC. Ao atualizar o
registrador DAC1_DAT0H a saída é atualizada. O Kinetis possui um
conjunto de 32 registradores intitulados DACx_DATxL E DACxDATxH, ambos
de 8 bits, para cada um dos seus módulos DAC. A representação deles
neste artigo ocuparia muito espaço, sendo melhor sua verificação no
reference manual (box 2);
•
Rotina de interrupção gerada a cada 6,25 µs. Esta rotina é baseada no
timer PIT0, para maiores informações sobre a sua inicialização vide
capítulo TIMER (box 3). Nesta rotina foi implementada uma tabela onde cada valor diz respeito a uma posição da senoide (figura 4);
•
Rotina Principal inicializa a PLL, configura o TIMER e o DAC. A partir
deste ponto uma interrupção é gerada a cada 6,25 µs atualizando o DAC e,
consequentemente gerando uma senoide. O código-fonte para a PLL e o
Timer está presente no CD que acompanha o livro.
Neste momento o programa será gravado e executado e o resultado comentado a seguir:
Conforme mostra a figura 5 é
possível observar que o objetivo foi alcançado e uma senoide de 5 kHz
foi gerada na saída do DAC. É importante salientar que para que o
resultado fosse alcançado uma interrupção foi gerada a cada 6,25 µs e
uma posição de memória carregada, utilizando assim muito tempo de
processamento da CPU para uma tarefa relativamente simples para o
Kinetis.
Proposta B
Neste
segundo exemplo será utilizado um pouco mais dos features avançados do
Kinetis, o objetivo será o mesmo: gerar uma forma de onda senoidal de 5
kHz na saída do DAC, porém diminuindo um pouco mais o consumo em
processamento exigido da CPU. Para que este objetivo seja alcançado o
buffer de 16 words do Kinetis será habilitado e o trigger por software
realmente aproveitado:
•
Assim como na primeira proposta, o primeiro passo será configurar o
módulo. Algumas mudanças básicas podem ser observadas nesta nova
configuração como, por exemplo o buffer foi habilitado assim como o modo
swing;
• Habilitando-se o modo swing (box 4)
temos a nossa disposição 16 palavras do buffer e não 32 como utilizamos
anteriormente, portanto a tabela será carregada de tal forma que a cada
16 interrupções metade da senoide seja gerada, conforme ilustra a figura 6.
• Configurar os registradores de controle. A partir deste ponto apenas mudanças ou adaptações no código serão explicadas (tabela 2);
•
Carregar a tabela no buffer do DAC. Ao contrário da primeira proposta, a
tabela será carregada uma única vez no buffer, excluindo a necessidade
de acesso a memória pela CPU todas as vezes que um novo dado deva ser
carregado (box 5);
• Reescrever a rotina de interrupção. Neste caso uma interrupção a cada
6,25 µs ainda se faz necessário, porém o único processamento por parte
da CPU será o de acionar o trigger por software e o periférico se
encarregará de atualizar a saída do DAC (tabela 3);
• Não há mudanças significativas na rotina principal:
•
Como observado, a rotina grava_dac não se faz necessária assim como não
será mais preciso carregar uma posição da tabela Dac_Tab a cada
interrupção.
• Através da figura 7 é possível notar que o resultado obtido foi o mesmo da proposta anterior, utilizando muito menos processamento da CPU.
Proposta C
Neste
terceiro exemplo o objetivo será o mesmo: gerar uma forma de onda
senoidal de 5 kHz. O principal diferencial desta proposta será o de que
não haverá consumo da CPU para geração da senoide, sendo esta tarefa
executada única e exclusivamente pelos periféricos DAC e PDB.
• O
módulo PDB provê tempos controlados em função de triggers externos ou
internos, ou de pulsos programados para os periféricos ADC e DAC;
utilizando estes “TICs” programados, podemos automatizar a geração da
senoide, onde cada atualização do DAC será disparada através de um TIC
do PDB. Este módulo não será alvo de estudos neste momento, mas é
possível verificar um pouco de sua estrutura através do Diagrama de
Blocos da figura 8;
•
Como de costume, o primeiro passo será o de configurar os registradores
de controle, e para tal utilizaremos a mesma função da proposta
anterior, fazendo apenas uma pequena alteração comentada (box 6);
• Observe que
a máscara DAC_C0_DACTRGSEL_MASK, foi retirada do código, fazendo com
que o bit DACTRGSEL do registrador C0 fique em zero. Habilitando assim o
trigger por hardware;
• Configurar o módulo PDB (Programable Delay Block). O PDB é um periférico do Kinetis que torna possível gerar triggers periódicos tanto para os módulos ADC quanto DAC. Através deste periférico também é possível gerar delays
entre conversões dos ADCs e conversões do DAC. Devido a complexidade e
versatilidade destes módulos, aqui serão apenas configurados os
registradores pertinentes ao DAC, conforme figura 9 (para maiores esclarecimentos consultar o capitulo PDB no Reference Manual).
•
Como regra uma das dicas mais importantes é: nunca se esqueça de
habilitar o clock do módulo, caso contrário uma interrupção por hard
falt será gerada (box 7).
• Veja um exemplo do contador em modo contínuo na figura 10;
• Rotina de interrupção. Não há mais necessidade de uma rotina de interrupção, o PDB se encarregara de gerar uma atualização do DAC a cada 6,25 µs;
• Rotina Principal.
Foi retirada a rotina configura timer, a qual não mais se faz
necessária e acrescentada a rotina configura PDB que, a partir deste
momento, será responsável pela atualização do DAC (box 8);
• Conforme a figura 11, é possível notar que o
resultado obtido foi o mesmo alcançado pelas propostas anteriores, com a
vantagem de que a partir do momento em que o PDB foi inicializado Não
há consumo em processamento da CPU, ficando esta livre para executar
outras tarefas.
Conclusão
O
Conversor digital-analógico do Kinetis pode ser configurado e utilizado
de várias formas, desde as mais simples até as mais avançadas, cabendo
ao programador identificar a melhor maneira de se implementar a sua
solução. Ainda é possível otimizar o funcionamento do DAC fazendo uso de
suas interrupções, ou até mesmo do DMA, quando a quantidade de dados a
se transferir se torna uma preocupação. Em algum momento pode-se
questionar a qualidade da senoide gerada, porém para o entendimento do
projeto esta foi pensada desta maneira para proporcionar uma melhor
compreensão do periférico, e algumas soluções podem ser utilizadas para
melhorar a qualidade:
•
Colocar um filtro passabaixas na saída do DAC, utilizando-se um resistor
e um capacitor para obter uma senoide de 5 kHz perfeita;
•
Aumentar a taxa de amostragem de saída, para isto deveríamos ativar as
interrupções e alimentar o buffer do Kinetis a cada vez que o buffer
esvaziasse. E assim teríamos consumo de processamento da CPU novamente;
•
Ativar o DMA e programá-la para sempre que o buffer esvazie, a mesma
transfira um novo bloco de dados, desta forma sem consumo de
processamento da CPU.
Como,
foi visto, cabe ao programador desenvolvedor achar a solução que melhor
lhe atenda tanto em tempo de aprendizado quanto em custo.
* Matéria originalmente publicada na revista Saber Eletrônica; Ano: 47; N° 457; Outubro - 2011
Nenhum comentário:
Postar um comentário