|
UART и прерывания, передает назад не все |
|
|
|
Oct 21 2010, 00:00
|
Участник

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

|
не могу понять тут то ли строка записывается не до конца, то ли не до конца выводится В гипертерминале ввожу (123-enter) подряд много раз а в выводе получаю последовательно 1 потом после еще одного (123-enter) - 2, еще раз - 3 и пустая строка и так по кругу Код #include <avr\io.h> #include <util\delay.h> #include <stdlib.h> #include <avr\interrupt.h> //#include <stdio.h>
char *StrToPrint; //указатель на строку которую будем выводить uart char HelloWorld[]="Hello World";
//процедура отправки строки по UART//////// void u_send (char *str) { if (str==NULL) return; //проверяем не попался ли нам нулевой указатель, если попался то сразу выходим static char j=0; //счетчик if (*(str+j)!='\0'){ //проверяем не достигнут ли конец строки // USART_Transmit('t'); // UDR0=str[j]; //отправляеме байт (так компилятор ругается почему то) UDR0=*(str+j); //то же самое тока компиляиор не ругается j++; //инкрементируем счетчик } else { UCSR0B&=~(_BV(UDRIE0)); //запрещаем прерывание по опустошению регистра UDR j=0; //сбрасываем счетчик; } } //////////////////////////////////////////
//////////////////////////////////////////
//процедура приема строки по UART с использованием прерываний//////// /*при первом вызове функции создаем указатель на char выделяем память под 1 символ, ждем пока он не придет, когда пришел записываем его в выделенную память, если есть еще символы то выделяем еще байт и так до тех пор пока все символы не кончатся. При последуюющих вызовах функции сначала нужно очистить память которую выделяли в прошлый раз для этого указатель str объявляли как static.
выход из функции происходит только когда придет символ '\r' или '\0' */ char * u_receive_int (void) { static char * str=NULL; //объявляем указатель на строку статическим что бы при повторных вызовах можно было очистить память static int i=0; //создаем счетчик char temp; //временная переменная if (i==0) { //если i==0 то либо функция еще не вызывалась либо в прошлый раз строка закончилась и надо освободить память free(str); //то освобождаем память str=NULL; //сбрасываем указаель } temp=UDR0; //Считываем принятый байт в temp if ((temp!='\0')&&(temp!='\r')) { //Если приянтый байт не равен '\r' или '\0' то: str=(char*) realloc(str, i+1); //выделяем память под символы *(str+i)=temp; //записываем принятый байт в конец массива i++; //инкрементируем счетчик //PORTB=1<<1; return NULL; //так так это еще не конец строки то возвращаем нулевой указатель } else { //PORTB=1<<2; *(str+i)='\0'; //записываем '\0' в конец массива i=0; //обнуляем счетчик return str; // возвращаем указатель на область памяти, по которому можно обратиться к принятым данным };
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//Обработчик прерывания от UART, по завершению приема////////// SIGNAL(SIG_USART_RECV){ StrToPrint=u_receive_int(); // } //////////////////////////////////////////////////////////////
//Обработчик прерывания от UART, по опустошению UDR////////// SIGNAL(SIG_USART_DATA){ PORTB=1<<2; u_send (StrToPrint); } //////////////////////////////////////////////////////////////*/
void USART_Init( unsigned int baud ) { // Set baud rate //UCSRB|=_BV(RXCIE); //Разрешение прерывания по завершению приема UBRR0H = (unsigned char)(baud>>8); UBRR0L = (unsigned char)baud; // Enable receiver and transmitter & interrupts UCSR0B = (1<<RXCIE0)|(1<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0); // Set frame format: 8data, 1stop bit UCSR0C = (0<<USBS0)|(3<<UCSZ00); }
int main (void) { //char k='s';
DDRB=0x00;
USART_Init(47);
while(1){ sei();
//u_send(HelloWorld); if (StrToPrint){ //печатаем то на что указывает StrToPrint, если указатель нулевой, то ничего не напечатается u_send(StrToPrint); StrToPrint=NULL; //Если напечаталось, то сбрасываем указатель, что бы больш не печаталось } //printf("Hello, World"); //не работает _delay_ms(100); } }
|
|
|
|
|
 |
Ответов
|
Oct 21 2010, 17:33
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(XVR @ Oct 21 2010, 11:51)  Использование malloc/free в AVR явно плохая идея, у него и так памяти не много. А уж использование realloc, да еще побайтно - вообще полный абзац (и не только на AVR). Делайте статический кольцевой буфер и обмен с ним по прерываниям. Разобраться в вашей программе практически невозможно  Согласен полностью, это микроконтроллер а не ПК, хотя и на Си пишите, динамическое распределение памяти в МК с малым ОЗУ является потенциальным источником ошибок. Если с кольцевым буфером имеются затруднения, используйте простые с фиксированным размером.
Сообщение отредактировал Danis - Oct 21 2010, 17:37
--------------------
Magic Friend
|
|
|
|
|
Oct 21 2010, 19:05
|
Участник

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

|
Цитата(Danis @ Oct 21 2010, 21:33)  Согласен полностью, это микроконтроллер а не ПК, хотя и на Си пишите, динамическое распределение памяти в МК с малым ОЗУ является потенциальным источником ошибок. Если с кольцевым буфером имеются затруднения, используйте простые с фиксированным размером. А можно примерчик кольцевого буфера для usart на avr студии? попробовал для простоты переписать прогу так, начал с совсем простого, но прерывание не работает Код #include <avr/io.h> #include <avr/interrupt.h>
#define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void USART_Init( unsigned int baud ) { // Set baud rate UBRR0H = (unsigned char)(baud>>8); UBRR0L = (unsigned char)baud; // Enable receiver and transmitter & interrupts UCSR0B = (1<<RXCIE0)|(1<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0); // Set frame format: 8data, 1stop bit UCSR0C = (0<<USBS0)|(3<<UCSZ00); }
int main (void) { USART_Init(BAUD_PRESCALE); sei();
for(;;) // Loop forever { /* while ((UCSR0A & (1 << RXC0)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived"
while ((UCSR0A & (1 << UDRE0)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it UDR0 = ReceivedByte; // Echo back the received byte back to the computer*/ } } ISR(USART_RX_vect) { char ReceivedByte; ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived" UDR0 = ReceivedByte; // Echo back the received byte back to the computer } Забыл написть - Мега48 на плате STK48 добавил в бесконечный цикл мигание диодом если закомментироваль глобальное разрешение прерываний - мигает, если нет то нет
Сообщение отредактировал AnKing - Oct 21 2010, 19:58
|
|
|
|
Сообщений в этой теме
AnKing UART и прерывания Oct 21 2010, 00:00 smalcom Цитатаstatic char j=0; //с... Oct 21 2010, 08:55 AnKing Переписал по другому, теперь легче разобраться заю... Oct 21 2010, 16:12 Сергей Борщ Цитата(AnKing @ Oct 21 2010, 19:12) прога... Oct 21 2010, 16:25 DpInRock Вы бы посмотрели какие-нибудь примеры для начала. ... Oct 21 2010, 16:24 AnKing Цитата(DpInRock @ Oct 21 2010, 20:24) Вы ... Oct 21 2010, 17:03 Danis Цитата(DpInRock @ Oct 21 2010, 20:24) То,... Oct 24 2010, 18:06 XVR ЦитатаНо у меня почемуто ничего не происходитЧто б... Oct 21 2010, 18:48 AnKing Разобрался почему не работало... Было включено пре... Oct 21 2010, 20:17 Danis Цитата(AnKing @ Oct 21 2010, 23:17) как м... Oct 22 2010, 04:04 AnKing Вам это может показаться элементарным но все же
... Oct 22 2010, 07:24 Палыч Цитата(AnKing @ Oct 22 2010, 11:24) Средн... Oct 22 2010, 07:56  Danis Цитата(Палыч @ Oct 22 2010, 10:56) Символ... Oct 22 2010, 08:36  ILYAUL Цитата(Палыч @ Oct 22 2010, 11:56) (учите... Oct 22 2010, 08:56   Danis Цитата(ILYAUL @ Oct 22 2010, 12:56) Похож... Oct 22 2010, 16:12 AnKing Спасибо что разъяснили, хотя над сдвигом еще приде... Oct 23 2010, 07:27 Палыч Цитата(AnKing @ Oct 23 2010, 11:27) ... в... Oct 23 2010, 08:00  rezident Цитата(Палыч @ Oct 23 2010, 14:00) Если д... Oct 23 2010, 19:15   Палыч Цитата(rezident @ Oct 23 2010, 23:15) Иде... Oct 24 2010, 11:18
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|