cancel
Showing results for 
Search instead for 
Did you mean: 

1-Wire library for STM32 in C

raivo
Associate II
Posted on December 29, 2012 at 08:38

Could not find a ready solution for using 1-wire protocol with STM32 in C (working wiwth IAR), so I decided to rework the C++ library that came with arduino.

So, if anyone needs it - here it is a fully working solution (compiled wit IAR, tested on STM32F103VET6 processor running at 72 Mhz - Delay functions need to be modified for other frequencies). I have not yet add comments to functions in code, but it should not be hard to understand, as it is 1:1 ported from arduino library. Sample code:

OWire OneWire;
unsigned char DeviceAddress[8];
int nCount = 0;
OWInit(&OneWire, GPIOB, GPIO_Pin_14); 
while(OWSearch(&OneWire, DeviceAddress))
{
printf(''Device %d: %02X %02X %02X %02X %02X %02X %02X %02X \n\r'',
nCount+1,
DeviceAddress[7],DeviceAddress[6],
DeviceAddress[5],DeviceAddress[4],
DeviceAddress[3],DeviceAddress[2],
DeviceAddress[1],DeviceAddress[0]);
nCount++;
}
printf(''DeviceCount: %d'',nCount);

Output: 0690X00000602n4QAA.jpg May be someone finds the Delay library useful too. Working on DallasTemp library now - will post here when finished.. Any comments, suggestions are welcome... #1wire #delay #1-wire
14 REPLIES 14
Posted on February 03, 2017 at 14:26

Sorry for the 2nd solution - I have not noticed that you have all UARTs occupied.

gjepali
Associate
Posted on February 20, 2018 at 09:30

Hi, thanks for your OneWire library and sorry for my bad english. It's working, but not on F0. I tried it on F0 with 48 MHz, but input and output initialization takes too long (almost 20 us - F0 has only Thumb instruction list). So I tried to optimize the code slightly. I have found that there is no need to reconfigure pin to input or output. If the pin is set as output, it can be read at the same time. So when initializing OneWire_Init(..) I set the pin once as open-drain output and then set only its logic zero or high (high impedance) and then read its real state. And it works well. The delay is almost zero. You need only these functions:

void ONEWIRE_OUTPUT(OneWire_t *gp)

{

   GPIO_InitTypeDef gpinit;

   gpinit.GPIO_Mode = GPIO_OType_OD;

   gpinit.GPIO_PuPd = GPIO_PuPd_NOPULL;

   gpinit.GPIO_Speed = GPIO_Speed_Level_2;

   gpinit.GPIO_Pin = gp->GPIO_Pin;

   GPIO_Init(gp->GPIOx,&gpinit);

}

void ONEWIRE_LOW(OneWire_t *gp)

{

   gp->GPIOx->BSRR = gp->GPIO_Pin<<16;

}

void ONEWIRE_HIGH(OneWire_t *gp)

{

   gp->GPIOx->BSRR = gp->GPIO_Pin;

}

uint8_t ONEWIRE_READ(OneWire_t *gp)

{

   return GPIO_ReadInputDataBit(gp->GPIOx, gp->GPIO_Pin);

}

Further adjustment for F0 (original delay library is not working with Thumb instruction list):

#define ONEWIRE_DELAY(us) do {\

asm volatile ( 'MOV R0,%[loops]\n\t'\

'1: \n\t'\

'SUB R0, #1\n\t'\

'CMP R0, #0\n\t'\

'BNE 1b \n\t' : : [loops] 'r' (8*us) : 'memory'\

);\

} while(0)

You need to adjust the constant '8' depending on the processor frequency. This Delay loop takes 6 ticks (48 MHz / 6 = 8). The delay function is not dependent on code optimization. So the function is written in the assembler and it's also as macro, so there are no jumps depended on optimization and compiler.

Posted on February 20, 2018 at 11:25

It's an old question but, for completeness:

mahdi zamani wrote:

can connect two micro stm32f103xxxx whit this protocol ?

In principle, yes - you could use the 1-Wire protocol.

But note that the code here implements only the 1-Wire Master - so you would need to do your own Slave implementation.

Or use a 

https://www.maximintegrated.com/en/products/digital/memory-products/DS2408.html/tb_tab2

  - as shown in Fig 17 of the Datasheet:

https://datasheets.maximintegrated.com/en/ds/DS2408.pdf

 
Posted on February 20, 2018 at 13:14

Onewire slave is a problem. You may create a OneWire master, but never write your own OneWire slave. You're breaking patents. For development purposes, it might not matter, but commercially it's a big problem.

Stoian Ivanov
Associate II
Posted on April 04, 2018 at 01:56

I'm working on stm32f0 lib for interrupt driven 1-wire library supporting multiple buses on different pins. It seems possible with only PLL-doubled internal 8MHz.  The sending seem working with decent speeds and almost no busy-waiting. The interface allows series of 'driver' implemented reset_presence-write-read with callback for result. I anyone is interested PM me I hope to have it done in few days (working late at night, robbing myself of sleep)