Advertisement  

Friday, 28 July 2017
     
 
Main Menu
Home Home
Shop Shop
News News
BASCOM-AVR BASCOM-AVR
BASCOM-8051 BASCOM-8051
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-AVR Help BASCOM-AVR Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login
Username

Password

If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News
 
     
 

 
   
     
 
AN #168 - Dallas DS2450 emulation with Tiny AVR Print
This article describes basic approach to building 1-wire slave devices by uC emulation on example of DS2450 1-Wire Quad A/D Converter. Besides lower cost, emulated device allows to get more precision that the prototype and more flexibility by adding various extra software options. Also, 12 bit ADC conversion was realized by oversampling technique.
Vladimir I. Yershov  (first price winner in Russian BASCOM contest)
Chloride Rus, Moscow, Russia


The idea to replace standard DS2450 [1] came during the development battery monitoring system, when it became obvious that declared precision of the DS2450 does not exceed 8 bits.

The Hardware
.
ATTiny45 chip finally was chosen for the emulation although PIC12F675/683 also were tested but failed due to the speed limitations.
Tiny45 was configured for operation from internal RC clock at 8 MHz with RESET pin configured as analog input. Pin configuration shown on Fig.1.


Fig. 1 Pinout of the design

A lab sample of the battery measuring board based on Tiny emulator shown below on Fig.2. As galvanic isolation is mandatory for such applications, there are two optocouplers on the sides of the board. So 1-wire communication is performed via optical link. But it’s a topic for another article.


Fig.2 Sample board for battery monitoring system. Tiny is in the middle.

The Firmware
Present software version supports most basic operations of DS2450 except output pins control and alarms function. To achieve 12 bit resolution, a well known over sampling technique [2] was used.


Fig.3 Simplified software flowchart

The design is also allows addressable firmware upgrade via 1-wire network with the Bootloader by Peter Dannegger [3].
To demonstrate the operation of the device a compilation option for Mega32 (Tiny45 is not available for simulation) was added and Proteus simulation design was made.

Simplified software flowchart shown on Fig.3. The program flow divides into the several stages.

•    Main Loop – polling of the state of the 1-wire pin Dq for Reset Pulse from Master. Once the low state of Dq has been distinguished Timer starts to counts and the program waits for High Dq. On the High Dq Timer stops and the comparison with the predefined Min and Max intervals made. If the pulse seems to be Reset the program performs output of the Presence Pulse and the program begin to wait a general command from the Master.
•    General commands reception. General commands could be only: Read ROM, Search ROM, Skip ROM or Match ROM. If received byte corresponds to one of the General Commands the control passed to second command acquisition block which recognize device specific commands. Oversize flow returns to the Main Loop.
•    Device specific commands reception. These commands for this emulator are: Start ADC Conversion, Read Memory (ADC results and settings), Write Memory (Device Setup) and Firmware Upgrade.
•    ADC Conversion, according to the Oversampling Technique Idea executed 64 times with summing conversion results in word array for each ADC channel with subsequent division by 16 which results in 12 bit value. Resulting conversion time is similar with the prototype DS2450.
•    CRC16 Calculation is necessary for 1-wire protocol requirements almost for any transaction. In this program CRC16 calculated for each sent/received byte on the fly immediately as the byte is available. It’s the task of CRC_Update subroutine.
•    Interrupt Service Routine (ISR) on timer overflow used here to prevent program endless cycling in cases of transmition errors or if the master sleeps too long. It returns the control to the different points of the Main Loop depending of the state of Dq.
•    Firmware Upgrade performed via 1-wire bus. This design was developed to work with the intermediate PIC uC which serves as a Master, accumulates, process data and send results to PC. At the beginning of FW Upgrade Master sent to Slave Bootload command byte. Slave responses with the same byte and jumps to Bootloader. Master come into transparent mode and translates the Bootloader traffic from PC to Slave and back.
•    Tiny programming consists of two steps: 1. Flashing the Bootloader 2. Downloading Firmware via Bootloader.   
 
Results
Testing of the design was performed in virtual and real environments. Real tests were done with 4 Tiny emulator modules, united in 1-wire net  and connected to the 16 x 12V VRLA batteries of the 10 kVA UPS. Also modules based on DS2450 prototype were tested in the same conditions. Monitoring parameters were: battery voltage, charge-discharge current, measuring accuracy and transmition errors. Tiny modules shows better performance over DS2450 by all parameters except current consumption which was 1.5 times greater. There were no any power optimization in current version, so it’s optimistic to think it’ possible to improve in the future releases.
Proteus simulations were helpful for debug and presentation. Below is the screen short of such simulation.
      

