Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> I2c для Atmega8, Програмvно I2c 
:(
    Опции темы
Alex1984
Дата 25.6.2005, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 299
Регистрация: 6.3.2005
Где: Киев

Репутация: 2
Всего: 2



Не могу реализовать I2c для Atmega8.
При посылке старта сразу возвращается ошибка.
Хочу связать по I2c Atmega8 часы и термодатчик.
Может кто уже писал подобные вещи на асме
smile

PM MAIL WWW ICQ   Вверх
PILOT
Дата 26.6.2005, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


производство
****


Профиль
Группа: Модератор
Сообщений: 2724
Регистрация: 4.4.2002
Где: москва

Репутация: 20
Всего: 54



Код


;***************************************************************************
;* AVR Temper8 AT90S2313 version                                           *
;* Reads up to eight Dallas DS1820/DS18S20 Temperature sensors connected   *
;* to an AVR port bit. The temperature (degrees C, ASCII, + CRLF) is sent  *
;* out the serial port when a Tn (where n is a single digit from 0 to 7)   *
;* is received by the serial port.                                         *
;* An R character returns a count of the devices found, plus a list of     *
;* their ROM IDs                                                           *
;* Here's an example:                                                      *
;* command sent : r                                                        *
;* program returns:                                                        *
;* 4                                                                       *
;* 0800080007CC0010                                                        *
;* C000080007728A10                                                        *
;* 0D00080007455E10                                                        *
;* 3300080007B60510                                                        *
;* 0000000000000000                                                        *
;* 0000000000000000                                                        *
;* 0000000000000000                                                        *
;* 0000000000000000                                                        *
;*                                                                         *
;* command sent: t1                                                        *
;* program returns:                                                        *
;* +023.50C                                                                *
;*                                                                         *
;* 1-Wire port bit:                                                        *
;* Port B bit 2 (PB2) -- The code turns on the pullup feature of the AVR   *
;* port bit used. This is enough to enable the 1-Wire bus.                 *
;* The 4.7K pullup resistor required in most applications (see the DS18S20 *
;* data sheet) can also be used without changing the software.             *
;* Acknowledgments                                                         *
;* This code was ported from my AT90S8515 program, 8515Temp8, which is     *
;* in turn a port from my 68HC11 program, LCDTemper8                       *
;* The ROMSrch (ROM Search) routine was ported from ML6805,a Public Domain *
;* assembly language example from Dallas Semiconductor.                    *
;* It was originally written for the 6805. I also used the code in         *
;* The Dallas/Maxim Application Note 162:                                  *
;* INTERFACING THE DS18X20/DS1822 1-WIRE TEMPERATURE SENSOR IN A           *
;* MICRO-CONTROLLER ENVIRONMENT as a guide.                                *
;* I also borrowed from a few Atmel AVR application notes                  *
;*                                                                         *
;* The DS1820 devices are read only after setup (to read their ROM codes)  *
;* and during a temperature conversion request.                            *
;* Results are sent to the serial port                                     *
;* FH 030111  First mod of AT90S8515 version                               *
;* FH 030112  Enabled the internal pullup resistor for Port B pin 2. The   *
;*            typical 4.7K pullup resistor on the DS line no longer needed *
;*                                                                         *
;* Frank Henriquez [email protected] http://www.bol.ucla.edu/~frank/          *
;* Please do not delete any of the text in this comment box.               *
;* Please do not redistribute modified versions of this code               *
;***************************************************************************

.include "2313def.inc"

;**********************************************
;* Equates                                    *
;**********************************************

.equ    clock       = 8000000  ;clock frequency 
.equ    baudrate    = 9600     ;choose a baudrate 
.equ    baudconstant= (clock/(16*baudrate))-1

.equ    STACKTOP    = RAMEND - 100 

;**********************************************
;* Registers used                             *
;**********************************************

.def    Done        = r10      ;used in GetROMs
.def    ROMCount    = r11      ;number of devices found
.def    SaveSREG    = r12      ;used in Delay
.def    BitNum      = r13      ;used in ROMsrch
.def    LastDis     = r14      ;used in ROMsrch
.def    LasDisCpy   = r15      ;used in ROMsrch

.def    AReg        = r16      ;working reg, like the 68HC11 A register
.def    BReg        = r17      ;working reg, like the 68HC11 B register
.def    ScratchL    = r18
.def    ScratchH    = r19
.def    ByteCount   = r20      ;used in ShowROM
.def    Count8      = r21
.def    DelayVal    = r22

;**********************************************
;* DS1820 Command bytes                       * 
;**********************************************
.equ    ReadROM     = $33
.equ    MatchROM    = $55
.equ    SkipROM     = $cc
.equ    SearchROM   = $f0
.equ    SearchAlarm = $ec

.equ    ConvertTemp = $44
.equ    CpyScratch  = $48
.equ    WrScratch   = $4e
.equ    RdScratch   = $be
.equ    RecallEE    = $b8
.equ    ReadPS      = $84

;**********************************************
;* The following delay constants are based on * 
;* an 8MHZ clock (CLK)                        *
;* times are not exact.                       *
;**********************************************

.equ    d250us  = 6            ;250us CLK/8
.equ    d100us  = $9c          ;70us  CLK/8
.equ    d44us   = $d4          ;44us  CLK/8
.equ    d15us   = $f2          ;14us  CLK/8
.equ    d2us    = $fe          ;2us   CLK/8


.equ    TSTOP   =0             ;Stop Timer/Counter
.equ    TCK1    =1             ;Timer/Counter runs from CK
.equ    TCK8    =2             ;Timer/Counter runs from CK / 8
.equ    TCK64   =3             ;Timer/Counter runs from CK / 64
.equ    TCK256  =4             ;Timer/Counter runs from CK / 256
.equ    TCK1024 =5             ;Timer/Counter runs from CK / 1024
.equ    TEXF    =6             ;Timer/Counter runs from external falling edge
.equ    TEXR    =7             ;Timer/Counter runs from external rising edge

.equ    DSBus   =2             ;PORTB bit used for the 1-wire bus


;**********************************************
;* 100 bytes of internal data RAM are used by *
;* the program                                *
;**********************************************
.dseg
.org RAMEND - 99 
                  
Buffer:        .byte 16
;**********************************************
;* 9 bytes below are the register contents    *
;* of the last DS18S20 read                   *
;**********************************************
TempLSB:       .byte 1
TempMSB:       .byte 1
THUB1:         .byte 1
TLUB2:         .byte 1
Res1:          .byte 1
Res2:          .byte 1
CountRem:      .byte 1
CntPerC:       .byte 1
CRC:           .byte 1

ExtTemp:       .byte 1
romoff:        .byte 2         ;Pointer to Sensor address         
romdta:        .byte 8         ;ROM address of urrent device
Sensor0:       .byte 8         ;DS1820 sensor 0 ID #
Sensor1:       .byte 8         ;DS1820 sensor 1 ID #
Sensor2:       .byte 8         ;DS1820 sensor 2 ID #
Sensor3:       .byte 8         ;DS1820 sensor 3 ID #
Sensor4:       .byte 8         ;DS1820 sensor 4 ID #
Sensor5:       .byte 8         ;DS1820 sensor 5 ID #
Sensor6:       .byte 8         ;DS1820 sensor 6 ID #
Sensor7:       .byte 8         ;DS1820 sensor 7 ID #


.cseg
.org    $000                   ;Reset Vector
        rjmp    Reset
   
 ;Interrupt vectors

.org    INT0addr               ;External Interrupt0 Vector
        reti
.org    INT1addr               ;External Interrupt1 Vector
        reti
.org    ICP1addr               ;Input Capture1 Interrupt Vector
        reti
.org    OC1addr                ;Output Compare1 Interrupt Vector Address
        reti
.org    OVF1addr               ;Overflow1 Interrupt Vector
        reti
.org    OVF0addr               ;Overflow0 Interrupt Vector
        rjmp    Tim0int
.org    URXCaddr               ;UART Receive Complete Interrupt Vector
        rjmp    ParseIn
.org    UDREaddr               ;UART Data Register Empty Interrupt Vector
        reti
.org    UTXCaddr               ;UART Transmit Complete Interrupt Vector
        reti
.org    ACIaddr                ;Analog Comparator Interrupt Vector
        reti
    

Reset:
        ldi    AReg,low(STACKTOP)
        out    SPL,AReg        ;set low byte for stack pointer
        rcall  Setup           ;set up DS1820 bits, Serial I/O

RPLoop:
        rjmp   RPLoop          ;wait here until something interesting happens
            
;********************************************** 
;* Setup                                      *
;* Initialize the 1-Wire bus  & serial port   *
;**********************************************
Setup:               
;** serial port setup **
        ldi    AReg,baudconstant     
        out    UBRR,AReg       ;load baudrate 
;**enable UART receiver & transmitter and IRQ on serial in:
        ldi    AReg, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)
        out    UCR,AReg        

        ldi    AReg,TSTOP      ;Timer 0 off (just in case)
        out    TCCR0,AReg      ;Stop timer
        ldi    AReg,0b00000010 ;Enable Timer 0 interrupt
        out    TIMSK,AReg

        sei                    ;enable interrupts
        rcall  GetROMS
        ret

