Mensagem

"Sonhar mais um sonho impossível, lutar quando é fácil ceder, vencer o inimigo invencível, negar quando a regra é vender."
Miguel de Cervantes.

"Os microprocessadores RISC funcionam a partir do princípio genial de se encarregar das coisas mais fáceis e deixar todas as partes difíceis para outras pessoas resolverem."
Douglas Adams.

Mostrando postagens com marcador One Wire UART. Mostrar todas as postagens
Mostrando postagens com marcador One Wire UART. Mostrar todas as postagens

Protocolo 1 Wire usando UART com o STM32

   O protocolo 1 wire é muito interessante para uso de somente um pino de I/O de um microcontrolado. Protocolo simples e baseado em janelas de tempo entre os sinais. Todavia, o uso de atrasos para escrita e leitura do pino pode resultar em perda de desempenho e complicar a vida do programador. Isso ocorrerá se a temporização for feita através da execução de laços vazios.
   Visando superar essas complicações e otimizar a programação e desempenho do microcontrolador, a Maxim (compradora da Dallas Semiconductor Corp. , que criou o protocolo), apresenta uma nota de aplicação para realizar a comunicação 1 wire empregando o protocolo serial simples (UART). 

   O detalhe está em trocar a taxa de transmissão entre 9600 e 115200 bps. No Reset usa-se 9600 e envia-se o dado 0xF0. Para escrita e leitura, 115200 bps. Na escrita de 1 lógico envia-se 0xFF, de 0, 0x00. Na leitura se envia 0xFF para cada bit a ser lido, retorno 0xFF significa bit 1. O uso da UART é, portanto, simples e prático.
   A comunicação deve ser configurada para 8 bits de dados, um bit de parada, sem bit de paridade.

   A seguir código exemplo para o DS80B20 (sensor de temperatura), empregado para um Corte-M0+ da STM, baseado na camada de abstração de hardware (HAL). Os detalhes foram suprimidos, pois a ideia é apresentar o algoritmo básico.


//--------------------------------------------------------------------------
// 1 WIRE functions - UART 2
//--------------------------------------------------------------------------
// 1 WIRE functions - UART 2
void reset_1w()
{
unsigned char  buff[2];
buff[0]=0xF0;

huart2.Init.BaudRate = 9600; // para o reset a taxa deve ser 9600
HAL_UART_Init(&huart2);

HAL_UART_Transmit(&huart2, buff, 1, HAL_MAX_DELAY);

huart2.Init.BaudRate = 115200; // 115200 para rescrita e leitura
HAL_UART_Init(&huart2);
}
//--------------------------------------------------------------------------
void write_byte_1w(unsigned char data)
{
uint32_t i;

for(i=0; i<8; i++)
{
if(tst_bit(data,i))
USART2->TDR = 0xFF; // logico 1 envia FF
else
USART2->TDR = 0x00; // logico 0 envia 00

HAL_UART_Receive(&huart2, (uint8_t *)aRxBuffer, 1,0xFFFF);
}
}
//---------------------------------------------------------------------------
unsigned char read_byte_1w()
{
unsigned int i;
unsigned char dado = 0; // todos os bits são zero por default

for (i=0;i<8;i++)
{
   USART2->TDR = 0xFF; // para ler um bit envia FF

   HAL_UART_Receive(&huart2, (uint8_t *)aRxBuffer, 1,0xFFFF);

   if(aRxBuffer[0] == 0xFF) //se for igual a FF o bit é um, zero se contrário
      set_bit(dado,i);

}
return (dado);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------


//DS18B20 - uma conversão

reset_1w(); //reset do sensor (a resposta de presença é retornada mas não avaliada).
write_byte_1w(0xCC); //comando para pular ROM (só 1 dispositivo no barramento).
write_byte_1w(0x44); //manda iniciar a conversão
HAL_Delay(750);
reset_1w();
write_byte_1w(0xCC);
write_byte_1w(0xBE); //avisa que quer ler a memória

temp_LSB = read_byte_1w();//só interesse em ler os dois bytes da temperatura
temp_MSB = read_byte_1w();


temp_16bits = (temp_MSB<<8) | (temp_LSB);

if (temp_MSB > 7)
{
  temp_16bits = 0xFFFF - temp_16bits + 1; 
  sinal = '-';
}
else
  sinal = '+';

  temperatura = (5*temp_16bits)/8;