Schematic



Source code:


'****************************************************************
'*  Name    : Tiny_DS2450.BAS                                   *
'*  Author  : Vladimir I. Yershov                               *
'*                                                              *
'*  Date    : 21.12.2008                                        *
'*  Version : 1.0                                               *
'*  Notes   : Firmware for Tiny and Mega AVR to emulate Dallas  *
'*            DS2450 1-Wire Quad A/D Converter                  *
'*          :                                                   *
'****************************************************************
 '$regfile = "attiny45.dat" : Const Chip = 45         ' Choose chip for compilation by uncomment line
$regfile = "m32def.dat" : Const Chip = 32

$crystal = 8000000

#if Chip = 45
$loadersize = 512                                           ' bootloader space reservation
Config Clockdiv = 1
#endif

' HW Config
$hwstack = 32
$swstack = 8
$framesize = 16
Config Adc = Single , Prescaler = Auto
Config Timer0 = Timer , Prescale = 64

Const Dqpin = 1
Const Ipin = 0                                              ' value in DDRB for input
Const Opin = 1                                              ' value in DDRB for output

Timer Alias Tcnt0

Dq Alias Pinb.dqpin

' Commands
Const Search_rom = &HF0
Const Skip_rom = &HCC
Const Match_rom = &H55
Const Read_rom = &H33
Const Writemem = &H55
Const Convert = &H3C
Const Read_mem = &HAA
Const Bootload = &HEE
Const Write_epr = &HE0

' Timings

Const Owpresent = 150                                       '  60us < OWPresent < 240us
Const Owpause = 50                                          '  15us < OWPause   < 60us
Const Owstrobe = 15                                         '  read Dq value after Owstrobe us                                          '12                  '10 4MHz      12 8 MHz
Const Owdata = 25                                           '  Valid output data for Owdata us                                         '20 '15                                           '12                  '7            12

' Timer Delays

Const T1reset = 60                                          'T1us * 490 Min Reset width
Const Timeout = 120                                         'T1us * 970 Max Reset width

' Allocate variables

Dim I As Byte
Dim B As Byte
Dim Inmask As Byte
Dim Readout As Byte
Dim Addrlo As Byte
Dim Adcnum As Byte

Dim Myrom(8) As Byte

Dim Crc16_hi As Byte
Dim Crc16_lo As Byte

Dim Ram(32) As Byte
Dim Ramw(16) As Word At Ram() Overlay
Dim Ad_result As Word
Dim Bytedat As Byte
Dim Wreg As Byte

Dim Tstval As Byte
Dim Temp As Byte
Dim Templ As Byte
Dim Temph As Byte
Dim Tempw As Word At Templ Overlay

Dim Overresol As Byte
Dim Oversample As Byte
Dim Overcount As Byte
Dim Overshift As Byte
Dim Normshift As Byte

Dim Bitdat As Bit

 Enable Interrupts
 Enable Timer0
 On Timer0 Isr Nosave

 Restore MyromData
 For Addrlo = 1 To 8
 Read B
         Myrom(addrlo) = B
 Next Addrlo

 Stop Timer0

#if Chip = 45
 Admux = &B00100000
 Adcsra = &B00000110
         Adcsrb = &B00000000
'         Didr0 = &B00111101
         Didr0 = &B00111100
#endif
 Open "comb.0:57600,8,n,1" For Output As #1
 Print #, "T45.3 18.11.07" ' version info

 Waitms 500
'-----------------------------------

Mainloop:
Waitreset:

 Disable Interrupts
 Timer = 0

Waitfall:

L1:
 sbis pinb, DqPin
 rjmp L1
L2:
 sbic pinb, DqPin
 rjmp L2

 Start Timer0

Rwaitrise:

L01:
 sbic pinb, DqPin
 rjmp L01
L02:
 sbis pinb, DqPin
 rjmp L02

 Stop Timer0

 If Timer < T1reset Then Goto Waitreset
 If Timer > Timeout Then Goto Waitreset


Sendpresense:
 Waitus Owpause

 Ddrb.dqpin = Opin

 Waitus Owpresent
 Ddrb.dqpin = Ipin
 Timer = 0
 Enable Interrupts

Readb:

 Gosub Readbyte
Readb1:

 If Bytedat = Read_rom Then Goto Readrom
 If Bytedat = Search_rom Then Goto Sendrom
 If Bytedat = Skip_rom Then Goto Funct
 If Bytedat = Match_rom Then Goto Matchrom
 Goto Readb
End



