реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Прием передача по USARTу
Timofey
сообщение Jul 3 2006, 06:38
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Добрый день, помогите пожалуйста, я новичок в этом деле и только начал осваивать AT91SAM7S64-EK
Мне дали программу, сделанную на делфи, она отсылает на ком порт данные, в виде 01 07 41 Е2 (4 байта). Мне нужно хотя бы считать их и передать назад. Но чего то не выходит. Принимается только последний байт. Подскажите пожалуйста, где моя ошибка. Пробывал передавать просто левые данные, то есть завел отдельную переменную где ручками уже указал что нужно отпоравлять, и оказалось что больше 4 байт он не отправляет, может я не сбрасываю какой то регистр? или что?
И еще, подскажите пожалуйста значение этих строк:
AT91C_BASE_US0->US_RCR = 100;
AT91C_BASE_US0->US_RTOR = 5;
Обязательно их снова вставлять в прерывании, ведь при конфигурации уже указывалось (слизано с примера из инета)?


Вот листинг программы полностью:

#include "Board.h"
#include <stdio.h>



#define USART_BAUD_RATE 9600

#define USART_INTERRUPT_LEVEL 6


#define AT91C_US_ASYNC_MODEmy ( AT91C_US_USMODE_NORMAL + \
AT91C_US_NBSTOP_1_BIT + \
AT91C_US_PAR_EVEN + \
AT91C_US_CHRL_8_BITS + \
AT91C_US_CLKS_CLOCK )

char BUFFREAD[100];
int len = 0 ;
int flag = 0;



////////////////////////////////////////////////
////функция разбора данных пришедших на порт////
////////////////////////////////////////////////
void funkc (char data[10])
{
AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_US0);
flag=0;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED1);
int j=0;
while (j<4){
while (!AT91F_US_TxReady(AT91C_BASE_US0));
AT91F_US_PutChar(AT91C_BASE_US0,datal[j]);
j++;
}

AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED1);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED2);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED3);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED4);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);
}



///////////////////////////////////////////
////////Прерывание USARta//////////////////
///////////////////////////////////////////
void Usart_c_irq_handler(void)
{

AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED2);
if (len>3) len=0;
BUFFREAD[len]=AT91F_US_GetChar(AT91C_BASE_US0);
len++;
AT91F_US_ResetRx(AT91C_BASE_US0);
AT91C_BASE_US0->US_RCR = 100;
AT91C_BASE_US0->US_RTOR = 5;
AT91C_BASE_US0->US_CSR=0x00;
AT91C_BASE_AIC->AIC_EOICR=0x00;
AT91C_BASE_AIC->AIC_ICCR=0x00;
flag=1;

}


///////////////////////////////////////////
////////Конфигурирование USARta////////////
///////////////////////////////////////////
void CnfUS ( void)
{
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<<AT91C_ID_US0 ) ;
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA,
((unsigned int) AT91C_PA5_RXD0 ) |
((unsigned int) AT91C_PA6_TXD0 ) ,
0 );
AT91F_US_Configure(AT91C_BASE_US0,
MCK ,
AT91C_US_ASYNC_MODEmy ,
USART_BAUD_RATE , 0);
AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN ;
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_US0,
USART_INTERRUPT_LEVEL,
AT91C_AIC_PRIOR_LOWEST,
Usart_c_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);
AT91C_BASE_US0->US_RCR = 100;
AT91C_BASE_US0->US_RTOR = 5;
AT91F_US_EnableIt(AT91C_BASE_US0, AT91C_US_RXBUFF | AT91C_US_TIMEOUT );

}




////////////////////////////////////////
// Основная функция////////////////////
///////////////////////////////////////
main (void)
{



//конфигурируем кнопки и светодиоды, порты
AT91F_PIOA_CfgPMC();

AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, LED_MASK);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED_MASK);

//232
CnfUS ();


//бесконечный цикл
while(1)
{
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED4);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED2);

