O que é pouco batendo

26

Eu sou novo na programação de microcontroladores. Estou usando o controlador ATmega32-A e o compilador CodeVisionAVR. Estou usando o gerador de forma de onda (AD9833) para gerar um sinal de onda senoidal usando a comunicação SPI. Eu sou capaz de gerar a onda senoidal com sucesso. Agora estou passando esse sinal para o sensor. A saída do sensor é selecionada através do multiplexador e enviada ao ADC. Agora eu quero ler os valores ADC usando a comunicação SPI. Eu tentei muito configurar os registros do ADC. Ainda não está funcionando. Para ver o código de comunicação SPI, dê uma olhada no meu post anterior O ADC registra a configuração usando a comunicação spi . Estou usando a comunicação USART (RS232) para imprimir valores no PC (PuTTY).

Alguém me aconselhou a usar bit-bang. Eu sou novo nesse conceito. Qualquer um pode me fornecer um exemplo de código de troca de bits da comunicação SPI. Como iniciar esse procedimento? Qualquer um pode me fornecer um bom material. Preciso de algum hardware externo?

Eu escrevi isso, incluindo conexões de pinos:

#define ADC_CS PORTB.3
#define MOSI PORTB.5
#define MISO PINB.6
#define SCK PORTB.7

void send_8bit_serial_data(unsigned char data)
{
    int i;  
    ADC_CS=0;
    for (i = 0; i < 8; i++)
    {
        // consider leftmost bit
        // set line high if bit is 1, low if bit is 0
        if (data & 0x80)
            output_high(PORTB.5);
        else
            output_low(PORTB.5);

        // pulse clock to indicate that bit value should be read
        output_low(PORTB.7);
        output_high(PORTB.7);

        // shift byte left so next bit will be leftmost
        data <<= 1;
    }

    // deselect device
    ADC_CS=1;
}
verendra
fonte
Seu código parece bom, exceto pela saída do relógio, que deve estar baixa antes da configuração e atraso do bit. Você precisa de alguns atrasos para fixar o tempo (para que o relógio seja mais ou menos o mesmo período). Verifique o código de Steven novamente. Se você quiser ler também, precisará adicionar o código para isso também.
Oli Glaser
@ OliGlaser Posso usar diretamente esse código em vez do código SPI normal para configurar os registros.
Verendra #
@verendra - não sei o que você quer dizer com "código SPI normal". Se você quer dizer, em vez de SPI de hardware, o ADC não se importa como os pulsos são gerados, desde que concordem com o protocolo e o tempo.
Oli Glaser

Respostas:

25

A batida de bit está criando toda a série de pulsos no software, em vez de depender de um pedaço de hardware dentro do microcontrolador.

Muitos microcontroladores têm uma SPI de hardware, e tudo o que você precisa fazer é gravar um byte no registro de saída, e o controlador SPI retirará os dados e, ao mesmo tempo, receberá os dados do escravo. Você pode interromper quando a transferência estiver concluída e ler os dados recebidos.

Mas alguns microcontroladores não possuem o hardware SPI integrado e, em seguida, você deve simulá-lo fazendo tudo manualmente. O SPI possui vários modos diferentes, usarei este diagrama de pulso como exemplo:

insira a descrição da imagem aqui

Portanto, enquanto um controlador SPI dedicado cuida de todos os pulsos, mudança de dados e tempo, ao fazer um bit-bang, você deve executar todas as ações:

Make Slave Select low  
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low 
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data  
  Add brief delay  
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0   
  Add brief delay  
  Shift the data byte 1 bit left
Make Slave Select high again  

O SPI de interrupção de bits é relativamente simples, o código para I2C de interrupção de bits, por exemplo, será mais complexo e você precisará de um temporizador de alguma forma, se desejar interromper o protocolo UART.

stevenvh
fonte
2
Você pode fornecer um código c de amostra.
verendra
11
@verendra - eu adicionei um exemplo pseudocódigo, que você deve ser capaz de traduzir facilmente em C.
stevenvh
Estou gerando Wavefrom com êxito usando a comunicação SPI. Tenho problemas com a leitura de valores ADC usando apenas SPI. Eu tenho que usar pouco para ambos ou apenas para ler valores ADC. Você pode dar uma olhada no meu código para enviar 8 bits, é escrever. mas estou confuso como usá-lo. Posso colocar esse código diretamente em vez do meu código SPI para configurar o registro.
verendra
@ Steven - o diagrama que você mostra é o MSB primeiro, então você precisa sair da esquerda de 7 e da esquerda de 0. Eu sei que não há um padrão para que possa ser o LSB primeiro, mas acho que a maioria dos periféricos SPI o faz dessa maneira .
Oli Glaser
2
@ Oli - bom ponto, eu perdi isso. Vou consertar, obrigado pelo feedback. A razão pela qual não existe um padrão é que isso não importa, desde que o número de bits transferidos seja igual ao comprimento do registro de deslocamento. Recentemente, alguns microcontroladores (como o NXP Cortec-M3) possuem um registro de deslocamento de comprimento variável, e a direção pode ser importante. IIRC no AVR, você pode selecionar MSB primeiro ou LSB primeiro.
Stevenvh 15/10/12
6

