| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
Не выпоняется основной код в PIC16F877A
09.10.2007, 10:44
|
|
|
Вид на жительство
Регистрация: 18.06.2006
Сообщений: 434
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Спасибо с разъяснениями про EEPROM.
|
Цитата:
|
|
ну первое что бросилось в глаза, это бесконечный цикл в прерываниях.
|
Это для того чтоб не использовать функцию типа GO TO.
Там из каждой точки есть выход с цикла, даже если не одно условие не выполнилось то все равно выходим, так что у этого безконечног8о цикла нет шансов выполнить более 1 цикла.
Да у меня есть индикация, я ведь в проблеме описал, до каких действий доходит и перестает работать индикация
В моем примери если убрать функцию Pause() и из функции ReadStandartSetings() убрать запись в EEPROM мы попадаем в функцию Expectation и там висним.
|
Код:
|
void Expectation(void)
{
f_indication=0;//индикация выключена
while (f_expectation==1) continue;
return;
} |
Хотя если в функции которая обрабатывается в прерывании менять индикацию, то все работает.
Ну типа так
|
Код:
|
void Keypres(void)
{
int i=0;
if (f_expectation==1 | f_protection==1)
{
if (key==setings[pass_exp]) pass_exp++;
else pass_exp=0;
if (pass_exp==4 & f_expectation==1)
{
f_indication=1;//*********это здесь************
f_expectation=0;
f_protection=1;
pass_exp=0;
return;
}
if (pass_exp==4 & f_protection==1)
{
f_indication=0;//*********это здесь************
f_expectation=1;
f_protection=0;
pass_exp=0;
return;
}
}
} |
то есть флаги f_expectation=1; f_protection=0; переключаются что по идее должно давать возможность переходить из Expectation в Protection и обратно.
Но этого не происходит.
Я дал урезаную часть кода, там у меня во многих ситуациях зависал, так же и связанных с вычислениями.
|
|
|
|
09.10.2007, 11:41
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
|
Сообщение от maxNTF
|
|
Цитата:
|
|
ну первое что бросилось в глаза, это бесконечный цикл в прерываниях.
|
Это для того чтоб не использовать функцию типа GO TO.
Там из каждой точки есть выход с цикла, даже если не одно условие не выполнилось то все равно выходим, так что у этого безконечног8о цикла нет шансов выполнить более 1 цикла.
|
Ну вот не надо делать то - чего не надо делать, а точнее бесконечных циклов в прерываниях.
Для выхода из функции используется оператор return;, если с помощью него не обойтись, значит следует пересмотреть алгорит. Для это следует взять карандаш и лист бумаги, далее как учили в школе/техникуме/институте с помощью квадратиков/прямоугольничков нарисовать алгоритм, и после этого он легко перенесется на исходник.
|
Цитата:
|
мы попадаем в функцию Expectation и там висним.
|
Код:
|
void Expectation(void)
{
f_indication=0;//индикация выключена
while (f_expectation==1) continue;
return;
} |
|
Ну так вот здесь у вас и вешается программа если f_expectation==1, то получается бесконечный цикл, и только прерывания смогут этот флаг сбросить, если этого не сделать, то прога в этом месте виснет, я вас еще раз призываю пересмотреть алгоритм работы программы!
|
|
|
|
09.10.2007, 11:50
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Хм, счас подробнее глянул ваш исходник в первом посте.
Пара замечаний:
1.в прерываниях не должно быть никаких бесконечных циклов (да и вообще циклов не должно быть!), прерывание это быстрый обработчик события! т.е. событие произошло =› быстренько его обработали и вышли, что бы не мешать работать программе и не пропустить остальные события.
2. в прерываниях не вызывать никакие процедуры/функции, тем-более на 16м пике!
3. опрос кнопок это не самое важное событие, его надо перенести в основной цикл программы, а в прерываниях просто выставлять флаг, что надо опросить клавиатуру.
4.математику типа
|
Код:
|
i++;
if (i›=20)
{
обработчик клавиатуры
} |
заменить на
|
Код:
|
i--;
if(!i) {
i=20;
выставить флаг
} |
[/b]
|
|
|
|
09.10.2007, 12:14
|
|
|
Вид на жительство
Регистрация: 18.06.2006
Сообщений: 434
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Хорошо, вот пример, виснит на функции Pause(), хотя эта функция взята с проги под PIC16F628A и там она работает без проблем!
|
Код:
|
#include ‹pic.h›
/*****************Functions*******************/
void Expectation(void);//дежурный режим
void Pause(int time, int divider);
/******************Variable*******************/
int bank1 seconds_1=0;//счетчик для паузы
int bank1 seconds_2=0;//счетчик для индикации
/******************Flags**********************/
char f_pause=0;//пауза
char f_expectation=1;//вход в режим ожидания
char f_indication=0;//общая индикация
void interrupt other(void)
{
int i=0;
if (TMR2IF==1)
{
//зедержка для функции Pause
if (f_pause==1) seconds_1++;
//общая индикация
if (f_indication==0) RE1=0, seconds_2=0;
if (f_indication==1) RE1=1, seconds_2=0;
TMR2IF=0;
}
}
void main()
{
int i=0;
__CONFIG(HS & PWRTDIS & WDTDIS & BORDIS & LVPDIS);
STATUS=0x00;
RCSTA=0b10010000;//настройка приемника uart
TXSTA=0b00100100;//настройка передатчика uart
SPBRG=10;// скорость uart 57600 baund
INTCON=0b11000000;//разрешения прирываний
T2CON=0b00001110;//предделитель TMR2 256
RCIE=1;//прерывания от приемника uart
TMR2IE=1;//прерывания от TMR2
ADCON1=0b00001001;;//выключаем компараторы
TRISA=0b00101111;//настройка порта A
TRISB=0b11110000;//настройка порта В
TRISC=0b10011111;//настройка порта C
TRISD=0b00000000;//настройка порта D
TRISE=0b00000101;//настройка порта E
PORTD=0b00000000;//значение порта D
RB0=0;//buzzer
RE1=0;//индикатор состаяния
Pause(2,1);
f_expectation=1;
for(;;)
{
if (f_expectation==1) Expectation();
}
}
void Expectation(void)
{
f_indication=1;//индикация выключена
while (f_expectation==1) continue;
return;
}
void Pause(int time, int divider)
{
seconds_1=0;//обнуления переменной таймера TMR0
f_pause=1;
if (divider==1)
{
while (seconds_1‹(time*305)) continue;//ждем
}
if (divider==0)
{
while (seconds_1‹(time*30)) continue;//ждем
}
f_pause=0;
return;
} |
|
|
|
|
09.10.2007, 12:25
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
|
Сообщение от maxNTF
|
|
Хорошо, вот пример, виснит на функции Pause(), хотя эта функция взята с проги под PIC16F628A и там она работает без проблем!
|
Вы хотите что бы вам код переписали или помогли найти косяки?
Я предполагаю второе, ибо косяк вы сами смогли локализовать, а первое делать нахаляву здесь никто не будет.
Знаете в чем проблема, дык копайтесь с этим дальше и будет вам решение, а за ним счастье.
Из предположений запрещены прерывания, не запускается таймер, выставляются/обрабатываются не те флаги, получается большая задержка и т.д. пройдитесь симулятором этот кусок кода и все выяснится само собой.
и еще:
|
Код:
|
void Pause(int time, int divider)
{
....
while (seconds_1‹(time*305)) continue;//ждем
....
} |
Как компилится этот код?
проц не имеет команды умножения, я думаю что (time*305) выполняется честно, на каждой итерации, а это до нескольких милисекунд может занимать, если сюда добавить то, что какие-то прерывания выставляются, но они не обрабатываются (например разрешили прерывания от UARTA, обработчик еще не написали. получается: вошли в обработчик прерываний и вышли, а флаг оставлся, проц выполнит одну команду из основной проги и опять ввалится в прерывания.) может получиться оч. веселая картина
|
|
|
|
09.10.2007, 12:25
|
|
|
Вид на жительство
Регистрация: 18.06.2006
Сообщений: 434
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Взял новый контроллер, то же самое!!!
Может каки проблемы с программатором?
То что на вхот MCLR при записи идет 12В это нормально?
-- Прилагается рисунок: --
|
|
|
|
09.10.2007, 12:35
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Лучше писать вот так:
|
Сообщение от maxNTF
|
|
Код:
|
...
void Pause(int time, char divider);
void interrupt other(void)
{
if (TMR2IF)
{
//зедержка для функции Pause
if (f_pause) seconds_1++;
//общая индикация
if (!f_indication)
{
RE1=0;
seconds_2=0;
}
if (f_indication)
{
RE1=1;
seconds_2=0;
}
TMR2IF=0;
}
}
...
void Pause(int time, unsigned char divider)
{
if (divider)
...
else
...
return;
} |
|
ну и return в конце ставить не обязательно.
Значит так, что я имел в виду:
проверка на ноль осуществляется так:
if(!var)
проверка на не ноль осуществляется так:
if(var)
Еще, без необходимости тип int использовать не следует. Надо использовать char иначе контроллер будет честно проверять 2 байта (int столько занимает) на равенство 0, вместо одного.
лучше использовать unsigned char если нет необходимости использовать signed, тут логика проверки может отличать не в лучшую для производительности сторону.
|
|
|
|
09.10.2007, 12:36
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
|
Сообщение от maxNTF
|
Взял новый контроллер, то же самое!!!
Может каки проблемы с программатором?
То что на вхот MCLR при записи идет 12В это нормально?
|
Нет, не нормально, туда должно идти 13,5 вольт  подробнее на эту тему следует читать даташит, и спецификацию по програмированию чипа
-- Прилагается рисунок: --
|
|
|
|
09.10.2007, 12:38
|
|
|
Вид на жительство
Регистрация: 18.06.2006
Сообщений: 434
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Да лажа пока точно с тем что прерывания на UART поставил, а обработчик не написал.
Спасибо за консультацию, приму к сведению все то что сообщили.
Буду разбераться дальше.
|
|
|
|
09.10.2007, 13:02
|
|
|
Частый гость
Регистрация: 02.04.2007
Сообщений: 37
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
|
Сообщение от maxNTF
|
Да лажа пока точно с тем что прерывания на UART поставил, а обработчик не написал.
Спасибо за консультацию, приму к сведению все то что сообщили.
Буду разбераться дальше.
|
На здоровье, а вообще хороший процессор, только вот старый он уже, лучше сразу посмотрите на 18F452 он с этим даже по ножкам совместим, памяти в нем больше, аппаратное умножение есть, еще много чего. К тому же он дешевле
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:51.
|
|