PIC16F876A и АЦП
|
|
Klim |
Дата: Пн, 16.01.2012, 15:21 | Сообщение # 16 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Т.е. я правильно понимаю, что цепляюсь к PORTA.0, выставляю биты (опорное напряжение идет внутреннее) и читаю порт? Больше ничего цеплять не надо? Порт при этом оформляем как цифровой?
Добавлено (16.01.2012, 15.21.42) --------------------------------------------- И че-то я врубиться не могу, что в PIC16F876A нет компаратора? P.S. Покурил даташит, действительно нету... Странно в 628а есть, а тут нет...
Вот наваял схему и софт, но почему-то не работает... Может кто-то поправит? Задуманный принцип отловить прерывание по компаратору. Но почему-то прерывание не наступает...
Сообщение отредактировал
Klim - Пн, 16.01.2012, 17:31
|
|
|
|
retas |
Дата: Пн, 16.01.2012, 21:46 | Сообщение # 17 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
Klim, кидай курить! Смотри прицеп и 135стр.
'-------------------------- Регистры специального назначения------------------- CMCON = %00000010 ' Настроим компаратор VRCON = %10001001 ' Установим напряжение срабатывания 1.88-2.66 вольт - либо 1,88 либо 2,66 зависимо от 5ого бита (для 1ого компара) - если эта напруга будет превышена, должен сработать первый компар.
'-------------------------- Прерывания-------------------------- Int_Label: If CMIF = 1 then ... ' привыкай к порядку - мало ли из за чего может наступить прерыв Context Save '
CMIF = 0 ' Сбросим флаг прерывания по компаратору Context Restore ' Возврат из обработчика прерывания
А как ты определил что компар не срабатывает?
|
|
|
|
Klim |
Дата: Вт, 17.01.2012, 10:38 | Сообщение # 18 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Спасибо, с горем пополам с компараторами разобрался. Действительно в 16F876A есть два компаратора, просто там другой регистр , который отвечает за опорное напряжение (CVRCON), это и ввело меня в заблуждение. Компаратор теперь срабатывает. Зато возникла новая проблема... Все это работает, я пытаюсь вычислить длительность одного импульса. Подключил к порту генератор синусоиды, настроил таймер TMR1 на 10 микросекунд (хотя в идеале нужно на 5). А он, собака, отсчитывает мне только 2 при частоте 100 герц... Я понимаю, что где-то в софте нахомутал, но не пойму, где. Я заранее извиняюсь, за то, что уже задолбал всех здесь, но очень хочется згрысть камень науки . Файлы прилагаю.
Сообщение отредактировал
Klim - Вт, 17.01.2012, 10:39
|
|
|
|
ivan_fd |
Дата: Вт, 17.01.2012, 12:26 | Сообщение # 19 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
Посмотрел на Ваш код, и мало что понял. Что он должен делать?
В Вашем коде прерывание от компаратора отключено, и что бы сбросить флаг прерывания от компаратора, нужно сначала прочитать значение регистра CMCON.
|
|
|
|
Klim |
Дата: Вт, 17.01.2012, 12:56 | Сообщение # 20 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Извиняюсь, я случайно не тот файл сбросил. Сейчас поправлю.
Вот, что я хотел:
Левый проц при нажатии на кнопку формирует импульс длительностью 100 милисекунд. Правый проц должен замерить эту длительность.
Сообщение отредактировал
Klim - Вт, 17.01.2012, 13:20
|
|
|
|
ivan_fd |
Дата: Вт, 17.01.2012, 13:17 | Сообщение # 21 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
Посмотрел еще Ваш код. У Вас опорное настроено на на 2.66В. При переходе синуса за >2.66В срабатывает прерывание и при переходе синуса <2.66В так же срабатывает прерывание. Вам, что нужно вычислить, сколько времени будет держать больше 2.66В или меньше? Еще, в прерывании по таймеру нужно выставить значение для таймера, иначе он начинает считать от 0.
|
|
|
|
Klim |
Дата: Вт, 17.01.2012, 13:23 | Сообщение # 22 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Должен читать длительность превышения напряжения. Вот накропал. Левый проц при нажатии на кнопку выдает одиночный импульс длительностью 100 милисекунд. Правый должен считать эту длительность. Но ничего не происходит.
Сообщение отредактировал
Klim - Вт, 17.01.2012, 13:23
|
|
|
|
ivan_fd |
Дата: Вт, 17.01.2012, 14:06 | Сообщение # 23 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
Посмотрите, может так пойдет.
|
|
|
|
Klim |
Дата: Ср, 18.01.2012, 10:51 | Сообщение # 24 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Огромное спасибо. Пошаманил немного и все заработало. Приведу все в порядок и выложу, чтоб и другие могли посмотреть и разобраться. Люди, а случайно ни у кого нету таблицы опорных напряжений на регистр CVRCON (PIC16F886A), по ходу он отличается от регистра VRCON (PIC16F628A)?
Добавлено (18.01.2012, 10.51.17) --------------------------------------------- Все отладил и все работает. На один 120-и микросекундный импульс делает ровно 8 отсчетов, на 60-и микросекундный 4 отсчета, что очень даже хорошо. Работает четко. Но вот беда, взят тот же код, исправил все под PIC16F876A (пришлось подправить регистр компараторов CMCON и регистр опорного напряжения VRCON заменить на CVRCON) и началась ахинея... Сейчас приеду на работу и выложу исходники. Вот, все предоставил.
Сообщение отредактировал
Klim - Ср, 18.01.2012, 12:37
|
|
|
|
ivan_fd |
Дата: Ср, 18.01.2012, 13:36 | Сообщение # 25 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
И первый, и второй код работает неправильно. Проблема заключается в том, что у Вас шагов до прерывания 25. Происходит прерывание, далее идет присваивание таймеру значений, далее инкремент i и по выходу из прерывания таймер уже снова переполнен, и снова происходит прерывание. Получается, что программа постоянно висит в прерывании.
И второе, я Вам уже писал об этом и в примере давал. Флаг прерывания по компаратору не сбросится если не прочитать CMCON.
|
|
|
|
Klim |
Дата: Ср, 18.01.2012, 13:58 | Сообщение # 26 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Подправить код можно?
|
|
|
|
ivan_fd |
Дата: Ср, 18.01.2012, 14:25 | Сообщение # 27 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
Если Вам нужно считать длину "превышения напряжения", я думаю, что лучше будет по срабатыванию компаратора, включить таймер от нуля (прерывание от таймера не нужно). А по второму прерыванию от компаратора, когда напряжение будет меньше порога, остановить таймер. То, что он насчитал и будет искомым значением.
|
|
|
|
Klim |
Дата: Ср, 18.01.2012, 14:34 | Сообщение # 28 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Таймер оставить TMR1 ? А сам алгоритм точки (что в теле программы) начала отсчета правильный? И совсем детский вопрос, а как перевести значение таймера TMR1 в обычное десятичное число? Допустим в переменную i загнать данные таймера TMR1L и TMR1H ?
Сообщение отредактировал
Klim - Ср, 18.01.2012, 14:43
|
|
|
|
ivan_fd |
Дата: Ср, 18.01.2012, 15:02 | Сообщение # 29 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
Вот наваял, смотрите, что то типа этого. Quote (Klim) И совсем детский вопрос, а как перевести значение таймера TMR1 в обычное десятичное число?
Можно так:
Code dim i as word
i.LowByte = TMR1L i.HighByte = TMR1H
а можно и так:
Code Symbol TIMER1 = TMR1L.Word
i = timer1
Сообщение отредактировал
ivan_fd - Ср, 18.01.2012, 15:04
|
|
|
|
Klim |
Дата: Ср, 18.01.2012, 15:49 | Сообщение # 30 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
79
Замечания:
±
На сайте с 21.12.2009
Статус:
Offline
|
Спасибо, все доступно и понятно. Один вопрос остался - почему считает неправильно? Вроде как частоте 8333 Гц соответствует длительность импульса 120 микросекунд?
|
|
|
|