Gönderen Konu: USART veri gönderme hatası  (Okunma sayısı 159 defa)

Çevrimdışı ugurer

  • Üye
  • **
  • İleti: 48
USART veri gönderme hatası
« : 02 Aralık 2016, 06:30:31 »
Merhaba arkadaşlar codevisionavr ile haberleşme yapmaya çalışıyorum. İlk bilgiyi yolladığımda sorunsuz çalışıyor fakat tekrar bilgi yollamaya çalışıtığım zaman kesmeye giriyor ve buffer dolmadan kesmeden çıkmıyor. Örnek vermek gerekirse "merhaba" yazıp gönderdiğimde sorun olmuyor fakat program tekrar başka bir mesaj yolladığımda kesmeye giriyor ve bu sefer saçmalıyor.
Kod: [Seç]
#include <mega32a.h>
#define FCLK 8000000
#define UBRR ((long) FCLK/(16*9600)-1)     //timer kesmesi
// USART Receiver buffer
#define RX_BUFFER_SIZE 24
int saydir=0;
char Rx_Buffer[RX_BUFFER_SIZE+1]; // character array (buffer)
char RX_Wr_Index; //index of next char to be put into the buffer
char RX_Rd_Index; //index of next char to be fetched from the buffer
char RX_Counter; //a total count of characters in the buffer
bit RX_Buffer_Overflow; // This flag is set       

// USART Transmit buffer
#define TX_BUFFER_SIZE 24
char TX_Buffer [TX_BUFFER_SIZE+1]; // character array (buffer)
char TX_Rd_Index; //index of next char to be put into the buffer
char TX_Wr_Index; //index of next char to be fetched from the buffer
char TX_Counter; //a total count of characters in the buffer
bit fPrimedIt; // this flag is used to start the transmit
// interrupts, when the buffer is no longer empty           

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char c;
c = UDR;
Rx_Buffer[RX_Wr_Index] = c; /* put received char in buffer */
if(++RX_Wr_Index > RX_BUFFER_SIZE) /* wrap the pointer */
RX_Wr_Index = 0;
if(++RX_Counter > RX_BUFFER_SIZE) /* keep a character count */
{ /* overflow check.. */
RX_Counter = RX_BUFFER_SIZE; /* if too many chars came */
RX_Buffer_Overflow = 1; /* in before they could be used */
} /* that could cause an error!! */
}
// Get a character from the USART Receiver buffer
char getchar(void)
{
char c;
while(RX_Counter == 0) /* wait for a character... */
;
c = Rx_Buffer[RX_Rd_Index]; /* get one from the buffer..*/
if(++RX_Rd_Index > RX_BUFFER_SIZE) /* wrap the pointer */
RX_Rd_Index = 0;
if(RX_Counter)
RX_Counter--; /* keep a count (buffer size) */
return c;
}
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if(TX_Counter != 0)
{
if(fPrimedIt == 1)
{ /* only send a char if one in buffer */
fPrimedIt = 0; /* transmission, then don’t send the */
/* test and wrap the pointer */
if(++TX_Rd_Index > TX_BUFFER_SIZE)
TX_Rd_Index = 0;
TX_Counter--; /* keep track of the counter */
}
if(TX_Counter != 0)
{
UDR = TX_Buffer[TX_Rd_Index];
/* otherwise, send char out port */
/* test and wrap the pointer */
if(++TX_Rd_Index > TX_BUFFER_SIZE)
TX_Rd_Index = 0;
TX_Counter--; /* keep track of the counter */
}
}
UCSRA |= 0x40; /* clear TX interrupt flag */
}
// Write a character to the USART Transmitter buffer
void putchar(char c)
{
char stuffit = 0;
while(TX_Counter > (TX_BUFFER_SIZE-1))
; /* WAIT!! Buffer is getting full!! */
if(TX_Counter == 0) /* if buffer empty, setup for interrupt */
stuffit = 1;
TX_Buffer[TX_Wr_Index++]=c; /* jam the char in the buffer.. */
if(TX_Wr_Index > TX_BUFFER_SIZE) /* wrap the pointer */
TX_Wr_Index = 0;
/* keep track of buffered chars */
TX_Counter++;
if(stuffit == 1)
{ /* do we have to "Prime the pump"? */
fPrimedIt = 1;
UDR = c; /* this char starts the TX interrupts.. */
}
}

