Свежие обсуждения
Микроконтроллеры

Разработка таймера на основе PIC16F628(A) с программой на языке С

1 7 21

Замечаний по техзаданию и схеме больше нет?
Выкладываю вариант графа. На нём изображена только основная часть программы, для обработчика прерываний у меня отдельный граф. В аттаче - пояснения к предлагаемому графу.
http://p.foto.radikal.ru/0701/2a9c5e9f14a1.gif

Это пока так, информация к размышлению.

P.S. Если есть замечания - обговорим, конечно, обсуждение ещё не закончено. И техзадание, и схема ещё не утверждены.

72974.rtf

 

picmaniac: Замечаний по техзаданию и схеме больше нет?

Что-то мне напоминает эта фраза в аспекте фразеологической науки.

 

и ?..

 

picmaniac: и ?..

Выступление секретаря парторганизации. picmaniac, это шутка, не обижайтесь! Просто по существу ничего пока не могу сказать. А вот ассоциация такая в мозгах возникла.

 

может графы и флочаты в проге какойто рисовать ? есть простенькая общедоступная ?

 

Ага. Пайнт называется. Я рисую в visio.

Splav56: не обижайтесь! Да ну, какие обиды!.. просто не просёк юмор сразу.

Чё-то нм.ру глючит, зараза. Файлы не могу выкладывать. Написал им, мож починят... Или это происки всем нам хорошо известного конкурента?

 

picmaniac: Выкладываю вариант графа.
Граф красивый! К сожалению, не могу сейчас погрузиться в задание, очень срочная работа, отложить и перенести невозможно.

 

Думаю вопросов и не возникнет пока это все не перейдет на стадию воплощения в жизнь и тестирования.
Разрешить прерывания с периодом 4000 мкс от TMR0 (TMR2 ?) - думаю лучше от TMR0, проще с одним ИНТКОНом работать. А там еще в Т2КОН лезть.....
Разобрался я почему таймер спешил у меня. Само прерывание то происходит через нужное время, вот только еще уходит время на вход в прерывание, определие источника прерывания, инкремент переменной и сравнение переменной с нужной величиной как минимум. Поэтому если нам нужно инкрементировать переменную каждую секунду, то остаток от деления нужно брать не на 250 (если прерывания кажые 4мс). От какого числа брать остаток от деления можно установить экспериментально поганяв в симуляторе. Процедуры, которые могут обработаться а могут и не обработаться (в зависимости от состояния) лучше туда не пихать. А если пихать то только после инкремента/декремента нужного нам значения.

 

Maksim_86: Само прерывание то происходит через нужное время, вот только еще уходит время на вход в прерывание, определие источника прерывания, инкремент переменной и сравнение переменной с нужной величиной как минимум. Поэтому если нам нужно инкрементировать переменную каждую секунду, то остаток от деления нужно брать не на 250 (если прерывания кажые 4мс).
А если подумать? Прерывание по таймеру происходит строго через каждые 4 мс, и этот интервал не зависит от времени входа в прерывание, определения источника и т.п. Промежуток времени между моментами инкремента переменной всё равно останется 4 мс. На то он и таймер.

 

Хочу предложить свой вариант обработки прерывания:

char RB; // глобальная переменная состояния кнопок
char min10; // значение десятков минут
char min1; // значение едениц минут

void int(void) // ну это точка входа в прерываение
{
ShowValue(); // функция отображения информации на дисплее
CheckButtons(); // проверка нажатия кнопок
incTimer(); // прибавление отсчет времени
}

void CheckButtons(void)
{
// установка RA2...RA3 как входы
// установка RB3...RB6 как входы
// установка RB0 как выход
PortB.RB0=1; // устанавливаем на ножке RB0 лог. "1"
RB=PORTB; // Сохраняем в переменную RB состояние входов порта В
RB // Здесь в биты №0, 1, 2, 3 и 7 записываем лог. "0", т.к. они не несут полезной информации

/* Здесь мы проверяем нажатые кнопки. Если переменная будеть иметь значения 32, 64 и 128 то нажата соответствующая кнопка, в противном случае нажато несколько кнопок или вовсе не нажато. Тут будем проверять и на дребезг.*/
if RB==32 // КД
{
state=1;
/* проверяем, если все еще нажата клавиша КД, то устанавливаем "состояние" в режим 1 (установка). Текущая нажатая клавиша находится в переменной RB.*/
}
// аналогично проверяем остальные кнопки
if RB==64 {state=1;} // КС
if RB==128 {state=1;} // КЕ
} // Подавление дребезга будем проводить в самой функции установки показаний
}

ShowValue() // Функция вывода значения времени на экран
{
ShowDigit(min10); // вызываем функцию вывода десятков минут на дисплей
PortB.RA2=1; // Устанавливаем RA2 в лог. "1".
wait(5мс); // пауза, для отображения первой цифры
PortB.RA2=0; // "Выключаем" цифру

ShowDigit(min1); // вызываем функцию вывода едениц минут на дисплей
PortB.RA3=1; // Устанавливаем RA3 в лог. "1".
wait(5мс); // пауза, для отображения первой цифры
PortB.RA3=0; // "Выключаем" цифру

wait(*мс); // Пауза, необходимая для изменения яркости свечения цифр
/* Яркость можно менять уменьшая продолжительность свечения одной цифры и увеличения длительности паузы в погашеном состоянии */
}

void ShowDigit(char Digit) // Функция вывода цифры на дисплей (порт)
{
case (Digit) // Проверяем номер цифры
{
case0: PortB= <0>; break; //если =1, то приводим состояние порта
case1: PortB= <1>; break; // в соответсвие, обеспечивающее
case2: PortB= <2>; break; // отображение нужной цифры.
....
case9: PortB= <9>; break;
}
}

надо будет еще пересмотреть время прерывания с учетом динамичесой индикации