|
Проблема с приемом данных USART в ATtiny2313 |
|
|
|
Oct 29 2008, 09:28
|

Участник

Группа: Участник
Сообщений: 20
Регистрация: 28-10-08
Из: Москва
Пользователь №: 41 264

|
Помогите, плиз, разобраться с проблемой!
Спаял схему, в которой данные в МК должны поступать по протоколу Модбас через ADM1485. В CodeVisionAVR создаю проект, в котором настраиваю все параметры МК. Снизу часть сгенерированного текста, относящаяся к обработке прерывания:
// USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status= UCSRA; data=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) ...
Все вроде бы собрано правильно, но МК не хочет воспринимать данные. Для проверки срабатывания прерывания я включил в текст строку:
// USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status= UCSRA; data=UDR; PORTB.7=1; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) ...
После прихода на МК посылки, PORTB.7 меняет свое состояние, что говорит об срабатывании прерывания. Но если я включаю строчку после проверки if:
// USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status= UCSRA; data=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) PORTB.7=1; ...
, то МК перестает реагировать на пакеты. Скорость передатчика и приемника выставлены одинаковыми. Я пробывал с разными скоростями. Пробывал и от внешнего кварца и от внутреннего генератора. Где-то я прочел, что в этом условии проверяется наличие аппаратной ошибки. Получается, что МК плохой? Или еще какая-то другая причина может быть?
|
|
|
|
|
 |
Ответов
|
Oct 29 2008, 10:11
|

Участник

Группа: Участник
Сообщений: 20
Регистрация: 28-10-08
Из: Москва
Пользователь №: 41 264

|
Текст программы я не приводил, так как она мало отличается от сгенерированной CodeVisionAVR.
Красным выделены те строки, которые я добавляю. Они мне нужны для того, чтобы понять, что прием хотя бы начался (я не говорю уж о правильности полученной информации).
#include <tiny2313.h> #include <stdio.h> #include <delay.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 8 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;
USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status=UCSRA; data=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
PORTB.7=1; delay_ms(100); PORTB.7=0;
rx_buffer[rx_wr_index]=data; if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0; if (++rx_counter == RX_BUFFER_SIZE) { rx_counter=0; rx_buffer_overflow=1; }; }; }
#ifndef _DEBUG_TERMINAL_IO_ // Get a character from the USART Receiver buffer #define _ALTERNATE_GETCHAR_ #pragma used+ char getchar(void) { char data; while (rx_counter==0); data=rx_buffer[rx_rd_index]; if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0; #asm("cli") --rx_counter; #asm("sei") return data; } #pragma used- #endif
// Standard Input/Output functions #include <stdio.h>
// Declare your global variables here
void main(void) { // Declare your local variables here
// Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
PORTA=0x00; DDRA=0x00;
PORTB=0x00; DDRB=0x80;
PORTD=0x00; DDRD=0x04;
// USART initialization // Communication Parameters: 8 Data, 2 Stop, No Parity // USART Receiver: On // USART Transmitter: Off // USART Mode: Asynchronous // USART Baud Rate: 9600 UCSRA=0x00; UCSRB=0x90; UCSRC=0x0E; UBRRH=0x00; UBRRL=0x33;
ACSR=0x80;
// Global enable interrupts #asm("sei")
while (1) { // Place your code here
}; }
|
|
|
|
|
Oct 29 2008, 12:09
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Прораб счастья @ Oct 29 2008, 10:11)  UCSRC=0x0E; Вполне возможно, что эта строчка в инициализации приводит к ошибке. Для записи в UCSRC надо старший бит установить в 1, т.е. UCSRC=0x8E. В прерывании вы зачем-то проверяете паритет, а этой строчкой вы паритет запрещаете. Тогда получается, что МК получает байты с паритетом, но интерпретирует бит паритета, как стоп-бит, отсюда могут возникать ошибки FE - Frame Error.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 29 2008, 12:52
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(=GM= @ Oct 29 2008, 15:09)  Для записи в UCSRC надо старший бит установить в 1... Увы, нет. Цитата(=GM= @ Oct 29 2008, 15:09)  ...получается, что МК получает байты с паритетом, но интерпретирует бит паритета, как стоп-бит, отсюда могут возникать ошибки FE - Frame Error. Цитирую datasheet: "If Parity Check is not enabled the UPE bit will always be read zero." Остается пока теоретически возможность грешить на 10% нестабильность внутренного RC-генератора и неточность установки baudrate при кварце 10 МГц...
|
|
|
|
|
Oct 29 2008, 15:22
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SysRq @ Oct 29 2008, 12:52)  Цитирую datasheet: "If Parity Check is not enabled the UPE bit will always be read zero." Бит чётности читается 0, всё правильно, но если он физически передаётся другой стороной, то МК принимает его за стоп-бит, поскольку его инициализировали не принимать бит чётности. На последовательности бит отлично видно, бит чётности передаётся, START-B0-B1-B2-B3-B4-B5-B6-B7-P-STOP1-STOP2, а МК думает, что уже идёт первый бит STOP1.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 29 2008, 15:40
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(=GM= @ Oct 29 2008, 18:22)  Бит чётности читается 0, всё правильно, но если он физически передаётся другой стороной, то МК принимает его за стоп-бит, поскольку его инициализировали не принимать бит чётности. Вы правы, я прочитал начало фразы, а основную вашу мысль почему-то не воспринял. Решил, что автор все же занает что и как он передает. И написал о своем :)
|
|
|
|
Сообщений в этой теме
Прораб счастья Проблема с приемом данных USART в ATtiny2313 Oct 29 2008, 09:28 Vladimir_J Доброе время суток !!!
1. После услови... Oct 29 2008, 09:39 Прораб счастья Скобка - { есть, просто здесь я ее забыл поставить... Oct 29 2008, 09:51 GDI Вы бы привели код полностью, чтоб никто не гадал, ... Oct 29 2008, 09:56  =GM= Цитата(Прораб счастья @ Oct 29 2008, 12:1... Oct 29 2008, 13:16 IVANS 1. Если данные передаются непрерывно, то задержка ... Oct 29 2008, 10:49 Прораб счастья Подключение А и В я неоднократно проверял.
Насчет ... Oct 29 2008, 11:19 Polaris Цитата(Прораб счастья @ Oct 29 2008, 13:1... Oct 29 2008, 11:48 SysRq Цитата(Прораб счастья @ Oct 29 2008, 14:1... Oct 29 2008, 11:52 defunct Цитата(Прораб счастья @ Oct 29 2008, 12:2... Oct 29 2008, 11:47 Прораб счастья defunct:
Спасибо! Сегодня посмотрю Oct 29 2008, 11:51 Прораб счастья Цитата(Polaris @ Oct 29 2008, 14:48) Прер... Oct 29 2008, 12:19 Прораб счастья Сегодня вечером заменю кварц на 7.3728МГц, проверю... Oct 29 2008, 13:30 Прораб счастья Я, в общем-то, знаю что я передаю
Посылка у меня ... Oct 30 2008, 07:30 =GM= Цитата(Прораб счастья @ Oct 30 2008, 07:3... Oct 30 2008, 10:01 SysRq Попробуйте отправить неразрывно два байта: [0xFF][... Oct 30 2008, 08:46 IVANS GM
может так?
PORTB.7=~PINB.7
Попробуй включить п... Oct 30 2008, 10:13 SysRq Цитата(IVANS @ Oct 30 2008, 13:13) GM
мож... Nov 1 2008, 18:28  =GM= Цитата(SysRq @ Nov 1 2008, 18:28) Восстан... Nov 1 2008, 20:50
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|