|
Не выходит из прерывание по Инт1. Пишу на СИ для 8051 |
|
|
|
Mar 18 2011, 09:07
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
У меня возникла очень странная на мой взгляд проблема. Перешел к изучению програмирования МК на языке высокого уровня. Выбрал Си. Написал пару очень простых задач из университетского курса. Но в обоих програмах возникла проблема с прерыванием. у меня на плате к прерыванию по внешнему срезу 1- подключена кнопка. При нажатии на кнопку, в прерывание попадает как и положенно. А вот потом я так и не понял толи у меня из прерывания вообше не выходит, то ли выходит но сразу запрыгивает назад. итог один. прерывание после одной активации работает как зацикленную функцию. Не могу понять в чем дело? те же проги на асемблере у меня выходили нормально. Пример. программы. Прграмма не сложная должна инвертировать светодиоды, после определенного нажатия нак кнопку. ( а делает: после вызова прерывания 1 раз. прерывание циклиться и светдиоды просто мигают постоянно) #include <reg51.h> #include <stdlib.h> #include <stdio.h> #include <math.h> //#include <avr/io.h> //#include <avr/interrupt.h> sbit P3_5 = P3^5; \\ светодиод1 sbit P3_4 = P3^4; \\ светодиод 2 sbit P3_3 = P3^3; \\ светодиод 3 static unsigned int delay = 0; char xdata str[20]; unsigned int N; int i ; int b = 0; int c = 0; int a = 1; /* начало коментария // enter MK to PowerDown while int1 = 0 void EnterPowerDown(void) { MCUCR = (1 << SE) | (1 << SM1); // int1 level sensitive + power-down GICR = (1 << INT1); asm("sleep"); } //enter MK in idle mode, while INT1 in zero. void WaitOnInt1ToGetHigh(void) { if (PIND & (1 << PD3)) // INT1 high? { // the level already high, no need to go idle return; } MCUCR = (1 << SE) | (1 << ISC11) | (1 << ISC10); // int1 on rising edge + idle GICR = (1 << INT1); asm("sleep"); }*/ закоментированная часть проги, подозреваю что не для той версии кейла, или вообще не к этому процесору. void initialize_system (void){ SCON = 0x52; TMOD |= 0x20; TH1 = 0xFa; TR1 = 1; TI = 1; } unsigned int num_element() { printf("\nEnter the number of push on button Int1 for invert led\n",str); gets (str, sizeof(str)); N = atoi(str); // ASCII to integer return N; } void intrrupt_butInt1(void) interrupt 2 { if (N >= i){ i = 0; if (a == 1, b == 0, c == 0){ a = 0; b = 1; c = 1; } else{ a = 1; b = 0; c = 0; } P3_3 = a; P3_4 = b; P3_5 = c; for (delay = 0; delay < 0x1FF; delay++); } else {i++;} // WHY? WHEN cursor CAME TO THIS POINT, JUMP TO BEGIN INTERRUPT. BUT DON'T T0 MAIN } void main( void ){ P3 ^= 0x00; initialize_system(); for (delay = 0; delay < 0x1FFF; delay++); P3_3 = a; P3_4 = b; P3_5 = c; N = num_element(); while(TH0 < 6){ TCON |=0x04; IE |=0x84; } } макет платы на протеусе прилагаеться.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 18 2011, 15:31
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
У меня возникла очень странная на мой взгляд проблема. Перешел к изучению програмирования МК на языке высокого уровня. Выбрал Си. Написал пару очень простых задач из университетского курса. Но в обоих програмах возникла проблема с прерыванием. у меня на плате к прерыванию по внешнему срезу 1- подключена кнопка. При нажатии на кнопку, в прерывание попадает как и положенно. А вот потом я так и не понял толи у меня из прерывания вообше не выходит, то ли выходит но сразу запрыгивает назад. итог один. прерывание после одной активации работает как зацикленную функцию. Не могу понять в чем дело? те же проги на асемблере у меня выходили нормально. Пример. программы. Прграмма не сложная должна инвертировать светодиоды, после определенного нажатия нак кнопку. ( а делает: после вызова прерывания 1 раз. прерывание циклиться и светдиоды просто мигают постоянно) #include <reg51.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include "C:\Keil\C51\inc\Pprintf.h" #include "C:\Keil\C51\inc\kscanf.h"
sbit P3_5 = P3^5; sbit P3_4 = P3^4; sbit P3_3 = P3^3; static unsigned int delay = 0; char xdata str[200]; unsigned int N; unsigned int A; unsigned int i = 0; int b = 0; int c = 0; int a = 1;
void initialize_system (void){ SCON = 0x52; TMOD |= 0x20; TH1 = 0xFa; TR1 = 1; TI = 1;
P3_3 = a; P3_4 = b; P3_5 = c;
EA = 1; EX1 = 1; IT1 = 1; }
unsigned int num_element() { printf("\nEnter the number of push on button Int1 for invert led\n",str); gets (str, sizeof(str)); N = atoi(str); // ASCII to integer return N; }
void intrrupt_butInt1(void) interrupt 2 { if (i == N - 1){ i = 0; if (a == 1, b == 0, c == 0){ a = 0; b = 1; c = 1; } else{ a = 1; b = 0; c = 0; } P3_3 = a; P3_4 = b; P3_5 = c; } i++; // WHY WHEN cursor CAME TO THIS POINT, JUMP TO BEGIN INTERRUPT. BUT DON'T T0 MAIN // IE1 = 0; если активировать то выйдет, но назад по нажатиюю кнопки не попадет. }
void main( void ){ P3 ^= 0x00; initialize_system(); for (delay = 0; delay < 0x1FFF; delay++); N = num_element(); kscanf(str); A = atoi(str); while(TH0 < A){ pprintf(str); } } макет платы на протеусе прилагаеться.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 18 2011, 16:00
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Цитата(DpInRock @ Mar 18 2011, 17:45)  У человека скорее всего "не работает" модель в протеусе.
Что будет делать программа когда перестанет выполняться условие while в main? У меня работает модель в протеусе. Аедь не может быть что бы на ассемблере програма выходила из прерывания а в си модель не работала. я пробывал делать while бесконечный. тоже самое. Цитата(sigmaN @ Mar 18 2011, 14:04)  Я бы в прерывании задержки не ставил... мутное какое-то прерывание однако...мутное...
а ещё volatile на все глобальные переменные, которые используются в прерывании - прописная истина же. Эм, обьясни зачем оно переменным в данном случае. Ну кроме того что прописаная истина. переписывал с таким концом void main( void ){ P3 ^= 0x00; initialize_system(); for (delay = 0; delay < 0x1FFF; delay++); N = num_element(); // kscanf(sss); // L = atoi(sss); while(TH0 < 10){ L++; // pprintf(L); } } цикл Вайл теперь бесконечный, не помогло.
Сообщение отредактировал Дар - Mar 18 2011, 16:02
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 18 2011, 16:51
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Цитата(_Pasha @ Mar 18 2011, 18:30)  Тогда в чем проблема? Берете в пошаговой трассировке включаете ctrl-D(дизассемлер) - и разбор полетов. проблема в том что я вижу в дизасеблере как включаеться команда reti выходит в точку и тут же возвращаеться назад как будто кнопка нажата еще раз. то есть выходит и сразу заходит на зад на вектор прервания.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 18 2011, 19:04
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Цитата(DpInRock @ Mar 18 2011, 20:39)  А какой именно 8051 вы используете. --- Ибо вы куда-то дели настройку прерывания по фронту. --- intel 8051AH EA =1; разрешение всех прерываний EX1 IE.2 Бит разрешения внешнего прерывания 1. Установка/сброс программой для разрешения/запрета прерываний. IT1 ОН ЖЕ TCON.2 Бит управления типом прерывания 1. Устанавливается/ сбрасывается программно для спецификации запроса ЗПР1/ (срез/низкий уровень). IE1 TCON.3 Флаг фронта прерывания 1. Устанавливается аппаратно, когда детектируется срез внешнего сигнала ЗПР1/ (INT1/) Сбрасывается при обслуживании прерывания . ЕСЛИ УСТАНОВИТЬ ЭТОТ БИТ В РУЧНУЮ ТО ПРОСТО БУДЕТ ПОПАДПТЬ В ПРЕРЫВАНИЕ БЕЗНАЖАТИЯ НА КНОПКУ. тАК ЧТО Я НЕ ПОНЯЛ О КАКОЙ НАСТРОЙКЕ МЕНЯ СПРАШИВАЛИ, ЕСЛИ МОЖНО ОБЬЯСНИ.TCON |=0x04; IE |=0x84; ТОЧНО ТАКИЕ ЖЕ НАСТРОЙКИ, ТОЛЬКО НЕ ПО БИТОВО , А НАПРЯМУЮ В РЕГИСТРЫ // Цитата(_Pasha @ Mar 18 2011, 20:42)  И шо показывает SP? И когда заходит - хоть одну команду выполняет или нет? да когда повторно попадает\заходит в прерывание выполняет все команды в нем. SP ? А что сп востанавливаеться. после выхода, и ояпть меняеться после вход. только очень быстро не пошагово не видно. если в числах(хотя не знаю что это может показать то sp=0x2f в main и 31 при начаде прерывания, потом 35 и опять 2а после reti и след шагом снова 31.) Я очень подробно описываю и часто повторяюсь по старой привычке инфы мало не бывает.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 09:45
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Цитата(DpInRock @ Mar 19 2011, 08:30)  Скакой частотой мигают диоды (оценочно - герцы, много герц). Стоит ли большой конденсатор на кнопке. Ну я не знаю как определить частотоу мигания в герцах. но мне кажтеться не очень быстро(нет ну на вид так мелкают почти не разглядеть, но если учесть что если устроить мигание диодов в цикле без прерывания. то без задержки не будет видно как они зжаигаються и тухнут. Слишком быстро, будет видно что они как будто поагшены вся время). СКорость передчи 4800 бод. , а внутреяя частота процсора 11.0592 мГц. стоит. но вот еще и картинка сехемы, что б в портеусе не открыватья макет(тем более что его может и не быть)
Сообщение отредактировал Дар - Mar 19 2011, 09:49
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 11:08
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
я пробывал вырубать все оставляя только светодиоды и прерывание. #include <reg51.h> //#include <stdlib.h> //#include <stdio.h>
sbit P3_5 = P3^5; sbit P3_4 = P3^4; sbit P3_3 = P3^3; static unsigned int delay = 0; char xdata str[200]; //volatile int N; unsigned int L = 1; unsigned int i = 0; unsigned int a = 1; unsigned int b = 0; unsigned int c = 0;
void initialize_system (void){ // SCON = 0x52; // TMOD |= 0x20; // TH1 = 0xFa; // TR1 = 1; // TI = 1;
P3_3 = a; P3_4 = b; P3_5 = c;
TCON |=0x04; // 3 IE |=0x84;
}
/* unsigned int num_element() { printf("\nEnter the number of push on button Int1 for invert led\n",str); gets (str, sizeof(str)); N = atoi(str); // ASCII to integer return N; } */ void intrrupt_butInt1(void) interrupt 2 { while (i == 5 - 1){ i = 0; if (a == 1, b == 0, c == 0){ a = 0; b = 1; c = 1; } else { a = 1; b = 0; c = 0; } P3_3 = a; P3_4 = b; P3_5 = c; } i++; // IE1 = 0; }
void main( void ){ P3 ^= 0x00; initialize_system(); for (delay = 0; delay < 0x1FFF; delay++); // N = num_element(); while(TH0 < 10){ L++; } }
тот же эфект. Не понятно вообще ничего. почему при записи на языке Асм вся норально, а на Си. такая хрен. ведь не олжно быть разницы. посути в дизасемблировании то эе самоенаписано.
Сообщение отредактировал Дар - Mar 19 2011, 11:11
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 12:15
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
реальная схема в аудитории. но макет с нее делался.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 14:13
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
И что в схеме не так? и почему этого раньше никто не заметил. В КПИ уже 3 курс используют этот макет.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 15:28
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Спасибо за указания, попробую переделать макет. Хотя все еще не понимаю как по вашему функция atoi. и printf могут быть связаны с прерыванием(я их на ассеблере видел, ну то что отображаеться в cntrl+D).
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 17:28
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
бЛин точно, спасибо. это да, это дали маху.
только что попробывал вырубить, походу это не едиственый бок. так как не помогло.
Сообщение отредактировал Дар - Mar 19 2011, 17:30
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 19 2011, 20:01
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
диод который на порте 3_3
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 20 2011, 12:16
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
Цитата(SysRq @ Mar 19 2011, 22:27)  Ну Proteus вполне себе переключает два оставшихся на каждое четвертое нажатие кнопки, согласно логике выложенной вами выше (#15) программы (а на P3_5 еще пищалка висит у вас, дада). Собстно, поэтому и интересуюсь, что же там "не помогло", и чего ж надобно-то? не помогло, изтятие из програмы 3 диода, оставил только два. тоже самое. заскакивает в прервание сраху после выхода.
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 20 2011, 13:27
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(Дар @ Mar 20 2011, 15:16)  не помогло, изтятие из програмы 3 диода, оставил только два. Дайте KEIL'овский проект целиком, посмотрим.. -- Цитата(_Pasha @ Mar 20 2011, 14:49)  "Пляска Святого Витта." Ну и аватарка у него в Википедии
|
|
|
|
|
Mar 20 2011, 15:42
|

Группа: Участник
Сообщений: 14
Регистрация: 18-03-11
Из: Киев
Пользователь №: 63 685

|
--------------------
Восточные девушки хороши до безобразия, а также во время безобразия и после безобразия. Не знаешь класики, не узнаешь ничего.
|
|
|
|
|
Mar 20 2011, 18:50
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(Дар @ Mar 20 2011, 18:42)  Вот Проэкт. 0) Где файл "DEBUG.A51"? 1) Опции проекта таковы, что ни *.hex, ни что иное, пригодное для Proteus'а\прогрмматора, не создаётся. Отладчик KEIL'а настроен на что-то внешнее (не симулятор). Собственно, чем же вы проверяете работоспособность? 2) В опциях linker'а жёстко задан начальный адрес сегмента кода (и не только). Значение не является верным для 8051AH. В Proteus'е работать будет, в реальном МК - нет. Ежели собрать проект со стандартным startup'ом, то в Proteus'е, в вашей же схеме, оно исправно работает...
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|