Технический форум по робототехнике.
Змей-Горыныч » 10 мар 2005, 14:12
Может посоветует кто сталкивался...
Задача такая:
Нужно подключить к AVR микроконтроллеру интегральный резистор с цифровым управлением типа AD8402. Для управления им используется 3-х проводный (SPI-совместимый, как написано в описании
http://www.promelec.ru/pdf/ad8400_2_3_c.pdf ) интерфейс. Два старших бита это адрес потенциометра, и 8 бит - код управления. Так вот, разве можно из порта SPI контроллера послать 10 бит? Там же всего 8-разрядный регистр сдвига. Или можно както обмануть его. Я просто до этого не сталкивался с SPI.
Предвижу предложение использовать просто 3 линии одного из портов... может быть так и придётся сделать.
Mike_MA » 10 мар 2005, 15:08
Я порекомендовал не париться.... Как я понимаю, сначала надо послать байт данных, а потом адрес. .... Собственно не вижу проблемы....посылаешь один байт, потом пишешь туда же второй, отсчитываешь два периода и отключаешь передачу. Т.е. заведя сигнал CLK на одну из ног и считай переданные битики...
Змей-Горыныч » 10 мар 2005, 15:35
Не понял.
Суть не в посилке двух байт, это то как раз не проблемма. А суть в том, что надо сразу в одной последовательности послать 10 бит (причем первые два - адрес, последующие 8 - данные). См. рис.
- Вложения
-
- Вот как это должно выглядеть.
- byte.JPG (9.41 КиБ) Просмотров: 10124
RoboAlex » 11 мар 2005, 10:30
Проще всего - реализовать програмно. если контроллер под это "не заточен", то заставить его трудно. В частности, каким образом определить, когда переданы только 2 бита ? Прерывания такого нет.
SPI ведь синхронный интерфейс, скорость передачи определяет мастер (вы). Если у вас контроллер не перегружен задачами, лучше самому написать ф-цию посылки
Mike_MA » 11 мар 2005, 12:29
Змей-Горыныч писал(а): А суть в том, что надо сразу в одной последовательности послать 10 бит (причем первые два - адрес, последующие 8 - данные). См. рис.
А 10 бит в 8-ми разрядный регистр не засунешь. Либо вешаешь сигнал "CLK" на вход внешнего прерывания и считаешь переданные биты, или управляешь сигналом "CS". Можно использовать и то и то.
Змей-Горыныч » 14 мар 2005, 14:06
RoboAlex писал(а):SPI ведь синхронный интерфейс, скорость передачи определяет мастер (вы). Если у вас контроллер не перегружен задачами, лучше самому написать ф-цию посылки
Спасибо. Я так и предполагал. Вы подтвердили мои догадки. Что ж реализую сам это дело програмно. Уже придумал как передовать биты в соответствии с их порядком в нужном регистре.
Змей-Горыныч » 16 мар 2005, 09:18
Ну, в общем сделал я это дело! :lol:
Кстати очень понравились цифровые резисторы. Запросто (и главное дёшево!) можно с их помощью АЦП сварганить.
В общем рекомендую. Может кого заинтересует, вот кратко чего они умеют:
AD5204/ AD5206 является 256 позиционным четырех-/ шестиканальным 8 битным цифровым переменным резистором (VR) с цифровым управлением. Эти устройства исполняют ту же самую электронную функцию настройки как потенциометр или регулируемый резистор. Каждый канал AD5204/AD5206 содержит установленный резистор с контактом движка, который устанавливается в точку, определяемую цифровым кодом, загруженным во входной регистр по SPI - совместимому последовательному интерфейсу. Сопротивление между движком и любым выводом цифрового резистора изменяется линейно в соответствии с цифровым кодом, загруженным во входной регистр VR. Регулировочный движок устанавливается в любое положение от одного вывода до другого. Фиксированное сопротивление между выводами А и В имеет значение 10 кОм, 50 кОм, или 100 кОм и имеет номинальный температурный коэффициент сопротивления 700 ррm/ °C.
Каждый VR имеет свой собственный регистр VR, который содержит кодовое значение сопротивления. Эти регистры VR обновляются от внутреннего последовательно- параллельного регистра сдвига, который загружается по стандартному 3 проводному цифровому SPI интерфейсу. Одиннадцать информационных бит составляют информационное слово, загружаемое во входной регистр синхронно. Первые три бита содержат информацию о номере загружаемого регистра VR, последующие восемь бит содержат информацию о положении движка потенциометра, в который он устанавливается при возвращении стробирующего сигнала CS в высокое состояние. Вывод в противоположном конце последовательного регистра (только у AD5204) позволяет просто организовать последовательную цепочку данных для множества VR без применения дополнительной декодирующей логики.
setar » 16 мар 2005, 12:16
А не затруднит ли в виде обучающей статейки с кодом оформить?
что то вроде "Управление цифровым потенциометром с помощью AVR"
Змей-Горыныч » 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 В.
Stepan » 16 апр 2005, 21:18
Змей-Горыныч писал(а):Кстати очень понравились цифровые резисторы. Запросто (и главное дёшево!) можно с их помощью АЦП сварганить.
По-моему ещё проще и дешевле с помощью ШИМа.
Nihilant » 28 авг 2006, 11:57
У меня похожая задача, только передать надо серию байт. Контроллер - Мега8. Там есть SPI. Надо переслать 5 байт в контроллер LCD от кассового аппарата COP472N-3.
Loading Sequence у него такой, что после опускания !CS надо послать 4 байта для цифр и байт служебной информации. И только потом на !CS выставить высокий уровень. Насколько я понял, Мега моя будет после каждого байта !CS дергать. Поэтому планирую такой алгоритм:
установить ногу, на которой !CS в 1
НЦ (бесконечного)
дернуть ногу, на которой !CS в 0
отправить 1-й байт, ждать прерывания SPI
...
отправить 5-й байт, ждать прерывания SPI
дернуть ногу, на которой !CS в 1
КЦ
причем нога, на которую вешаем !CS, не совпадает со штатной !CS от Меги
Буду благодарен за любые замечания.
Nihilant » 28 авг 2006, 11:57
У меня похожая задача, только передать надо серию байт. Контроллер - Мега8. Там есть SPI. Надо переслать 5 байт в контроллер LCD от кассового аппарата COP472N-3 с интерфейсом Microwire(tm).
Loading Sequence у него такой, что после опускания !CS надо послать 4 байта для цифр и байт служебной информации. И только потом на !CS выставить высокий уровень. Насколько я понял, Мега моя будет после каждого байта !CS дергать. Поэтому планирую такой алгоритм:
установить ногу, на которой !CS в 1
НЦ (бесконечного)
получить по UART 5 байт
дернуть ногу, на которой !CS в 0
отправить 1-й байт, ждать прерывания SPI
...
отправить 5-й байт, ждать прерывания SPI
дернуть ногу, на которой !CS в 1
КЦ
причем нога, на которую вешаем !CS, не совпадает со штатной !CS от Меги
Буду благодарен за любые замечания.
J.Joker » 28 мар 2010, 17:34
Добрый день, не могли бы Вы мне помочь с моим проектом. Я программно реализовал SPI, но потенциометр реагирует слабо, то есть изменения буквально в сотых долях (в модели, в реальности напряжение вообще не меняется). Подскажите пожалуйста, где я ошибся.
- Вложения
-
- SPI.rar
- схема, файлы для Proteus 7.6 и исходники для CV AVR
- (125.5 КиБ) Скачиваний: 0
tsrodger » 29 мар 2010, 07:57
нельзя вешать напрямую на резистор такую нагрузку, поставьте буфер хотя бы на операционике