# Microcontrolador PIC

microcontroladores da arquitetura Harvard modificada fabricados pela Microchip Technology, que processam dados de 8 bits, de 16 bits e, mais recentemente, de 32 bits. São derivados do PIC1650 originalmente desenvolvidos pela divisão de microeletrônica da General Instrument. Seu nome é oriundo de "Programmable Interface Controller" (Controlador de Interface Programável), anteriormente conhecido como "Peripheral Interface Controller" (Controlador de Interface Periférica), hoje conhecido apenas como PIC. Contam com extensa variedade de modelos e periféricos internos. Possuem alta velocidade de processamento devido a arquitetura Harvard e conjunto de instruções RISC (conjuntos de 35 instruções e de 76 instruções), com recursos de programação por Memória flash, EEPROM e OTP. Os microcontroladores PIC têm famílias com núcleos de processamento de 12 bits, 14 bits e 16 bits, e trabalham em velocidades de 0 kHz (ou DC) a 48 MHz e velocidades de 16 MIPS em alguns modelos. Há o reconhecimento de interrupções tanto externas como de periféricos internos. Funcionam com tensões de alimentação de 1.8 a 6V e os modelos possuem encapsulamento de 6 a 100 pinos em diversos formatos (SOT23, DIP, SOIC, TQFP, etc).
Os PICs são populares, tanto industrialmente como para hobbystas graças ao seu baixo custo, ampla disponibilidade, grande base de usuários, extensa coleção de notas de aplicação, disponibilidade de ferramentas de desenvolvimento de baixo custo ou grátis, e capacidade de programação serial e reprogramação com memória flash.

## História

As raízes dos PICs se originaram na universidade de Harvard com um projeto para o Departamento de Defesa, mas este foi vencido por um projeto de memória mais simples (e mais confiável na época) da Universidade de Princeton. A arquitetura de Harvard foi primeiramente usada no 8x300 da Signetics, e foi adotada pela General Instruments para uso como interface controladora de periféricos (PIC) que foi projetada para compensar o fraco barramento de I/O da sua CPU CP1600 de 16 bits. A divisão de microeletrônica foi depois transformada na Arizona Microchip Technology (por volta de 1985), com os PICs como seu produto principal. Os PICs tinham um grande conjunto de registradores (de 25 a 192 registradores de 8 bits, comparado com os 144 do Z8). Existem até 31 registradores diretos, mais um acumulador W, embora R1 a R8 também tenham funções especiais - R2 é o PC (com uma pilha implicita de 2 a 16 níveis), e R5 a R8 controlam as portas de I/O. R0 é mapeado no registrador R4 (FSR) e serve como apontador (semelhante ao ISR no F8, ele é o único meio de se acessar o registrador R32 ou acima).
O PIC16x é muito simples, tem somente 33 instruções de 12 bits de largura fixa, incluindo diversas instruções de salto condicional a flags para a próxima instrução (para loops e rotinas condicionais), produzindo um código enxuto importante para aplicações em sistemas embarcados. Ele tem pipelines marginais (2 estágios, 1 de busca e 1 de execução), combinados com execução em um ciclo (exceto para saltos, com 2 ciclos), tendo um desempenho muito bom para a sua categoria.
O PIC 17x tem mais modos de endereçamento (direto, indireto, e relativo; as instruções de modo indireto gastam 2 ciclos para execução), mais instruções (58 de 16 bits), mais registradores (232 a 454), mais até 64k palavras de espaço de programa (2k a 8k no chip). As versões top de linha também possuem instruções de multiplicação de 8 bits sem sinal de 1 ciclo. Esse modelo está obsoleto, não sendo mais recomendado para novos projetos de acordo com a Microchip.
O PIC 16x é uma variante interessante do projeto de 8 bits feita por volta de 1985 pela General Instruments com técnicas de projeto mais inovadoras do que a de outras CPUs da lista (o 1650, o sucessor do 1600 mais comum). Ela perdeu para outras CPUs mais populares e foi posteriormente vendida para a Microchip Technology, que ainda o vende para pequenas aplicações em sistemas embarcados. Um exemplo deste microcontrolador é uma pequena placa chamada Basic Stamp. que consiste em 2 circuitos integrados (1 PIC 16C56 de 18 pinos, um interpretador Basic em 512 palavras de ROM e uma memória EEPROM serial de 256 bytes) com uma porta de I/O onde os programas do usuário podem ser armazenados (por volta de 80 linhas de comando de Basic).

### Do controle de portas para controlador RISC