;**********************************************
;* DS1820 Routines                            *
;**********************************************

;**********************************************
;* DSReset                                    *
;* Sends a reset pulse to all devices.        *
;* Returns carry set if devices present.      *
;* Returns carry clear if no devices present. *
;**********************************************
DSReset: 
        sbi    DDRB,DSBus      ;DDRB bit 2 = 1 = output
        cbi    PORTB,DSBus     ;set 1-wire bus low
        ldi    DelayVal,d250us
        rcall  Delay
        rcall  Delay           ;Wait 250us x 2 = 500 us
        cbi    DDRB,DSBus      ;Switch DS bus bit to input (pulled up high)
        sbi    PORTB,DSBus     ;turn on pullup
        ldi    DelayVal,d100us
        rcall  Delay           ;Wait 100 us for the DS1820 to respond
        clc                    ;exit with carry clear if no device
        sbis   PINB,DSBus      ;skip next if port B bit 2=1
        sec                    ;bit was clear (=0) so set carry flag  
        ldi    DelayVal,d250us
        rcall  Delay
        rcall  Delay           ;Wait 500 us
        ret
                                
;**********************************************
;* GetBit                                     *
;* Carry holds the bit from the DS1820 bus    *
;**********************************************
GetBit:
        ldi    DelayVal,d2us   ;wait for the 1820 data
        sbi    DDRB,DSBus      ;DDRB bit 2 = 1 = output
        cbi    PORTB,DSBus     ;set 1-wire bus low
        rcall  Delay
        cbi    DDRB,DSBus      ;DDRB bit 2 = 0 = input
        sbi    PORTB,DSBus     ;turn on pullup

        ldi    DelayVal,d15us  ;wait 15us for the 1820 data
        rcall  Delay
        clc                    ;assume 1-Wire bus is low
        sbic   PINB,DSBus
        sec                    ;1-Wire bus is high, so set carry flag 
        ldi    DelayVal,d44us
        rcall  Delay
        ret
        
