|
Прием передача по USARTу |
|
|
|
Jul 3 2006, 06:38
|
Частый гость
 
Группа: Участник
Сообщений: 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); } } }
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 34)
|
Jul 3 2006, 07:44
|

Профессионал
    
Группа: Свой
Сообщений: 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 !!!
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 3 2006, 08:24
|
Частый гость
 
Группа: Участник
Сообщений: 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 действительно ... ступил )) Заработался блин ...
|
|
|
|
|
Jul 11 2006, 20:03
|
Группа: Новичок
Сообщений: 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) в чем может быть проблема?
|
|
|
|
|
Jul 12 2006, 03:47
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Нууууу ....... US1, насколько я понимаю, - это 485 .... Его у меня нет на плате  Поэтому отвечу с точки зрения новичка не работавшего с ним )) Мне кажется в конфигурировании нужно еще и другую скорость указать. В конфигурировании 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 .... Ну а так .... фиг знает ... "бывалых" хотелось бы тоже послушать ... так как самому интересно ....
|
|
|
|
|
Jul 12 2006, 06:45
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
такссс... вобщем: скажите плиз, чем должна отличаться инициализация USART0 от USART1? на сколько я понимаю, нужно всего лишь поменять конфигурацию ножек, так? P.S если это поможет, я использую AT91SAM7S256
Сообщение отредактировал Zarya - Jul 12 2006, 06:46
|
|
|
|
|
Jul 12 2006, 07:14
|
Группа: Новичок
Сообщений: 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 также не дала результатов.
|
|
|
|
|
Jul 12 2006, 08:28
|

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

|
Цитата скажите плиз, чем должна отличаться инициализация USART0 от USART1? Ничем. Но есть один вопрос. Поправили ли вы обработчик прерывания? Там полно обращений к MR и CSR.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 12 2006, 08:48
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
если честно, я даже не знаю как и ответить  я пытаюсь разобраться с USARTом основываясь больше на примере сайта IARа, нежели на примере Тимофея. Так вот там где устанавливаются эти прерывания я не нашел. На сколько я понимю это надо делать при инициализаци. beer_warrior, можешь рассказать поподробнее?
|
|
|
|
|
Jul 12 2006, 09:20
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Цитата(beer_warrior @ Jul 12 2006, 14:28)  Цитата скажите плиз, чем должна отличаться инициализация USART0 от USART1? Ничем. Но есть один вопрос. Поправили ли вы обработчик прерывания? Там полно обращений к MR и CSR. Ну я сделал как смог ... Основываясь на примерах с офиц сайта .... Никто ж не подсказал .... А если читать .... То я незнаю англ., поэтому все методом проб и ошибок делаю. Если я не буду трогать те регистры, у меня вобще ничего не передает .... А 485 у меня работает, проверил осцилографом ..... Чего то там прыгает, пытается передать. Принять соответственно не откуда, поэтому насчет приема ничего сказть не могу.
Сообщение отредактировал Timofey - Jul 12 2006, 09:25
|
|
|
|
|
Jul 12 2006, 09:56
|

Профессионал
    
Группа: Свой
Сообщений: 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; } //--------------------------------------------------------------------------
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 12 2006, 10:25
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

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

Дух погибшего транзистора
   
Группа: Свой
Сообщений: 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? Я тут забыл как-то про него, очень долго голова болела почему прерывание один раз только вызывается.
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Jul 12 2006, 14:25
|
Частый гость
 
Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528

|
Цитата(SpiritDance @ Jul 12 2006, 20:00)  Во превых не видно что это за USART_INTERRUPT_LEVEL, это должен быть приоритет прерывания, чем больше тем выше У меня он для US0 равен 6 а для US1 7, это я вычитал в инструкции, правильно? Или тут можно самому раставлять? Цитата(SpiritDance @ Jul 12 2006, 20:00)  Во вторых внутренняя преферия может конфигурироватся только как EDGE_TRIGGERED и LEVEL_SENSITIVE, остальные конфигурации бессмысленны. А я ставлю обычный AT91C_AIC_PRIOR_LOWEST. На что это влияет? Цитата(SpiritDance @ Jul 12 2006, 20:00)  beer_warrior а ваш обработчик и вправду работает? Судя по всему под IAR. Никак не пойму чем он отличается от обычной функции и как из него выход организуется? И как вы обходитесь без записи чего-либо в EIOCR? Я тут забыл как-то про него, очень долго голова болела почему прерывание один раз только вызывается.  Без EIOCR у меня программа из прерывания вобще не выходила ... Так что пока не стал обнулять - никак .... Может это изза того что использую AT91C_AIC_PRIOR_LOWEST? И еще, у меня такой вопрос, я использую PDA для отправки по US0. А сегодня решил это же использовать для работы с SPI, у меня начались какие то глюки ... Может так нельзя? И в SPI нужно сейчас только побайтно?
|
|
|
|
|
Jul 12 2006, 15:03
|

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

|
Сам посмотрел еше раз. Для внутренней переферии в принципе одинаково High level или Level Sensetive. Прошу прощения. Да что-то трудный этот SAM. С разбегу разбиратся не получается. Хотя все равно больше чем philips нравиться  .
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Jul 12 2006, 15:15
|

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

