Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USART на AT91rm9200
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Daermon
Помогите разобраться с последовательностью действий для работы с USART на AT91rm9200

Произвожу след действия:

_Usart.Init(AT91C_BASE_US1,AT91C_US_ASYNC_MODE, AT91C_ID_US1);
_Usart.AIC_Config_EnableInterrupt(AT91C_BASE_US1,AT91C_ID_US1);
_Usart.Start(AT91C_BASE_US1,AT91C_ID_US1);


void Usart1::Init(AT91PS_USART USART_PT, unsigned int Mode, unsigned int UsartId)
{
AT91F_US_Close(USART_PT);
AT91C_BASE_PMC->PMC_PCDR |= (1<<UsartId);

// На плате AS-9200 выведен разьем USART1 его и конфигурирую...вот правильно или нет - не знаю!
AT91C_BASE_PIOB->PIO_ASR = ((unsigned int) AT91C_PB21_RXD1)|((unsigned int) AT91C_PB20_TXD1);
AT91C_BASE_PIOB->PIO_BSR = 0;
AT91C_BASE_PIOB->PIO_PDR = ((unsigned int) AT91C_PB21_RXD1)|((unsigned int) AT91C_PB20_TXD1);

AT91C_BASE_PMC->PMC_PCER |=(1<< UsartId);

AT91F_US_Configure(USART_PT, MCK, Mode ,57600 ,0 );

}


void Usart1::AIC_Config_EnableInterrupt(AT91PS_USART USART_PT,unsigned int UsartId)
{
unsigned int status;
status=(USART_PT->US_CSR) ;
status=status;
AIC_DisableInterrupt(UsartId);
AIC_Config(USART_PT,UsartId);
AIC_EnableInterrupt(UsartId);
}


void Usart1::Start(AT91PS_USART USART_PT,unsigned int UsartId)
{
AT91F_US_EnableTx(USART_PT);
WriteData(USART_PT,"0xaa",sizeof("0xaa"),0,0);
}

void Usart1::WriteData(AT91PS_USART USART_PT ,char *buffer, unsigned int counter,char *buffer2,unsigned int counter2)
{
AT91PS_PDC pPDC= (AT91PS_PDC) &(USART_PT->US_RPR);
if( ( pPDC->PDC_TCR)==0)
{
pPDC->PDC_TPR = (unsigned int)buffer;//RS232_Buf.Buf_Out;//
pPDC->PDC_TCR = counter;//RS232_Buf.TxSize;//
AT91F_US_EnableIt (USART_PT, AT91C_US_ENDTX);
}
if((pPDC->PDC_TNCR)==0)
{
pPDC->PDC_TNPR = (unsigned int)buffer2;
pPDC->PDC_TNCR = counter2;
AT91F_US_EnableIt (USART_PT, AT91C_US_ENDTX);
}
return;
}


Правильно ли я делаю?
Daermon
void Init(AT91PS_USART USART_PT, unsigned int Mode, unsigned int UsartId)
{
AT91F_US_Close(USART_PT); // çàêðûâàåì
AT91C_BASE_PMC->PMC_PCDR |= (1<<UsartId); // îòêëþ÷àåì


AT91C_BASE_PIOB->PIO_PDR = ((unsigned int) AT91C_PB21_RXD1)|((unsigned int) AT91C_PB20_TXD1);

AT91C_BASE_PMC->PMC_PCER |=(1<< UsartId); // ðàçðåøàåì

AT91F_US_Configure(USART_PT, MCK, Mode ,57600 ,0 );

//**********************************************************************
AT91C_BASE_AIC->AIC_IDCR |= ( 1<<UsartId) ;

if(USART_PT==AT91C_BASE_US1){AT91C_BASE_AIC->AIC_SVR[UsartId] = ( AT91_REG )IRQ1_RS232 ;}
AT91C_BASE_AIC->AIC_SMR[UsartId] = ( AT91C_AIC_PRIOR_LOWEST )|( 7 ) ;

AT91C_BASE_AIC->AIC_ICCR |= ( 1<<UsartId) ;
AT91C_BASE_AIC->AIC_IECR |= ( 1<<UsartId) ;

AT91F_US_EnableTx(USART_PT);

AT91F_US_EnableIt (USART_PT, AT91C_US_ENDTX);

AT91F_US_SendFrame(USART_PT,"55",sizeof("55"),0,0 );
}

Использую все функции inline из lib_AT91RM9200.h
Подскажите чего не хватает??????????????
Leen
Не увидел разрешения клоков на ПИОБ и разрешения пину ТХ работать как выход. Могу кинуть примером (самописным) для САМ7С
Daermon
Цитата(Leen @ Nov 12 2007, 15:48) *
Не увидел разрешения клоков на ПИОБ и разрешения пину ТХ работать как выход. Могу кинуть примером (самописным) для САМ7С