Em 1965 a General Instruments criou a divisão de microeletrônica, e sem dúvida usou esta divisão para gerar algumas das primeiras arquiteturas de memórias EPROM e EEPROM viáveis. A Divisão de Microeletrônica da General Instrumens foi responsável também por uma grande variedade de funções digitais e analógicas, com as famílias AY3-xxxx e AY5-xxxx.
A General Instruments também criou um microprocessador de 16 bits chamado CP1600, no começo dos anos 70. Era um microprocessador razoável, mas especialmente era pobre em portas de entrada e saída. Para algumas aplicações muito específicas onde as portas de I/O eram necessárias, a General Instruments projetou uma interface controladora de periféricos (ou PIC abreviadamente, de Peripherical Interface Controller em inglês), por volta de 1975. Ele era projetado para ser muito rápido, dado que era para ser portas de I/O de uma máquina de 16 bits, mas não tinha uma grande capacidade de funcionalidade, tendo um conjunto de instruções microcodificadas pequeno. A arquitetura projetada em 1975 é substanciamente a arquitetura de hoje do PIC16C5x. A versão de 1975 foi fabricada em NMOS, e era somente disponível em versões ROM mascaradas. O mercado, contudo, não pensava particularmente assim, e os PICs permaneceram projetados somente para um punhado de grandes clientes.
No final dos anos 80, a General Instruments fez uma grande revisão no seu negócio e se restruturou, deixando para se concentrar nas suas atividades principais, que eram essencialmente semicondutores de potência. A Divisão de Microeletrônica da General Instruments se tornou a General Instruments Microelectronics Inc. (subsidiária integral), da qual 85% foi finalmente vendida para alguns investidores, incluindo a fábrica em Chandler, no Arizona. O pessoal desses investidores analisou profundamente a linha de produtos e fez uma limpeza na maioria deles, como a linha AY3 e AY5 e outros produtos, restando como negócio principal os PICs e as EEPROMs paralelas. Houve uma decisão de reiniciar uma nova empresa, chamada Arizona Microchip Technology.
Como parte da estratégia, a família NMOS PIC165X foi reprojetada para usar um recurso em que a empresa era muito, o EPROM, o conceito de ser baseado em CMOS, one-time-programmable e assim a família PIC16C5X de memória de programa EPROM apagável tinha nascido.
PIC é uma família de microcontroladores RISC fabricada pela Microchip, derivada do PIC1650 originalmente desenvolvida pela divisão de microeletrônica da General Instruments. A Microchip não usa PIC como um acrônimo, na realidade a marca é PICmicro. Geralmente é conhecido que PIC significa Peripherical Interface Controller, embora o acrônimo original para o PIC1650 era Programmable Intelligent Computer.
O PIC original foi fabricado para ser usado com a nova CPU de 16 bits da General Instruments, o CP1600. Apesar de ser uma boa CPU, o CP1600 tinha fraco desempenho de portas de I/O, e o PIC de 8 bits foi desenvolvido em 1975 para melhorar o desempenho do sistema em geral liberando as tarefas de I/O da CPU. O PIC usava simples microcódigos armazenados na ROM para desempenhar suas tarefas, e e embora o termo não tenha sido usado na época, ele tinha um projeto RISC que executava uma instrução por ciclo (4 ciclos de 'clock').
Em 1985, a General Instruments vendeu a divisão de microeletrônica, e os novos donos cancelaram quase tudo, o que na época era obsoleto. Os PICs contudo, foram atualizados com EPROM para produzir um controlador programável, e hoje uma grande variedade de PICs é disponível com vários periféricos internos (módulos de comunicação serial, UARTS, núcleos de controle de motores, etc.) e memória de programa de 512 a 32k palavras.

## Arquitetura de núcleo

A arquitetura do PIC é caracterizada pelos seus múltiplos atributos:
* Espaços separados de instruções e dados (Arquitetura Harvard).
* Um pequeno número de instruções de tamanho fixo.
* A maioria das instruções são de execução de único ciclo (2 ciclos de clock, ou 4 ciclos de clock em modelos de 8 bits), com um ciclo de atraso em desvios (branch) e saltos.
* Um acumulador (W0), cuja utilização (como fonte operando) está implícita (ou seja, não é codificado no código de operação, ou opcode).
* Todos os locais de memória RAM funcionam como registradores como fonte e / ou destino de matemática e outras funções.
* Uma pilha em hardware para armazenamento de endereços de retorno.
* Uma pequena quantidade de espaço de dados endereçável (32, 128, ou 256 bytes, dependendo da família), alargada através de banking.
* Sinalizadores de status da ULA são mapeados para o espaço de dados.
* O Program Counter também é mapeado no espaço de dados e é gravável (este é usado para implementar saltos indirectos).
Não há distinção entre o espaço de memória e o espaço de registradores porque a RAM faz o trabalho de memória e de registradores, e a memória RAM é geralmente referida apenas como o arquivo de registro ou simplesmente como os registradores.

### Espaço de Dados (RAM)