|
Цитата а ваш обработчик и вправду работает? Судя по всему под IAR. Никак не пойму чем он отличается от обычной функции и как из него выход организуется? И как вы обходитесь без записи чего-либо в EIOCR? Я тут забыл как-то про него, очень долго голова болела почему прерывание один раз только вызывается. Нет я сторонник gcc, проcто есть такая неявная фича в Cstartup.S  Код //*------------------------------------------------------------------------------ //*- Function : IRQ_Handler_Entry //*- Treatments : IRQ Controller Interrupt Handler. //*- Called Functions : AIC_IVR[interrupt] //*------------------------------------------------------------------------------*/ .global IRQ_Handler_Entry .func IRQ_Handler_Entry
IRQ_Handler_Entry:
/*- Manage Exception Entry */ /*- Adjust and save LR_irq in IRQ stack */ sub lr, lr, #4 stmfd sp!, {lr}
/*- Save SPSR need to be saved for nested interrupt */ mrs r14, SPSR stmfd sp!, {r14}
/*- Save and r0 in IRQ stack */ stmfd sp!, {r0}
/*- Write in the IVR to support Protect Mode */ /*- No effect in Normal Mode */ /*- De-assert the NIRQ and clear the source in Protect Mode */ ldr r14, =AT91C_BASE_AIC ldr r0 , [r14, #AIC_IVR] str r14, [r14, #AIC_IVR]
/*- Enable Interrupt and Switch in Supervisor Mode */ msr CPSR_c, #ARM_MODE_SVC
/*- Save scratch/used registers and LR in User Stack */ stmfd sp!, { r1-r3, r12, r14}
/*- Branch to the routine pointed by the AIC_IVR */ mov r14, pc bx r0 /*- Restore scratch/used registers and LR from User Stack*/ ldmia sp!, { r1-r3, r12, r14}
/*- Disable Interrupt and switch back in IRQ mode */ msr CPSR_c, #I_BIT | ARM_MODE_IRQ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*- Mark the End of Interrupt on the AIC */ ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*- Restore SPSR_irq and r0 from IRQ stack */ ldmia sp!, {r0}
/*- Restore SPSR_irq and r0 from IRQ stack */ ldmia sp!, {r14} msr SPSR_cxsf, r14
/*- Restore adjusted LR_irq from IRQ stack directly in the PC */ ldmia sp!, {pc}^ .size IRQ_Handler_Entry, . - IRQ_Handler_Entry .endfunc Чтобы окончательно закрыть вопрос привожу init Код void InitUSART(AT91S_USART *pUSART, DWORD imode, DWORD baudrate) { //-------------------------------------------------------------------------- //clear all //-------------------------------------------------------------------------- pUSART->US_CR = AT91C_US_RSTRX | // Reset Receiver AT91C_US_RSTTX | // Reset Transmitterp AT91C_US_RXDIS | // Receiver Disable AT91C_US_TXDIS; // Transmitter Disable AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_RXTDIS |AT91C_PDC_TXTDIS; //PDC off AT91C_BASE_US1->US_TCR = 0; AT91C_BASE_US1->US_RCR = 0; //-------------------------------------------------------------------------- //configure interrupt //-------------------------------------------------------------------------- AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, //base adr AT91C_ID_US1, //int number AT91C_AIC_PRIOR_HIGHEST - 1,//priority //AT91C_AIC_PRIOR_HIGHEST, //priority 3, //int source type USARTInterrupt //handler ); //-------------------------------------------------------------------------- //USART on //-------------------------------------------------------------------------- AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,(1 << AT91C_ID_US1)); //-------------------------------------------------------------------------- //configure interrupt //-------------------------------------------------------------------------- pUSART->US_IDR = 0xFFFFFFFF; pUSART->US_IER = imode; //-------------------------------------------------------------------------- //set baudrate //-------------------------------------------------------------------------- AT91F_US_SetBaudrate(pUSART,48054857,baudrate); //-------------------------------------------------------------------------- //set timeouts //-------------------------------------------------------------------------- pUSART->US_TTGR = 20; pUSART->US_RTOR = 200; //-------------------------------------------------------------------------- //set mode //-------------------------------------------------------------------------- pUSART->US_MR = AT91C_US_USMODE_NORMAL | // Normal Mode AT91C_US_CLKS_CLOCK | // Clock = MCK AT91C_US_CHRL_8_BITS | // 8-bit Data AT91C_US_PAR_NONE | // No Parity AT91C_US_NBSTOP_2_BIT; // 1 Stop Bit //-------------------------------------------------------------------------- //Init DMA //-------------------------------------------------------------------------- AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_RXTDIS; AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_TXTDIS; //active buffer (start from buf 0) act_buf = 0; //first RX buffer pUSART->US_RPR = (DWORD)&rx_buf[0]; //set pointer as register value pUSART->US_RCR = sizeof(BUF); //base buffer size // enable the RX and TX PDC transfer requests AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_RXTEN; AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_TXTEN; //-------------------------------------------------------------------------- //enable device //-------------------------------------------------------------------------- pUSART->US_CR = AT91C_US_RXEN | AT91C_US_TXEN; //-------------------------------------------------------------------------- //enable interrupt //-------------------------------------------------------------------------- AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1); } BUF объявлен typedefом как массив заданной размерности. rx_buf как массив из двух BUF
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 13 2006, 03:04
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
а можете поделиться ссылочками на доки по USARTу? чтоб подробненько и четко было все написано. А то, если честно, не все понимаю о чем ведется речь
|
|
|
|
|
Jul 13 2006, 05:34
|

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

|
Цитата а можете поделиться ссылочками на доки по USARTу? чтоб подробненько и четко было все написано. А то, если честно, не все понимаю о чем ведется речь Пользовался только даташитом, разделы AIC, PDC, USART. А также описанием ядра ARM и руководством по gcc. Насколько я знаю подробной доки, типа аппликэйшенов для AVR в природе не существует.Разберите подробно исходник - все станет ясно. PS Свежим взглядом, обнаружил в Init несколько мелких ошибок - нессоответсвие комментов константам, явно заданные указатели вместо параметров.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 13 2006, 19:20
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
Для начала всем огромное спасибо, по крайней мере передачу байтов организовал  Но вот такая штука, на самом деле думаю не совсем в тему, но все же... рассказываю обстановку. Есть комп, есть ноут, на обоих стоит IAR. Компилю и прогаю ARM с компа, прога кидает в ком порт последовательность чисел, ловлю их через ComTest - всё отлично. Компилю, запускаю все тоже самое на ноуте - принимаю абракадабру. В последствии, выясняю, что com порт на ноуте глючит, т.е соединяю com ноута с com компа, запускаю на обоих ComTest, с компа посылаю байты, на ноут приходит ерунда, посылаю с ноута, на комп приходит всё норм (недлю назад, все работало)  тогда соединил com порт платы c com компа, компилю с ноута, запускаю - .... на комп приходит опять абракадара!!! объясните пожайдуста в чем заключается мистика??? я уже ничего не понимаю  менял j-link, usb кабель, перустанавливал IAR, менял дрова на j-link  )
|
|
|
|
|
Jul 18 2006, 10:58
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
Еще один вопрос назрел  Принимаю данные вот так: Код void AT91F_US_Get(void) { int d[10]; memset(d, 0, sizeof(d)); int j = 0; while(1) { while (!AT91F_US_RxReady(COM0)); d[j] = AT91F_US_GetChar(COM0); if (d[j] == 0x4B || j > 10) break; else j++; } d[++j] = 0; AT91F_US_Put((char*)&d); } по поводу кода не ругайтесь, ибо он кривой, я и сам знаю, просто от безисходности начал уже извращаться  суть следущая, хочу получить строчку из 10 байт или если меньше байт, но со "стоповым" байтом ,например, здесь символ "К" с кодом 0x4B. посылаю на USART все через туже прогу ComTest допустим байт 0x40 20 раз (по идее 10 должно прийти и отправиться назад, остальные проигнориться)... но как оказывается даже из 20 не все доходят! Во время дебага заметил, что как только кликаю в ComTest'e на отправить, US_RHR сразу принимает значение байта, который пришел на USART, заменяя старое. Так вот у меня предположение, что просто ARM как бы не успевает принимать каждый пришедший байт, хотя могу и ошибаться. Объясните пожалуйста, что я не так понял, и как сделать по-правильному  А еще, разве нет какого-нить буфера, куда будут скапливаться приходящие байты? Вобщем, еще было бы хорошо если б объяснили, как происходит прием байтов в асинхронном режиме (т.е в каком порядке какие флаги в каких регистрах ставятся и снимаются... куда байты потом деваются... ну и тд  ), раньше думал, что я это понимаю... теперь вот засомневался. P.S. Код __inline int AT91F_US_GetChar ( const AT91PS_USART pUSART) { return((pUSART->US_RHR) & 0x1FF); }
|
|
|
|
|
Jul 18 2006, 11:42
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zarya @ Jul 18 2006, 14:58)  Еще один вопрос назрел  Принимаю данные вот так: Код void AT91F_US_Get(void) { int d[10]; memset(d, 0, sizeof(d)); int j = 0; while(1) { while (!AT91F_US_RxReady(COM0)); d[j] = AT91F_US_GetChar(COM0); if (d[j] == 0x4B || j > 10) break; else j++; } d[++j] = 0; AT91F_US_Put((char*)&d); } по поводу кода не ругайтесь, ибо он кривой, я и сам знаю, просто от безисходности начал уже извращаться  Код уж слишком кривой, чтобы не ругаться: - индекс j трижды выходит за границы массива d[10]. - я не использую атмеловские библиотеки, но сдается мне, что AT91F_US_Put нужен на входе указатель на char, а массив d[10] объявлен как int Цитата(Zarya @ Jul 18 2006, 14:58)  А еще, разве нет какого-нить буфера, куда будут скапливаться приходящие байты? Почитайте про PDC
|
|
|
|
|
Jul 18 2006, 12:04
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
aaarrr, насчет переполнения массива, вы впринципе правы, но, если честно массив, когда ему посылал 20 элементов, забивался всеголишь 7ью элементами, такое ощущение, что RXReady не срабатывал те 20 раз  На счет Цитата сдается мне, что AT91F_US_Put нужен на входе указатель на char, а массив d[10] объявлен как int да, на вход нужен указатель char, но в d хранится hex ascii код символа, и когда я передаю, его в char через (char*)&int, абсолютно ничего страшного. А вот про PDC, с удовольствием бы почитал... только где? P.S. давно созрел вопрос, но стеснялся спросить, что имеется ввиду под "даташит" ?
|
|
|
|
|
Jul 18 2006, 12:24
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
по поводу int и char извиняюсь... действительно, налажал  но, все же не в этом суть  жду-жду... ответов и помощи, рабочий день подходит к концу
|
|
|
|
|
Jul 18 2006, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zarya @ Jul 18 2006, 16:04)  да, на вход нужен указатель char, но в d хранится hex ascii код символа, и когда я передаю, его в char через (char*)&int, абсолютно ничего страшного. Т.е. Вы выдаете наружу только первый элемент массива? Цитата(Zarya @ Jul 18 2006, 16:04)  А вот про PDC, с удовольствием бы почитал... только где?  Здесь (в форуме ARM) только что обсуждали, поиском воспользуйтесь. Цитата(Zarya @ Jul 18 2006, 16:24)  но, все же не в этом суть  Вот я и не могу уяснить, в чем именно суть проблемы. Данные теряются? Попробуйте сделать совсем простой loopback: просто отправляйте каждый полученный символ назад, убедитесь, что количество совпадает.
|
|
|
|
|
Jul 18 2006, 13:45
|
Группа: Новичок
Сообщений: 10
Регистрация: 11-07-06
Пользователь №: 18 752