Isr:
 Spl = &H5F
 Sph = 1

 If Dq = 0 Then
 Timer = T1reset

 Goto Rwaitrise
 Else
 Goto Waitreset
 End If

Return
'-------------------------------
Readrom:
 For B = 1 To 8
       Bytedat = Myrom(b)
 Gosub Sendbyte
 Next B
Goto Readb
'----------------------------------
Matchrom:
 For B = 1 To 8
 Gosub Readbyte
 If Bytedat <> Myrom(b) Then Goto Mainloop
 Next B
Funct:
 Gosub Readbyte

 If Bytedat = Convert Then Goto Conversion

 If Bytedat = Read_mem Then Goto Readmem

 If Bytedat = Writemem Then Goto Write_mem

 If Bytedat = Bootload Then Goto Fwupgrade

 '    If Bytedat = Write_epr Then Goto Writeepr

Goto Readb1
'----------------------------------------
Fwupgrade:
 Gosub Sendbyte
 jmp 0

Readmem:
        Crc16_lo = 0
        Crc16_hi = 0
        B = 0

 Gosub Crc_update                                    ' ByteDat = ReadMem

 Gosub Readbyte
        Addrlo = Bytedat
 Gosub Crc_update                                    ' ByteDat = AddrLo

 Gosub Readbyte
 Gosub Crc_update                                    ' ByteDat = AddrHi
Readloop:
        Bytedat = Ram(addrlo + 1)

 Gosub Sendbyte
 Gosub Crc_update

 Incr Addrlo
 Incr B

 If B = 8 Then Goto Exitreadmem
 Goto Readloop
Exitreadmem:
        B = 0

        Bytedat = Crc16_lo Xor &HFF
 Gosub Sendbyte
        Bytedat = Crc16_hi Xor &HFF
 Gosub Sendbyte

        Crc16_lo = 0
        Crc16_hi = 0

 If Addrlo < 31 Then Goto Readloop

Goto Mainloop

'----------------------------------------
Write_mem:
        Crc16_lo = 0 : Crc16_hi = 0

 Gosub Crc_update                                    'Bytedat = Writemem

 Gosub Readbyte
        Addrlo = Bytedat
 Gosub Crc_update                                    ' AddrLo

 Gosub Readbyte
 Gosub Crc_update                                    ' AddrLo

 Gosub Readbyte
        Ram(addrlo + 1) = Bytedat
 Gosub Crc_update                                    ' MemByte

        Bytedat = Crc16_lo Xor &HFF
 Gosub Sendbyte

        Bytedat = Crc16_hi Xor &HFF
 Gosub Sendbyte

        Bytedat = Ram(addrlo + 1)
 Gosub Sendbyte
' ====== END OF FIRST PASS ===========
 Writememloop:
 Incr Addrlo
            Crc16_hi = 0
            Crc16_lo = Addrlo                               ' low (Crc16) = Addrlo

 Gosub Readbyte
            Ram(addrlo + 1) = Bytedat
 Gosub Crc_update

            Bytedat = Crc16_lo Xor &HFF
 Gosub Sendbyte

            Bytedat = Crc16_hi Xor &HFF
 Gosub Sendbyte

            Bytedat = Ram(addrlo + 1)
 Gosub Sendbyte

 If Addrlo < 31 Then Goto Writememloop

Goto Mainloop

' =============
Conversion:
        Crc16_lo = 0 : Crc16_hi = 0
 Gosub Crc_update                                    'ByteDat = Convert

 Gosub Readbyte                                      'ByteDat = InMask
 Gosub Crc_update

 Gosub Readbyte                                      'ByteDat = ReadOut
 Gosub Crc_update

        Bytedat = Crc16_lo Xor &HFF
 Gosub Sendbyte

        Bytedat = Crc16_hi Xor &HFF
 Gosub Sendbyte

        Overresol = 12                                      ' Desired Oversample Resolution
        Overshift = Overresol - 10                          ' Shift Left After Oversampling
        Normshift = 6 - Overshift
        Oversample = 4 ^ Overshift

#if Chip = 45
        Didr0 = &B00111100
 Adcsra = &B00000101                                 ' ADC clock = 250 kHz
 Adcsra.= 1                                        ' Enable ADC
        Adcsrb = &B00000000

#endif
 For Adcnum = 1 To 4
             Ramw(adcnum) = 0
 Next Adcnum
#if Chip = 45
 For Overcount = 1 To Oversample
 Admux = &B00000000                            ' Righ aligned result
 For Adcnum = 1 To 4
 Adcsra.= 1
 While Adcsra.= 1 : Wend
              Templ = Adcl : Temph = Adch
              Ramw(adcnum) = Ramw(adcnum) + Tempw
 Incr Admux
 Next Adcnum
 Next Overcount
