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

 
 
> Проблема с UART, Не могу разобраться с прерыванием
uzzzer
сообщение Apr 7 2011, 09:52
Сообщение #1


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

Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985



Доброго времени, суток)

Такая проблема:
Пишу программу на WINAVR, смысл таков - по прерыванию UART по линии Rx, программа должна возвращать символ, в зависимости от символа введенного в терминале.
НО, все попытки - сравнение строк, условия if и т.д. были тщетными... компилятор выдавал ворнинги...

В общем вопрос:

Как организовать отправку строки символов, в зависимости от строки введенной в теминале ?
Либо как корректно передать в main() содержание UDR из SIGNAL (SIG_UART_RECV)

Вот так я писал функцию обработки прерывания изначально, но ничего не получалось:

SIGNAL (SIG_UART_RECV)

uint8_t usart_data;
uint8_t *pInpunStr = "start";
char *pDispatch;
int flag;

usart_data= UDR;
flag = strcmp(pInpunStr,usart_data);

if(flag = 1)
pDispatch = "GOOD";

else{
pDispatch = "TRY AGAIN";
}

usart_send_c(pDispatch);

}


CODE
#include <avr/io.h>
#include <avr/interrupt.h>

#include <inttypes.h>
#include <util/delay.h>

#define F_OSC 16000000 /* oscillator-frequency in Hz (F_OSC) - caiaieou!!! */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1)

void delay_ms(unsigned short ms) {
unsigned short outer1, outer2;
outer1 = 200;
while (outer1) {
outer2 = 1000;
while (outer2) {
while ( ms ) ms--;
outer2--;
}
outer1--;
}
}

int strcmp(unsigned char *t1,unsigned char *t2)
{
while(*t1)
if(*t1-*t2)
return 0;
else{
t1++;
t2++;
}
return 1;
}

void usart_send_c(uint8_t c) {
// wait until UDR ready
while(!(UCSRA & (1 << UDRE)));
UDR = c; // send character
}

void uart_send_s(uint8_t *s) {
// loop until *s != NULL
while (*s) {
usart_send_c(*s);
s++;
}
}


/*Eieoeaeecaoey UART*/
void init(void) {
// set baud rate
UBRRH = (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OSC)>>8);
UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC);

// Enable receiver and transmitter; enable RX interrupt
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);

//asynchronous 8N1
UCSRC = (1 << URSEL) | (3 << UCSZ0);
}


SIGNAL (SIG_UART_RECV) { // USART RX interrupt

uint8_t usart_data;

usart_data= UDR;
usart_send_c(usart_data);
}

int main(void) {
init(); // init USART

while(!(UCSRA & (1 << UDRE)));
UDR = 0x0d;

char *p = "READY!";

while (*p){
while(!(UCSRA & (1 << UDRE)));
UDR = (uint16_t)*p;
p++;
}


#define LED1 7
#define LED_PORT PORTD
#define LED_DDR DDRD

LED_DDR = 1<<LED1;


sei(); // enable interrupts




while(1)
{
LED_PORT=0<<LED1;
_delay_ms(1000);
LED_PORT=1<<LED1;
_delay_ms(1000);
}


return 0;
}


Сообщение отредактировал IgorKossak - Apr 7 2011, 10:57
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
nk@
сообщение Apr 7 2011, 22:27
Сообщение #2


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

Группа: Участник
Сообщений: 78
Регистрация: 8-12-09
Пользователь №: 54 138



Прошу прощения за неоригинальность, но AVRLIB от Pascal Stang включает в себя замечательную библиотечку для работы с UART, причем с FIFO, поддержкой прерываний итд sm.gif Имеется также реализация VT100 и даже command-line интерфейса с редактированием, автокомплишеном. Зачем сушить себе мозги и изобретать колесо - берите готовое и радуйтесь.
http://www.mil.ufl.edu/~chrisarnold/compon...ard/AVR/avrlib/

Сообщение отредактировал nk@ - Apr 7 2011, 22:28
Go to the top of the page
 
+Quote Post
uzzzer
сообщение Apr 15 2011, 05:48
Сообщение #3


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

Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985



Огромное все спасибо за помощь.
Вообщем я частично решил проблему с помощью примера к статьи: http://www.chipenable.ru/index.php/program...sart-uart-queue

Переделав основную программу таким образом:

Код
int main(void)
{
  
  unsigned char counter=0; // for test
  
  unsigned char StrRx[counter];// for test
  unsigned char StrTx[counter];
  unsigned char index; //for test
  char *pRx=0;
  unsigned char *pTx=0;  
  char pCmd[]="START";
  unsigned char pEcho[]="TEST PASS !!!";
  unsigned char pFail[]="Try again !!!";
  
  unsigned char symbol;
  int flag;

  //unsigned char symbol;
  USART_Init();
  asm("sei");



  

while(1){
    
    
    /*symbol = USART_GetChar();
    if (symbol == 't')
      USART_SendStr(pEcho);
        
    */
unsigned char tmp;
tmp = USART_GetChar();
//pRx=pCmd;

while(tmp){
pRx++;
*pRx = tmp;

tmp=USART_GetChar();
}


flag = strcmp(pRx,pCmd);

  if(flag==0)
   USART_SendStr(pEcho);
  //else {USART_SendStr(pFail);}


}
return 0;    
}


Но возник такой вопрос:

USART_SendStr(pEcho); - выводит строку символов pEcho ("TEST PASS !!!"), примерно так: TEST PASS !!! TES т.е. по 18 символов, причем три раза нажимаю энтер и три раза выводится по 18 символов... стоит уменьшить SIZE_BUF, до 10 - 11 символов, выводится строка с меньшим количеством символов и два раза нажав энтер выводится два раза соответственно... причем больше трех раз при значении SIZE_BUF=16 не выводится и больше двух раз при значении SIZE_BUF = 10...

Это скрин терминалки:


Прикрепленные файлы
Прикрепленный файл  UART_2.rar ( 19.88 килобайт ) Кол-во скачиваний: 20
 
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 20th August 2025 - 10:23
Рейтинг@Mail.ru


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