mailto::daemonwww@mail.ru

Скинь плиз

Могу добавить:
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,1<<20 );
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB,1<<20 );

А в PMC уже разрешал USART1
AT91C_BASE_PMC->PMC_PCER |=(1<< UsartId); // ðàçðåøàåì

Все равно не пашет
Leen
Код
AT91C_BASE_PMC->PMC_PCER =(1<< PioBId);

И, кстати, этот регистр writeonly? Если да, то писать
AT91C_BASE_PMC->PMC_PCER |=(1<< UsartId); - ошибка, т.к. это чтение-модификация-запись. Если регистр read-write, то все нормально.
Daermon
Опа..точно он же только на запись...
Daermon
Почему не могу вызвать прерывания?
Передача осуществляется, а ни каких прерываний не происходит...пытался средствами IAR отловить переход на вектор прерывания.

void Usart1::AIC_Init(void)
{
AT91F_AIC_CfgPMC();
}
//------------------------------------------------------------------------
void Usart1::UART1_Init(void)
{
AT91F_US1_CfgPMC();


AT91F_US_Configure (
AT91C_BASE_US1, // \arg pointer to a USART controller
60000000, // \arg peripheral clock - 60 ÌÃö
AT91C_US_USMODE_NORMAL | // normal mode
AT91C_US_CLKS_CLOCK | // clock is MCK
AT91C_US_CHRL_8_BITS | // 8 databits
AT91C_US_PAR_NONE | // no parity
AT91C_US_NBSTOP_1_BIT | // 1 stopbit
AT91C_US_CHMODE_NORMAL // channel mode - normal
// AT91C_US_CHMODE_LOCAL // channel mode - local
, // \arg mode Register to be programmed
57600 , // \arg baudrate to be programmed
0 ); // \arg timeguard to be programmed

AT91F_US_ResetTx(AT91C_BASE_US1);
AT91F_US_ResetRx(AT91C_BASE_US1);

AT91F_US_EnableTx(AT91C_BASE_US1);
AT91F_US_EnableRx(AT91C_BASE_US1);

AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US1,AT91C_AIC_PRIOR_LOWEST, 0, (void (*)(void))IRQ1_RS232);
__enable_interrupt( ) ;

AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US1);
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_RXRDY|AT91C_US_TXRDY|AT91C_US_ENDRX| AT91C_US_ENDTX|AT91C_US_TXEMPTY|AT91C_US_TXBUFE|AT91C_US_RXBUFF); Разрешаю все прерывания USART
char buf[1];
buf[0] = 65;
AT91F_US_SendFrame(AT91C_BASE_US1, buf,sizeof(buf[0]),0,0);

}
Leen
Цитата(Daermon @ Nov 13 2007, 19:37) *
Почему не могу вызвать прерывания?
Передача осуществляется, а ни каких прерываний не происходит...пытался средствами IAR отловить переход на вектор прерывания.

void Usart1::AIC_Init(void)
{
AT91F_AIC_CfgPMC();
}
//------------------------------------------------------------------------
void Usart1::UART1_Init(void)
{
__enable_interrupt( ) ;

AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US1);
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_RXRDY|AT91C_US_TXRDY|AT91C_US_ENDRX| AT91C_US_ENDTX|AT91C_US_TXEMPTY|AT91C_US_TXBUFE|AT91C_US_RXBUFF); Разрешаю все прерывания USART
char buf[1];
buf[0] = 65;
AT91F_US_SendFrame(AT91C_BASE_US1, buf,sizeof(buf[0]),0,0);

}

1 Как я понял, есть дебагер. Ставь бряк на вектор IRQ (не помню, там в дизассемблере что-то типа LDR PS,PS, -0xсколько-то, расположено почи сразу после 0-го вектора - 4 или 5-е слово памяти). Мониторь состояние усарта. Если есть один вход в прерывание, а второго и последующего - нет, значит, не пишешь AIC->AIC_EOICR = чему_угодно. Хотя вроде, если память не спит с другим, яр сам генреит это в эпилоге. не уверен.
2 А AIC_Init(void) точно вызывается?
3 А не проще ли вместо
Цитата
char buf[1];
buf[0] = 65;
AT91F_US_SendFrame(AT91C_BASE_US1, buf,sizeof(buf[0]),0,0);

писать
Цитата
char buf;
buf = 65;
AT91F_US_SendFrame(AT91C_BASE_US1, &buf,sizeof(buf),0,0);

4 Если есть AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US1); то зачем __enable_interrupt( ) ;?
5 Если попробовать разрешить AT91F_US_EnableIt(AT91C_BASE_US1,0xFFFFFFFF)
sergeeff
Ну а таблица векторов прерываний? Сама процедура обработки прерываний?

К тому же, начала надо AT91F_US_EnableIt(..), а потом AT91F_AIC_EnableIt(..).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.