Сергей Борщ 123 17 ноября, 2010 Опубликовано 17 ноября, 2010 · Жалоба Может где-то нужно вектора прописывать? Кусок с прерываниями взял из примера.Понятия не имею как в последних версиях, в 4.хх надо было перед вектором прописывать #pragma vector. А что у вас дизассемблер отладчика показывает по адресу вектора IRQ (0x18)? И если на этот адрес поставить точку останова - туда программа попадает? Глобально прерывания разрешены (бит I в CPSR)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 18 ноября, 2010 Опубликовано 18 ноября, 2010 · Жалоба Добавил #pragma vector = 0x18, если на этот адрес поставить точку останова - туда программа НЕ попадает. Бит I в CPSR установлен в 1, хотя я его не устанавливал. Куда еще глянуть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 18 ноября, 2010 Опубликовано 18 ноября, 2010 · Жалоба Бит I в CPSR установлен в 1, хотя я его не устанавливал. Куда еще глянуть?Для начало в описание ядра ARM7, там написано что 1 в бите I означает "прерывания глобально запрещены в ядре" и оно в таком состоянии оказывается каждый раз после сброса. Потом гляньте описание компилятора на предмет функции enable_interrupt(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 18 ноября, 2010 Опубликовано 18 ноября, 2010 · Жалоба Да, спасибо, я уже проделал данные манипуляции (добавил функцию enable_interrupt()). Но в ломаной версии IAR5, прерывания не заработали. Скачал новый v. 6.10, 32K Kickstart Edition. Там прерывания заработали. Кстати, как вы и говорили, если в дебагере смотреть регистры прерывания, то получаются некорректные результаты. И в обработчике прерывания нужно обязательно прописывать #pragma vector = 0x18, иначе не работает, хотя в примерах от самого IAR нет ни enable_interrupt(), ни #pragma vector = 0x18. Теперь настраиваю UART в 8-ми битном режиме, потом нужно будет как-то 9-ти битный режим запускать. Пока из массива в несколько байт, UART передает только первые 2 и умолкает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 18 ноября, 2010 Опубликовано 18 ноября, 2010 · Жалоба Кстати, как вы и говорили, если в дебагере смотреть регистры прерывания, то получаются некорректные результаты.Да, потому что чтение некоторых из этих регистров может изменять их значения (неважно какое чтение - ядром или отладчиком). И в обработчике прерывания нужно обязательно прописывать #pragma vector = 0x18, иначе не работает, хотя в примерах от самого IAR нет ни enable_interrupt(), ни #pragma vector = 0x18.Обработчики прерываний можно оформлять разными способами. Посмотрите здесь: http://electronix.ru/forum/index.php?showt...mp;#entry191159 Пока из массива в несколько байт, UART передает только первые 2 и умолкает.Не видя кода подсказать могут разве что очень продвинутые телепаты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 18 ноября, 2010 Опубликовано 18 ноября, 2010 · Жалоба Не видя кода подсказать могут разве что очень продвинутые телепаты. Да я понимаю, просто в данный момент программы нет под рукой :))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 19 ноября, 2010 Опубликовано 19 ноября, 2010 (изменено) · Жалоба Привожу текст программы, которую сейчас ковыряю. Данная программа взята из примеров, но почему-то без дополнительных костылей не работает. Как уже говорил ранее, UART отсылает первые 2 байта из массива szTemp[] и умолкает, хотя прерывания генерируются. // Bit Definitions #define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 #define BIT8 0x100 #define BIT9 0x200 #define BIT10 0x400 #define BIT11 0x800 #define BIT12 0x1000 #define BIT13 0x2000 #define BIT14 0x4000 #define BIT15 0x8000 #include <Analogdevices/ioaduc7061.h> # include "stdio.h" # include "string.h" #include <intrinsics.h> #include <arm_interrupt.h> volatile unsigned char bSendResultToUART = 0; // Flag used to indicate ADC0 resutl ready to send to UART unsigned char szTemp[16] = ""; // Used to store ADC0 result before printing to UART unsigned char ucTxBufferEmpty = 0; // Used to indicate that the UART Tx buffer is empty volatile unsigned long ulADC0Result = 0; // Variable that ADC0DAT is read into in ADC0 IRQ float V; int main(void) { unsigned char i = 0; unsigned char nLen = 0; POWKEY1 = 0x1; POWCON0 = 0x78; // Set core to max CPU speed of 10.24Mhz POWKEY2 = 0xF4; // Initialize the UART for 9600-8-N GP1CON = BIT0 + BIT4; // Select UART functionality for P1.0/P1.1 COMCON0 = BIT7; // Enable access to COMDIV registers COMDIV0 = 0x21; // Set baud rate to 9600. COMDIV1 = 0x00; //COMDIV2 = 0x21 + BIT11; // Enable fractional divider for more accurate baud rate setting COMCON0 = BIT0 + BIT1 + BIT2; COMIEN0 = BIT0 + BIT1; // Enable UART interrupts when Rx full and Tx buffer empty. // Configure ADC0 for continuous conversions, 1Khz, AIN0 in Single-ended mode ADCMSKI = BIT0; // Enable ADC0 result ready interrupt source ADCFLT = 0x7; // Chop off, 1Khz samping rate, SF = 7. No averaging ADCMDE = BIT0 + BIT7; // Continuous Conversion mode, Normal mode, 4Mhz clock source to ADC. ADC0CON = BIT4 + BIT6 + BIT7 + BIT8 + // AIN0 selected in Single ended mode BIT10 + // Unipolar ADC output BIT15; // Gain = 1, Buffer on. Also, Int reference, ADCCFG = 0; IRQEN = BIT10 + BIT11; // Enable ADC and UART interrupts __enable_interrupt(); bSendResultToUART = 0; while (1) { if (bSendResultToUART == 1) // Is there an ADC0 result ready for UART transmission? { sprintf ( (char*)szTemp, "%lu\r",ulADC0Result ); // Send the ADC0 Result to the UART nLen = strlen((char*)szTemp); for ( i = 0 ; i < nLen ; i++ ) // loop to send ADC0 result { COMTX = szTemp[i]; ucTxBufferEmpty = 0; while (ucTxBufferEmpty == 0) } } } } #pragma vector = 0x18 __irq __arm void IRQ_Handler(void) { unsigned long IRQSTATUS = 0; unsigned char ucCOMIID0 = 0; IRQSTATUS = IRQSTA; // Read off IRQSTA register if ((IRQSTATUS & BIT11) == BIT11) //UART interrupt source { ucCOMIID0 = COMIID0; if ((ucCOMIID0 & 0x2) == 0x2) // Transmit buffer empty { ucTxBufferEmpty = 1; } } if ((IRQSTATUS & BIT10) == BIT10) //If ADC0 interrupt source { ulADC0Result = ADC0DAT; // Read ADC0 conversion result bSendResultToUART = 1; } } Оказалось, причина умолкания UARTа в том, что регистр COMRX нигде не считывался, соответственно, флаг прерывания по приему не сбрасывался и программа крутилась в прерывании по UART. Вот, что добавил: if ((ucCOMIID0 & 0x4) == 0x4) // Receive buffer empty { V=COMRX; } Теперь вопрос. Как организовать прием и обработку 9-ого бита данных? Изменено 19 ноября, 2010 пользователем IgorKossak Пользуйтесь тэгами Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 19 ноября, 2010 Опубликовано 19 ноября, 2010 · Жалоба Привожу текст программы, которую сейчас ковыряю.1) ucTxBufferEmpty должен быть volatile. 2) COMTX = szTemp[i]; ucTxBufferEmpty = 0; while (ucTxBufferEmpty == 0); попробуйте переделать в ucTxBufferEmpty = 0; COMTX = szTemp[i]; while (ucTxBufferEmpty == 0); или while (ucTxBufferBusy == 1); ucTxBufferBusy = 1; COMTX = szTemp[i]; Данная программа взята из примеров Такими примерами лучше не пользоваться. Теперь вопрос. Как организовать прием и обработку 9-ого бита данных?Понятия не имею. Может кто-то другой подскажет, или придется вам перечитывать даташит и думать, думать, думать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 19 ноября, 2010 Опубликовано 19 ноября, 2010 · Жалоба Я пример этот взял, чтобы можно было на что-то опираться при обсуждении возникающих вопросов. Мне кажется, что не удобно приводить куски кода с кучей непонятных переменных, а здесь все просто. Сейчас сделал обработку 9-ого бита. Все работает пока идут запросом, например только четные байты, если приходит нечетный байт, то происходит перенастройка регистра, который определяет установлен ли 9-ый бит. при этом на этот запрос ответа не получаем. На следующий нечетный байт мы нормально отвечаем, это длится пока идут нечетные байты. Картина повторяется при приходе четного байта. Из-за потерь на перенастройку у головного устройства возникают ошибки по неответам - это плохо. Сейчас думаю как все поправить. Код пока не привожу, т.к. там сейчас черт ногу сломит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gmp 0 24 ноября, 2010 Опубликовано 24 ноября, 2010 (изменено) · Жалоба Привожу кусок кода с обработкой 9-ого бита, может кому пригодится. Здесь 0x81, 0x3F и 0xC2 это адресные байты, которые мне надо обрабатывать. У вас могут быть свои. // Initialize the UART for 9600-9-N GP1CON = BIT0 + BIT4; // Select UART functionality for P1.0/P1.1 COMCON0 = BIT7; // Enable access to COMDIV registers COMDIV0 = 0x21; // Set baud rate to 9600. COMDIV1 = 0x00; COMCON0 = BIT0 + BIT1 + BIT3+BIT4 COMIEN0 = BIT0 + BIT1; // Enable UART interrupts when Rx full and Tx buffer empty. // Прерывания #pragma vector = 0x18 __irq __arm void IRQ_Handler(void) { unsigned long IRQSTATUS = 0; unsigned char ucCOMIID0 = 0; unsigned char ucCOMSTA0 = 0; unsigned char UDR_t; IRQSTATUS = IRQSTA; // Read off IRQSTA register if ((IRQSTATUS & BIT11) == BIT11) //UART interrupt source { ucCOMIID0 = COMIID0; if ((ucCOMIID0 & 0x4) == 0x4) // Receive buffer empty { UDR_t=COMRX; ucCOMSTA0=COMSTA0; if (((ucCOMSTA0 & 0x4) == 0x4)&&((UDR_t==0x81)||(UDR_t==0x3F))) bit9=1; else if (((ucCOMSTA0 & 0x4) != 0x4)&&(UDR_t==0xC2)) bit9=1; else bit9=0; .................... } } } Изменено 24 ноября, 2010 пользователем gmp Вопросы таблеток здесь не обсуждаются Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться