Код:
;----------------------------------------------------------------------------
;Title : FC-510 prescaler (LMX2306)
;Version: 1.00
;Target : ATtiny2313
;Author : wubblick@yahoo.com
;AVR Assembler 2.0
;----------------------------------------------------------------------------
.include "tn2313def.inc"
;----------------------------------------------------------------------------
;Константы:
.equ N = 100 ;желаемый коэффициент деления
.equ PRE = 8 ;коэффициент деления встроенного прескалера
.equ NR = 3 ;коэффициент деления Ref (не используется)
.equ FO = 2 ;FoLD = N divider output
.equ NB = (N / PRE)
.equ NA = (N - NB * PRE)
.if (NA > NB) || (NB < 3) || (NB > 8191)
.error "Недопустимый коэффициент деления!"
.endif
;Биты регистра R:
.equ R_CNTR = (NR << 2) ;значение счетчика R (3..16383)
.equ R_ADDR = (0 << 0) ;адрес регистра R
;Биты регистра N:
.equ NB_CNTR = (NB << 7) ;значение счетчика NB (3..8191)
.equ NA_CNTR = (NA << 2) ;значение счетчика NA (0..7)
.equ N_ADDR = (1 << 0) ;адрес регистра N
;Биты регистра F:
.equ FFOLD = (FO << 4) ;FoLD control
.equ F_ADDR = (3 << 0) ;адрес регистра F + Init
;Код для загрузки в регистр R:
.equ REG_R = R_CNTR | R_ADDR
;Код для загрузки в регистр N:
.equ REG_N = NB_CNTR | NA_CNTR | N_ADDR
;Код для загрузки в регистр F:
.equ REG_F = FFOLD | F_ADDR
;----------------------------------------------------------------------------
;Ports definition:
.equ LE = PB7 ;сигнал LE
.equ SDATA = PD0 ;сигнал SDATA
.equ SCLK = PD1 ;сигнал SCLK
;Направление порта B:
.equ DIRB = (1 << LE)
;Начальное состояние/пуллапы:
.equ PUPB = 0xFF
;Направление порта D:
.equ DIRD = (1 << SDATA) | (1 << SCLK)
;Начальное состояние/пуллапы:
.equ PUPD = 0xFF
;----------------------------------------------------------------------------
;Глобальные регистровые переменные:
.def tempL = r16
.def tempM = r17
.def tempH = r18
.def Cnt = r19
;----------------------------------------------------------------------------
.CSEG
.org 0
;Инициализация:
ldi tempL,RAMEND
out SPL,tempL
ldi tempL,PUPB
out PORTB,tempL
ldi tempL,DIRB
out DDRB,tempL
ldi tempL,PUPD
out PORTD,tempL
ldi tempL,DIRD
out DDRD,tempL
;Основная программа:
Main:
;Загрузка регистра F:
ldi tempL,byte1(REG_F)
ldi tempM,byte2(REG_F)
ldi tempH,byte3(REG_F)
rcall SPI_Load
;Загрузка регистра R:
ldi tempL,byte1(REG_R)
ldi tempM,byte2(REG_R)
ldi tempH,byte3(REG_R)
rcall SPI_Load
;Загрузка регистра N:
ldi tempL,byte1(REG_N)
ldi tempM,byte2(REG_N)
ldi tempH,byte3(REG_N)
rcall SPI_Load
sleep
rjmp Main
;----------------------------------------------------------------------------
;Загрузка слова 21 бита из tempH:tempM:tempL по SPI:
SPI_Load:
cbi PORTB,LE ;LE = 0
ldi Cnt,21
Loop:
cbi PORTD,SCLK ;SCLK = 0
sbrc tempH,1
rjmp data1
data0:
cbi PORTD,SDATA ;SDATA = 0 или
rjmp dataX
data1:
sbi PORTD,SDATA ;SDATA = 1
dataX:
lsl TempL
rol TempM
rol TempH
sbi PORTD,SCLK ;SCLK = 1
dec Cnt
brne Loop
sbi PORTD,SDATA ;SDATA = 1
sbi PORTB,LE ;LE = 1
ret
;----------------------------------------------------------------------------