;**********************************************
;* Write bit in CC to DS bus                  *
;**********************************************
PutBit:
        sbi    DDRB,DSBus      ;DDRB bit 2 = 1 = output
        cbi    PORTB,DSBus     ;Pull Port B, bit 2 low
        ldi    DelayVal,d15us  ;wait for the 1820 sample window
        rcall  Delay           
        brcc   Put0            ;if carry = 0, send a 0
        cbi    DDRB,DSBus      ;otherwise, send a 1
        sbi    PORTB,DSBus     ;turn on pullup
Put0:
        ldi    DelayVal,d44us  ;load 44us delay in delay register
        rcall  Delay           ;and wait
        cbi    DDRB,DSBus      ;this signals the end of a write 0
        sbi    PORTB,DSBus     ;turn on pullup
        ldi    DelayVal,d2us   ;let the DS1820 rest & digest
        rcall  Delay
        ret

;**********************************************
;* GetByte                                    *
;* AReg returns the byte from the DS1820 bus  *
;**********************************************
GetByte:
        ldi    BReg,8          ;bit count
        clr    AReg
NxtBit:
        rcall  GetBit
        ror    AReg            ;shift carry bit into AReg
        dec    BReg
        brne   NxtBit          ;repeat for all 8 bits
        ret

;**********************************************
;* PutByte                                    *
;* data in AReg                               *
;**********************************************
PutByte:
        ldi    BReg,8          ;bit counter