PICs têm um conjunto de registradores que funcionam como uma RAM de propósito geral. Registradores de controle especiais para recursos de hardware também são mapeados para o espaço de dados. A capacidade de endereçamento de memória varia dependendo da série de dispositivo, e todos os dispositivos PIC tem algum mecanismo para estender para endereçamento de memória adicional. Séries de dispositivos mais recentes possuem instruções de transferências que podem cobrir todo o espaço endereçável, independente do banco seleccionado. Em dispositivos anteriores, qualquer movimento nos registradores tinha que ser feito através do acumulador.
Para implementar endereçamento indireto, um "file select register" (registrador de seleção de arquivo - FSR) e "indirect register" (registrador indireto - INDF) são usados. Um número de registrador é gravado no FSR, após o que lê ou escreve para INDF vai ser realmente para ou a partir do registrador apontado por FSR. Dispositivos posteriores estenderam esse conceito com pós e pré-incremento / decremento para maior eficiência no acesso aos dados armazenados sequencialmente. Isto também permite que o FSR seja tratado quase como um ponteiro de pilha (SP).
Memória de dados externa não é endereçável diretamente, exceto em alguns dispositivos PIC18 com grande quantidade de pinos.

### Espaço de Instruções

O espaço de instruções geralmente é implementado como ROM, EPROM ou flash ROM. Em geral, a memória de instruções externa não é endereçável directamente devido à falta de uma interface de memória externa. As exceções são PIC17 e selecione dispositivos PIC 18 com grande quantidade de pinos.

### Palavra de memória

Todos os PICs manipulam (e endereçam) dados em blocos de 8 bits. No entanto, a unidade de endereçamento do espaço de código geralmente não é o mesmo que o espaço de dados. Por exemplo, famílias de PICs na linha de base (PIC12) e mid-range (PIC16) têm memória de instruções endereçável no mesmo tamanho como a largura de instrução, ou seja, 12 ou 14 bits, respectivamente. Em contraste, na série PIC18, a memória de instruções é dirigido em incrementos de 8 bits (bytes), que difere da largura da instrução de 16 bits.

### Pilhas

PICs têm uma pilha de chamadas implementada em hardware, que é utilizada para guardar endereços de retorno. A pilha de hardware não é acessível por software em dispositivos anteriores, mas isso mudou com os dispositivos da série 18.
Suporte de hardware para uma pilha de parâmetros de uso geral era ausente em séries anteriores, mas isso melhorou muito na série 18, fazendo com que a arquitetura da série 18 mais amigável para compiladores de linguagem de alto nível.

### Conjunto de Instruções

Instruções de um PIC podem variar de cerca de 35 instruções (PICs mais simples) para mais de 80 instruções para os PICs high-end. O conjunto de instruções inclui instruções para executar uma variedade de operações em registros diretamente, o acumulador e uma constante literal ou o acumulador e um registrador, bem como para a execução condicional, e saltos de execução.
Algumas operações, como bit setting e testes, pode ser realizada em qualquer registrador numerado, mas operações aritméticas bi-operando sempre envolvem o W (acumulador), escrevendo o resultado de volta para W ou outro registrador operando. Para carregar uma constante, é necessário carregá-lo em W antes de ser transferida para outro registrador. Nos cores mais antigos, todos os movimentos de registrador precisavam passar por W, mas isso mudou nos núcleos "high-end".
Núcleos do PIC tem instruções de saltos que são utilizados para a execução condicional e desvios. As instruções de salto são "skip if bit set" e "skip if bit not set". Porque os núcleos anteriores ao PIC18 tinham apenas instruções de desvio incondicional, saltos condicionais são implementados por um desvio condicional (com a condição oposta), seguido de um desvio incondicional. Pulos também são de utilidade para a execução condicional de qualquer instrução simples imediatamente seguinte. Também é possível pular instruções de salto. Por exemplo, a sequencia de instruções "pular se A; pular se B; C" irá executar C se A é verdadeiro ou B for falso.
A série PIC18 implementou registradores "sombra" (shadow registers) que salvam vários registradores importantes durante uma interrupção, fornecendo suporte de hardware para salvar automaticamente o estado do processador durante a manutenção de interrupções.
Em geral, as instruções do PIC são divididas em 5 classes:
* Operação no registrador de trabalho (WREG), com imediato ("literal") operando de 8 bits. Por exemplo, movlw (mover literalmente para WREG), andlw (AND literal com WREG). Uma instrução peculiar é retlw, que carrega imediatamente em WREG e retorna, que é usado com desvios computados para produzir tabelas de consulta.
* Operação com WREG e registrador indexado. O resultado pode ser escrito ou no registrador de trabalho (ex.: addwf reg, w) ou o registrador selecionado (ex.: addwf reg, f).
* Operações em bits. Estes tomam um número do registrador e um número de bit, e realiza uma das 4 ações: definir ou limpar um bit, e testar e pular na definição/limpeza. Estas últimas são utilizadas para realizar desvios condicionais. Os sinalizadores de status habituais da ULA estão disponíveis em um registrador numerado, então operações como "desvio de carga clara" são possíveis.
* Controle de transferência. Além das instruções de salto previamente mencionadas, existem apenas dois: goto e call.
* Algumas instruções diversas sem operando, como retorno de subrotina e sleep para entrar em modo de economia de energia.

### Desempenho

As decisões da arquitetura são direcionadas para a maximização da relação de velocidade-custo. A arquitetura Harvard - onde as instruções e os dados são provenientes de fontes diferentes - simplifica muito o tempo e o desenho do circuito, beneficiando velocidade do clock, preço e consumo de energia.
O conjunto de instruções PIC é adequado para a implementação de tabelas de consulta rápida no espaço do programa. Tais consultas tomam uma instrução e dois ciclos de instrução. Muitas funções podem ser modeladas deste modo. A optimização é facilitada pelo espaço relativamente grande do espaço de instruções (como 4096 x palavras de 14 bits no 16F690) e pelo projeto do conjunto de instruções, que permite constantes embutidas.
Latência de interrupção é constante em três ciclos de instrução. Interrupções externas precisam ser sincronizadas com o ciclo de instruções de 4 ciclos de clock, caso contrário, poderá haver um ciclo jitter de uma instrução. Interrupções externas já estão sincronizadas. A latência de interrupção constante permite que os PICs consigam atingir sequências de baixa oscilação. Um exemplo disto é um gerador de impulsos de sincronização de vídeo. Isso não é mais realidade nos mais novos modelos do PIC, porque eles têm uma latência de interrupção síncrona de três ou quatro ciclos.

### Vantagens

* Pequeno conjunto de instruções para aprender
* Arquitetura RISC
* Oscilador embutido com velocidade selecionável
* Kits de desenvolvimentos para iniciantes disponíveis por menos de 50 dólares
* Microcontroladores baratos
* Grande disponibilidade de interfaces, como USB, I²C, SPI, Ethernet, entre outros
* Disponibilidade de processadores em pacote DIL torná-los fáceis de manusear para uso como hobby.

### Limitações

* Um acumulador
* Bank switching por registrador é necessário para acessar a RAM em diversos dispositivos
* Operações e registradores não são ortogonais; algumas instruções podem endereçar RAM e/ou constantes imediatas, enquanto outros podem usar apenas o acumulador.
As seguintes limitações em pilhas foram corrigidos na série PIC18, mas ainda são presentes em PICs anteriores:
* A pilha de chamadas em hardware não é endereçável, a alternância de tarefas de modo preemptivo não pode ser implementado
* Pilhas implementadas por software não são eficientes, por isso é difícil gerar código reentrante e suportar as variáveis locais
Com memória de instruções paginada, há dois tamanhos de página para se preocupar: um para CALL e GOTO e outro para GOTO computada (normalmente usado para consultas de tabela). Por exemplo, em PIC16, CALL e GOTO tem 11 bits de endereçamento, de modo que o tamanho da página é de 2048 palavras de instrução. Para GOTOs computadas, onde você adicionar ao PCL, o tamanho da página é de 256 palavras de instrução. Em ambos os casos, os bits de endereço superiores são fornecidos pelo registrador PCLATH. Este registrador deve ser trocado a cada transferência de controle de tempo entre as páginas. PCLATH também deve ser preservado por qualquer manipulador de interrupção.

### Desenvolvimento de Compiladores

Enquanto vários compiladores comerciais estão disponíveis, em 2008, a Microchip lançou seus próprios compiladores C, C18 e C30, para a linha de processadores 18F 24F e 30/33F.
A partir de 2013, a Microchip oferece sua série de compiladores XC, para uso com MPLAB X. Microchip acabará por eliminar gradualmente os seus compiladores mais antigos, como C18, e recomenda o uso de seus compiladores série XC para novos modelos.
O conjunto de instruções RISC do código de linguagem de montagem do PIC, embora sendo simples, pode fazer o fluxo global difícil de compreender. O uso criterioso de macros simples podem melhorar a legibilidade da linguagem assembly do PIC. Por exemplo, o assembler original Parallax PIC ("SPASM") tem macros que escondem W e fazem o PIC ficar parecido com uma máquina de dois endereços.

## Diferenças arquiteturais

Os PICs usam a arquitetura Harvard, e as palavras de instrução possuem tamanhos incomuns. Originalmente, instruções de 12 bits incluíam endereço de 5 bits para especificar o operando em memória, e destinos de desvios de 9 bits. Revisões posteriores adicionaram bits aos códigos de operações (opcode), permitindo adicionar bits para endereços.

