|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:16 am
|
Страница 1 от 1
|
[ 4 мнения ] |
|
RQ: ATMega външни прекъсвания - странност
| Автор |
Съобщение |
|
NikB
Ранг: Почетен член
Регистриран на: Съб Сеп 25, 2004 10:32 pm Мнения: 710
|
 RQ: ATMega външни прекъсвания - странност
RQ: ATMega външни прекъсвания - странност, която не мога да си обясня.
Кодът е дълъг за пример, но е спретнат и еднотипен  .
(В атачнатия файл сорсът е заедно с проектни файлове за AvrStudio 4 и 5 и Протеус симулация)
Та по същество:
Въпреки, че всичко е абсолютно еднакво за външни прекъсвания от 4 до 7, бит 7 се държи различно от останалите - сработва при отпускане на бутона, а не при натискане.
Дори след инициализация (след глобалното разрешаване на прекъсванията - реда "sei();") състоянието на изхода, "свързан" към SIG_INTERRUPT7 е различно от останалите.
(Ако не разреша прекъсванията, т.е. ако sei() е в коментар - състоянията са еднакви).
Някъде не доглеждам нещо (или не съм дочел някоя особеност).
 |  |  |  | Код: #include <avr/io.h> #include <avr/interrupt.h>
volatile uint8_t LedIsOn[4] = {0, 0, 0, 0}; volatile uint8_t LedPortB[4] = {PORTB4, PORTB5, PORTB6, PORTB7}; volatile uint8_t bit_DDE[4] = {DDE4, DDE5, DDE6, DDE7}; volatile uint8_t bit_PortE[4] = {PORTE4, PORTE5, PORTE6, PORTE7}; volatile uint8_t bit_ISC0[4] = {ISC40, ISC50, ISC60, ISC70}; volatile uint8_t bit_ISC1[4] = {ISC41, ISC51, ISC61, ISC71}; volatile uint8_t bit_INT[4] = {INT4, INT5, INT6, INT7};
// Обработчик прерывания. void Interrupt_Ext( uint8_t aInd){ LedIsOn[ aInd] ^= 1; if ( LedIsOn[ aInd]) { PORTB |= (1 << LedPortB[ aInd]); // Включаем светодиод. } else { PORTB &= ~(1 << LedPortB[ aInd]); // Выключаем светодиод } } SIGNAL(SIG_INTERRUPT4){ Interrupt_Ext( 0); } SIGNAL(SIG_INTERRUPT5){ Interrupt_Ext( 1); } SIGNAL(SIG_INTERRUPT6){ Interrupt_Ext( 2); } SIGNAL(SIG_INTERRUPT7){ Interrupt_Ext( 3); }
int main(void){ void xInit_Inp( uint8_t aInd){ // Настраиваем порт на котором висят кнопки DDRE &= ~(1 << bit_DDE[ aInd]); // Port direction: input PORTE |= (1 << bit_PortE[ aInd]); // PulUp: On EICRB = (1 << bit_ISC0[ aInd]) | (1 << bit_ISC1[ aInd]); // Прерывание по возрастающий фронту сигнала. EIMSK |= (1 << bit_INT[ aInd]); // Разрешаем внешнее прерывание, заведенное на порт кнопки. } // Конфигурируем порт на выход. DDRB |= (1 << DDB7) | (1 << DDB6) | (1 << DDB5) | (1 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (1 << DDB0); PORTB = 0; // Настраиваем порт на котором висят кнопки xInit_Inp( 0); xInit_Inp( 1); xInit_Inp( 2); xInit_Inp( 3); sei(); // Глобальное разрешение прерываний.
/* !!! */ // Бесконечный цикл. while(1) { uint16_t i; for(i = 65535; i != 0; i--); PORTB &= ~(1 << PORTB0); // Выключаем светодиод 1. for(i = 65535; i != 0; i--); PORTB |= (1 << PORTB0); // Включаем светодиод 1. } /* */ } |  |  |  |  |
Последна промяна NikB на Пет Мар 18, 2011 2:19 pm, променена общо 1 път
|
| Пет Мар 18, 2011 2:03 pm |
|
 |
|
NikB
Ранг: Почетен член
Регистриран на: Съб Сеп 25, 2004 10:32 pm Мнения: 710
|
Да сложа и картинка
|
| Пет Мар 18, 2011 2:06 pm |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Това което на пръв поглед виждам е, че си изпуснал един "OR"
според мен трябва да е
Защото, на всяко конфигуриране на пин, се записва само неговите сенс конфигурационни битове, и свяко следващо презаписва предходната конфигурация
|
| Пет Мар 18, 2011 2:54 pm |
|
 |
|
NikB
Ранг: Почетен член
Регистриран на: Съб Сеп 25, 2004 10:32 pm Мнения: 710
|
Не съм го изпуснал, ами съм го "подредил" (вероятно съм го изтрил, докато съм се опитвал да "подредя" сорса).
И без него - в EICRB остава само това, което е за bit7 (щото се инициализира последен)
МНОГО благодаря
(въобще не мио мина през ума, че може да е такава грешката, за да проверя, а е било доста логично)
(а сега си мисля, че докато съм се чудел е можело да разместя битовете, за диагностика  )
Благодаря!
|
| Пет Мар 18, 2011 3:09 pm |
|
|
|
Страница 1 от 1
|
[ 4 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 3 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|