В смысле, входы 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". Или помещайте текст программы в присоединённый файл. А то трудно проверять Вашу программу.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения