|
|
  |
Простецкий код на си подскажите где туплю, PIC на си |
|
|
|
Apr 20 2011, 16:48
|
Частый гость
 
Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001

|
Подскажите пожалуйста начал разбираться с мплаб и HI-TECH такой код простой, по переполнению таймера меняет состояние одной из ножек и по нажатию кнопки (появлению там единицы) должен подать на RA3 проверяю в протеусе подцепил кнопку на RA0 подаю +5в туда но это событие не обрабатывается а если в коде меняю параметр в условии на противоположном то условие выполняется (вывод на RA3 единицу и запрет прерывания) вот сам код Код #include <htc.h>
/* * Interrupt test for PIC * * Copyright (C)1997 HI-TECH Software. * Freely distributable. */ #define BUTTON RA0 //bit 1 of PORTC static volatile long count; static volatile bit bad_intr;
void main(void) { /* setup stuff */
T0CS = 0; // Timer increments on instruction clock TRISA = 0x01; // Port A is input TRISB = 0xFE; // Port B bit 0 is output T0IE = 1; // Enable interrupt on TMR0 overflow GIE = 1; // Global interrupt enable
CLRWDT(); // Idly kick the dog
//RA3=1; while(1){ if (BUTTON==1){RA3=1; GIE=0;}; };
}//End of main
static void interrupt isr(void) // Here be interrupt function - the name is // unimportant. { if(!T0IF) // Was this a timer overflow? bad_intr = 1; // NO! Shock horror! count++; // Add 1 to count - insert idle comment T0IF = 0; // Clear interrupt flag, ready for next PORTB ^= 1; // toggle bit 0 of Port B, to show we're alive } заранее спасибо
Сообщение отредактировал Vny4ek - Apr 20 2011, 16:52
|
|
|
|
|
Apr 21 2011, 06:31
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 31-01-10
Из: Минск
Пользователь №: 55 176

|
Во-первых, выключите аналоговые функции порта А Во-вторых, разве T0IF = 1 не является сигналом переполнения? Вы проверяете если T0IF = 0 и тут же ему присваиваете 0
|
|
|
|
|
Apr 21 2011, 13:41
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Vny4ek @ Apr 21 2011, 09:10)  Пипец 40 просмотров и 0 ответов Полностью соответствует осмысленности описания проблемы - контроллер не указан, даташит на него не читан, прогу вывалили как есть, даже не попытавшись убрать явные странности. Цитата Я понял в чем ошибка, порта А сконфигурировать надо, вывел на B порт кнопку все заработало А я в дцатый раз перечитываю - вроде такая простая фраза, но ниасилил. Возможно, Вы хотели сказать, что заглянули в даташит и обнаружили, что RA3 может работать только входом? Цитата(sargein @ Apr 21 2011, 10:31)  Во-вторых, разве T0IF = 1 не является сигналом переполнения? Вы проверяете если T0IF = 0 и тут же ему присваиваете 0  ТС работает над какой-то "рыбой", в которой предполагается, что прерывание может произойти только по TMR0, и "bad_intr = 1;", если прерывание приключилось от чего-то ещё.
|
|
|
|
|
Apr 21 2011, 13:59
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 31-01-10
Из: Минск
Пользователь №: 55 176

|
Цитата(ViKo @ Apr 21 2011, 16:49)  Когда таймер переполняется, то T0IF станет равным 1. А ТС проверяет его на равенство 0. О чем и сказал предыдущий участник. Совершенно верно, и для меня остается непонятным смысл программы "Если х = 0, то присвоим иксу 0"
|
|
|
|
|
Apr 21 2011, 14:20
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 31-01-10
Из: Минск
Пользователь №: 55 176

|
а кстати по таймеру, тут нигде явно не задается сколько тактов будет считать таймер (PS2..PS0) и значение TMR0 нигде не обнуляется, и на фоне всего сказанного всеми ранее, вот это: Цитата(Vny4ek @ Apr 21 2011, 08:10)  вывел на B порт кнопку все заработало для меня вообще сплошная загадка зы. ну и напоследок, наверное, еще неплохо было бы от дребезга избавится
Сообщение отредактировал sargein - Apr 21 2011, 14:22
|
|
|
|
|
Apr 21 2011, 15:22
|
Частый гость
 
Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001

|
Извините, просто поставил MPLAB и попытался задействовать прерывание, ну что бы понять как это выглядит. Использую пример с компилятора. "вывел на B порт кнопку все заработало"  ну входом с кнопки сделал не RA0 а RB3 До дребезга, как и до чего то путного еще очень далеко, начал только разбираться изучаю  проц PIC16F913 сильно не пинайте пытаюсь программировать как хобби чтоли
Сообщение отредактировал Vny4ek - Apr 21 2011, 15:28
|
|
|
|
|
Apr 21 2011, 17:10
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 31-01-10
Из: Минск
Пользователь №: 55 176

|
Смотреть в даташит  пункт 3.1 PORTA and TRISA Registers Цитата Note 1: The CMCON0 (9Ch) register must be initialized to configure an analog channel as a digital input. Pins configured as analog inputs will read ‘0’. Дальше ищем зверя CMCON0, в частности читаем про компаратор, и там видим что СM2..CM0 = 111 соответствует выключенному модулю компаратора. По умолчанию он включен, следовательно, чтобы использовать порт А так как вы хотите, нужно вставить в код такую строчку: Код CMCON0 = 0x07;
|
|
|
|
|
Apr 21 2011, 17:47
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Vny4ek @ Apr 21 2011, 20:44)  Забыл еще спросить как в двух словах можно по наименованию пика определить примерно его функционал По наименованию, имхо, никак. Если нужно подобрать контроллер под задачу, то как обычно - параметрический поиск на сайте производителя. Цитата ну то что 12 16 18 это как тини мега хмега у авр условно я понял но что значит C или F и цифры после них не особо ясно у Авр понятней хотя может просто с неривычки и незнания так C - OTP (OneTimeProgrammable); про исключение PIC16C84 можно забыть CR - масочные F - флэш LF - флэш с потенцией к низкому потреблению.
|
|
|
|
|
Apr 23 2011, 17:07
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 14-05-08
Пользователь №: 37 515

|
1. Обязательно предопределять фьюзы (CONFIG). 2. Аналоговые функции порта PORTA при ненадобности отключать. Как уже было сказано, для этого выключить компаратор в CMCON0. Во многих PIC также нужно определять PORTA как цифровой в настройках АЦП. 3. Обязательна задержка против дребезга. 4. Настройка пред/пост делителя используемого таймера. 5. В обработке прерывания от таймера видимо все-таки правильнее будет как-то так: CODE static void interrupt isr(void) // Here be interrupt function - the name is // unimportant. { if(T0IF) { // Was this a timer overflow? count++; // Add 1 to count - insert idle comment T0IF = 0; // Clear interrupt flag, ready for next PORTB ^= 1; // toggle bit 0 of Port B, to show we're alive } else {bad_intr = 1;}// NO! Shock horror! }
Сообщение отредактировал Genius1 - Apr 23 2011, 17:08
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|