if (flag==1 && len==3/ ) {


funkc (BUFFREAD, len);

}
}

}
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jul 3 2006, 07:44
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



RTOR - Receive TimeOut Register - устанавлиавет таймаут - если в течении N битовых интервалов нет приема взводит флаг TIMEOUT вCSR.
RCR Receive Count Register - счетчик приема DMA(PDC).
Цитата
и оказалось что больше 4 байт он не отправляет,

Код
int j=0;
while (j<4){
while (!AT91F_US_TxReady(AT91C_BASE_US0));
AT91F_US_PutChar(AT91C_BASE_US0,datal[j]);
j++

j !!!


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 3 2006, 08:24
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(beer_warrior @ Jul 3 2006, 13:44) *
RTOR - Receive TimeOut Register - устанавлиавет таймаут - если в течении N битовых интервалов нет приема взводит флаг TIMEOUT вCSR.
RCR Receive Count Register - счетчик приема DMA(PDC).
Цитата
и оказалось что больше 4 байт он не отправляет,

Код
int j=0;
while (j<4){
while (!AT91F_US_TxReady(AT91C_BASE_US0));
AT91F_US_PutChar(AT91C_BASE_US0,datal[j]);
j++

j !!!



Спасибо большое! .... Разобрался .... Прикольно оказывается ....
А насчет j действительно ... ступил )) Заработался блин ...
Go to the top of the page
 
+Quote Post
Zarya
сообщение Jul 11 2006, 20:03
Сообщение #4





Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752



В продолжение темы.
тоже только начал знакомится с IAR. задача в принципе тажа: нужно отправлять\принимать по USARTу.
проблема в следущем. у меня на плате используется USART1, а не как в примере USART0, казалось бы остается только переделать инициализацию ком порта и всё... а ничего подобного, не хочет отправлять посылать.
меняю просто константы для усарта, PA ... т.е пишу во так:
Цитата
void CnfUS ( void)
{
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<<AT91C_ID_US1 ) ;
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA,
((unsigned int) AT91C_PA21_RXD1 ) |
((unsigned int) AT91C_PA22_TXD1 ) ,
0 );
AT91F_US_Configure(AT91C_BASE_US1,
MCK ,
AT91C_US_ASYNC_MODEmy ,
USART_BAUD_RATE , 0);
AT91C_BASE_US1->US_CR = AT91C_US_RXEN | AT91C_US_TXEN ;
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_US1,
USART_INTERRUPT_LEVEL,
AT91C_AIC_PRIOR_LOWEST,
Usart_c_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
AT91C_BASE_US1->US_RCR = 100;
AT91C_BASE_US1->US_RTOR = 5;
AT91F_US_EnableIt(AT91C_BASE_US1, AT91C_US_RXBUFF | AT91C_US_TIMEOUT );
}


и не работает.... т.е компилится выполняется... но молчит, на второй конец ком порта пробовал "вешать" ComTest, прожка такая, принимает и отправляет байты.
А вот еще, на той плате впринципе есть еще и USART0 так там все нормально (но нужен именно USART1)
в чем может быть проблема? wacko.gif
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2006, 03:47
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Нууууу ....... US1, насколько я понимаю, - это 485 .... Его у меня нет на плате sad.gif Поэтому отвечу с точки зрения новичка не работавшего с ним ))
Мне кажется в конфигурировании нужно еще и другую скорость указать.
В конфигурировании AT91C_US_ASYNC_MODEmy вместо AT91C_US_USMODE_NORMAL поставил бы AT91C_US_USMODE_RS485.
И эту программу я еще дополнил двумя строчками, чтобы пользоваться DMA(PDC):
концовка конфигурирования
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);
AT91F_PDC_Open (AT91C_BASE_PDC_US0);
AT91C_BASE_US0->US_RPR = (unsigned int) BUFFREAD;
AT91C_BASE_US0->US_RCR = 100;
AT91C_BASE_US0->US_RTOR = 16;
AT91F_US_EnableIt(AT91C_BASE_US0, AT91C_US_RXBUFF | AT91C_US_TIMEOUT );
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS);