ShiftB:
        lsr    AReg            ;shift bits in AReg into carry
        rcall  PutBit
NextB:
        dec    BReg
        brne   ShiftB
        ret

;**********************************************
;* Search for devices on DS bus               *
;* Based on Dallas Semiconductor's ML6805     *
;* code.                                      *
;**********************************************
ROM1st:
        ldi    AReg,$41        ;Point Rom Search to top (1st part).
        mov    LastDis,AReg
        rcall  ROMSrch
        ret

ROMSrch:
        push   XL
        push   XH

        rcall  DSReset         ;Reset 1-wire bus.
        brcs   r_look
        rjmp   NoDev
r_look:
        ldi    AReg,$40        ;Prepare to find 64 bits of ROM data.
        mov    BitNum,AReg
        ldi    Count8,8        ;Initial value for eight counter.
        mov    LasDisCpy, LastDis ;Save copy of last dis. from last search.
        ldi    XL,low(romdta)
        ldi    XH,high(romdta) ;point to 1st byte of ROM data
        sts    romoff,XL       ;buffer in rombuff.
        sts    romoff+1,XH
        ldi    AReg,SearchROM  ;Get ROM search command in AReg.
        rcall  PutByte         ;Send ROM search command to DOW bus.

NxtRBit:
        clr    AReg
        clr    BReg
        rcall  GetBit          ;1st read time slot.
        rol    BReg            ;reg BReg, bit0 has first result
        rcall  GetBit          ;2nd read time slot.
        rol    AReg
        cpi    BReg,1          ;Was the first bit received 1?
        brne   no_or           ;Branch if it wasn't
        ori    AReg,2          ;Set bit 1 in AReg

no_or:
        cpi    AReg,3          ;See if error condition occurred.
        breq   NoDev           ;Abort if error.
        cpi    AReg,0          ;Was there a disagreement on bus.
        brne   nosave          ;Branch if there wasn't.
        cp     LasDisCpy,BitNum ;Compare last dis to current position.        
        brne   lwhere          ;If its not equal look some more.
        ldi    AReg,1          ;We've been on this path and sent a 0.
        rjmp   wrtBit          ;now lets send a 1.

lwhere:
        brcs   sLstBit         ;Stay on previous path.
        clr    AReg            ;Past last dis. fall to the right.
        rjmp   savedis         ;Send 0 to bus.
sLstBit:
        lds    XL,romoff       ;Get offset of ROM data buffer in
        lds    XH,romoff+1  
        ld     AReg,X          ;index register, and byte in AReg.
        andi   AReg,1          ;Isolate lsb of AReg.
        cpi    AReg,1          ;See if it was a 1.
        breq   wrtBit          ;Don't save as dis position if so.
savedis: 
        mov    LastDis,BitNum  ;Get current position in x register.
                               ;Save current last disagreement pos.
        rjmp   wrtBit          ;Send the write bit time slot.
nosave:
        ldi    BReg,1
        eor    AReg,BReg       ;Flip lsb of AReg.
wrtBit:
        andi   AReg,1          ;Isolate lsb of AReg
        mov    BReg,AReg
        lsr    BReg
        rcall  PutBit          ;Send lsb of AReg to 1-wire bus.
        lds    XL,romoff 
        lds    XH,romoff+1     ;Get offset into ROM data buffer.
        ld     AReg,X          ;Get previous val of rombyte.
        ror    AReg            ;Get ROM bit in MSB of rombyte.
        st     X,AReg          ;Store new byte value & point to next byte 
        dec    Count8          ;Decrement byte counter.
        brne   bnfull          ;Branch if we don't have full byte.
        adiw   XH:XL,1         ;increment x
        sts    romoff,XL       ;buffer in rombuff.
        sts    romoff+1,XH
        ldi    Count8,8        ;reload the eight counter.