// These defines tell the compiler to replace the stdio.h
// version of getchar() and putchar() with ours..
// That way, all the other stdio.h functions can use them!!
#define _ALTERNATE_GETCHAR_
#define _ALTERNATE_PUTCHAR_
// now, we include the library and it will understand our
// replacements
#include <stdio.h>
while (1)
      {
   if(RX_Counter) // are there any received characters??
       {     
       for(i=0;i<RX_Wr_Index;i++)
        {
        klavye[i]=getchar();                               
       }
 printf("\n              1  %s                       ",klavye);delay_us(5);
}
Yani ilk mesajı gönderdikten sonra bir şeyleri sıfırlamam gerekiyor ama ne olduğunu bulamadım. Yardımınız için şimdiden teşekkürler.
« Son Düzenleme: 02 Aralık 2016, 06:32:27 Gönderen: ugurer »

Çevrimdışı berkay_91

  • Kıdemli
  • ****
  • İleti: 247
Ynt: USART veri gönderme hatası
« Yanıtla #1 : 02 Aralık 2016, 11:42:03 »
alttaki program Atmega32 için Atmel Studio 6.0 da daha önce yazmış olduğum bir UART haberleşme programıdır, birde bununla deneyin takıldığınız yer olursa yine konuşalım

Kod: [Seç]
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define BAUDRATE 9600
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)


void uart_init()
{

UBRRH = (uint8_t)(UBRRVAL >> 8);
UBRRL = (uint8_t)(UBRRVAL);
UCSRB = ((1<<RXEN) | (1<<TXEN) | (1<<RXCIE));   // Enable Receiver, Transmitter, Receive Interrupt
UCSRC = ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0));     // 8N1 data frame
sei();
}



void USART0SendByte(char u8Data){
while(!(UCSRA&(1<<UDRE))); //wait while previous byte is completed
UDR = u8Data; // Transmit data
}



void uart_puts(const char *s ){

while (*s)
USART0SendByte(*s++);
}


void uart_writing_string_of_number(int16_t in){

uint8_t started = 0;
uint16_t pow = 10000;

while (pow >= 1){

if (in/pow > 0 || started || pow == 1){

USART0SendByte((uint8_t) (in/pow) + '0');
started = 1;
in = in % pow;
}

pow = pow / 10;

}
}


int main(void){

uart_init();

uart_writing_string_of_number(100);

uart_puts(" BERKAY");
USART0SendByte('.');
USART0SendByte('.');
USART0SendByte(33); // ASCI de !

while(1){

}
return 0;
}

Çevrimdışı ugurer

  • Üye
  • **
  • İleti: 48
Ynt: USART veri gönderme hatası
« Yanıtla #2 : 03 Aralık 2016, 00:04:12 »
@berkay_91 yorumun için teşekkürler. Fakat araştırırken şöyle bir şeyle çözdüm problemi.
Kod: [Seç]
       if(RX_Counter) // are there any received characters??
       {saydir++;
        if(saydir==1){
       for(i=0;i<RX_Wr_Index;i++)
        {
        klavye[i]=getchar();               
        } RX_Counter=0;RX_Wr_Index=0;UDR=0;RX_Rd_Index=0;
       }
        else if(saydir==2){
          for(i=0;i<RX_Wr_Index;i++)
        {
        klavye2[i]=getchar();       
        } RX_Counter=0;RX_Wr_Index=0;UDR=0;RX_Rd_Index=0;     
        }     
        else if(saydir==3){
       
          for(i=0;i<RX_Wr_Index;i++)
        {
        klavye3[i]=getchar();       
        } RX_Counter=0;RX_Wr_Index=0;UDR=0;RX_Rd_Index=0;           
        }   
        if(saydir==4){saydir=0;}
             
       }       
       printf("\n  %d  ",saydir);delay_us(5);
       printf("\n              1  %s                       ",klavye);delay_us(5);     
       printf("\n              2  %s                       ",klavye2);delay_us(5); 
       printf("\n              3  %s                       ",klavye3);delay_us(5);

Haberleşmeyle alakalı bir değişiklik yapmadım sadece parametreleri her değer aldığında sıfırlıyorum.