## Dispositivos com núcleo básico (12 bits)

Estes dispositivos apresentam memória de instruções com 12 bits, um arquivo de registradores de 32 bytes, e uma pequena pilha de chamadas de dois níveis de profundidade. Eles são representados pela série PIC10, bem como por alguns dispositivos PIC12 e PIC16. Dispositivos da linha de base estão disponíveis em pacotes de 6 pinos a 40 pinos.
Geralmente os primeiros 7-9 bytes do arquivo de registradores são registradores de uso especial, e os bytes restantes são de uso geral RAM. Os ponteiros são implementados usando um par de registradores: depois de escrever um endereço para o FSR (selecionador de arquivo de registradores), o registrador INDF (f indireto) torna-se um alias para o registrador abordado. Se RAM comutada é implementada, o número do banco é selecionado pelos 3 primeiros bits do FSR. Isso afeta os números de registradores 16-31; registradores 0-15 são globais e não são afetados pelos bits selecionados.
Devido ao espaço dos registradores ser muito limitado (5 bits), 4 registradores raramente lidos não foram atribuídos endereços, mas são escritos por instruções especiais (OPTION e TRIS).
O espaço de endereço ROM é de 512 palavras (12 bits cada), que podem ser estendidos a 2048 palavras por comutação. Instruções CALL e GOTO especificar as últimos 9 bits do novo local do código; bits de ordem superior adicionais são tomadas a partir do registrador de status. Note-se que a instrução CALL inclui apenas 8 bits de endereço, e só pode especificar endereços no primeira metade de cada página de 512 palavras.
Tabelas de consulta são implementadas utilizando um GOTO computado (atribuição de registrador PCL) em uma tabela de instruções RETLW.
O conjunto de instruções será apresentado a seguir. Números de registrador são referidos como "f", enquanto que as constantes são referidos como "k". Números binários (0-7) são seleccionados por "b". O bit "d" seleciona o destino: 0 indica W, enquanto que 1 indica que o resultado é escrito de volta para registrador fonte f. Os sinalizadores de status C e Z podem ser definido com base no resultado; caso contrário, eles são não modificados. Instruções de soma e subtração (mas não rotação) que definem C também definem o sinalizador DC (digit carry), o carry do bit 3 para o bit 4, que é útil para a aritmética em BCD.
Conjunto de instruções PIC 12 bits :
| 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Mnemônico | C? | Z? | Descrição |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | opcode | opcode | opcode | opcode | opcode | Instruções diversas | Instruções diversas | Instruções diversas | Instruções diversas |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NOP | | | Nenhuma operação (MOVW 0,W) |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | OPTION | | | Copia W para o registrador OPTION |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | SLEEP | | | Entra em modo de economia de energia |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | CLRWDT | | | Reinicia o watchdog timer |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | f | f | TRIS f | | | Copia W para o registrador de triplo estado (f = 1, 2 or 3) |
| 0 | 0 | opcode | opcode | opcode | opcode | d | register | register | register | register | register | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | f | f | f | f | f | MOVWF f | | | dest ← W |
| 0 | 0 | 0 | 0 | 0 | 1 | d | f | f | f | f | f | CLR f,d | | Z | dest ← 0, normalmente escrito CLRW ou CLRF f |
| 0 | 0 | 0 | 0 | 1 | 0 | d | f | f | f | f | f | SUBWF f,d | C | Z | dest ← f−W (dest ← f+~W+1) |
| 0 | 0 | 0 | 0 | 1 | 1 | d | f | f | f | f | f | DECF f,d | | Z | dest ← f−1 |
| 0 | 0 | 0 | 1 | 0 | 0 | d | f | f | f | f | f | IORWF f,d | | Z | dest ← f | W, OU inclusivo lógico |
| 0 | 0 | 0 | 1 | 0 | 1 | d | f | f | f | f | f | ANDWF f,d | | Z | dest ← f & W, AND (E) lógico |
| 0 | 0 | 0 | 1 | 1 | 0 | d | f | f | f | f | f | XORWF f,d | | Z | dest ← f ^ W, XOR lógico |
| 0 | 0 | 0 | 1 | 1 | 1 | d | f | f | f | f | f | ADDWF f,d | C | Z | dest ← f+W |
| 0 | 0 | 1 | 0 | 0 | 0 | d | f | f | f | f | f | MOVF f,d | | Z | dest ← f |
| 0 | 0 | 1 | 0 | 0 | 1 | d | f | f | f | f | f | COMF f,d | | Z | dest ← ~f, complemento bit a bit |
| 0 | 0 | 1 | 0 | 1 | 0 | d | f | f | f | f | f | INCF f,d | | Z | dest ← f+1 |
| 0 | 0 | 1 | 0 | 1 | 1 | d | f | f | f | f | f | DECFSZ f,d | | | dest ← f−1, então pula se 0 |
| 0 | 0 | 1 | 1 | 0 | 0 | d | f | f | f | f | f | RRF f,d | C | | dest ← CARRY<<7 &#124; f>>1, rotacionar para a direita através do carry |
| 0 | 0 | 1 | 1 | 0 | 1 | d | f | f | f | f | f | RLF f,d | C | | dest ← F<<1 | CARRY, rotacionar para a esquerda através do carry |
| 0 | 0 | 1 | 1 | 1 | 0 | d | f | f | f | f | f | SWAPF f,d | | | dest ← f<<4 | f>>4, swap nibbles |
| 0 | 0 | 1 | 1 | 1 | 1 | d | f | f | f | f | f | INCFSZ f,d | | | dest ← f+1, então pula se 0 |
| 0 | 1 | op | op | bit | bit | bit | register | register | register | register | register | Operações em Bits | Operações em Bits | Operações em Bits | Operações em Bits |
| 0 | 1 | 0 | 0 | bit | bit | bit | f | f | f | f | f | BCF f,b | | | Limpar bit b de f |
| 0 | 1 | 0 | 1 | bit | bit | bit | f | f | f | f | f | BSF f,b | | | Definir bit b de f |
| 0 | 1 | 1 | 0 | bit | bit | bit | f | f | f | f | f | BTFSC f,b | | | Pular se bit b de f está limpo |
| 0 | 1 | 1 | 1 | bit | bit | bit | f | f | f | f | f | BTFSS f,b | | | Pular se bit b de f está definido |
| 1 | 0 | op | op | k | k | k | k | k | k | k | k | Transferências de controle | Transferências de controle | Transferências de controle | Transferências de controle |
| 1 | 0 | 0 | 0 | k | k | k | k | k | k | k | k | RETLW k | | | Define W ← k, então retorna de uma subrotina |
| 1 | 0 | 0 | 1 | k | k | k | k | k | k | k | k | CALL k | | | Chama uma subrotina, endereço de 8 bits k |
| 1 | 0 | 1 | k | k | k | k | k | k | k | k | k | GOTO k | | | Pula para o endereço de 9 bits k |
| 1 | 1 | op | op | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) |
| 1 | 1 | 0 | 0 | k | k | k | k | k | k | k | k | MOVLW k | | | W ← k |
| 1 | 1 | 0 | 1 | k | k | k | k | k | k | k | k | IORLW k | | Z | W ← k | W, OU lógico (OR) bit a bit |
| 1 | 1 | 1 | 0 | k | k | k | k | k | k | k | k | ANDLW k | | Z | W ← k & W, E lógico (AND) bit a bit |
| 1 | 1 | 1 | 1 | k | k | k | k | k | k | k | k | XORLW k | | Z | W ← k ^ W, OU exclusivo (XOR) bit a bit |
| 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Mnemônico | C? | Z? | Descrição |

