Mikro-kontroler TM4C123GH6PM posiada 8 modułów UART - Universal Asynchronous Receiver/Transmitter. Do obsługi transmisji 1-Wire należny przygotować wyjście TX i wejście RX tak aby sygnały były współdzielone z jednym przewodem na którym musi być oparta cała transmisja. Do fizycznego połączenia pinów RX i TX potrzebne są dwa tranzystory NPN BC547 i dwa rezystory, przy testach i pisaniu kodu korzystałem z dokumentacji Atmel i Maxim integrated.
Testowa płytka stykowa połączona z lanunchpadem.
Do inicjacji UART służy poniższa funkcja, nie wykorzystałem przerwań i buforów FIFO. Należy w opcjach projektu dodać "predefined symbols" "PART_LM4F230H5QR", gdyż bez tego biblioteka nie zwróci odpowiednich map dla naszego procesora. W zależności od płytki może być potrzebny inny zapis, więcej na forum TI link.
void OneWire_init(void)
{
// Enable Peripheral Clocks
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// Enable pin for UART URX
GPIOPinConfigure(GPIO_PB0_U1RX);
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0);
// Enable pin for UART UTX
GPIOPinConfigure(GPIO_PB1_U1TX);
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_1);
UARTClockSourceSet(UART1_BASE, UART_CLOCK_SYSTEM);
UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
UARTFIFODisable(UART1_BASE);
UARTEnable(UART1_BASE);
}
Podstawowe funkcje jakie będą niezbędne do obsługi 1-Wire na wyższym poziomie to wczytywanie 1, wczytywanie 0, odczyt jednego bitu i reset. W jednym bajcie przekazywany jest tylko jeden bit, cała ramka jest potrzebna do spełnienia czasowego wymogu transmisji. Baud rate ustawione w większości operacji na 115200.
Po nadaniu bajtu funkcja czeka aż bajt zostanie wysłany przez UART i następnie odebrany i odczytany (możliwe, że odczytanie jest zbędne, ma na celu oczyszczenie bufora).
Wczytanie 0 na magistrale, TX nadaje bajt składający się z samych zer.
void OneWire_write0()
{
UARTCharPut(U_BASE, 0x00);
while(UARTBusy(U_BASE))
{
}
while(UARTCharsAvail(U_BASE))
{
UARTCharGetNonBlocking(U_BASE);
}
}
Wczytanie 1 na magistrale, TX nadaje bajt składający się z samych 1.
void OneWire_write1()
{
UARTCharPut(U_BASE, 0xFF);
while(UARTBusy(U_BASE))
{
}
while(UARTCharsAvail(U_BASE))
{
UARTCharGetNonBlocking(U_BASE);
}
}
Odczytanie jednego bitu ze slave. Wczytanie 1 na magistrale i odczyt bajtu który przy zmodyfikowaniu przez slave będzie inny niż 1 co oznacza nadanie przez slave 0.
Read 0
Read 1
unsigned char OneWire_Read()
{
// function reads 1-wire bus
// return 1 or 0
unsigned long tmp;
UARTCharPut(U_BASE, 0xFF);
while(UARTBusy(U_BASE))
{
}
while(UARTCharsAvail(U_BASE))
{
tmp=UARTCharGetNonBlocking(U_BASE);
}
return (0xFF==tmp);
}
Dodatkową ważną funkcja jest reset, musi być wykonany przy niższym baud rate = 9600.
Polega na wczytanie 0xF0 na magistrale i odczycie bajtu który przy zmodyfikowaniu przez slave będzie inny niż 0xF0 co oznacza, że jest działający slave na magistrali.
Reset - brak slave na magistrali.
Reset - slave odpowiedział.
unsigned char OneWire_Reset(void){
// function reset bus and returns 1 if is presence pulse
unsigned long tmp=0;
UARTDisable(U_BASE);
UARTConfigSetExpClk(U_BASE, SysCtlClockGet(), 9600, (UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
UARTEnable(U_BASE);
UARTCharPut(U_BASE, 0xF0);
while(UARTBusy(U_BASE))
{
}
while(UARTCharsAvail(U_BASE))
{
tmp=UARTCharGetNonBlocking(U_BASE);
}
UARTDisable(U_BASE);
UARTConfigSetExpClk(U_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
UARTEnable(U_BASE);
return (0xF0!=tmp);
}





