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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> AT91SAM7X256 и Keil Vision 3V3.20a
Limp
сообщение Mar 31 2008, 11:39
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Опять проблема с DBGU.
Посылаю байт и тут же вывожу количество принятых байт.
Вот обработчик прерывания:

void Uart_dbgu_irq_handler()__irq
{
if ((pDBGU->DBGU_CSR & AT91C_US_RXRDY))
{
count_byte++;
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = count_byte;
}
pDBGU->DBGU_CR = AT91C_US_RSTSTA;
AT91C_BASE_AIC->AIC_EOICR=0x00;
}
При передаче даже одного байта, происходит постоянный вызов обработчика прерывания, соответственно бесконечно плюсуется count_byte. То есть не происходит сброс прерывания, но я ведь это делаю AT91C_BASE_AIC->AIC_EOICR=0x00 или что-то нужно еще?
Кстати, в USART та же картина.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 31 2008, 11:41
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Нужно прочитать DBGU_RHR.
Go to the top of the page
 
+Quote Post
Limp
сообщение Mar 31 2008, 12:13
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ Mar 31 2008, 15:41) *
Нужно прочитать DBGU_RHR.


Да, действительно, затормозило.
Но вот от чего весь сыр бор:
void Uart_dbgu_irq_handler()__irq
{

if ((pDBGU->DBGU_CSR & AT91C_US_RXRDY)) /* Wait for Full Rx Buffer */
{
count_byte++;
if(count_byte<5)
{
zumer[0]=zumer[0]<<8 | pDBGU->DBGU_RHR;
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = zumer[0];
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = count_byte;
}

}

pDBGU->DBGU_CR = AT91C_US_RSTSTA;
AT91C_BASE_AIC->AIC_EOICR=0x00;
}
Посылаю данные: d;4;5;6;7;8;9;a;b;c;d
Получаю назад такую картину:
D 1
4 2
5 3
6 4
7 0
8 1
9 2
A 3
B 4
C 0
D 1
Почему когда выполнится условие, count_byte сбрасывается в ноль и портит мне настроение. 07.gif
Для полной картины:
count_byte описан как глобальная unsigned char и обнуляется в main(), в самом начале и все, дальше бесконечный цикл.
в файле uart.c, где у меня обработчик прерываня пишу extern unsigned char count_byte.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 31 2008, 12:19
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Limp @ Mar 31 2008, 16:13) *
Почему когда выполнится условие, count_byte сбрасывается в ноль и портит мне настроение. 07.gif

Потому что при count_byte >= 5 перестает считываться DBGU_RHR. Что происходит дальше, надеюсь, понятно.
Go to the top of the page
 
+Quote Post
Limp
сообщение Mar 31 2008, 12:28
Сообщение #20


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ Mar 31 2008, 16:19) *
Потому что при count_byte >= 5 перестает считываться DBGU_RHR. Что происходит дальше, надеюсь, понятно.


Понятно. Спасибо aaarrr.
Когда перестает считывать DBGU_RHR, постоянно влетает в обработчик и count_byte переполняется и обнуляется и т.д. Хреново. Как же все это затормозить?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 31 2008, 12:39
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Прерывание запретить, например. А чего Вы хотите добиться в конечном итоге?
Go to the top of the page
 
+Quote Post
Limp
сообщение Mar 31 2008, 12:57
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ Mar 31 2008, 16:39) *
Прерывание запретить, например. А чего Вы хотите добиться в конечном итоге?

Да в приципе почти уже добился своего. В обработике надо записать 8 байт, по 4 в два 32 разрядных слова, потом сравнить с требуемыми константами. Приблизительно так как показывал выше. Еще конкретнее это АТ команда от модема. Пробую всякие варианты, вот и возникают всякие непонятки. Дело в том, что может зациклиться если придет более 8 байт.

if(count_byte<5)
{
zumer[0]=zumer[0]<<8 | pDBGU->DBGU_RHR;
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = zumer[0];
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = count_byte;
}
if(4<=count_byte && count_byte<9 )
{
zumer[1]=zumer[1]<<8 | pDBGU->DBGU_RHR;
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = zumer[1];
while (!(AT91C_BASE_DBGU->DBGU_CSR &AT91C_US_TXRDY));
AT91C_BASE_DBGU->DBGU_THR = count_byte;
}
if(zumer[0] == 0x0D0A5249 && zumer[1]== 0x4E470D0A)
.
.
.
Получаю
D 1
A 2
52 3
49 4 49 4 07.gif
4E 5
47 6
D 7
A 8

Спасибо aaarrr. Учту ваше замечание.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 31 2008, 13:17
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