### Dispositivos intermediários (14 bits)

Estes dispositivos apresentam uma memória de 14 bits e um pilha de chamada com 8 níveis. O conjunto de instruções difere muito pouco a partir dos dispositivos da linha de base, mas os 2 bits adicionais permitem opcode com 128 registradores e 2048 palavras de código para ser diretamente endereçados. Existem algumas instruções diversas adicionais, e duas instruções adicionais literais de 8 bits, somar e subtrair. O núcleo intermediário está disponível na maior parte dos dispositivos PIC12 e PIC16.
Os primeiros 32 bytes do espaço de registradores são alocados aos registradores de uso especial; os 96 bytes restantes são usados para RAM de propósito geral. Se RAM comutada é utilizada, os 16 registros (0x70-0x7F) são globais, assim como alguns dos mais importantes registradores para fins especiais, incluindo o registrador STATUS que detém os bits de seleção de banco de memória RAM.
As fontes de registrador PCLATH de alta ordem bits de endereço de instrução, quando os 8 bits fornecidos por uma gravação para o registrador PCL, ou os 11 bits fornecidos por uma instrução GOTO ou CALL, não é suficiente para resolver o espaço de ROM disponível.
Conjunto de instruções do PIC 14 bits :
| 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Mnemônico | C? | Z? | Descrição |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | opcode | opcode | opcode | opcode | opcode | opcode | opcode | Instruções diversas | Instruções diversas | Instruções diversas | Instruções diversas |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NOP | | | Nenhuma operação (MOVW 0,W) |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | RETURN | | | Retorna de uma subrotina, W não é modificado |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | RETFIE | | | Retorna de uma interrução |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | OPTION | | | Copia W para o registrador OPTION (obsoleta) |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | SLEEP | | | Entra em modo de economia de energia |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | CLRWDT | | | Reinicia o watchdog timer |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | f | f | TRIS f | | | Copia W para um registrador de triplo estado (f = 1, 2 or 3) (obsoleta) |
| 0 | 0 | opcode | opcode | opcode | opcode | d | registrador | registrador | registrador | registrador | registrador | registrador | registrador | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) | Operações na ULA: dest ← OP(f,W) |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | f | f | f | f | f | f | f | MOVWF f | | | f ← W |
| 0 | 0 | 0 | 0 | 0 | 1 | d | f | f | f | f | f | f | f | CLR f,d | | Z | dest ← 0, normalmente escrito como CLRW or CLRF f |
| 0 | 0 | 0 | 0 | 1 | 0 | d | f | f | f | f | f | f | f | SUBWF f,d | C | Z | dest ← f−W (dest ← f+~W+1) |
| 0 | 0 | 0 | 0 | 1 | 1 | d | f | f | f | f | f | f | f | DECF f,d | | Z | dest ← f−1 |
| 0 | 0 | 0 | 1 | 0 | 0 | d | f | f | f | f | f | f | f | IORWF f,d | | Z | dest ← f | W, ou inclusivo (OR) lógico |
| 0 | 0 | 0 | 1 | 0 | 1 | d | f | f | f | f | f | f | f | ANDWF f,d | | Z | dest ← f & W, e lógico (AND) |
| 0 | 0 | 0 | 1 | 1 | 0 | d | f | f | f | f | f | f | f | XORWF f,d | | Z | dest ← f ^ W, ou exclusivo (XOR) |
| 0 | 0 | 0 | 1 | 1 | 1 | d | f | f | f | f | f | f | f | ADDWF f,d | C | Z | dest ← f+W |
| 0 | 0 | 1 | 0 | 0 | 0 | d | f | f | f | f | f | f | f | MOVF f,d | | Z | dest ← f |
| 0 | 0 | 1 | 0 | 0 | 1 | d | f | f | f | f | f | f | f | COMF f,d | | Z | dest ← ~f, complemento bit a bit |
| 0 | 0 | 1 | 0 | 1 | 0 | d | f | f | f | f | f | f | f | INCF f,d | | Z | dest ← f+1 |
| 0 | 0 | 1 | 0 | 1 | 1 | d | f | f | f | f | f | f | f | DECFSZ f,d | | | dest ← f−1, então desvia se zero |
| 0 | 0 | 1 | 1 | 0 | 0 | d | f | f | f | f | f | f | f | RRF f,d | C | | dest ← CARRY<<7 &#124; f>>1, rotaciona à direita através do carry |
| 0 | 0 | 1 | 1 | 0 | 1 | d | f | f | f | f | f | f | f | RLF f,d | C | | dest ← f<<1 | CARRY, rotaciona à esquerda através do carry |
| 0 | 0 | 1 | 1 | 1 | 0 | d | f | f | f | f | f | f | f | SWAPF f,d | | | dest ← f<<4 | f>>4, swap nibbles |
| 0 | 0 | 1 | 1 | 1 | 1 | d | f | f | f | f | f | f | f | INCFSZ f,d | | | dest ← f+1, então desvia se zero |
| 0 | 1 | op | op | bit | bit | bit | registrador | registrador | registrador | registrador | registrador | registrador | registrador | Operações em bits | Operações em bits | Operações em bits | Operações em bits |
| 0 | 1 | 0 | 0 | bit | bit | bit | f | f | f | f | f | f | f | BCF f,b | | | Limpa bit b de f |
| 0 | 1 | 0 | 1 | bit | bit | bit | f | f | f | f | f | f | f | BSF f,b | | | Define bit b de f |
| 0 | 1 | 1 | 0 | bit | bit | bit | f | f | f | f | f | f | f | BTFSC f,b | | | Pula se bit b de f está limpo |
| 0 | 1 | 1 | 1 | bit | bit | bit | f | f | f | f | f | f | f | BTFSS f,b | | | Pula se bit b de f está definido |
| 1 | 0 | op | k | k | k | k | k | k | k | k | k | k | k | Transferências de controle | Transferências de controle | Transferências de controle | Transferências de controle |
| 1 | 0 | 0 | k | k | k | k | k | k | k | k | k | k | k | CALL k | | | Chama subrotina |
| 1 | 0 | 1 | k | k | k | k | k | k | k | k | k | k | k | GOTO k | | | Pula para o endereço k |
| 1 | 1 | opcode | opcode | opcode | opcode | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | 8-bit immediate | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) | Operações com W e 8 bit literal: W ← OP(k,W) |
| 1 | 1 | 0 | 0 | x | x | k | k | k | k | k | k | k | k | MOVLW k | | | W ← k |
| 1 | 1 | 0 | 1 | x | x | k | k | k | k | k | k | k | k | RETLW k | | | W ← k, então retorna de uma subrotina |
| 1 | 1 | 1 | 0 | 0 | 0 | k | k | k | k | k | k | k | k | IORLW k | | Z | W ← k | W, ou lógico (OR) bit a bit |
| 1 | 1 | 1 | 0 | 0 | 1 | k | k | k | k | k | k | k | k | ANDLW k | | Z | W ← k & W, e lógico (AND) bit a bit |
| 1 | 1 | 1 | 0 | 1 | 0 | k | k | k | k | k | k | k | k | XORLW k | | Z | W ← k ^ W, ou exclusivo (XOR) bit a bit |
| 1 | 1 | 1 | 0 | 1 | 1 | k | k | k | k | k | k | k | k | (reservado) | (reservado) | (reservado) | (reservado) |
| 1 | 1 | 1 | 1 | 0 | x | k | k | k | k | k | k | k | k | SUBLW k | C | Z | W ← k−W (dest ← k+~W+1) |
| 1 | 1 | 1 | 1 | 1 | x | k | k | k | k | k | k | k | k | ADDLW k | C | Z | W ← k+W |
| 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Mnemônico | C? | Z? | Descrição |

