В смысле, входы 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:34:00, всего редактировалось 1 раз.
Нет. Вывод программируется на вход и в него записывается лог. 1, как будто он выход. Тогда включается внутренний резистор. Или наоборот, сначала записывается 1, а потом он конфигурируется на вход - точно не помню. Надо в даташит глянуть.
Но можно сделать проще. В CodeVisionAVR в автоматическом генераторе указать чтобы резисторы были включены. На закладке конфигурирования портов есть столбец под названием Pullup/Output Value. Если в этом столбце против порта кликнуть мышом и поставить букву P, то подтягивающий резистор будет включён.
На закладке конфигурирования портов есть столбец под названием Pullup/Output Value. Если в этом столбце против порта кликнуть мышом и поставить букву P, то подтягивающий резистор будет включён.
Карма: 16
Рейтинг сообщений: 14
Зарегистрирован: Вс июн 01, 2008 00:17:35 Сообщений: 4673 Откуда: Я всего лишь плод вашего воображения...
Рейтинг сообщения:0 Медали: 1
Если лень такую кучу писать, то делайте цикл. А в цикле можно сначала флаг С установить и делать сдвиг влево через перенос в обнуленное исходно число, а по достижении заполнения сбросить флаг С и делать снова сдвиг влево через перенос.
Можно попробовать сделать со сдвигом, но мне кажется, что то, чем мигать, лучше задать в виде таблицы (массива). Тогда содержание этого массива можно задавать, как угодно.
Код:
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); } }; }
Карма: 16
Рейтинг сообщений: 14
Зарегистрирован: Вс июн 01, 2008 00:17:35 Сообщений: 4673 Откуда: Я всего лишь плод вашего воображения...
Рейтинг сообщения:0 Медали: 1
Можно и так. Тоже способ. По крайней мере подобным образом делаю, когда надо выводить ограниченный набор слов - задаю массив слов и вывожу их, вместо запоминания таблицы символов с ее последующим вспоминанием.
А вот расскажите про АЦП. Как его использовать? Я понимаю, что эта штука преобразует аналоговые величины в цифровые, но как это работает? Можно ли (чисто для примера) поставить на вход АЦП переменный резистор, и чтобы в зависимости от напряжения на входе, загоралось определённое количество светодиодов (например от 1 до 8 )?
Как это можно реализовать программно?
Последний раз редактировалось SeregaT Вт фев 24, 2009 11:54:47, всего редактировалось 1 раз.
А вот расскажите про АЦП. Как его использовать? Я понимаю, что эта штука преобразует аналоговые величины в цифровые, но как это работает? Можно ли (чисто для примера) поставить на вход АЦП переменный резистор, и чтобы в зависимости от напряжения на входе, загоралось определённое количество светодиодов (например от 1 до ? Как это можно реализовать программно?
Подскажите плиз вот такой момент:
Вот есть фрагмент
Цитата:
unsigned char i = 0; void main(void) { PORTD=0x00; //Выставляем все выходы порта D на 0, то есть, выключаем весь порт D DDRD=0xFF; //Делаем порт D, как выход, чтобы на выходах порта было напряжение 5В while (1) { unsigned char migalka[i] = { 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;
Но вот что-то не правильно и я не могу понять что именно... Уже по всякому пробовал.
А с какой это радости у Вас массив migalka[i] определятся внутри главного цикла? И определяется как то странно. Такая прнография получилась из-за неправильного цитирования? При цитировании текста программы используйте кнопочки "Code". Или помещайте текст программы в присоединённый файл. А то трудно проверять Вашу программу.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения