TechMike (30.07.2008 14:08, просмотров: 8194)
Появилась проблема с COM- портом при работе с mega16+8МГц кварц. МК подключена через классическую схему на MAX232 к COM-порту и с определенного момента, не зависит от прошивки или внешний условий, МК перестает принимать команды по USART, хотя МК данные успешно безошибочно отправляет и в терминале это видно.
Закорачиваю перемычкой RX-TX на шнурке от COM-порта, но в терминали (Hyper Terminal, ZOC и т.д.) все равно не приходит посылаемый символ. Тоже самое делаю после MAX-232, результат тот же, от МК при этом RX-TX отключаю.
Пробовал обрабатывать данные от USART не по прерыванию, а просто в цикле, все равно не возвращает посылаемый с терминала символ.
Пробовал сделать шнурок от ПК как нуль-модем: закоротил ножки на COM-разъеме 1-4-6 и 7-8, остальное, как и было: 2-прием, 3- передача, 5-земля.
Осциллограф вешал на прием, там сигнал от МК есть, а на передачу нет (при наборе символов в терминале).
Пробовал подключить внешний модем, он на все команду откликается и работает без проблем, т.е. порт не горелый.
Настройки порта в windows:
скорость - 9600
биты данных - 8
четность - нет
стоп биты - 1
управление портом - нет
USART у МК сконфигурен также.
Пробовал поставить управление портом - Аппаратное, тоже не помогло.
Что посоветуете еще?
Текс программы с использованием прерывания:
void USART_Init(unsigned int baud )
{
#define UBRRVAL ((F_CPU/(baud*16UL))-1)
//Set baud rate
UBRRL=UBRRVAL; //low byte
UBRRH=(UBRRVAL>>8); //high byte
//Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)| (0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);
//Enable Transmitter and Receiver
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}
void USART_Send( unsigned int Txt )
{
while (!(UCSRA&(1<<UDRE))){};
UDR=Txt; //send number to USART
}
SIGNAL (SIG_USART_RECV)
{
char status,data;
status=UCSRA;
data=UDR;
led2_test_on;
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
led2_test_off;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
rx_wr_index ++; // инкремент индекса
if (rx_wr_index == RX_BUFFER_SIZE)
{
rx_wr_index=0;
};
++rx_counter;
if (rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
if (data==13){
EnterPress=1;
}
USART_Send(data);
};
}
int main(void)
{
// настраиваем порты(ножки)
DDRB=0b11111110; //делаем выходами все порты PINB кроме 0.
PINB=0b00000001; //выводим на все выходы PORTB 0, кроме 0
PORTB=0b00000001; // и подягиваем на +питания.
//задержка для включения
//dial_nums(DialNumber);
sei(); //разрешаем прерывания глобально
//настраиваем UART
USART_Init(9600);
//настроили UART
while(1)
{ //начало бесконечного цикла
};// конец бесконечного цикла
}// конец main
Без прерывания:
int main(void)
{
// настраиваем порты(ножки)
DDRB=0b11111110; //делаем выходами все порты PINB кроме 0.
PINB=0b00000001; //выводим на все выходы PORTB 0, кроме 0
PORTB=0b00000001; // и подягиваем на +питания.
//задержка для включения
//dial_nums(DialNumber);
sei(); //разрешаем прерывания глобально
//настраиваем UART
USART_Init(9600);
//настроили UART
while(1)
{ //начало бесконечного цикла
/*for (;;) // Loop forever
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR
ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"
led2_test_on;
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
led2_test_off;
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
};// конец бесконечного цикла
}// конец main