### Microcontroladores PIC32 de 32 bits

Em novembro de 2007, a Microchip apresentou a nova família de microcontroladores PIC32MX de 32 bits. A linha inicial do dispositivo é baseada no padrão da indústria MIPS32 M4K Core. O dispositivo pode ser programado usando o "Microchip MPLAB C Compiler for PIC32 MCUs", uma variante do compilador GCC. Os primeiros 18 modelos atualmente em produção (PIC32MX3xx e PIC32MX4xx) são pino a pino compatível e compartilham os mesmos periféricos estabelecidos com a família de dispositivos PIC24FxxGA0xx (16 bits), permitindo o uso de bibliotecas comuns, software e ferramentas de hardware. Hoje está disponível em 28 pinos em pacotes QFN pequenos até dispositivos de alto desempenho com Ethernet, CAN e USB OTG.
A arquitetura PIC32 traz uma série de novos recursos para portfólio da Microchip, incluindo:
* A maior velocidade de execução: 80 MIPS (mais de 120 MIPS @ 80 MHz com o benchmark Dhrystone)
* A maior memória flash: 512 KB
* Execução de uma instrução por ciclo de clock
* O primeiro processador com cache
* Permite a execução a partir RAM
O próximo produto da Microchip será a família de microcontroladores PIC32MZ.