У Вас условия накладываются:
Цитата(Limp @ Mar 31 2008, 16:57) *
if(count_byte<5)
...
if(4<=count_byte && count_byte<9 )


Прием AT-команд лучше так не делать. Правильнее будет в прерывании записать строку в буфер, контроллируя конец строки по 0x0d 0x0a, а затем спокойно разобрать её в основной программе.
Go to the top of the page
 
+Quote Post
Limp
сообщение Apr 1 2008, 04:26
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ Mar 31 2008, 16:17) *
У Вас условия накладываются:
Прием AT-команд лучше так не делать. Правильнее будет в прерывании записать строку в буфер, контроллируя конец строки по 0x0d 0x0a, а затем спокойно разобрать её в основной программе.


Спасибо. Сделаю.
Go to the top of the page
 
+Quote Post
Limp
сообщение May 28 2008, 06:59
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Всем доброго дня!
Прошу снова помощи.
Для обучения и отладки обмена по СОМ порту использовал плату AT91SAM7x-EK.
Использовал готовые примеры кода.
Обмен проходит нормально и собственно проблем нет. Но...
Наши разработчики сделали свое устройство на базе AT91SAM7x256 где заложили кварц с частотой 14745600. В плате AT91SAM7x-EK кварц с частотой, если не ошибаюсь, 18432000. Естественно, обмен по СОМ порту в доморощенном устройстве не выполняется.

Использую следующие для настройки скорости передачи данных.

#define BRD (MCK/16/BR) /* Baud Rate Divisor */
#define BR 115200 /* Baud Rate */
#define MCK 47923200 // MCK (PLLRC div by 2)
#define AT91B_MAIN_OSC 18432000 // Main Oscillator MAINCK

pUSART->US_BRGR = BRD; /* Baud Rate Divisor */

Теперь вопрос:
Откуда берется или как вычисляется значение #define MCK 47923200 ?

Пожалуйста, подскажите! help.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 28 2008, 07:12
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Limp @ May 28 2008, 10:59) *
Откуда берется или как вычисляется значение #define MCK 47923200 ?

Смотрите настройку PLL, число приходит оттуда. После замены кварца на 14.745M значение MCK должно быть 38338560.
Go to the top of the page
 
+Quote Post
Limp
сообщение May 28 2008, 10:40
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ May 28 2008, 10:12) *
Смотрите настройку PLL, число приходит оттуда. После замены кварца на 14.745M значение MCK должно быть 38338560.


Уважаемый, aaarrr!
Посмотрел настройку своего PLL, она у меня производится в стартапе (см. самое мое первое сообщение).

Надо полагать, что МСК-> (18432000*(25+1)/5)/2=47923200.
Для другого кварца: МСК-> (14745600*(25+1)/5)/2=38338560.

Не пойму, почему выбирается именно MUL=25, а DIV=5 ?
К сожалению установив #define MCK 38338560 и #define AT91B_MAIN_OSC 14745600 обмен так и не заработал.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 28 2008, 10:53
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Limp @ May 28 2008, 14:40) *
Не пойму, почему выбирается именно MUL=25, а DIV=5 ?

Выбрали, подгоняя выходную частоту к 48.0МГц.

Цитата(Limp @ May 28 2008, 14:40) *
К сожалению установив #define MCK 38338560 и #define AT91B_MAIN_OSC 14745600 обмен так и не заработал.

Правильно не заработал: делитель для скорости 115200 чуть-чуть не дотягивает до 21 (20.8), если при его вычислении не используется округления, то получится очень большая ошибка.
Go to the top of the page
 
+Quote Post
Limp
сообщение May 28 2008, 11:12
Сообщение #29


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 6-02-08
Пользователь №: 34 796



Цитата(aaarrr @ May 28 2008, 13:53) *
Выбрали, подгоняя выходную частоту к 48.0МГц.
Правильно не заработал: делитель для скорости 115200 чуть-чуть не дотягивает до 21 (20.8), если при его вычислении не используется округления, то получится очень большая ошибка.


Прошу прощения за свою тупость smile.gif , но можно чуть подробнее о "делитель для скорости 115200 чуть-чуть не дотягивает до 21 (20.8), если при его вычислении не используется округления, то получится очень большая ошибка" ?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 28 2008, 11:52
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Очень просто все:
Код
#define BRD (MCK/16/BR) /* Baud Rate Divisor */

Даст BRD=20 из-за отсутствия округления - (int)20.8=20.

Для того, чтобы избежать этой неприятности, сделайте так:
Код
#define BRD ((MCK + BR * 8)/16/BR)
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 Текстовая версия Сейчас: 7th July 2025 - 06:04
Рейтинг@Mail.ru


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