Este artigo descreve as notas de aplicação simétricas PIC1000 e AVR1000b, mostrando como elas se aplicam ao código gerado pelo fenomenal MPLAB® Code Configurator (MCC). O artigo mostra como usar essas notas de aplicação para entender o código bare metal gerado pelo MCC como referência. Ou, se você começar com as notas de aplicação bare metal, aprenderá como escrever código bare-metal a partir do zero e este artigo mostrará como aplicar esse conhecimento para projetar com o MCC com mais confiança e flexibilidade. A escolha é sua! As notas de aplicação descrevem detalhadamente as razões para as convenções de nomenclatura e os métodos de acesso a registradores para cada arquitetura, ajudando você a compreender as diferenças entre o código de baixo nível das MCUs PIC® e AVR®. Independentemente de como você aborda seus projetos, você será capaz de escrever código C bare metal rapidamente e entender os drivers gerados pelo MCC.
Selecionando um MCU para sua aplicação (Baseado em Periféricos Diferenciados, não na Experiência com uma Família de MCU Específica)
Combinando as impressionantes famílias de microcontroladores PIC e AVR, a Microchip possui uma linha líder de MCUs de 8 bits no mercado. Como engenheiro de sistemas embarcados, idealmente a seleção de um MCU para um projeto específico é baseada no dispositivo (periférico) que melhor permite as características desafiadoras de implementação da sua aplicação. Muitas vezes, isso é determinado pela combinação de periféricos diferenciados nesse MCU. Por exemplo, você pode ter requisitos desafiadores de medição analógica em uma aplicação, exigindo uma análise cuidadosa do conversor analógico para digital (ADC) do MCU. Em uma aplicação, o periférico Conversor Analógico para Digital com Computação (ADCC) de 10 bits do MCU PIC pode ter uma vantagem devido aos vários tipos de cálculos pós-amostragem independentes do núcleo suportados. Para outra aplicação, o ADC diferencial de 12 bits do MCU AVR pode ter vantagens devido à sua resolução ou operação com o Sistema de Eventos do MCU AVR. Ambos os ADCs oferecem funcionalidades relativamente especializadas, oferecendo certas vantagens, dependendo dos requisitos da aplicação.
Frequentemente, o suporte a um ecossistema familiar tem um impacto significativo na seleção de um MCU. Para manter o foco na escolha do MCU e periféricos ideais para o projeto, nos últimos anos foram feitos grandes esforços para alinhar o suporte de ferramentas para as famílias de produtos PIC e AVR da Microchip. A Microchip continua comprometida em oferecer suporte aos novos dispositivos AVR no ecossistema Atmel Studio 7 e Atmel START. Além disso, os MCUs AVR foram adicionados tanto ao Ambiente de Desenvolvimento Integrado (IDE) MPLAB X quanto ao MPLAB Code Configurator (MCC), unificando a experiência de desenvolvimento entre essas famílias de MCU. O suporte de um ecossistema de ferramentas comum foi projetado para permitir que você comece rapidamente com novas famílias de MCU, reduzindo significativamente a barreira para exploração. No entanto, para um desenvolvedor embarcado, o desenvolvimento confortável com um MCU vai além do ecossistema de ferramentas, chegando até o nível de programação de registros, ou seja, codificação bare-metal.
Compreendendo Todo o Código em seu Projeto
Ferramentas de geração de código como o MPLAB Code Configurator (MCC) ou o Atmel START são uma maneira fantástica de economizar muito tempo em seu projeto. No entanto, você pode nunca se sentir completamente confortável com essas ferramentas se não entender o código que elas geram. Ironicamente, você pode confiar na ferramenta apenas quando não precisar mais dela. Como desenvolvedor embarcado, você também sabe que é improvável que você entre em produção sem ter que modificar pelo menos algum código de nível de registro por conta própria.
Programação Bare-Metal: Utilizando Datasheet do Dispositivo e Arquivo de Cabeçalho como Principais Referências de Programação
Os MCUs são compostos por vários blocos de construção ou módulos: CPU, SRAM, Flash, EEPROM e periféricos (por exemplo, um ADC). Cada um deles é definido no datasheet do dispositivo e pode ser configurado por meio de registros. A referência ao ‘metal’ na programação ‘bare-metal’ refere-se aos registros do dispositivo, ou seja, à prática de escrever o código de nível de registro necessário para configurar os módulos de um MCU. A forma deste código de nível de registro é influenciada pelo arquivo de cabeçalho do dispositivo, que por sua vez é influenciado pela estrutura dos módulos periféricos do MCU (datasheet). Portanto, escrever código bare-metal de forma eficiente requer um conhecimento prático da estrutura dos módulos do datasheet, bem como das definições do arquivo de cabeçalho. Além de exemplos de código, as principais referências de programação para desenvolver nesse nível são geralmente o datasheet do MCU e o arquivo de cabeçalho do dispositivo.
A programação bare-metal é uma habilidade de desenvolvimento embarcado que tende a ser dominada ao longo de vários projetos na mesma família de MCUs. Para um MCU específico, o engenheiro se familiariza com os padrões implícitos de como os módulos do datasheet e os arquivos de cabeçalho são organizados para uma família de MCUs. O conhecimento desses padrões facilita um desenvolvimento rápido para aquela família de MCU, mas também cria uma resistência em escolher um MCU diferente, mesmo que possa ser mais adequado para um novo projeto. Com o tempo, adquire-se a capacidade de trabalhar rapidamente com as convenções de nomenclatura relacionadas às definições do arquivo de cabeçalho, permitindo que os engenheiros aproveitem os recursos de preenchimento automático de código de uma IDE moderna, como o MPLAB X IDE (ou o Atmel Studio).
Embora os exemplos utilizados neste artigo se refiram ao código gerado pelo MCC, as lições são igualmente aplicáveis à escrita de código a partir do zero. O estilo de programação e a estrutura de um projeto gerado pelo MCC podem diferir do que você implementaria por conta própria. No entanto, no nível de registro, o código gerado pelo MCC é bastante semelhante ao que você poderia codificar manualmente. Portanto, o código gerado pelo MCC é usado como um exemplo de contexto para explorar as diferenças entre o código de nível de registro para MCUs PIC e AVR por meio das notas de aplicação PIC1000 e AVR1000b. Ao longo do caminho, também destacamos algumas características interessantes do editor MPLAB X IDE que você pode não conhecer.
Drivers do MCC para ADC no MCU PIC (ADC com Computation) e MCU AVR (ADC diferencial de 12 bits)
Os drivers periféricos no MCC oferecem suporte completo às capacidades do módulo, incluindo todos os recursos diferenciados que podem ter motivado a seleção do seu MCU. O MCC é, portanto, uma ótima maneira de avaliar rapidamente o desempenho desses periféricos, independentemente de você decidir ou não usar esse código gerado na produção. Na figura abaixo, é mostrada uma listagem de todas as funções da API para os drivers periféricos ADC dos MCUs PIC e AVR. Como você pode ver, uma vez que a funcionalidade periférica difere, as APIs naturalmente são diferentes. No entanto, em um nível básico, ambos são drivers de ADC, então há funcionalidade comum e, portanto, várias APIs comuns. Por exemplo, se você está apenas interessado em obter um resultado do ADC, em ambos os casos você simplesmente chamará: ADCx_GetConversionResult().
Veja a versão de alta resolução da Figura 1 aqui.
Observação: O Navegador mostrado na Figura 1 está por padrão ao lado do painel do projeto. Ele também pode ser aberto na barra de pesquisa superior direita no MPLAB X IDE.
As listagens de código geradas pelo MCC para ADCx_GetConversionResult(), na Figura 2, mostram as respectivas implementações dessa função para o PIC18F47Q10 e AVR128DA48. Os drivers do MCC tendem a ser relativamente lineares. As funções raramente chamam outras funções, mas se o fizerem, costumam ser imediatamente adjacentes. Observe como o código dentro da função implementa diretamente a funcionalidade requerida, com código de nível de registro, semelhante ao código que você poderia escrever manualmente.
Em grande parte, o código gerado pelo MCC é adaptado à maneira padrão de escrever código para a respectiva família de MCUs, seguindo as melhores práticas. O estilo de programação, portanto, é muito semelhante ao código encontrado em notas de aplicação ou documentos técnicos escritos manualmente pelos engenheiros de aplicação da Microchip. No entanto, você também notará diferenças significativas entre o código para MCUs PIC e o código para MCUs AVR.
Veja a versão de alta resolução da Figura 2 aqui.
Background e Motivação para as Notas de Aplicação PIC1000 e AVR1000b
Na Microchip, engenheiros de aplicação proficientes em escrever código bare-metal para MCUs PIC ou AVR não fizeram uma transição natural para a outra família, contando inicialmente com ferramentas como o MCC ou o Atmel START. Da minha parte, trabalhando no escritório da Microchip em Trondheim, na Noruega (a casa dos MCUs AVR), eu me sentia muito mais confiante usando o MCC para MCUs AVR do que para MCUs PIC. Como mencionei acima, só nos sentimos 100% confortáveis com essas ferramentas quando podemos escrever o código que elas geram por nós mesmos. Como achei desafiador escrever um código básico de nível de registro para MCUs PIC, isso era de se esperar. Além disso, o preenchimento automático de código só funciona quando conhecemos os padrões, então eu estava recebendo pouca ajuda frustrante ao tentar escrever código de nível de registro para MCUs PIC.
Visualize a versão de alta resolução da Figura 3 aqui.
A única nota de aplicação clássica que abordava esse tópico era a “AVR1000: Introdução à escrita de código C para XMEGA”. Ela foi publicada em 2008, quando foram feitas extensões e melhorias na estrutura do módulo (periférico) e nos arquivos de cabeçalho da então nova família de MCUs AVR, a XMEGA. Essas mesmas convenções foram aplicadas internamente a todos os novos dispositivos AVR MCU lançados desde então. Pode não ter sido óbvio que essa nota de aplicação ainda era fundamental em termos de descrever os padrões de escrita de código C para todos os novos dispositivos AVR MCU. Além disso, era necessário algum tipo de documentação para ajudar a compreender as diferenças entre o código de nível de registro das MCUs PIC e AVR.
Para aproveitar a experiência existente em MCUs AVR ou PIC, foram criadas duas notas de aplicação. Elas foram projetadas para serem lidas lado a lado, de modo que um cliente (ou engenheiro de aplicação da Microchip) familiarizado com uma das arquiteturas pudesse facilmente compreender as diferenças entre as duas e começar a trabalhar mais rapidamente com a outra.
Vamos explorar essas notas de aplicação simétricas, que foram projetadas para ajudar a compreender as diferenças entre o código de nível de registro das MCUs PIC e AVR:
- AVR1000b: Introdução à escrita de código C para AVR
- PIC1000: Introdução à escrita de código C para PIC16 e PIC18
As seguintes seções apresentam exemplos do que é abordado em cada capítulo das notas de aplicação PIC1000 e AVR1000b:
- Capítulo 1: Estrutura do módulo e convenções de nomenclatura do datasheet
- Capítulo 2: Representação do módulo nos arquivos de cabeçalho
- Capítulo 3: Escrita de código C para MCUs PIC e AVR (PIC1000 e AVR1000b)
- Capítulo 4: Exemplo de aplicação que demonstra diferentes formas de escrever o código
Capítulo 1: Estrutura do Módulo do Datasheet e Convenções de Nomenclatura (PIC1000 e AVR1000b)
Pelo menos parte da razão pela qual a proficiência em programação bare-metal não se traduz facilmente de uma família de produtos MCU para outra é que os padrões organizacionais dos módulos no datasheet costumam ser implícitos e as convenções de nomenclatura geralmente precisam ser deduzidas.
O primeiro capítulo de cada nota de aplicação tenta remediar isso, fornecendo um guia explícito para a organização dos módulos e as convenções de nomenclatura.
Visualize a versão de alta resolução da Figura 4 aqui.
Por exemplo, vamos considerar as convenções de nomenclatura dos registradores para os MCUs AVR e PIC em relação aos registradores de controle do ADC.
Visualize a versão de alta resolução da Figura 5 aqui.
Ao trabalhar com o MPLAB X IDE (ou o Atmel Studio 7), uma visualização útil dos registradores, bits e campos de bits pode ser encontrada usando a visualização de IO (IO view). Se você iniciar uma sessão de depuração, poderá manipular diretamente os bits dos registradores, por exemplo, para ligar/desligar LEDs na sua placa.
Visualize a versão de alta resolução da Figura 6 aqui.
Observação: Você também pode usar a visualização IO como uma forma mais eficiente de usar o datasheet, selecionando um registrador e clicando no ícone do arquivo PDF. Isso abrirá a versão HTML do datasheet no contexto desse registrador. Esse recurso de ajuda contextual é suportado para os dispositivos PIC e AVR mais recentes.
Além disso, para as MCUs AVR, você também pode navegar pelo datasheet HTML usando o editor. Isso é feito selecionando o PERIPHERAL.REGISTER e clicando no ícone do datasheet PDF, veja a Figura 7. Veja também MPLAB® X – Context Datasheet Help & AVR® Interrupts (aos 2min38).
Visualize a versão de alta resolução da Figura 7 aqui.
Capítulo 2: Representação do Módulo nos Arquivos de Cabeçalho (PIC1000 e AVR1000b)
Neste capítulo, você encontrará resumos das várias definições de arquivos de cabeçalho do dispositivo para MCUs PIC e AVR, como structs, unions e máscaras de bit fields. Essas definições determinarão qual ajuda de preenchimento de código você receberá ao escrever código para o dispositivo. Usando essas definições, seu código será mais legível do que simplesmente atribuir valores hexadecimais a um registrador. Mesmo que você comente seu código, se os comentários ficarem desatualizados, você pode ter um código que é muito difícil de depurar.
Vamos considerar novamente os exemplos de preenchimento automático de código usados na Figura 1.
- Para um MCU PIC, a razão pela qual são fornecidas opções de preenchimento automático de código para os bits no registrador ADCON0 se deve à definição de tipo ADCON0bits_t, composta por definições de bit fields em structs e unions nos arquivos de cabeçalho do dispositivo.
- Para um MCU AVR, a razão pela qual o preenchimento automático de código sugere uma lista de registradores na instância ADC0 do módulo ADC se deve à definição de uma struct ADC_t, compreendendo todos os registradores em um módulo ADC.
visualize a versão de alta resolução da Figura 8 aqui.
Observação: Os nomes de registradores para um módulo AVR MCU não são exclusivos, ou seja, pode haver várias instâncias de um módulo ADC em um MCU, e além disso, pode haver mais de um tipo de módulo que possui um registrador CTRLA. Portanto, para um AVR MCU, um registrador é totalmente definido no contexto de uma instância específica do módulo. No entanto, um MCU PIC possui tanto o módulo quanto a instância embarcados no nome do registrador, por exemplo, ADCON1.
Observação: para MCUs AVR, existem definições de registradores de instância de módulo disponíveis como opção.
visualize a versão de alta resolução da Figura 9 aqui.
Capítulo 3: Escrita de Código C para MCUs PIC ou AVR (PIC1000 e AVR1000b)
Este capítulo das notas de aplicação associadas aborda alguns casos de uso-chave relacionados à escrita em registradores do dispositivo. Usando as várias construções no arquivo de cabeçalho do dispositivo discutidas no Capítulo 2, são fornecidas recomendações de melhores práticas para os seguintes casos de uso:
- Definir e Limpar Bits de Registrador
- Configurar Campos de Bits de Registrador
- Atualizar/Alterar Campos de Bits de Registrador
Observe que atualizar um registrador é diferente de uma configuração inicial desse registrador quando ele está em um estado conhecido após a reinicialização do dispositivo. Considerações de leitura-modificação-escrita devem ser levadas em conta para atualizar apenas os bits ou campos de bits pretendidos.
No exemplo usado neste artigo, o código gerado pelo MCC foi escrito como apresentado, porém várias alternativas são possíveis.
Capítulo 4: Exemplo de Aplicação Mostrando Formas Alternativas de Escrever Código
Neste capítulo, são fornecidas listagens de código para cada uma das diferentes formas alternativas de escrever código de nível de registro. É utilizado um exemplo simples, configurando os pinos e ligando um LED quando um botão é pressionado. Em seguida, são fornecidas listagens de código para cada um dos diferentes estilos de programação suportados, tanto para a versão do MCU PIC quanto para a versão do MCU AVR das notas de aplicação. Essas listagens de código podem ser uma referência útil para facilitar discussões sobre estilo de código em sua empresa. Por exemplo, se você estiver planejando um projeto que usará tanto MCUs PIC quanto AVR, o estilo de máscara de bits ou posição de bits pode permitir um código bastante similar entre os MCUs AVR e PIC.
Resumo
Essas notas de aplicação simétricas, Writing C-Code for PIC/AVR (PIC1000 e AVR1000b), foram escritas para ajudar os engenheiros a escreverem de forma mais fácil um código C de nível de registro legível, por meio de:
- Definição explícita de padrões de módulos e convenções de nomenclatura no datasheet do dispositivo.
- Descrição das estruturas de arquivos de cabeçalho e definições para cada módulo MCU.
- Fornecimento de exemplos de estilo de codificação recomendado para acessar e manipular registradores.
Essas notas devem ser úteis, quer você esteja escrevendo código do zero, tentando entender melhor o código gerado pelo MCC ou pelo Atmel START, ou procurando tomar uma decisão informada sobre o estilo de codificação, avaliando as opções. Além disso, quando usadas lado a lado, essas notas de aplicação ajudam a compreender as diferenças entre o código de nível de registro das MCUs PIC e AVR.
Especificamente, foi feita uma tentativa de entender o código gerado pelo MCC, bem como aproveitar ao máximo os recursos do MPLAB X IDE, como preenchimento automático de código e visualização IO, para escrever um código C fácil de ler e seguir as melhores práticas. Muitos desses recursos do MPLAB X IDE são demonstrados no vídeo: MPLAB® X – Context Datasheet Help & AVR® Interrupts, no processo de escrever o código AVR de nível de registro necessário para ligar um LED quando um botão é pressionado.
Então, se você está acostumado a escrever código de nível de registro para MCUs PIC ou AVR, por que não tentar fazer os conceitos básicos funcionarem na outra plataforma?
Faça o download de ambas as notas de aplicação e tente lê-las lado a lado para ter uma ideia das diferenças entre a MCU com a qual você está familiarizado e a nova. No final de cada uma, você também encontrará links para briefings técnicos, que fornecem exemplos de código bare-metal para uma variedade de periféricos diferentes.
- AVR1000b: Getting Started Writing C-code for AVR
- PIC1000: Getting Started Writing C-code for PIC16 and PIC18
Artigo publicado originalmente no Blog da Microchip: link do texto original
O autor do texto, Glen Nilsen, ficará feliz em responder a quaisquer perguntas e pensamentos que você possa ter. Conecte-se com ele no LinkedIn.
Microchip na América Latina
A Artimar é representante comercial das principais fábricas mundiais de componentes eletrônicos. Com 60 anos de tradição, atua em parceria com a Microchip por 31 anos, juntos sempre buscando trazer alta tecnologia com novos recursos e produtos que ajudam no setor de eletroeletrônica em toda a América Latina.
A Artimar pode te ajudar a encontrar a melhor solução para o seu projeto. Possuímos uma equipe de especialistas que estão prontos para te ajudar.
Clique abaixo e tenha acesso ao suporte técnico Artimar, distribuidores autorizados Microchip para adquirir os seus produtos ou entre em contato conosco: https://www.artimar.com.br/comprar-microchip/
Traduzido pela Equipe Embarcados. Visite a página da Microchip No Embarcados
(*) Este post foi patrocinado pela Microchip










A ideia de aprender por comparação é ótima! Gosto de usar o método bare-metal para MCU’s. Farei isso no meu próximo projeto com AVR já que estou bem familiarizado com a família PIC18 e Mplab X.
Olá! Agradecemos o seu comentário. Se precisar de ajuda técnica contate a artimar através do nosso site: http://www.artimar.com.br