Hier eine Library um mit dem STM32F4 einen OneWire-Bus steuern zu können.
(One-Wire => Eindrahtbus => 1-Wire-Bus => ist eine serielle Schnittstelle mit nur einer Datenleitung)
Der STM32F4 fungiert hierbei als “Master” und kann prinzipiell unendlich viele Slaves über die eine Datenleitung steuern. Die Slaves werden durch einen 8Byte RomCode unterschieden der in jedem Slave unterschiedlich ist.
Der Datenpin ist als “OpenDrain-Output” geschaltet und es muss zwingend ein externer PullUp (gegen 3,3V) von ca. 4k7 eingebaut werden. (Im H-File wird der Pin festgelegt)
Um zu erkennen ob überhaupt ein Slave am Datenbus hängt, gibt es die Funktion “UB_OneWire_ResetSequenz” die gleichzeitig alle Slaves in einen definierten Zustand bringt.
Die LoLevel-Lib besitzt die grundlegenden Funktionen zum lesen/schreiben eines Bits oder eines Bytes.
Zum Adressieren eines Slaves muss dessen RomCode bekannt sein. Um diesen auszulesen gibt es die Funktion “UB_OneWire_ReadRomCode”. (Bei dieser Funktion darf nur ein Slave am Bus hängen). Wer den RomCode als String sehen will, kann ihn per “UB_OneWire_RomCode2Str” umwandeln.
Damit der Code übersichtlicher bleibt, kann der 8Byte RomCode als String der Funktion “UB_OneWire_Str2RomCode” übergeben werden. Diese wandelt den String dann in 8 einzelne Bytes um. (siehe Quellcode vom OneWire DS1822 Temp-Sensor)
Pinbelegung :
1 | PD3 = Datenpin |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO, TIM, MISC, (Retarget Printf) Benutzte Librarys : keine |
Funktionen :
1 2 3 4 5 6 7 8 9 10 | void UB_OneWire_Init(void); // init der Library ErrorStatus UB_OneWire_ResetSequenz(void); // Reset-Sequenz ErrorStatus UB_OneWire_ReadRomCode(void); // ließt den RomCode void UB_OneWire_WriteByte(uint8_t wert); // schreibt ein Byte uint8_t UB_OneWire_ReadByte(void); // ließt ein Byte void UB_OneWire_WriteBitLo(void); // schreibt ein Bit (Lo) void UB_OneWire_WriteBitHi(void); // schreibt ein Bit (Hi) BitAction UB_OneWire_ReadBit(void); // ließt ein Bit ErrorStatus UB_OneWire_Str2RomCode(char *rom_code); // zum umwandeln vom String in RomCode void UB_OneWire_RomCode2Str(char *rom_code); // zum umwandeln von RomCode in String |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | //-------------------------------------------------------------- // File : main.c // Datum : 29.09.2013 // Version : 1.1 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.4 // GCC : 4.7 2012q4 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der OneWire-LoLevel-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_onewire.h" #include "stm32_ub_led.h" int main(void) { ErrorStatus check; char rom_code[20]; SystemInit(); // Quarz Einstellungen aktivieren // init der LEDs UB_Led_Init(); // init vom OneWire-Bus UB_OneWire_Init(); // test ob ein OneWire-Slave angeschlossen ist check=UB_OneWire_ResetSequenz(); if(check==SUCCESS) { UB_Led_On(LED_GREEN); // auslesen vom 8Byte RomCode // es darf nur EIN Slave angeschlossen sein ! UB_OneWire_ReadRomCode(); // RomCode in String wandeln // (String kann per Debugger angezeigt werden) UB_OneWire_RomCode2Str(rom_code); } else { UB_Led_On(LED_RED); } while(1) { } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Thank you very much for your code, I test the code with stm32f4discovery connect to DS18S20+, it’s work propery. Then I try to modify the code to use with stm32f103rb, it’s not work now.
http://www.electoday.com/index.php/topic,12412.0.html
please check the lenght of the signals with a oscilloscope.
the correct frq is important to work properly.
I use Systick instead of TIM2 for a delay function, it’s work now. Do you think about it? (My program is inside my link) Thanks.
TIM2 ?… in the Library TIM7 is used
and i dont search your failure…but when the function with systick is ok…then you have found the problem…the TIM7 ist not working correct , means runns with the wrong frequenz
I modified your code to use with stm32f103rb and use TIM2 instead of TIM7, I think TIM2 with interrupt in short period(1us) has overhead and extend the time more than 1us, with no problem on stm32f4idscovery that has high speed clock. I will use logic analyzer to check the signal compare between the used of TIM2 and Systick. Thank for your suggestion, I forgot to use the measuring tool.