|
aaarrr, спасибо за попытки помочь  Я очень-очень сильно ступил  вот в чем была проблема: Код while(1) { while (!AT91F_US_RxReady(COM0)); их надо поменять местами  Тока траблы все равно остались, завтра расскажу что и как
|
|
|
|
|
Jul 20 2006, 08:50
|
Участник

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

|
Можно тоже вопрос? Через USART1 пытаюсь организовать прием/отправку байт(ну вобщем как по теме) Вот собсно сам код процедуры Код void AT91F_US_Get(void) { char inCh, outCh; AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED_MASK); AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED_MASK);
while (!AT91F_US_RxReady(AT91C_BASE_US1)); inCh = (AT91C_BASE_US1->US_RHR) & 0x1FF; outCh = inCh; AT91C_BASE_US1->US_THR = outCh & 0x1FF; } В main() крутится цикл Код while(1) AT91F_US_Get(); Проблема в том, что отсылая, к примеру, 12 одинаковых байт через Comtest на USART1, обратно получаю неопределенное количество(8, 10, 9, очень редко 12). Даже если отсылаю по одному байту, то не всегда срабатывает ответ... Не могу найти причину... З.Ы. Использую обработчик прерываний, который предоставил beer_warrior
Сообщение отредактировал Redaer - Jul 20 2006, 08:53
|
|
|
|
|
Jul 20 2006, 09:49
|

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