и пользуешься потом SendFrame ....
Ну а так .... фиг знает ... "бывалых" хотелось бы тоже послушать ... так как самому интересно .... smile.gif
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2006, 04:04
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Да! Там же еще нужно сконфигурировать одну ногу ... Вроде бы ... Которая разрешает на прием-передачу .... У меня это PA24 ....
Go to the top of the page
 
+Quote Post
Zarya
сообщение Jul 12 2006, 06:45
Сообщение #7





Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752



такссс... вобщем:
скажите плиз, чем должна отличаться инициализация USART0 от USART1?
на сколько я понимаю, нужно всего лишь поменять конфигурацию ножек, так?
P.S если это поможет, я использую AT91SAM7S256

Сообщение отредактировал Zarya - Jul 12 2006, 06:46
Go to the top of the page
 
+Quote Post
Zarya
сообщение Jul 12 2006, 07:14
Сообщение #8





Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752



Вобщем, вот такая настройка ни к чему не привела... Ну не хочет отправляться ничего и никуда.

Код
void Usart_init ( void )
{
    COM= AT91C_BASE_US1;
    AT91F_PIO_CfgPeriph(
     AT91C_BASE_PIOA,
     ((unsigned int) AT91C_PA21_RXD1    ) |
     ((unsigned int) AT91C_PA22_TXD1    ) , 0 );
    AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<<AT91C_ID_US1 );

    AT91F_US_Configure (COM, MCK, AT91C_US_ASYNC_MODE, USART_BAUD_RATE, 0);

    COM->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;

    AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_US1, USART_INTERRUPT_LEVEL,
                           AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Usart_c_irq_handler);
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
    AT91F_PDC_Open (AT91C_BASE_PDC_US1);
    COM->US_RPR = (unsigned int) buff_rx;
    COM->US_RCR = 100;
    first = 0;
    COM->US_RTOR = 16;
     AT91F_US_EnableIt(COM, AT91C_US_RXBUFF | AT91C_US_TIMEOUT );
     AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS);
}



Ну и замена AT91C_US_USMODE_NORMAL на AT91C_US_USMODE_RS485 также не дала результатов.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jul 12 2006, 08:28
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
скажите плиз, чем должна отличаться инициализация USART0 от USART1?

Ничем.
Но есть один вопрос. Поправили ли вы обработчик прерывания?
Там полно обращений к MR и CSR.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Zarya
сообщение Jul 12 2006, 08:48
Сообщение #10





Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752



если честно, я даже не знаю как и ответить smile.gif

я пытаюсь разобраться с USARTом основываясь больше на примере сайта IARа, нежели на примере Тимофея. Так вот там где устанавливаются эти прерывания я не нашел. На сколько я понимю это надо делать при инициализаци.

beer_warrior, можешь рассказать поподробнее?
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2006, 09:20
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(beer_warrior @ Jul 12 2006, 14:28) *
Цитата
скажите плиз, чем должна отличаться инициализация USART0 от USART1?

Ничем.
Но есть один вопрос. Поправили ли вы обработчик прерывания?
Там полно обращений к MR и CSR.


Ну я сделал как смог ... Основываясь на примерах с офиц сайта .... Никто ж не подсказал .... А если читать .... То я незнаю англ., поэтому все методом проб и ошибок делаю. Если я не буду трогать те регистры, у меня вобще ничего не передает .... sad.gif

А 485 у меня работает, проверил осцилографом ..... Чего то там прыгает, пытается передать. Принять соответственно не откуда, поэтому насчет приема ничего сказть не могу.

