;************************************************************************** ;* File Name :HFRXV11.asm ;* Title :I2C für TSA6057 / TSA6060 ;* Date :Ingo Gerlach DH1AAD/ 21.07.99 ;* ;* Änderungen : ;* 1.1 14.03.01 , div. Anpassungen HW Version 8.1 ;* Version :1.0 / 21.08.99 , ein Kanal ;* Target MCU :AT90S2313 (90S1200) ;* ;* Benötigt : i2c.inc (c) Claus Kühnel http://www.ckuehnel.ch/ ;*************************************************************************** ;***** Directives .device AT90S2313 ;Device Type ;.device AT90S1200 .NOLIST .include "2313def.inc" ;.include "1200def.inc" .list .listmac ; ; Main Program Register variables ;--------------------------------------------------------------------------- .def temp = r16 .def chan = r26 .def toggle = r28 .def db0 = r22 .def db1 = r24 .def db2 = r25 ; TSA6057 spez. Daten .equ TSA = 196 ; Adresse .equ SUB_ADR = 0 ; Subadress = 0 .equ db3 = 0 ; db3 = 0 .equ multi = 3 ; Multi f. EEPROM Adr. ; Registers used by I2C ; define in calling program as needed (must be >= r16) ;--------------------------------------------------------------------------- .def bitcntr = r20 ; bit counter .def i2c_del = r21 ; delay loop variable .def i2c_buffer = r27 ; async serial data byte transmit/received .def bus_check = r23 ; check for bus idle ;--------------------------------------------------------------------------- .equ i2c_delay = 50 ; wait 4.75 us at 4 MHz 25 .equ i2c_port = PORTD ; port supporting i2c .equ i2c_pins = PIND ; port pins supporting i2c .equ i2c_ddr = DDRD ; data direction register for port .equ sda = 0 ; bit within port for serial data in .equ scl = 1 ; bit within port for serial data out ;***** Interrupt vector table reset: rjmp main ; Main routine rjmp int0isr ; External Interrupt0 handle, Signal liegt an, L reti ; External Interrupt1 handle, ScanTaste H reti ; T/C1 Capture Event Interrupt handle reti ; T/C1 CompareA Interrupt handle reti ; T/C1 Overflow Interrupt handle reti ; T/C0 Overflow Interrupt handle reti ; UART Rx Complete Interrupt handle reti ; UART Data Register Empty Interrupt handle reti ; UART Tx Complete Interrupt handle reti ; Analog Comparator Interrupt handle ;***** Functionen ********************************************************* ;*************************************************************************** ;* ;* "mpy8u" - 8x8 Bit Unsigned Multiplication ;* ;* This subroutine multiplies the two register variables mp8u and mc8u. ;* The result is placed in registers m8uH, m8uL ;* ;* Number of words :9 + return ;* Number of cycles :58 + return ;* Low registers used :None ;* High registers used :4 (mp8u,mc8u/m8uL,m8uH,mcnt8u) ;* ;* Note: Result Low byte and the multiplier share the same register. ;* This causes the multiplier to be overwritten by the result. ;* ;*************************************************************************** ;***** Subroutine Register Variables .def mc8u =r16 ;multiplicand .def mp8u =r17 ;multiplier .def m8uL =r17 ;result Low byte .def m8uH =r18 ;result High byte .def mcnt8u =r19 ;loop counter ;***** Code mpy8u: clr m8uH ;clear result High byte ldi mcnt8u,8 ;init loop counter lsr mp8u ;rotate multiplier m8u_1: brcc m8u_2 ;carry set add m8uH,mc8u ; add multiplicand to result High byte m8u_2: ror m8uH ;rotate right result High byte ror m8uL ;rotate right result L byte and multiplier dec mcnt8u ;decrement loop counter brne m8u_1 ;if not done, loop more ret ;** "Ende 8x8 Bit Unsigned Multiplication*** ;*************************************************************************** ;* ;* "SetFreq 1.0" ;* Setzt Teiler ;* ;* ;*************************************************************************** SetFreq: rcall i2c_setup rcall i2c_start ; I2C Start Condition ldi i2c_buffer,TSA ; 1. Modul Adresse rcall i2c_write ; Write Slave address ldi i2c_buffer,SUB_ADR ; 2. SubAdress , fest auf 0 rcall i2c_write ; Write Word address mov i2c_buffer,db0 ; db0 rcall i2c_write ; Write Word address mov i2c_buffer,db1 ; db1 ; rcall i2c_write ; Write Word address mov i2c_buffer,db2 ; db2 rcall i2c_write ; Write Word address ldi i2c_buffer,db3 ; db3 rcall i2c_write ; Write Word address ret ;***** SetFreq Ende ****** ;*************************************************************************** ;* ;* "ReadEEP 1.0" ;* Liest EEProm aus ;* ;* ;*************************************************************************** ReadEEp: mov temp,R17 ; Eprom lesen out EEAR,temp ; Adresse sbi EECR,0 ; Lesen in db0,EEDR inc temp out EEAR,temp ; Adresse sbi EECR,0 ; Lesen in db1,EEDR inc temp out EEAR,temp ; Adresse sbi EECR,0 ; Lesen in db2,EEDR ret ;***** Main ******************************** main: ldi temp, LOW(RAMEND) ; StackPointer Setup out SPL, temp ; Initialize SPL . nicht 90S1200 ldi toggle,0 ; LED 0 = aus clr temp ; temp = 00 out ddrb,temp ; Port B als Eingang in chan,PinB ; PortB einlesen, BCD Schalter Stellung cbi DDRD,2 ; ScanControl Input sbi DDRD,4 ; LED to output mov mc8u,chan ; Channel in R26 ldi mp8u,multi ; Multi für EEProm Adresse rcall mpy8u ; result: in R17 rcall ReadEEP rcall SetFreq rcall SetFreq ;***** Interrupt mask setup ********************* ldi temp,0b01000000 ; INT0 mask out GIMSK,temp ldi temp,0b00000000 ; INT0 falling edge mask out MCUCR,temp SEI ; Global interrupt enable mainloop: in temp,PinB ; PortB einlesen, BCD Schalter Stellung cp temp,chan ; Kanal geändert ? breq mainloop ; nein, dann Schleife mov chan,temp ; sonst neu setzen mov mc8u,chan ; Channel in R26 ldi mp8u,multi ; Multi für EEProm Adresse rcall mpy8u ; result: in R17 rcall ReadEEP rcall SetFreq ; wenn nur einmal, wird mitunter rcall SetFreq ; die Freq. nicht korrekt geschaltet!? rcall i2c_stop ; I2C Stop Condition forever: rjmp mainloop ; ***** Ende MainProgramm ******************* ;*** (Int0-Signal liegt an **************** .def ac_tmp =r0 ;temporary storage register for SREG int0isr: cli ; Global interrupt disable in ac_tmp,SREG ; temporarily store the Status register ldi temp,0b01000000 ; Clear general interrupt flag register out GIFR,temp cpi toggle,0 ; beide 0, LED aus ? ja dann einschalten brne iloop_1 ; sonst ausschalten inc toggle ; toggle = 1 sbi PortD,4 ; LED einschalten ldi temp,0b00000011 ; INT0 rising edge mask, H=kein Signal out MCUCR,temp rjmp iloop ; iloop_1: ldi toggle,0 cbi PortD,4 ; LED aus ldi temp,0b00000000 ; INT0 low level mask out MCUCR,temp iloop: out SREG,ac_tmp ; restore Status register reti ; Global interrupt enable and return ; **** Ende Int0ISR ********** ; *** Include Files *** .include "i2c.inc" ; *** Eprom Daten *** .ESEG .org 0x00 echan0: .db 223,48,160 ; 145,675 / 25 KHz , VCO +10.7 MHz echan1: .db 225,48,160 ; 145,700 / 25 KHz , VCO +10.7 MHz echan2: .db 227,48,160 ; 145,725 / 25 KHz , VCO +10.7 MHz echan3: .db 229,48,160 ; 145,750 / 25 KHz , VCO +10.7 MHz echan4: .db 231,48,160 ; 145,775 / 25 KHz , VCO +10.7 MHz echan5: .db 232,48,160 ; 145,800 / 25 KHz , VCO +10.7 MHz echan6: .db 197,48,160 ; 145,350 / 25 KHz , VCO +10.7 MHz echan7: .db 235,49,160 ; 149,025 / 25 KHz , VCO +10.7 MHz echan8: .db 205,124,96 ; 149,040 / 10 KHz , VCO +10.7 MHz echan9: .db 237,49,160 ; 149,025 / 25 KHz , VCO +10.7 MHz ; **** EEProm Daten Ende ************************* ; **** SRAM Daten *** ; **** SRAM Daten Ende ***************************