Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

STM32VLDiscovery - One wire temerature sensor - UART

Status
Not open for further replies.

Hittive

New Member
Hi, I want connect a one wire temperature sensor with UART. My problem is a two registers of measurement is always equal 255 ( temp_LSB and temp_MSB).
And I have problem that
Code:
int USART2_Read()
{    
    //  while ((USART2->SR & USART_SR_RXNE) == 0);
      return USART2->DR & 0x1FF;
}
while ((USART2->SR & USART_SR_RXNE) == 0); must be comment because program can't exit the loop.

Impulse RESET work, because I can read PRESENCE impuls.

Configuration:
Code:
    //usart2
    GPIOA->CRL |= GPIO_CRL_CNF3_0;
    GPIOA->CRL |= GPIO_CRL_MODE2_1;
    GPIOA->CRL |= GPIO_CRL_CNF2_1 ;
    RCC->APB1ENR|=  RCC_APB1ENR_USART2EN;
    USART2->CR1 |= USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
    USART2->CR3|=USART_CR3_HDSEL;
    USART2->BRR = (SystemCoreClock /9600);
    NVIC_EnableIRQ(USART2_IRQn);

Main program:
Code:
const TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
    const TickType_t xDelay2 = 800 / portTICK_PERIOD_MS;
     int temp_LSB = 0;
    int temp_MSB = 0;
    int temp_celsius = 0;
    char temp[8];
    while(1)
        {
              vTaskDelay(xDelay);
              if(one_wire_reset())
            {
                USART2->BRR = (SystemCoreClock /115200);
                one_wire_write_byte(0xCC);
                one_wire_write_byte(0x44);
                vTaskDelay(xDelay2);
                one_wire_reset();
                USART2->BRR = (SystemCoreClock /115200);
                one_wire_write_byte(0xCC);
                one_wire_write_byte(0xBE);
                temp_LSB = one_wire_read_byte();
                temp_MSB = one_wire_read_byte();
                one_wire_reset();
                USART2->BRR = (SystemCoreClock /115200);
                USART1_PutString("     ");
                USART1_PutString(itoa(temp_LSB,temp,10));
                USART1_PutString(itoa(temp_MSB,temp,10));
                USART1_PutString("     ");
                temp_celsius = ((temp_MSB * 256) + temp_LSB) / 16.0;
                USART1_PutString(itoa(temp_celsius,temp,10));
            }

        }


and functions:
Code:
int one_wire_read_byte()
{

int byte = 0;
int i=0,bit=0;

for (i = 0; i < 8; i++)
{
USART2_PutChar(0xFF);
bit =  USART2_Read()==0xFF ? 1 : 0;
byte = (byte >> 1) + 0x80 * bit;
}

return byte;
}

void one_wire_write_byte(int byte)
{
    int i=0;int bit;
    for (i = 0; i < 8; i++, byte = byte >> 1)
    {
        bit=byte & 0x01;
        bit = bit ? 0xFF : 0x00;
        USART2_PutChar(bit);
    }
}


int one_wire_reset()
{
        USART2->BRR = (SystemCoreClock /9600);
        while(!(USART2-> SR & USART_SR_TXE));
        USART2->DR =0xF0;
        if (USART2_Read()==0xF0) return 0; else return 1;
        return 1;
}
/********************************************
*
*/

void USART1_PutChar(uint8_t ch)
{
    while(!(USART1-> SR & USART_SR_TXE));
    USART1->DR =ch;
}
void USART2_PutChar(uint8_t ch)
{
    while(!(USART2-> SR & USART_SR_TXE));
    USART2->DR =ch;
}
void USART1_Read()
{
      while ((USART1->SR & USART_SR_RXNE) == 0);
      UART_Read=USART1->DR & 0x1FF;
}
int USART2_Read()
{    
    //  while ((USART2->SR & USART_SR_RXNE) == 0);
      return USART2->DR & 0x1FF;
}
void USART1_PutString(uint8_t * str)
{
while(*str != 0)
  {
  USART1_PutChar(*str);
  str++;
}
}
void USART1_IRQHandler(void)
{
     USART1_Read();
}
void USART2_IRQHandler(void)
{
    USART2_Read();
}

I used this sites to learn about one wire:
https://electricimp.com/docs/resources/onewire/
https://www.maximintegrated.com/en/app-notes/index.mvp/id/214
 
Some comments on the code would help.

Apart from the presence pulse, every bit is initiated by the master. The master pulls the wire down and releases it, and the slave either lets the wire go straight back up or the slave extends the pulse. That should be seen by the USART as either a start bit followed by all bits high, or a start bit followed by several low bits. Therefore your you should be able to receive characters that read 0xFF from the USART even without a temperature sensor.

The line that you are commenting out seems to be the one that is waiting for data from the USART, so it seems that your receiver is not seeing the pulse that should have been sent by the transmitter.

As a general note, it is very difficult to fault-find on serial lines without an oscilloscope or logic analyser.
 
When i send a RESET pulse (0xF0) i receive OxE0. I don't have oscylloscope. I think i do this without uart.
 
When i send a RESET pulse (0xF0) i receive OxE0. I don't have oscylloscope. I think i do this without uart.
I think that all the communication is with a USART.

What Baud rate do you get 0xE0? Do you receive a different value if the 1-wire device is removed?

The reset pulse is a minimum of 480 μs, and after the end of the pulse, the 1-wire device waits 15 - 60 μs, and then pulls the wire low for 60 - 240 μs

The receiver will detect the wire going low if it is pulled down by the transmitter or by the 1-wire device, so this is what is happening when the reset pulse is sent.

1) The transmitter sends 0xF0 at 9600 baud. The start bit is 0, followed by four more zeros (the lsb of 0xF0), so the wire is pulled low for 5 bits periods
At 9600 baud that is 5/9600 = 520 μs.
2) The 1-wire device pulls the wire low.
3) The receiver sees the start bit as low, the four more zeros as low, and then the presence pulse from 1-wire device should make one or more of the last 4 bits low
4) The 1-wire device completes the presence pulse in less than 300 μs, so that the wire goes high before the stop bit, which has to be 1 for the receiver to work.

When 0xF0 is transmitted, the signal sent is a low pulse for 520 μs. You received 0xE0, which is a low pulse for about 625μs. If the receiver is working at 9600 baud, the pulse could be anywhere between 5.5 bit periods and 6.5 bit periods, so it could be 572 to 677 μs long. With a reset pulse of 520 μs, the presence pulse could end at any time between 595 and 820 μs, so the 0xE0 signal that you are getting looks right, but you must check that you receive 0xF0 when the 1-wire device is removed. It is possible that the wire is staying low because of capacitance and that is giving the oxEo signal.
 
Without 1 wire device, master received 0xF0. With 1 wire device - 0xE0. Now i did a program without uart and it work. But if you want help me with uart communication, you can :)
 
If you've got it working without the UART, I don't particular want to spend time helping.

One advantage of using the UART is that the processor can be doing other things while the communication is going on.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top