P: Os pinos individuais de diferentes portas de um microcontrolador podem ser mapeados para um registrador e seus valores alterados ao alterar o valor do registrador?
Cenário: usei alguns pinos de cada porta (8 bits) do microcontrolador. Agora, quero fazer interface com um dispositivo que precise de um barramento de 8 bits (suponha D0 a D7 EM SEQUÊNCIA), ou seja, preciso de 8 pinos do controlador para poder conectá-los de maneira individual.
portx0 -> D0 // x is the name of port followed by bit location on that port
portx1 -> D1
...
portx7 -> D7
mas eu não tenho uma porta inteira de 8 pinos que eu posso conectar com este dispositivo, mas tenho alguns pinos do portx, alguns do porty e outros do portz. O novo cenário de conexão é como (conexão do microcontrolador ao dispositivo, respectivamente)
portx0 -> D0
portx1 -> D1
portx2 -> D2
porty4 -> D3
porty5 -> D4
porty6 -> D5
porty7 -> D6
portz1 -> D7
Nesta condição, se eu quiser enviar um valor, diga
unsigned char dataReg = 0xFA;
para o meu dispositivo do controlador, tenho que executar operações pouco inteligentes no valor a ser enviado e definir cada pino de acordo com o valor no registro individualmente. Por exemplo
portx0 = ((dataReg & 0x01) >> 0 ); // Masking and shifting as bit position
portx1 = ((dataReg & 0x02) >> 1 );
portx2 = ((dataReg & 0x04) >> 2 );
porty4 = ((dataReg & 0x08) >> 3 );
porty5 = ((dataReg & 0x10) >> 4 );
porty6 = ((dataReg & 0x20) >> 5 );
porty7 = ((dataReg & 0x40) >> 6 );
portz1 = ((dataReg & 0x80) >> 7 );
Agora, chegando à questão principal, para evitar esses cálculos individuais em cada bit em portas diferentes, pinos individuais de portas diferentes de um microcontrolador podem ser mapeados para um registro e seus valores podem ser alterados ao alterar o valor do registro?
Respostas:
Parece que sua pergunta se resume a ter um valor de 8 bits no firmware e querer ler e escrever isso de e para uma coleção arbitrária de pinos de porta.
Não há uma maneira direta de hardware para fazer isso. Você precisa escrever duas rotinas, uma para ler o valor de 8 bits e outra para escrevê-lo. Outros mencionaram o uso de sindicatos, mas isso é uma péssima idéia. Com os sindicatos, você precisa lidar com todos os bits separadamente, e o código se torna dependente da ordem de bits do micro. Este pode ser o caminho a seguir de qualquer maneira, se todos os 8 bits estiverem espalhados de forma completamente independente. Nesse caso, há pouco que você pode fazer além de criar um código especial para cada bit.
A melhor maneira de fazer isso, especialmente se você pode agrupar os bits em alguns blocos contíguos nas portas físicas, é usar mascaramento, deslocamento e ORing. Por exemplo, se os três bits mais baixos do byte interno estiverem nos bits <6-4> de uma porta, mova à direita esse valor da porta em 4 e AND com 7 para colocar esses bits em sua posição final. Shift e mascarar (ou mascarar e shift) bits de outras portas no lugar e montar o byte final de 8 bits ORing os resultados nele.
Esse tipo de ajuste de bits de baixo nível é mais fácil de fazer no assembler que o C. Eu provavelmente colocaria as rotinas de leitura e gravação de bytes em um único módulo do assembler e tornaria a interface acessível pelo C.
fonte
Em geral, isso não é possível. Tanto quanto eu sei, não é possível com PICs.
Só sei que existe um microcontrolador que pode fazer isso, o Cypress PSoC . É um sistema altamente configurável no chip. Entre as muitas coisas que permite, você pode definir literalmente seu próprio registro (1-8 bits) e conectá-lo a qualquer pino que desejar, ou mesmo a circuitos internos.
Por exemplo, aqui eu criei um registro de controle de 6 bits. 5 dos bits vão direto para os pinos, enquanto o sexto bit que estou usando no XOR com a entrada de um 7º pino.
No chip, posso optar por alocar esses pinos a qualquer um dos pinos GPIO disponíveis. (São os cinza da imagem)
fonte
Você pode tentar o seguinte. Escreva uma estrutura própria que mapeie para os respectivos pinos das 2 portas (que devem ser usadas). Agora, a atualização do valor neste registro deve definir / redefinir os pinos dessas 2 portas. Apenas tente e deixe-nos saber se funcionou !!
Estou confiante de que isso deve funcionar.
fonte
Se entendi a pergunta corretamente, é fácil em C:
Declaração de tipo genérico, pode ser reutilizada para qualquer registro:
Então, para definir uma porta que queremos abordar:
E para ajustar diretamente um pino nessa porta:
Em código:
Registro completo:
Vale a pena ler sobre estruturas, uniões, typedefs e enums - tudo isso torna a vida muito mais agradável no incorporado e em geral!
fonte