#else
 Start Adc
 For Overcount = 1 To Oversample
 For Adcnum = 1 To 4
              B = Adcnum - 1
              Ad_result = Getadc(b)
              Ramw(adcnum) = Ramw(adcnum) + Ad_result
 Next Adcnum
 Next Overcount
#endif
 For Adcnum = 1 To 4
 Shift Ramw(adcnum) , Right , Overshift
 Shift Ramw(adcnum) , Left , Normshift
 Next Adcnum

Exit_case:
#if Chip = 45
 Adcsra.= 0                                        ' Disable ADC
#else
 Stop Adc
#endif
Goto Mainloop
'======================================================
Crc_update:

        Wreg = Bytedat
        Wreg = Wreg Xor Crc16_lo
        Temp = Wreg
        Wreg = Crc16_hi
        Crc16_lo = Wreg
        Wreg = 0

 If Temp.= 1 Then Wreg = &HCC

 If Temp.= 1 Then Wreg = Wreg Xor &H8D

 If Temp.= 1 Then Wreg = Wreg Xor &H0F

 If Temp.= 1 Then Wreg = Wreg Xor &H0A

        Crc16_hi = Wreg
        Wreg = Wreg And &HF0
        Crc16_hi = Crc16_hi Xor Wreg
        Crc16_lo = Crc16_lo Xor Wreg
        Wreg = 0

 If Crc16_hi.= 1 Then Wreg = &HCC

 If Temp.= 1 Then Wreg = Wreg Xor &HCC

 If Temp.= 1 Then Wreg = Wreg Xor &HD8

 If Temp.= 1 Then Wreg = Wreg Xor &HF0

 If Temp.= 1 Then Wreg = Wreg Xor &HA0

        Crc16_hi = Crc16_hi Xor Wreg
        Wreg = 1

 If Crc16_hi.= 1 Then Crc16_lo = Crc16_lo Xor Wreg

Return
'---------------------------------
'================================
Readbyte:
 For I = 0 To 7

L11:
 sbis pinb, DqPin
 rjmp L11
L12:
 sbic pinb, DqPin
 rjmp L12
 Timer = 256 - T1reset
 Start Timer0

 Rotate Bytedat , Right
 Waitus Owstrobe


         Bytedat.= Dq

 Next I
 Stop Timer0
Return
'----------------------------------
Sendbyte:
       Adcnum = Bytedat
 For I = 0 To 7

L21:
 sbis pinb, DqPin
 rjmp L21
L22:
 sbic pinb, DqPin
 rjmp L22
 Timer = 256 - T1reset
 Start Timer0

 If Bytedat.= 0 Then Ddrb.dqpin = Opin
 Waitus Owdata
 Ddrb.dqpin = Ipin

 Rotate Bytedat , Right

 Next I
        Bytedat = Adcnum
 Stop Timer0
Return
'-----------------------------------
Sendrom:
'    Stop Timer0
 For I = 1 To 8
          Bytedat = Myrom(i)
 For B = 0 To 7
'----------------------------
Sendcbit1:

L31:
 sbis pinb, DqPin
 rjmp L31
L32:
 sbic pinb, DqPin
 rjmp L32

 If Bytedat.= 0 Then Ddrb.dqpin = Opin
 Waitus Owdata
 Ddrb.dqpin = Ipin
'----------------------------
Sendcbit2:

L41:
 sbis pinb, DqPin
 rjmp L41
L42:
 sbic pinb, DqPin
 rjmp L42

 If Bytedat.= 1 Then Ddrb.dqpin = Opin
 Waitus Owdata
 Ddrb.dqpin = Ipin

'--------------------------
Readcbit:

L51:
 sbis pinb, DqPin
 rjmp L51
L52:
 sbic pinb, DqPin
 rjmp L52

 Waitus Owstrobe

           Bitdat = Dq

'-------------------------
 If Bitdat <> Bytedat.Then Goto Mainloop
 Rotate Bytedat , Right
 Next B
 Next I

Goto Readb
End


MyromData:
'Data &H20 , &H0D , &HCB , &H0A , 00 , 00 , 00 , &HEC
'Data &H81 , &H55 , &H22 , &H24 , 00 , 00 , 00 , &H6A
'Data &H20 , &HAC , &HC7 , &H0A , 00 , 00 , 00 , &HA6

'Data &H20 , &HA5 , &HC1 , &H0A , 00 , 00 , 00 , &HAC
Data &H81 , &H55 , &H22 , &H24 , 00 , 00 , 00 , &H6A