AVR-Ada Wiki
Ada cross compiler and libraries for AVR µCs
Status: Beta
Brought to you by:
rolf_ebert
-- -- Sample program that reads the temperatures from all attached -- 1-Wire temperature sensors and prints the values to the serial -- interface. -- -- std Ada type definitions, mostly needed for Unsigned_8 with Interfaces; use Interfaces; with AVR; use AVR; with AVR.Wait; -- address and bit name constants for the MCU with AVR.MCU; -- routines to send and receive data across the serial line with AVR.UART; -- Dallas 1-Wire definitions and routines for a bus master with One_Wire; use One_Wire; with One_Wire.Search; with One_Wire.ROM; with One_Wire.Temperature_Sensors; use One_Wire.Temperature_Sensors; with Crc8; -- temperature types using Ada's fixed point capabilities with Temperatures; use Temperatures; procedure Test_DS1820 is Found : Boolean; procedure Wait_1ms is new AVR.Wait.Generic_Wait_Usecs (Crystal_Hertz => 8_000_000, Micro_Seconds => 1000); -- workaround until a real Ada delay statement can be used procedure Wait_Long is begin -- delay 0.8; for J in 1 .. 800 loop Wait_1ms; end loop; end Wait_Long; -- this demo can handle up to 5 devices Max_OW_Devices : constant := 5; subtype OW_Device_Range is Unsigned_8 range 0 .. Max_OW_Devices; subtype OW_Valid_Device_Range is OW_Device_Range range 1 .. Max_OW_Devices; type OW_Device_A is array (OW_Valid_Device_Range) of One_Wire.ROM.Unique_Serial_Code; type OW_Temp_A is array (OW_Valid_Device_Range) of Temperature_12bit; OW_Devices : OW_Device_A; -- array of sensor rom codes OW_Temps : OW_Temp_A; -- array of corresponding temperatures OW_Sensor_Index : OW_Device_Range; Last_Sensor : OW_Device_Range; Crc : Unsigned_8; begin -- provide high voltage at D4 as power supply in non-parasite mode MCU.DDRD_Bits (4) := DD_Output; MCU.PORTD_Bits (4) := High; -- AVR.UART.Init (51); -- Baud rate = 9600bps, 8MHZ, u2x=0 One_Wire.Init_Comm; UART.Put_Line ("starting RE's 1-Wire to serial output test program"); loop UART.New_Line (2); UART.Put_Line ("--> Test 1-wire to serial output"); OW_Sensor_Index := 1; Last_Sensor := 0; -- first find all devices Found := One_Wire.Search.First; if Found then loop -- copy the rom code to our array OW_Devices (OW_Sensor_Index) := One_Wire.ROM.Identifier; -- increment the sensor index Last_Sensor := OW_Sensor_Index; OW_Sensor_Index := OW_Sensor_Index + 1; -- search the next device Found := One_Wire.Search.Next; exit when not Found; end loop; else Uart.Put_Line ("no device"); end if; -- print list of found IDs -- <sensor index> : <ROM code in hex> for Idx in 1 .. Last_Sensor loop UART.Put ("ID "); UART.Put (Nat8 (Idx)); UART.Put (": "); Crc := 0; for J in One_Wire.ROM.Serial_Code_Index loop Crc := Crc8 (Data => OW_Devices (Idx)(J), Seed => Crc); Uart.Put (Nat8 (OW_Devices (Idx)(J)), Base => 16); Uart.Put (' '); end loop; Uart.Put ("CRC: "); Uart.Put (Nat8 (Crc), Base => 16); Uart.New_Line; end loop; Wait_Long; -- start conversion for all sensors One_Wire.ROM.Identifier (1) := 0; -- see comment in One_Wire.Temperature_Sensors. If the first -- byte of the ROM code is zero, send the command to start -- temperature sampling to all temperature sensors. One_Wire.Temperature_Sensors.Init_T_Conversion; -- leave enough time for the temperature conversion. (750ms for -- 12 bit! see the DS18B20 data sheet.) Wait_Long; -- request temp reading for Idx in 1 .. Last_Sensor loop -- set the rom code One_Wire.ROM.Identifier := OW_Devices (Idx); -- and read the temperature if One_Wire.ROM.Identifier (1) = Family_Code (DS18S20) then OW_Temps (Idx) := To_Temperature_12bit (Read_Raw_Value * 8); else OW_Temps (Idx) := To_Temperature_12bit (Read_Raw_Value); end if; end loop; -- print list of temperature readings for Idx in 1 .. Last_Sensor loop Uart.Put ("ID "); Uart.Put (Nat8 (Idx)); Uart.Put (": T = "); Uart.Put (Image (OW_Temps (Idx))); Uart.Put ('C'); Uart.New_Line; end loop; Uart.Put_Line ("Test - off"); Wait_Long; end loop; end Test_DS1820;