bnfull:
        dec    BitNum          ;Decrement 64 bit counter.
        brne   NxtRBit         ;Go get next rom bit.
        cp     LasDisCpy,LastDis ;Compare to last dis. copy
        brne   MoDows          ;If not equal clear AReg.
        ldi    AReg,$41        ;Point ROM search algorithm back
        mov    LastDis,AReg    ;to first part.
        ldi    AReg,1          ;Indicate this was last part on bus.
        rjmp   lastdow         ;Skip the clra statement and leave.
MoDows:
        clr    AReg            ;Indicate that more parts are on bus.        
lastdow:
        sec                    ;Indicate success.
        rjmp   DevFnd          ;Skip clear carry stuff.
NoDev:
        clc                    ;Indicate failure.
DevFnd:
        pop    XH
        pop    XL
        ret

;********************************************** 
;* GetROMS                                    *
;* Looks for up to 8 DS1820s, reads their     *
;* 64 bit ROM codes and saves them in memory  *
;**********************************************
GetROMS:
        clr    AReg
        clr    ROMCount        ;clear out ROMCount
        clr    Done            ;clear Done flag
        ldi    YH,high(romdta)
        ldi    YL,low(romdta)  ;Y points to romdta buffer
ClrOut:
        st     Y+,AReg         ;clear out the ROM ID storage area
        cpi    YL,low(Sensor7+8)
        brcs   ClrOut
LookROM:
        rcall  DSReset         ;Reset 1-wire bus
;*** to send out the list of ROMs found, uncomment the line below
        brcc   SetExit         ;Abort if no presence detect
;*** to NOT send out the list of ROMs found, uncomment the line below
;        brcc   SetExit2       ;Abort if no presence detect 

        rcall  ROM1st          ;look for the first ROM
        mov    ScratchL,AReg
        brcc   SetExit         ;if AReg = 0 then there are more devices
        ldi    XH,high(Sensor0)
        ldi    XL,low(Sensor0) ;X points to first device ID  
        rjmp   MR0             ;process them & exit
LR1:
        rcall  ROMSrch         ;look for other devices
        mov    ScratchL,AReg
        breq   MR0             ;if AReg = 0 then there are more devices
        inc    Done
MR0:
        ldi    YH,high(romdta+8)
        ldi    YL,low(romdta+8) ;Y points to ROM just read
MoveROM:
        ld     AReg,-Y         ;move byte from romdta
        st     X+,AReg         ;to SensorX
        cpi    YL,low(romdta)  ;move all 8 bytes
        brne   MoveROM         ;of the ROM ID
        inc    ROMCount        ;increment the ROM counter
        tst    ScratchL        ;repeat until the last device found
        breq   MR2
        inc    Done
MR2:
        tst    Done
        brne   SetExit
        cpi    XL,low(Sensor7+8) ;or until the end of the ROM
        brcs   LR1             ;storage area is reached                     
SetExit:
        rcall  ShowROM         ;then Display the ROM IDs
SetExit2:
        ret

;********************************************** 
;* ShowROM                                    *
;* Converts data in the Sensor area to ASCII  *
;* hex and send them out the serial port.     *
;**********************************************
ShowROM:
        ldi    XL,low(Sensor0) ;X points to Sensor ID area
        ldi    XH,high(Sensor0)
SRLoop:
        ldi    YL,low(Buffer)  ;Y points to ASCII data buffer
        ldi    YH,high(Buffer)
        ldi    ByteCount,8
ROMHex:
        ld     AReg,X+         ;convert 8 bytes to 16 ASCII Hex
        rcall  Put1Hex         ;characters
        dec    ByteCount
        brne   ROMHex       

        ldi    YL,low(Buffer) 
        ldi    YH,high(Buffer)
ROMOut:
        ld     AReg,Y+         ;send characters in the buffer     
        rcall  SerOut          ;to the serial port

        cpi    YL,low(Buffer+16)
        brcs   ROMOut
        clr    AReg
        st     Y,AReg

 
      и т д


--------------------
тут могла быть Ваша реклама...
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.1212 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.