Страница 20 из 115

Добавлено: Пн фев 16, 2009 19:46:18
Барсик
А куда подключены ноги PINB.2 и PINB.3 ?

Добавлено: Пн фев 16, 2009 20:40:34
SeregaT
Я пробовал подавать на них т 0 и 1 (+5В) через резистор (ом на 300).
Кстати, в Вашей проге срабатывало почемуто на 0.

Добавлено: Пн фев 16, 2009 22:47:22
Барсик
Я спрашиваю, что у Вас подано на PINB.2 и PINB.3, в тот момент, когда Вы подаёте лог. 1 на вход PINB.1

Добавлено: Вт фев 17, 2009 03:45:59
SeregaT
Ничего не подано.

Добавлено: Вт фев 17, 2009 16:38:15
Барсик
В смысле, входы PINB.2 и PINB.3 висят в воздухе? Если это так, то они ловят помехи, из-за чего переменная i может принимать значения 2, 4, 6, 8, 10, 12, 14 . А вы пытаетесь отслеживать значение i равное 2. И, естественно, пролетаете мимо. Я же не просто так написал строчку:
i = i & 0b00001110; // маскируем разряды, которые нам не нужны
Это побитовая операция "И". В тех разрядах, где нули, всегда будут нули, а те разряды, где единицы, будут иметь значение, зависящее от состояния входов.
Чтобы на значение i влияли только PINB.1 PINB.2 и PINB.3, а остальне были нулями. Вот они, собаки, и влияют.
В моей программе, если получаете 6, 10, 12, 14, то попадаете под оператор "default:" под которым нет никаких команд.
Короче, надо PINB.1 PINB.2 и PINB.3 посадить через резисторы на землю.

Добавлено: Вт фев 17, 2009 19:18:11
SeregaT
А если мне надо подавать на вход лог 0, то входы надо посадить через резистор на +5В?
P.S. Ага, сейчас нормально работает :) :idea:

Добавлено: Вт фев 17, 2009 19:23:41
Барсик
Да. Или можно включить внутренние подтягивающие резисторы. Они подтягивают уровень на + питания контроллера. Но они довольно большие - десятки килоом.

Микроконтроллерная система это тесное взаимодействие двух частей - аппаратной и программной. Если какая-то из них с ошибкой, то система просто не работает. Поэтому надо относиться к обеим частям с максимальной аккуратностью. Если в аппаратной части косяк, то искать ошибку в программе - бесполезная трата времени. И наоборот.

Добавлено: Вт фев 17, 2009 19:29:06
SeregaT
А как кстати включаются эти встроеные резисторы? Фьюзами?

Добавлено: Вт фев 17, 2009 19:44:24
Барсик
Нет. Вывод программируется на вход и в него записывается лог. 1, как будто он выход. Тогда включается внутренний резистор. Или наоборот, сначала записывается 1, а потом он конфигурируется на вход - точно не помню. Надо в даташит глянуть.
Но можно сделать проще. В CodeVisionAVR в автоматическом генераторе указать чтобы резисторы были включены. На закладке конфигурирования портов есть столбец под названием Pullup/Output Value. Если в этом столбце против порта кликнуть мышом и поставить букву P, то подтягивающий резистор будет включён.

Добавлено: Вт фев 17, 2009 19:47:10
SeregaT
Барсик писал(а):На закладке конфигурирования портов есть столбец под названием Pullup/Output Value. Если в этом столбце против порта кликнуть мышом и поставить букву P, то подтягивающий резистор будет включён.
Да, видел. Еще спросить собирался, для чего это.

Добавлено: Ср фев 18, 2009 18:45:09
SeregaT
И снова бегущие огни :)
Например вот такое:
PORTD = 0b00000001;
delay_ms (200);
PORTD = 0b00000011;
delay_ms (200);
PORTD = 0b00000111;
delay_ms (200);
PORTD = 0b00001111;
delay_ms (200);
PORTD = 0b00011111;
delay_ms (200);
PORTD = 0b00111111;
delay_ms (200);
PORTD = 0b01111111;
delay_ms (200);
PORTD = 0b11111111;
delay_ms (200);
PORTD = 0b11111110;
delay_ms (200);
PORTD = 0b11111100;
delay_ms (200);
PORTD = 0b11111000;
delay_ms (200);
PORTD = 0b11110000;
delay_ms (200);
PORTD = 0b11100000;
delay_ms (200);
PORTD = 0b11000000;
delay_ms (200);
PORTD = 0b10000000;
delay_ms (200);
PORTD = 0b00000000;
delay_ms (200);
можно сделать как-то короче? Ну типа как массивы на ассемблере, или просто написать задержку 1 раз и чтобы она использовалась во всём цикле?