A batida de bits refere-se ao conceito de gerar / amostrar os sinais que saem ou entram em um dispositivo por software em vez de por hardware. Obviamente, é necessário algum hardware, mas, ao usar a troca de bits, o único hardware para cada saída é uma trava que pode ser explicitamente configurada ou limpa por software, e o único hardware para cada entrada é uma interface para permitir que o software teste se é alto ou baixo (e normalmente executa uma ramificação condicional para um estado, mas não para o outro).

A velocidade máxima que pode ser alcançada com o bit-banging geralmente será uma fração do que poderia ser alcançado com o hardware criado especificamente, mas fora das limitações impostas pela velocidade do processador, o bit-banging é muito mais versátil e pode ser usado em circunstâncias onde o hardware de uso geral não é bastante adequado e o hardware de uso especial não seria econômico.

Por exemplo, muitos controladores possuem uma porta "estilo SPI", que se comporta essencialmente da seguinte maneira: quando um byte é gravado em um determinado registro, o hardware gera um número de pulsos de clock (normalmente oito), atingindo o tempo limite de um bit de dados no ponta de cada pulso de clock e amostragem de um bit de dados recebido na borda de fuga. Geralmente, as portas no estilo SPI dos controladores permitem que vários recursos sejam configurados, mas, em alguns casos, pode ser necessário fazer a interface de um processador com um dispositivo que faz algo incomum. Um dispositivo pode exigir que os bits de dados sejam processados ​​em múltiplos diferentes de oito, ou pode exigir que os dados sejam de saída e amostrados na mesma borda do relógio, ou pode ter algum outro requisito incomum. Se o hardware específico no controlador que você está usando pode suportar os requisitos precisos, ótimo (alguns fornecem números configuráveis ​​de bits, tempo de transmissão e recepção configurável separadamente, etc.) Caso contrário, a troca de bits pode ser útil. Dependendo do controlador, a troca de bits de uma interface SPI-ish geralmente leva de 2 a 10 vezes o tempo que o hardware permitir, mas se os requisitos não se encaixarem no hardware existente, a troca de dados mais lentamente pode ser melhor do que não ser capaz de fazê-lo.

Uma coisa importante a ser observada nos projetos com interrupção de bits é que eles são mais simples e robustos em circunstâncias em que os dispositivos com os quais estão sendo comunicados aguardam que o controlador de interrupção de bits gere todo o tempo, ou onde o controlador poderá aguarde, sem distração, a chegada de um evento e onde ele poderá fazer tudo o que precisa fazer com esse evento antes de chegar outro evento em que ele precise agir. Eles são muito menos robustos em circunstâncias em que um dispositivo precisará ser capaz de reagir a estímulos externos dentro de um período de tempo relativamente curto, mas não pode usar 100% de sua energia para observar esses estímulos.

Por exemplo, suponha que se deseje que um processador transmita dados no estilo UART em série a uma taxa muito alta em relação à sua velocidade de clock (por exemplo, um PIC que esteja executando 8.192 instruções por segundo deseja gerar dados a 1200 bps). Se nenhuma interrupção estiver ativada, essa transmissão não será difícil (relógio um bit a cada sete ciclos de instruções). Se um PIC não estivesse fazendo nada além de aguardar um byte de dados de 1200bps de entrada, ele poderia executar um loop de 3 ciclos aguardando o bit de início e depois prosseguir com o registro dos dados em intervalos de sete ciclos. De fato, se um PIC tivesse um byte de dados pronto para enviar quando um byte de dados recebido chegasse, sete ciclos por bit seriam tempo suficiente para o PIC enviar seu byte de dados simultaneamente com a leitura do byte recebido. Da mesma forma,se tal resposta tivesse um tempo fixo em relação à transmissão original . Por outro lado, não haveria maneira de os PICs acelerarem o tratamento das comunicações bit-bang de tal forma que um ou outro dispositivo pudesse transmitir a qualquer momento que entendesse (em vez de ter um dispositivo que pudesse transmitir quando visse encaixar e fazer o que quiser quando não estiver transmitindo, e um dispositivo que teria que passar a maior parte do tempo sem fazer nada além de aguardar transmissões do primeiro dispositivo).

supercat
fonte