Заголовок сообщения: Делаем устройство "Бегущий огонек" на микроконтроллере
Добавлено: Пт июл 12, 2013 16:27:54
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
Всем добрый день! Начал обучение программирования микроконтроллеров AVR с раздела: РадиоКот > Обучалка > Микроконтроллеры и ПЛИС > Микроконтроллеры AVR - пишем, компилируем, прошиваем... Для тестов взял Attiny2313 Вроде получалось, вроде что-то даже работало пока не дошел до тем "Динамическая индикация" и "Что такое матрица и с кого все спросить". По теме "Динамическая индикация" нужно было собрать простую схемку с 7-и сегментными индикаторами. Схемку я паять не стал, так как нет у меня лишних индикаторов... а взял уже готовую, собранную по схеме "Цифровой термометр" (который у меня исправно работал). Только у меня вместо 3-х цифрового индикатора подключен 4-х цифровой. Вывод 1-цифры подключен к 7-й ноге Тиньки (как и должно быть). Все "Общие" выводы припаяны правильно: 1-я цифра к 7-й ноге тиньки, 2-я к 6-й, 3-я к 3-й, 4-я к 2-й. Как оказалось, выводы сегментов не совпадают. Перепаивать я не стал (зачем портить готовое и работающее) а просто внес изменения в символьную таблицу в коде.
а стало так: .db 0b01111110,0b00110000 ;0,1 .db 0b01101101,0b01111001 ;2,3 .db 0b00110011,0b01011011 ;4,5 db 0b01011111,0b01110000 ;6,7 .db 0b01111111,0b01110111 ;8,9
После проверки в Протеусе оказалось что отображение получатся в негативе, то есть если нужно вывести "1" то сегменты, отвечающие за единицу не светятся, зато светятся все остальные, которые не должны светиться. То же наблюдается для всех остальных цифр. Хотя, как я понял, "1" (единица из таблицы) отвечает за зажигание сегмента, а "0" (ноль из той же таблицы) говорит что сегмент погашен... Еще один момент: по заданию "Динамической индикации" нужно вывести на отображение число 1234, но вместо этого отображается 2341 (в виде инверсии)
Получатся в исходном коде 2 ошибки (или я что-то не понял или не так составил исходник): 1) инверсия цифр 2) Цифры смещены в лево на 1 символ. Вместо "1234" отображает "2341"
EXT_INT0 : ret EXT_INT1 : ret TIM_CAPT1 : ret TIM_OVF0 : ret TIM_OVF1 : ret UART_RXC : ret UART_DRE : ret UART_TXC : ret ANA_COMP : ret TIM_COMP1 : ret
reset: ldi Temp1,RamEnd ;инициализация стека out SPL,Temp1
cli
ldi Temp,0b11111111 ;настройка портов out ddrb,Temp
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Сб июл 13, 2013 20:58:31
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
Я понимаю что так можно решить проблему, но такой вариант решения не соответствует всему тому что написано в "Обучалке". И, к тому же, я лишь скопировал код, слегка подправив его под свою схему выводов. А это значит что ошибка в самом примере приведенном в статье. Вот и попобуй тут разобраться, где ошибка... Сейчас по-новой все перечитываю, пытаюсь вникнуть...
К тому же такой вариан не решает проблему со сдвигом цифр
_________________ Сделать своими руками всегда интересней чем просто купить и пользоваться
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Сб июл 13, 2013 21:32:13
Это не хвост, это антенна
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Это не ошибка. Просто перед выводом сегментов на индикацию есть строки ldi Temp,0b00000111 out PortD,Temp Значения в бинарном числе в каждом блоке подключают общие выводы индикаторов. Измените в любом блоке 1 на 0 и получите чудо.
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Сб июл 13, 2013 22:11:59
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
Исходя из этого кода: ldi Temp,0b11111111 ;настройка портов out ddrb,Temp ldi Temp,0b00001111 out ddrd,Temp все выводы порта b и четыре последних вывода порта d настроены на "вывод"
если не ошибаюсь, ldi Temp,0b00000111 out PortD,Temp отвечает за то, какой общий катод (анод) индикатора в данный момент задействован для вывода информации: 0b00000111 - 1-я цифра индикатора 0b00001011 - 2-я цифра 0b00001101 - 3-я цифра 0b00001110 - 4-я цифра то есть под "0" подразумевается что порт настроен на "вход"... Вроде так? Тогда почему все цыфры смещены влево?
Я так понимаю, если взять вот такие два кода: ldi Temp,0b11111111 out PortD,Temp ldi Temp,0b00001101 oout PortB,Temp то на индикаторе должна загореться 3-я цифра, отображая "8" и "точку", то есть все сегменты. а в таком варианте должна отображаться "1": ldi Temp,0b00000110 out PortD,Temp ldi Temp,0b00001101 oout PortB,Temp
Мне кажется что таблица символов и настройка портов сделаны верно... получается где-то в другом месте ошибка... Если не так что-то понимаю - ткните мордочкой и объясните пожалуйста.
_________________ Сделать своими руками всегда интересней чем просто купить и пользоваться
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Вс июл 14, 2013 09:14:47
Это не хвост, это антенна
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Число однотипных блоков равно числу семисегментных индикаторов. Выше Вы все правильно расписали. Для замены порядка отображения чисел нужно изменить само число, кодирующее катод. В качестве примера: ldi Temp,0b00001111 ; Не горит ни чего. ldi Temp,0b00000111 ; Загорелась одна цифра, допустим 3-я. Тогда биту №3 соответствует цифра 3 (по порядку отображения) ldi Temp,0b00001011 ; Загорелась вторая, допустим 1-я. Тогда биту №2 соответствует цифра 1 ldi Temp,0b00001101 ; Ну и так далее ldi Temp,0b00001110 ; После нахождения просто выставляем эти числа в блоках в порядке отображения. А если проще - посмотрите в каком порядке к порту PortD подключены катоды. К примеру PortD,0 - катод второго числа, ну и аналогично. Вот как-то так...
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Вс июл 14, 2013 10:21:24
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
Да, вот в том то и дело, что к порту PortD0 подключен катод 4-й цифры, к порту PortD1 - 3й цифры, и т.д.... (как по схеме) Это то меня и вводит в ступор. Уже несколько раз проверил и схему и плату. По коду программы, вроде тоже все верно...
Ладно, оставлю это все на потом, то есть я по-новой начал все перечитывать, что-то стато проясняться, но и появились другие вопросы: В теме Бегущий огонек v1.0 описывается создание задержки.
Цитата:
ldi Temp,0
Loop: dec Temp brne Loop
Сначала мы инициализировали Temp числом 0. Далее из Temp вычитается 1. Его значение становится -1 (иначе говоря, 255). Далее мы проверяем, не получился ли у нас ноль. Поскольку число 255 не равно нулю, нас снова перекидывают на операцию декремента. Значение Temp уменьшается еще на 1. Теперь оно - 254.
1) Разве РОН (регистр общего назначения) не может содержать отрицательное значение? 2) Почему 0-1=255 (ноль минус один равно 255)? Почему не -1, -2 и т.д.? Это таккая защита? (вспоминаются случаи когда написанные программы на компе "вылетали" из-за переполнения переменной) 3) 256 значений (от 0 до 255) - это размер одного байта? Если нет, то почему именно такое числовое ограничение?
И еще вопрос: наиболее подходящий/удобный язык для написания программ это Ассемблер? Или есть другие, более популярные (удобные/лучшие) языки?
_________________ Сделать своими руками всегда интересней чем просто купить и пользоваться
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Вс июл 14, 2013 11:30:42
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
a_skr, спасибо за разъяснение!
Цитата:
число 0b11111111 - это и 255, и одновременно -1.
как я понял число 0b11111111 - это отрицательное число а число 0b01111111 - это положительное ? и еще хочу уточнить, в школе нас учили что -2-1=-3 (то есть, числа складываем и прибавляем минус) а исходя из этого:
Цитата:
Поскольку число 255 не равно нулю... Temp уменьшается еще на 1. Теперь оно - 254.
получается что в программировании формула выглядит так: -2-1=-1 ? Точнее от имеющегося числа (0b11111111) отнимаем единицу, как от положительного, а разряд 0b11111111 лишь указывает нам на то, что число, в конечном итоге, отрицательно?
_________________ Сделать своими руками всегда интересней чем просто купить и пользоваться
Заголовок сообщения: Re: AVR - пишем, компилируем, прошиваем... НЕ работает!
Добавлено: Вс июл 14, 2013 14:10:23
Вымогатель припоя
Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Вс дек 30, 2012 00:32:06 Сообщений: 545 Откуда: Николаев / Украина
Рейтинг сообщения:0
Ага, понятно. Еще вопрос, как работать с отрицательными значениями, точнее что это за регистр флагов и как с ним работать?
Решил поекспериментировать с кодом, чтобы в нем разобраться. Написал это: Спойлер.include "g:\AVR-projects\tutorial\2313def.inc" .def Temp=R16 .cseg .org 0
ldi Temp, 0b11111111 ;присвоение константы out DDRB,Temp ;настройка порта
ldi Temp,0b00001111 ;присвоение константы out DDRD,Temp ;настройка порта
ldi Temp,0b00110000 out Portb,Temp ldi Temp,0b00001110 out Portd,Temp
IndicCycle: rjmp IndicCycle
Теоретически, должна была светиться 4-я цифра (ldi Temp,0b00001110) и отображать единицу (ldi Temp,0b00110000) Но Протеус выдал то, что и раньше - инверсия, но при этом светились 1,2 и 3-я цифры, а ту, которую выбирали (4-я) нет! у меня появились некоторые мысли на этот счет, если что - поправьте. Изначально в коде настраиваются порты:
Код:
ldi Temp, 0b11111111 out DDRB,Temp
и
Код:
ldi Temp, 0b00001111 out DDRD,Temp
Я так понимаю что обе части кода говорят о том, какие порты будут задействованы в программе? А не то какие порты настроены на ввод а какие на вывод? Судя то пому что дает протес, то єто так.
Какие порты будут на вход, а какие на выход отвечает эта часть программы?:
Код:
ldi Temp,0b00110000 out Portb,Temp ldi Temp,0b00001110 out Portd,Temp
Спасибо всем за помощь - решил проблему с инверсией Как оказалось - вся проблема была в том, что у меня на схеме стоит индикатор с общим Анодом, а надо было с общим Катодом !! Я сразу не понял в чем дело, потому что в коде используется не включение/отключение порта, а изменение "+" на "-" и наоборот. В схеме и прошивке Цифрового термометра это учтено, и если поставить не тот индикатор (общий вывод другой полярности) то на индикаторе ничего отображаться не будет. Поменял в протеусе индикатор - Заработало!
_________________ Сделать своими руками всегда интересней чем просто купить и пользоваться
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения