- O que é o Bit Banging?
- Quando usar o Bit Banging
- Algoritmo para comunicação serial via bit banging
- Batida de bits sobre SPI
- Exemplo de Bit Banging: comunicação SPI no Arduino
- Desvantagens do Bit Banging
- UART via Bit banging no Arduino
As interfaces de comunicação são um dos fatores que são considerados ao selecionar um microcontrolador a ser usado para um projeto. O projetista garante que o microcontrolador selecionado tenha todas as interfaces necessárias para se comunicar com todos os outros componentes a serem usados para o produto. A existência de algumas dessas interfaces, como SPI e I2C no microcontrolador, invariavelmente aumenta o custo desses microcontroladores e, dependendo do orçamento do BOM, pode tornar o microcontrolador desejado não acessível. Em situações como essas, técnicas como o Bit Banging entram em cena.
O que é o Bit Banging?
O bit banging é uma técnica de comunicação serial em que todo o processo de comunicação é feito por software em vez de hardware dedicado. Para transmitir dados, a técnica envolve o uso de software para codificar os dados em sinais e pulsos que são usados para manipular o estado de um pino I / O de um microcontrolador que serve como pino Tx para enviar dados para o dispositivo alvo. Para receber dados, a técnica envolve amostrar o estado do pino Rx após certos intervalos que são determinados pela taxa de transmissão de comunicação. O software define todos os parâmetros necessários para alcançar esta comunicação, incluindo sincronização, temporização, níveis, etc., que geralmente são decididos por hardware dedicado quando o bit banging não é usado.
Quando usar o Bit Banging
O bit-banging é geralmente usado em situações em que um microcontrolador com a interface necessária não está disponível ou quando mudar para um microcontrolador com a interface necessária pode ser muito caro. Assim, é uma maneira barata de permitir que o mesmo dispositivo se comunique usando vários protocolos. Um microcontrolador previamente habilitado apenas para comunicação UART pode ser equipado para se comunicar usando SPI e 12C via bit banging.
Algoritmo para comunicação serial via bit banging
Embora o código para implementar o bit banging possa ser diferente em diversos microcontroladores e também pode variar para diferentes protocolos seriais, o procedimento / algoritmo para implementar o bit banging é o mesmo em todas as plataformas.
Para enviar dados, por exemplo, o pseudo-código abaixo é usado;
- Começar
- Enviar bit inicial
- Espere que o tempo corresponda à taxa de transmissão do receptor
- Enviar bit de dados
- Aguarde até que a duração corresponda à taxa de transmissão do receptor novamente
- Verifique se todos os bits de dados foram enviados. Se não, vá para 4. Se sim, vá para 7
- Enviar bit de parada
- Pare
O recebimento de dados tende a ser um pouco mais complexo, geralmente uma interrupção é usada para determinar quando os dados estão disponíveis no pino do receptor. Isso ajuda a garantir que o microcontrolador não desperdice muito poder de processamento. Embora certas implementações usem qualquer um dos pinos de E / S dos microcontroladores, as chances de ruído e erros, se provavelmente não forem tratados, são maiores. O algoritmo para receber dados usando interrupções é explicado a seguir.
- Começar
- Ativar interrupção no pino Rx
- Quando a interrupção é acionada, obtenha o bit de início
- Aguarde o tempo de acordo com a taxa de transmissão
- Leia o pin Rx
- Repita de 4 até que todos os dados tenham sido recebidos
- Aguarde o tempo de acordo com a taxa de transmissão
- Verifique se há stop bit
- Pare
Batida de bits sobre SPI
Como mencionado acima, o bit banging para diferentes protocolos funciona de maneira diferente e, portanto, é importante ler sobre cada protocolo, para entender o enquadramento de dados e o clocking antes de tentar implementar. Tomando o modo SPI 1 como exemplo, o valor base do relógio é sempre 0 e os dados são sempre enviados ou recebidos na transição ascendente do relógio. O diagrama de tempo para o protocolo de comunicação do Modo 1 SPI é mostrado abaixo.
Para implementar isso, o seguinte algoritmo pode ser usado;
- Começar
- Defina o pino SS baixo para iniciar a comunicação
- Defina o pino para Master Out Slave In (MOSI) para o primeiro bit dos dados a serem enviados
- Defina o pino do relógio (SCK) alto para que os dados sejam transmitidos pelo mestre e recebidos pelo escravo
- Leia o estado do Master in Slave Out (MISO) para receber o primeiro bit de dados do escravo
- Defina SCK baixo para que os dados possam ser enviados na próxima borda ascendente
- Vá para 2 até que todos os bits de dados tenham sido transmitidos.
- Defina o pino SS alto para interromper a transmissão.
- Pare
Exemplo de Bit Banging: comunicação SPI no Arduino
Como exemplo, vamos implementar o algoritmo para comunicação SPI via bit banging no Arduino para mostrar como os dados podem ser bit- banging no SPI usando o código abaixo.
Começamos declarando os pinos do Arduino a serem usados.
const int SSPin = 11; const int SCKPin = 10; const int MISOPin = 9; const int MOSIPin = 8; byte sendData = 64; // Valor a ser enviado byte slaveData = 0; // para armazenar o valor enviado pelo escravo
Em seguida, passamos para a função void setup () onde o estado dos pinos é declarado. Somente o pino de saída Master in Slave (MISO) é declarado como uma entrada, pois é o único pino que recebe dados. Todos os outros pinos são declarados como saída. Depois de declarar os modos de pino, o pino SS é definido como HIGH. A razão para isso é garantir que o processo esteja livre de erros e a comunicação só comece quando estiver definida como baixa.
void setup () { pinMode (MISOPin, INPUT); pinMode (SSPin, OUTPUT); pinMode (SCKPin, OUTPUT); pinMode (MOSIPin, OUTPUT); digitalWrite (SSPin, HIGH); }
Em seguida, iniciamos o loop para enviar dados. Observe que esse loop continuará enviando os dados repetidamente.
Começamos o loop escrevendo o pino SS baixo, para iniciar o início da comunicação, e chamamos a função bitbangdata que divide os dados predefinidos em bits e envia. Feito isso, escrevemos o pino SS HIGH para indicar o fim da transmissão de dados.
loop vazio () { digitalWrite (SSPin, LOW); // SS baixo slaveData = bitBangData (sendData); // transmissão de dados digitalWrite (SSPin, HIGH); // SS alto novamente }
A função bitbangdata () é escrita abaixo. A função recebe os dados a serem enviados e os divide em bits e os envia fazendo um loop sobre o código para a transmissão, conforme indicado na etapa 7 do algoritmo.
byte bitBangData (byte _send) // Esta função transmite os dados via bitbanging { byte _receive = 0; for (int i = 0; i <8; i ++) // 8 bits em um byte { digitalWrite (MOSIPin, bitRead (_send, i)); // Definir MOSI digitalWrite (SCKPin, HIGH); // SCK bitWrite alto (_receive, i, digitalRead (MISOPin)); // Captura MISO digitalWrite (SCKPin, LOW); // SCK baixo } return _receive; // Retorna os dados recebidos }
Desvantagens do Bit Banging
Adotar o bit banging deve, entretanto, ser uma decisão bem pensada, pois existem várias desvantagens no bit banging que podem torná-lo não confiável para implementação em certas soluções. O bit banging aumenta a potência consumida pelo microcontrolador devido à alta potência de processamento consumida pelo processo. Comparado ao hardware dedicado, mais erros de comunicação, como falhas e jitters, ocorrem quando o bit banging é usado, especialmente quando a comunicação de dados está sendo realizada pelo microcontrolador ao mesmo tempo que outras tarefas. A comunicação via bit banging ocorre em uma fração da velocidade com a qual ocorre quando o hardware dedicado é usado. Isso pode ser importante em certas aplicações e pode fazer do bit banging uma escolha “não tão boa”.
O bit banging é usado para todos os tipos de comunicação serial, incluindo; RS-232, comunicação serial assíncrona, UART, SPI e I2C.
UART via Bit banging no Arduino
Uma das implementações populares de bit banging é a biblioteca Arduino Software Serial, que permite que o Arduino se comunique por UART sem usar os pinos UART de hardware dedicados (D0 e D1). Isso oferece muita flexibilidade, pois os usuários podem conectar tantos dispositivos seriais quanto o número de pinos na placa Arduino pode suportar.