Easy_I2C AVR ASM практикум PCF8591 & DS1307

AVR
PCF8591 это микросхема в которой 4 АЦП и 1 ЦАП на скорости до 100кГц по i2c
Вот я добрался до неё. Она, как мне казалось, не самая простая микросхема однако сложного в ней по сути ничего нет.
Единственное это «КОНТРОЛЬ БАЙТ» с которым проще разбираться когда уже начинаешь ставить эксперименты нежели когда читаешь даташит. Я же, не зная этого, изучал даташит может и не напрасно. Заодно зацепил DS1307 — та самая микросхема часиков. Напомню в очередной раз что я не преследую цели написания проекта имеющего какой-то практический смысл поэтому задания формируются самые простые, чтобы просто самому разобраться как работать с этими микросхемами. Вот какое задание на этот раз для изучения PCF8591 & DS1307:
Клавиша PCF8574key          |выполняемая функция для PCF8574led
----------------------------|-----------------------------------
Р0			    |вывести значение с PCF8591(AIN0)
Р1			    |вывести значение с PCF8591(AIN1)
Р2			    |вывести значение с PCF8591(AIN2)
Р3			    |вывести значение с PCF8591(AIN3)
Р4			    |вкл/вык отображение текущего значения
			    |на ЦАП - PCF8591(AOUT) 
Р5			    |вывести значение секунд с DS1307 	
Р6			    |вывести значение минут с DS1307 
Р7			    |вывести значение часов с DS1307 


Опрос каналов АЦП будет производится 10 раз в секунду. Выводится на ЦАП и светодиоды с этой же частотой. Опрос часиков 1 раз в секунду по прерыванию от самой DS1307 (вывод на ЦАП и светодиоды также 10 раз в сек).
Теперь «схема» по которой я подключал PCF8591

Схему на часики рисовать нет необходимости — там все по ДШ кроме батарейки.
Теперь немного по программе. Регистр (i2c_want_job) заданий для И2С у меня теперь увеличился до шести флагов. Вот его биты управления

i2c_want_job:	.byte	1	;флаговый регистр заданий шины и2ц чем младше бит тем он важнее в задании
		   0b 0 0 x x x x x x
		          | | | | | |_key_flag 
			  | | | | |___key_real
		          | | | |_____led_flag 
			  | | |_______time_flag
			  | |_________adc_flag
			  |___________dac_flag

key_real — не запускает шину ни на какие задания он просто нужен для того чтобы запустить анализ принятого байта от микросхемы клавиатуры PCF8574key и дабы не плодить лишние флаги вставил в этот регистр и кстати оказалось очень удобно. Все остальные биты запускают шину на опрос/запись соответствующей ему микросхеме (из названий я думаю понятно). Порядок опроса битов такой же от младшего к старшему. Теперь о том как зажигаются эти биты:
key_flag и time_flag как уже говорил от внешних прерываний INT0 INT1

		PUSHF	;прерывание от PCF8574key	
		SETB i2c_want_job,key_flag,temp
		POPF
		RETI
		
                PUSHF	;прерывание от часиков	
		SETB i2c_want_job,time_flag,temp
		POPF
		RETI

adc_flag зажигается после трех СТС Таймера0 значением 250 и делителем 1024. (запустит опрос АЦП каналов (PCF8591)
led_flag зажигается после каждого запуска шины на опрос АЦП каналов (PCF8591)
dac_flag зажигается тоже после запуска шины на опрос АЦП но лишь в том случае если ANALOGUE OUTPUT ENABLE FLAG (тот что в CONTROL BYTE у PCF8591) равен 1 те разрешен вывод значений в ЦАП а иначе нет смысла туда что-то грузить

Процедуры обработки этих флагов очень простенькие, короткие и однотипные
1. Проверить флаг процедуры. если =0 то переходим к следующей процедуре
2. Проверить регистр в РАМе i2c_busy, если =1 то шина И2С сейчас уже кем то занята и мы идем на выход
3. Очистить флаг процедуры
4. Сформировать задание для И2С и запустить шину
5. Установить другие флаги если необходимо
Теперь самое время сказать пару слов о CONTROL BYTE
Вообще его надо воспринимать как «адрес по которому обращаемся». Я например его приклеивал при любом обращении независимо читаю или пишу PCF8591.
bit6 — ANALOGUE OUTPUT ENABLE FLAG если =1 то при записи в PCF8591 значения оно выведется на выход AOUT
bit4 и bit5 — конфигурация аналоговых входов (у меня они = 00)
bit2 — AUTO-INCREMENT FLAG если =1 то PCF8591 будет выдавать значения АЦП по очереди один за другим возвращаясь к AIN0 (у меня =1 поскольку я решил читать все 4 значения сразу — так на мой взгляд проще)
Теперь то в чем я не разобрался и не понял почему именно так:
bit0 и bit1 — A/D CHANNEL NUMBER как я думал здесь указыввается номер канала с которого мне надо начать получать данные и я их сделал =00 т.е. с AIN0 (так по ДШ), однако почему-то значения начинают выдаваться начиная с предыдущего канала т.е. с AIN3. Для того чтобы получать с AIN0 пришлось задать значение =01.
Еще меня сильно удивил тот факт что PCF8591 нормально работает только на скорости до 100кГц — прям как по даташиту, а вот микросхема часиков DS1307 спокойно шуршит на 480кГц хотя по ДШ — 100кГц

Инициализация DS1307 построена просто:
Вносится 9 значений в i2c_Buffer_out (первое 0х00 чтобы начать запись с нулевого адреса и 8 данных) и как обычно отправляется в DS1307. Для удобства свернул в макрос «init_DS1307»

З.Ы. В прерывании TWI обнаружилось 2 ошибки которые на прошлых программах проходили мимо но здесь попались поскольку используется режим с предварительной адресацией которого там не было. В прошлых постах они так же исправлены. Проект сделан в Студии6
Вот видео того как это работает. Резисторы от какой то советской техники и как бы скрипят реально + канал 4 сильно дребезжит.

Как всегда готов выслушать порцию критики в комментариях.
  • +1
  • 02 февраля 2014, 22:14
  • deses
  • 1
Файлы в топике: I2C_pcf8591P.zip

Комментарии (5)

RSS свернуть / развернуть
Что за зверь PCF8591?
0
  • avatar
  • Vga
  • 02 февраля 2014, 22:32
4 АЦП 8бит + 1 ЦАП 8бит
0
В начало статьи это перенеси? Очень неудобно искать ДШ тольк для того, чтобы это узнать.
Ещё полезно было бы объяснить, зачем нужна такая внешняя АЦП/ЦАП для МК, где уже есть АЦП/ЦАП.
+1
8-bit DAC / ADC с частотой 11.1 кГц в дипе или со16?

what year is it?
0
Да это для меня навроде светодиодом поморгать. А так никакого практического смысла, и2с изучаю.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.