## Programação e desenvolvimento

Como qualquer arquitetura os processadores PIC apenas aceitam linguagem de máquina (assembly). No entanto a programação pode ser feita em linguagens de alto nível utilizando-se compiladores. Existem várias alternativas pagas de compiladores. Em geral é possivel utilizá-los de modo gratuito com algumas restrições. Para as famílias PIC16 e PIC18 existe uma alternativa opensource o SDCC, que pode ser configurado para operar com o MPLAB.
Existem ainda diversas IDE's disponíveis para a programação, entre elas a mais utilizada é o MPLab, disponibilizado de modo gratuito pela própria Microchip. Há atualmente uma versão beta de IDE baseada no Netbeans sendo desenvolvida pela Microchip: MPLABX. Esta IDE já vem com suporte para qualquer Windows, Mac e Linux.
Para gravar o programa no microcontrolador é utilizado um dispositivo dedicado. É comum que tais dispositivos também possuam capacidade de depurar o programa, o que auxilia muito na fase de testes dos sistemas. É possivel ainda encontrar diversas placas de desenvolvimento que já possuem um hardware pré-montado de modo a agilizar o projeto de um produto, permitindo que se comece a desenvolver o software em paralelo com o hardware.

## Periféricos internos

Seus principais periféricos internos (a disponibilidade varia conforme o modelo):
* USARTs
* Controladores de comunicação I2C, SPI, USB e Paralelo
* Controladores PWM
* Controladores de LCD
* Controladores de motores
* Gerador de energia de alta potência
* Periféricos para LIN, CAN
* Controladores Ethernet
* Periféricos IRDA
* Codificadores para criptografia Keeloq
* Watchdog timer
* Detetores de falha na alimentação
* Portas digitais com capacidade de 25mA (fornecer ou drenar) para acionar circuitos externos
* Osciladores internos
* RTCC - Real Time Clock and Calendar (Relógio de tempo real e calendário)
* Tecnologia Deep Sleep - consumo de nano Watt
* CRC - Cyclic Redundancy Check programável

## Modelos comuns de PICs

* PIC16F84/PIC16F84A
* PIC16F628/PIC16F628A
* PIC16F877/PIC16F877A
* PIC18F452/PIC18F4520
* PIC16F876
* PIC24F/PIC24H