Змей-Горыныч » 29 мар 2005, 06:38
Ну, на статью это пожалуй не потянет, но может кому и облегчит знакомство с этими устройствами.
Итак, вот фрагмент кода для AVR, который позволяет загрузить необходимое значение сопротивления в цифровой резистор AD8404 или любой другой, имеющий 10-битный последовательный синхронный интерфейс (или SPI).
В переменной AdresRezist содержится адрес резистора в микросхеме (2 бита), так как в одном корпусе может быть несколько потенциометров.
В переменной CodRezist соответственно заданое значение сопротивления (8 бит). Для вывода требуются 4 линии порта. А если вы не хотите посылать согнал сброса, то можно и тремя обойтись.
.equ SPI_PORT = PORTA ;Порт для вывода
.equ SDI = 0 ;Данные
.equ CLK = 1 ;Тактовый сигнал (по возр. фронту)
.equ CS = 2 ;Разрешение ("0" - разрешено)
.equ RS = 3 ;Сброс ("0" на 50 нс)
;______________ Переменные ____________________
.def temp = R16
.def CodRezist = R17 ;Заданое значение сопротивления
.def AdresRezist = R18 ;Адрес резистора в микросхеме
;Загрузка значения в AD8402
;Адрес
sbi SPI_PORT,RS ;Линию сброса в "1"
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
cbi SPI_PORT,CS ;Разрешение записи в микр.
cbi SPI_PORT,SDI ;Старший бит адреса A1 = 0
sbrc AdresRezist,1 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Старший бит данных A1 = 1
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Младший бит адреса A0 = 0
sbrc AdresRezist,0 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Младший бит данных A0 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
;Данные
cbi SPI_PORT,SDI ;Бит данных D7 = 0
sbrc CodRezist,7 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D7 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D6 = 0
sbrc CodRezist,6 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D6 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D5 = 0
sbrc CodRezist,5 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D5 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D4 = 0
sbrc CodRezist,4 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D4 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D3 = 0
sbrc CodRezist,3 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D3 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D2 = 0
sbrc CodRezist,2 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D2 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D1 = 0
sbrc CodRezist,1 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D1 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
cbi SPI_PORT,SDI ;Бит данных D0 = 0
sbrc CodRezist,0 ;Пропустить if бит в Rd очищен
sbi SPI_PORT,SDI ;Бит данных D0 = 1
cbi SPI_PORT,CLK ;В "0" линию тактового сигнала
sbi SPI_PORT,CLK ;"1" линию тактового сигнала (захват)
sbi SPI_PORT,CS ;Конец записи в микр.
ret
Поскольку интерфейс синхронный, не используются никикие задержки, програмные или по таймеру. Соответственно работать можно с любой тактовой частотой.
P.S. Уверен что кто-нибудь может сделать лучше. Это мой первый опыт. Я собирал регулируемый источник питания, с задаваемым с компа значением напряжения.
Выходное U оцифровывалось AVR контроллером, и в зависимости от его величины регулировалось сопротивление в цепи обратной связи (значение в переменной CodRezist).
Точность Uвых у меня полутилась +/- 0,02 В.