Добавлено: Ср фев 18, 2009 21:32:00
Пухич
Если лень такую кучу писать, то делайте цикл. А в цикле можно сначала флаг С установить и делать сдвиг влево через перенос в обнуленное исходно число, а по достижении заполнения сбросить флаг С и делать снова сдвиг влево через перенос.

Добавлено: Ср фев 18, 2009 22:56:43
Барсик
Можно попробовать сделать со сдвигом, но мне кажется, что то, чем мигать, лучше задать в виде таблицы (массива). Тогда содержание этого массива можно задавать, как угодно.

Код: Выделить всё

void main(void)
{
// определяем массив, чем будем мигать
unsigned char migalka[] =   { 0b00000001, 0b00000011, 0b00000111, 0b00001111
                            , 0b00011111, 0b00111111, 0b01111111, 0b11111111
                            , 0b11111110, 0b11111100, 0b11111000, 0b11110000
                            , 0b11100000, 0b11000000, 0b10000000, 0b00000000 };
unsigned char i = 0;
while (1)
    {
    // ну и мигаем себе в цикле
    for (i=0; i<16; i++)
    {
        PORTD = migalka[i];
        delay_ms (200);
    }
    };
}

Добавлено: Ср фев 18, 2009 23:17:33
Пухич
Можно и так. Тоже способ. По крайней мере подобным образом делаю, когда надо выводить ограниченный набор слов - задаю массив слов и вывожу их, вместо запоминания таблицы символов с ее последующим вспоминанием.

Добавлено: Чт фев 19, 2009 18:43:54
SeregaT
Барсик писал(а):но мне кажется, что то, чем мигать, лучше задать в виде таблицы (массива).
Да, это как раз то, что нужно.

Добавлено: Вт фев 24, 2009 11:13:38
SeregaT
А вот расскажите про АЦП. Как его использовать? Я понимаю, что эта штука преобразует аналоговые величины в цифровые, но как это работает? Можно ли (чисто для примера) поставить на вход АЦП переменный резистор, и чтобы в зависимости от напряжения на входе, загоралось определённое количество светодиодов (например от 1 до 8 )?
Как это можно реализовать программно?

Добавлено: Вт фев 24, 2009 11:29:39
ARV
SeregaT писал(а):А вот расскажите про АЦП. Как его использовать? Я понимаю, что эта штука преобразует аналоговые величины в цифровые, но как это работает? Можно ли (чисто для примера) поставить на вход АЦП переменный резистор, и чтобы в зависимости от напряжения на входе, загоралось определённое количество светодиодов (например от 1 до 8)?
Как это можно реализовать программно?
http://radiokot.ru/articles/21/

Добавлено: Вт фев 24, 2009 11:52:30
SeregaT
О, отлично! То что нужно. Есть даже ответы на некоторые мои следующие вопросы.
Спасибо :)

Добавлено: Чт фев 26, 2009 20:27:53
SeregaT
Подскажите плиз вот такой момент:
Вот есть фрагмент
unsigned char i = 0;
void main(void)
{
PORTD=0x00; //Выставляем все выходы порта D на 0, то есть, выключаем весь порт D
DDRD=0xFF; //Делаем порт D, как выход, чтобы на выходах порта было напряжение 5В
while (1)
{
unsigned char migalka = { 0b00000001, 0b00000011, 0b00000111, 0b00001111
, 0b00011111, 0b00111111, 0b01111111, 0b11111111
, 0b11111110, 0b11111100, 0b11111000, 0b11110000
, 0b11100000, 0b11000000, 0b10000000, 0b00000000
for (i=0; i<16 ; i++)
}

Вот как при (!PINB.1) прервать этот цикл и продолжить дальше (например PORTD.1=1)?
Как я понимаю, надо написать что-то наподобие
if (!PINB.1)
break;
PORTD.1=1;

Но вот что-то не правильно и я не могу понять что именно... Уже по всякому пробовал.

Добавлено: Чт фев 26, 2009 23:53:10
Барсик
А с какой это радости у Вас массив migalka определятся внутри главного цикла? И определяется как то странно. Такая прнография получилась из-за неправильного цитирования? При цитировании текста программы используйте кнопочки "Code". Или помещайте текст программы в присоединённый файл. А то трудно проверять Вашу программу.