Перейти к содержанию
    

Может где-то нужно вектора прописывать? Кусок с прерываниями взял из примера.
Понятия не имею как в последних версиях, в 4.хх надо было перед вектором прописывать #pragma vector. А что у вас дизассемблер отладчика показывает по адресу вектора IRQ (0x18)? И если на этот адрес поставить точку останова - туда программа попадает? Глобально прерывания разрешены (бит I в CPSR)?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добавил #pragma vector = 0x18, если на этот адрес поставить точку останова - туда программа НЕ попадает. Бит I в CPSR установлен в 1, хотя я его не устанавливал. Куда еще глянуть?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бит I в CPSR установлен в 1, хотя я его не устанавливал. Куда еще глянуть?
Для начало в описание ядра ARM7, там написано что 1 в бите I означает "прерывания глобально запрещены в ядре" и оно в таком состоянии оказывается каждый раз после сброса. Потом гляньте описание компилятора на предмет функции enable_interrupt().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, спасибо, я уже проделал данные манипуляции (добавил функцию enable_interrupt()). Но в ломаной версии IAR5, прерывания не заработали. Скачал новый v. 6.10, 32K Kickstart Edition. Там прерывания заработали.

 

Кстати, как вы и говорили, если в дебагере смотреть регистры прерывания, то получаются некорректные результаты. И в обработчике прерывания нужно обязательно прописывать #pragma vector = 0x18, иначе не работает, хотя в примерах от самого IAR нет ни enable_interrupt(), ни #pragma vector = 0x18.

 

Теперь настраиваю UART в 8-ми битном режиме, потом нужно будет как-то 9-ти битный режим запускать. Пока из массива в несколько байт, UART передает только первые 2 и умолкает.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, как вы и говорили, если в дебагере смотреть регистры прерывания, то получаются некорректные результаты.
Да, потому что чтение некоторых из этих регистров может изменять их значения (неважно какое чтение - ядром или отладчиком).

И в обработчике прерывания нужно обязательно прописывать #pragma vector = 0x18, иначе не работает, хотя в примерах от самого IAR нет ни enable_interrupt(), ни #pragma vector = 0x18.
Обработчики прерываний можно оформлять разными способами. Посмотрите здесь: http://electronix.ru/forum/index.php?showt...mp;#entry191159

Пока из массива в несколько байт, UART передает только первые 2 и умолкает.
Не видя кода подсказать могут разве что очень продвинутые телепаты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не видя кода подсказать могут разве что очень продвинутые телепаты.

 

Да я понимаю, просто в данный момент программы нет под рукой :)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привожу текст программы, которую сейчас ковыряю. Данная программа взята из примеров, но почему-то без дополнительных костылей не работает. Как уже говорил ранее, 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-ого бита данных?

Изменено пользователем IgorKossak
Пользуйтесь тэгами

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привожу текст программы, которую сейчас ковыряю.
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-ого бита данных?
Понятия не имею. Может кто-то другой подскажет, или придется вам перечитывать даташит и думать, думать, думать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я пример этот взял, чтобы можно было на что-то опираться при обсуждении возникающих вопросов. Мне кажется, что не удобно приводить куски кода с кучей непонятных переменных, а здесь все просто.

Сейчас сделал обработку 9-ого бита. Все работает пока идут запросом, например только четные байты, если приходит нечетный байт, то происходит перенастройка регистра, который определяет установлен ли 9-ый бит. при этом на этот запрос ответа не получаем. На следующий нечетный байт мы нормально отвечаем, это длится пока идут нечетные байты. Картина повторяется при приходе четного байта. Из-за потерь на перенастройку у головного устройства возникают ошибки по неответам - это плохо. Сейчас думаю как все поправить. Код пока не привожу, т.к. там сейчас черт ногу сломит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привожу кусок кода с обработкой 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;

 

....................

}

}

}

 

 

 

Изменено пользователем gmp
Вопросы таблеток здесь не обсуждаются

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...