Сообщение отредактировал Timofey - Jul 12 2006, 09:25
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jul 12 2006, 09:56
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Что сказать - USART вызывает одно прерывание на все возможные события, поэтому в обработчике должны стоять проверки статусного регистра на предмет выяснения источника прерывания(прием, передача, ошибки, флаги PDC).
Второй момент, это то, что часть флагов не снимаются автоматически,
поэтому надо писать в разные регистры. Приведу кусок кода с обработкой прерывания.Думаю идея будет понятна.
Код
//--------------------------------------------------------------------------
// USART interrupt
//--------------------------------------------------------------------------
void USARTInterrupt(void)
{
DWORD mask = AT91C_BASE_US1->US_CSR;
mask &= AT91C_BASE_US1->US_IMR;
// if BREAK state
if(mask & AT91C_US_RXBRK)
        {
        USART_PDC_Rx();
        }
//if RX timeout
if(mask & AT91C_US_TIMEOUT)
        {
        USART_Timeout();
        }
//if PDC transfer complete
if(mask & AT91C_US_ENDTX)
        {
        USART_PDC_Tx();
        }
AT91C_BASE_US1->US_CR = AT91C_US_RSTSTA;        
}
//--------------------------------------------------------------------------
void USART_PDC_Rx(void)
{
act_buf = (act_buf)    ? 0 : 1;
AT91C_BASE_US1->US_RPR = (DWORD)&rx_buf[act_buf];
AT91C_BASE_US1->US_RCR = sizeof(BUF);
}
//--------------------------------------------------------------------------
void USART_PDC_Tx()
{
act_buf = 0;
AT91C_BASE_US1->US_TPR = (DWORD)&tx_buf[act_buf];
AT91C_BASE_US1->US_TCR = 7;
}
//--------------------------------------------------------------------------
//process RX timeout
//--------------------------------------------------------------------------
void USART_Timeout(void)
{
if(mode == CONFIG)
    {
    ProcessCmd();
    }
AT91C_BASE_US1->US_RPR = (DWORD)&rx_buf[0];
AT91C_BASE_US1->US_RCR = sizeof(BUF);
AT91C_BASE_US1->US_CR = AT91C_US_STTTO;
}
//--------------------------------------------------------------------------


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2006, 10:25
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(beer_warrior @ Jul 12 2006, 15:56) *
Что сказать - USART вызывает одно прерывание на все возможные события, поэтому в обработчике должны стоять проверки статусного регистра на предмет выяснения источника прерывания(прием, передача, ошибки, флаги PDC).
Второй момент, это то, что часть флагов не снимаются автоматически,
поэтому надо писать в разные регистры. Приведу кусок кода с обработкой прерывания.Думаю идея будет понятна.


Спасибо
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 12 2006, 10:56
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Обычно если все правильно и не работает, то забыл клоки на устройство подать. smile.gif Проверь.
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jul 12 2006, 14:00
Сообщение #15


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



что Это?
Код
    AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_US1, USART_INTERRUPT_LEVEL,
                           AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Usart_c_irq_handler);

Во превых не видно что это за USART_INTERRUPT_LEVEL, это должен быть приоритет прерывания, чем больше тем выше
Во вторых внутренняя преферия может конфигурироватся только как EDGE_TRIGGERED и LEVEL_SENSITIVE, остальные конфигурации бессмысленны.
Код
    AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_US1,
                           USART_PRIOR_LEVEL, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
                           Usart_c_irq_handler);

где 0 < USART_PRIOR_LEVEL < 7
Usart_c_irq_handler - это как раз и есть имя функции-обработчика прерываний.
Может еще какието ошибки есть я не смотрел.

beer_warrior
а ваш обработчик и вправду работает? Судя по всему под IAR.
Никак не пойму чем он отличается от обычной функции и как из него выход организуется?
И как вы обходитесь без записи чего-либо в EIOCR? Я тут забыл как-то про него, очень долго голова болела почему прерывание один раз только вызывается. smile.gif


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 01:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01529 секунд с 7
ELECTRONIX ©2004-2016