سلام. من یه برنامه به زبان C تو محیط کدویژن نوشتم که برای ارتباط از طریق پورت سریال است. تا قسمتی درست کار می کنه اما یک مشکل خفن و اعصاب خورد کن داره که به نظر منطقی نیست. من که هرچی فکر کردم عقلم به جایی نرسید. من کامل توضیح می دم که مشکل چیه ببینید شما می تونید یه کاری واسه ما بکنید.
متن برنامه رو اینجا اوردم.این برنامه واسه ارتباط بین دو میکرو که یکی فرستنده و دیگری گیرنده است نوشته شده.( بعدا گسترش می دم تا هر دوشون بتونن هم بفرستن و هم بگیرن ) .نیازی به فایل پروتئوس هم نیست. اما اگه صلاح دیدین بزارم. ضمنا من هم تو پروتئوس بستمش و هم تو عمل اما جواب نداد. برنامه فرستنده که چیزی نداره و هم تو عمل و هم تو پروتئوس جواب می ده.
توضیح: فرستنده یه اسم مثل ali را می فرسته و گیرنده باید آن را گرفته و روی LCD نشان می دهد.فرستنده درست عمل می کند و اسم را اینطوره می فرسته :
char esm[10]="ALI"
while (1)
{
// Place your code here
delay_ms(100);
sprintf(str,"#%s\r",esm);
puts(str);
delay_ms(100);
}; \\ End of while
گیرنده هم تا حدودی درست عمل می کند. اینم برنامه گیرنده :
من مدار را هم در عمل امتحان کردم و هم در پروتئوس. هیچ چی روی LCD نشان داده نمی شه. اول فکر کردم متغیر receive_complete هیچ وقت یک نمی شه و برنامه وارد if(receive_complete) نمی شه تا اطلاعات را روی LCD نشان بده. اما بعد که با AVR STUDIO برنامه را DEBUG کردم دیدم که اطلاعات دریافت می شه و با رسیدن کاراکتر ENTER متغیر receive_complete هم یک می شه و برنامه وارد حلقه if(receive_complete) می شه اما همه اطلاعات را روی LCD نشان نمی ده. فقط کاراکتر # را روی LCD نشان می ده که تو عمل هم همینطوره. خیلی باهاش ور رفتم. واقعا مشکل عجیبیه.
من برنامه رو دقیق و کامل توی AVR STUDIO دیباگ کردم و به نظر همه چیز درست بود و اطلاعات تا رسیدن کاراکتر '\r' دریافت میشد.
به نظر شما چرا برنامه فقط کاراکتر اول از آرایه rx_buffer ( که از اطلاعات دریافتی پر شده است ) را نشان می دهد؟ یا مشکل از جای دیگه ای است؟
متن برنامه رو اینجا اوردم.این برنامه واسه ارتباط بین دو میکرو که یکی فرستنده و دیگری گیرنده است نوشته شده.( بعدا گسترش می دم تا هر دوشون بتونن هم بفرستن و هم بگیرن ) .نیازی به فایل پروتئوس هم نیست. اما اگه صلاح دیدین بزارم. ضمنا من هم تو پروتئوس بستمش و هم تو عمل اما جواب نداد. برنامه فرستنده که چیزی نداره و هم تو عمل و هم تو پروتئوس جواب می ده.
توضیح: فرستنده یه اسم مثل ali را می فرسته و گیرنده باید آن را گرفته و روی LCD نشان می دهد.فرستنده درست عمل می کند و اسم را اینطوره می فرسته :
char esm[10]="ALI"
while (1)
{
// Place your code here
delay_ms(100);
sprintf(str,"#%s\r",esm);
puts(str);
delay_ms(100);
}; \\ End of while
گیرنده هم تا حدودی درست عمل می کند. اینم برنامه گیرنده :
#include <mega16.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 16
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
bit receive_complete=0;
#pragma savereg-
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
#asm
push r26
push r27
push r30
push r31
in r26,sreg
push r26
#endasm
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
if(data=='#'
{
rx_buffer[0]=data;
rx_wr_index=1;
}
else if(rx_wr_index>=1 && data!='\r'
{
rx_buffer[rx_wr_index]=data;
rx_wr_index++;
}
else if(data=='\r'
{
receive_complete=1;
}
else
{
rx_wr_index=0;
}
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
#asm
pop r26
out sreg,r26
pop r31
pop r30
pop r27
pop r26
#endasm
} /* END OF INTERRUPT */
#pragma savereg+
// Standard Input/Output functions
#include <stdio.h>
void main(void)
{
// Declare your local variables here
char str[30];
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
// USART Baud Rate: 1200
UCSRA=0x00;
UCSRB=0x90;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei"
lcd_clear();
lcd_gotoxy(0,0);
while (1)
{
// Place your code here
if(receive_complete)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(str,"%s",rx_buffer);
lcd_puts(str);
receive_complete=0;
}
};
}
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 16
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
bit receive_complete=0;
#pragma savereg-
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
#asm
push r26
push r27
push r30
push r31
in r26,sreg
push r26
#endasm
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
if(data=='#'

{
rx_buffer[0]=data;
rx_wr_index=1;
}
else if(rx_wr_index>=1 && data!='\r'

{
rx_buffer[rx_wr_index]=data;
rx_wr_index++;
}
else if(data=='\r'

{
receive_complete=1;
}
else
{
rx_wr_index=0;
}
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
#asm
pop r26
out sreg,r26
pop r31
pop r30
pop r27
pop r26
#endasm
} /* END OF INTERRUPT */
#pragma savereg+
// Standard Input/Output functions
#include <stdio.h>
void main(void)
{
// Declare your local variables here
char str[30];
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
// USART Baud Rate: 1200
UCSRA=0x00;
UCSRB=0x90;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei"

lcd_clear();
lcd_gotoxy(0,0);
while (1)
{
// Place your code here
if(receive_complete)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(str,"%s",rx_buffer);
lcd_puts(str);
receive_complete=0;
}
};
}
من مدار را هم در عمل امتحان کردم و هم در پروتئوس. هیچ چی روی LCD نشان داده نمی شه. اول فکر کردم متغیر receive_complete هیچ وقت یک نمی شه و برنامه وارد if(receive_complete) نمی شه تا اطلاعات را روی LCD نشان بده. اما بعد که با AVR STUDIO برنامه را DEBUG کردم دیدم که اطلاعات دریافت می شه و با رسیدن کاراکتر ENTER متغیر receive_complete هم یک می شه و برنامه وارد حلقه if(receive_complete) می شه اما همه اطلاعات را روی LCD نشان نمی ده. فقط کاراکتر # را روی LCD نشان می ده که تو عمل هم همینطوره. خیلی باهاش ور رفتم. واقعا مشکل عجیبیه.
من برنامه رو دقیق و کامل توی AVR STUDIO دیباگ کردم و به نظر همه چیز درست بود و اطلاعات تا رسیدن کاراکتر '\r' دریافت میشد.
به نظر شما چرا برنامه فقط کاراکتر اول از آرایه rx_buffer ( که از اطلاعات دریافتی پر شده است ) را نشان می دهد؟ یا مشکل از جای دیگه ای است؟
دیدگاه