|
Цитата Использую обработчик прерываний, который предоставил beer_warrior Стоп-стоп. 1.В какой среде вы пишете? Как оформлено прерывание. 2.Вы одновременно пытаетесь пользоваться и прерыванием и поллом флажка. В чем логика. ЗЫ Полный код желателен.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jul 20 2006, 10:56
|
Участник

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

|
Пытаюсь прогать в IAR... Прочитал всю тему и возникла просьба... beer warrior, не могли бы Вы выложить, в дополнение к USARTinterrupt и InitUSART, ещё и процедуры отправки и получения данных... Ну тупо не получается у меня...
|
|
|
|
|
Jul 20 2006, 11:29
|

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

|
Ну что вам сказать... Весь код присутвует в ветке.Работа ведеться по PDC. Пока PDC включен все принятые символы падают в буфер на который он указывает. По достижении длины буфера ставиться флаг ENDRX, срабатывает прерывание, и там уже или подставляется следующий буфер или обрабатываеться текущий. Для передачи заполняеться буфер, ставится его длина.С этого момента он живет своей жизнью до момента обнуления счетчика. Тогда ставится флаг ENDTX. Вобщем все как у восьмибитников, только передача не побайтная, а сразу буферами. Еще раз просмотрите пост №12.
PS 1.В ИАРе функция прерывания объявляется по-своему. 2.Избегайте lib_SAM64.h там полно ошибок.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|