реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Проблема с приемом данных USART в ATtiny2313
Прораб счастья
сообщение Oct 29 2008, 09:28
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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;
...


, то МК перестает реагировать на пакеты.
Скорость передатчика и приемника выставлены одинаковыми. Я пробывал с разными скоростями. Пробывал и от внешнего кварца и от внутреннего генератора.
Где-то я прочел, что в этом условии проверяется наличие аппаратной ошибки. Получается, что МК плохой? Или еще какая-то другая причина может быть?
Go to the top of the page
 
+Quote Post
Vladimir_J
сообщение Oct 29 2008, 09:39
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 74
Регистрация: 9-01-07
Из: Украина
Пользователь №: 24 228



Доброе время суток !!!
1. После условия if есть открывающаяся { скобка - "Но если я включаю строчку после проверки .. то МК перестает реагировать на пакеты"
2. Посмотрите в настройках UART: длина пакета 8 или 9 бит, к-во стоповых бит и т.д.
Скорее в этом трабл.

С Уважением, Владимир.
Go to the top of the page
 
+Quote Post
Прораб счастья
сообщение Oct 29 2008, 09:51
Сообщение #3


Участник
*

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



Скобка - { есть, просто здесь я ее забыл поставить.

Длина пакета 8 бит установлена и на передающей и на принимающей стороне. Кол-во стоповых битов 2, но помоему они (стоповые биты) не должны влиять на начало приема.

По моему разумению, даже если установлены разные скорости обмена или(и) разная длина пакета в настройках, условие после if должно быть истина в любом случае при отсутствии аппаратной ошибки (если это она проверяется в условии).
У меня параметры приема и передачи идентичны.
Go to the top of the page
 
+Quote Post
GDI
сообщение Oct 29 2008, 09:56
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Вы бы привели код полностью, чтоб никто не гадал, где вы там забыли или поленились скобку поставить.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Прораб счастья
сообщение Oct 29 2008, 10:11
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 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

};
}
Go to the top of the page
 
+Quote Post
IVANS
сообщение Oct 29 2008, 10:49
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 2-12-04
Пользователь №: 1 296



1. Если данные передаются непрерывно, то задержка 100 мс внутри прерывания может вызвать переполнение (DATA_OVERRUN).
2. Могут быть банально перепутаны A и B проводники 485 - тогда ошибка кадрирования(FRAMING_ERROR)
IMHO
Go to the top of the page
 
+Quote Post
Прораб счастья
сообщение Oct 29 2008, 11:19
Сообщение #7


Участник
*

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



Подключение А и В я неоднократно проверял.
Насчет первого есть вопрос: прерывание вызывается единожды при начале приема пакета или каждый принятый бит вызывает прерывание? Или каждый принятый байт?
Задержка 100 мс стоит после того, как в регистр что-то записалось (видимо в UDR), т.е. то что записалось должно пройти проверку if-ом. Поправьте меня если я не прав!
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 29 2008, 11:47
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Прораб счастья @ Oct 29 2008, 12:28) *
После прихода на МК посылки, PORTB.7 меняет свое состояние, что говорит об срабатывании прерывания. Но если я включаю строчку после проверки if:, то МК перестает реагировать на пакеты.

Найдите какая именно ошибка возникает:
Код
if (status & FRAMING_ERROR)
   PORTB.7 = 1;
if (status & PARITY_ERROR)
   PORTB.6 = 1;
if (status & DATA_OVERRUN)
   PORTB.5 = 1;

от этого дальше будем плясать.


Цитата
По моему разумению, даже если установлены разные скорости обмена или(и) разная длина пакета в настройках, условие после if должно быть истина в любом случае при отсутствии аппаратной ошибки (если это она проверяется в условии).

По моему разумению если возникает ошибка - то первым делом надо ее идентифицировать и потом искать способы ее устранения. Ошибка это не значит "что МК плохой?"

Цитата
У меня параметры приема и передачи идентичны.

Это ничем не подтвержденный факт. Раз не работает - значит есть проблема, в том числе параметры приема-передачи могут отличаться.
Go to the top of the page
 
+Quote Post
Polaris
сообщение Oct 29 2008, 11:48
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 266
Регистрация: 8-12-05
Пользователь №: 11 964



Цитата(Прораб счастья @ Oct 29 2008, 13:19) *
Подключение А и В я неоднократно проверял.
Насчет первого есть вопрос: прерывание вызывается единожды при начале приема пакета или каждый принятый бит вызывает прерывание? Или каждый принятый байт?
Задержка 100 мс стоит после того, как в регистр что-то записалось (видимо в UDR), т.е. то что записалось должно пройти проверку if-ом. Поправьте меня если я не прав!

Прерывание в документе обозначается USART0, Rx Complete и вызывается, соответственно, после окончания приема всего байта. Насколько я понмю, в CodeVision запрещаются прерывания после вызова прерывания (хотя и в самой архитектуре AVR при входе в прерывание дальнейший вызов прерывания по умолчанию также блокируеся), так что задержки такой величины в прерываниях - это очень плохой тон, скорее всего, Вы пропускаете данные, на что потом и указывает DATA_OVERRUN. Чем вызвана первая ошибка - видимо, ошибкой формата пакета.
Go to the top of the page
 
+Quote Post
Прораб счастья
сообщение Oct 29 2008, 11:51
Сообщение #10


Участник
*

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



defunct:

Спасибо! Сегодня посмотрю smile.gif

Сообщение отредактировал Прораб счастья - Oct 29 2008, 11:53
Go to the top of the page
 
+Quote Post
SysRq
сообщение Oct 29 2008, 11:52
Сообщение #11


Чайник, 1 литр
****

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



Цитата(Прораб счастья @ Oct 29 2008, 14:19) *
...прерывание вызывается... каждый принятый байт.

Ага.

Управляете ADM1485 правильно? Для приёма на RE и DE надо выставить низкий уровень (в коде этого момента не видать без схемы).
Кварц 8 МГц?
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 29 2008, 12:09
Сообщение #12


Ambidexter
*****

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



Цитата(Прораб счастья @ Oct 29 2008, 10:11) *
UCSRC=0x0E;

Вполне возможно, что эта строчка в инициализации приводит к ошибке. Для записи в UCSRC надо старший бит установить в 1, т.е. UCSRC=0x8E. В прерывании вы зачем-то проверяете паритет, а этой строчкой вы паритет запрещаете. Тогда получается, что МК получает байты с паритетом, но интерпретирует бит паритета, как стоп-бит, отсюда могут возникать ошибки FE - Frame Error.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Прораб счастья
сообщение Oct 29 2008, 12:19
Сообщение #13


Участник
*

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



Цитата(Polaris @ Oct 29 2008, 14:48) *
Прерывание в документе обозначается USART0, Rx Complete и вызывается, соответственно, после окончания приема всего байта. Насколько я понмю, в CodeVision запрещаются прерывания после вызова прерывания (хотя и в самой архитектуре AVR при входе в прерывание дальнейший вызов прерывания по умолчанию также блокируеся), так что задержки такой величины в прерываниях - это очень плохой тон, скорее всего, Вы пропускаете данные, на что потом и указывает DATA_OVERRUN. Чем вызвана первая ошибка - видимо, ошибкой формата пакета.


По этой логике получается: после приема одного байта идет первая проверка на корректность приема именно одного первого байта (if ((status &.......). Значит задержка в 100 мс еще не была задействована и условие (при правильном приеме) должно быть истина!


Цитата(SysRq @ Oct 29 2008, 14:52) *
Управляете ADM1485 правильно? Для приёма на RE и DE надо выставить низкий уровень (в коде этого момента не видать без схемы).
Кварц 8 МГц?


На входах RE и DE у меня выставлен 0 постоянно. ADM принимает данные - проверенно логическим анализатором.
Я пробывал с 10МГц-овым кварцем и с внутренним генератором 8МГц. Фьюз деления частоты на 8 отключен. Конечно настройки в передатчике соответствовали настройкам приемника.

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


Это сгенерированный CodeVisionAVR текст. Ничего, кроме строчек выделенных красным цветом я не добавлял и не менял.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Oct 29 2008, 12:52
Сообщение #14


Чайник, 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 МГц...
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 29 2008, 13:16
Сообщение #15


Ambidexter
*****

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



Цитата(Прораб счастья @ Oct 29 2008, 12:19) *
Это сгенерированный CodeVisionAVR текст. Ничего, кроме строчек выделенных красным цветом я не добавлял и не менял

CodeVisionAVR тоже человек писал, Павел Гайдук, мог ошибиться(:-). Повторюсь
Цитата(=GM= @ Oct 29 2008, 12:09) *
Вполне возможно, что эта строчка в инициализации приводит к ошибке. В прерывании вы зачем-то проверяете паритет, а этой строчкой вы паритет запрещаете. Тогда получается, что МК получает байты с паритетом, но интерпретирует бит паритета, как стоп-бит, отсюда могут возникать ошибки FE - Frame Error.

С <7> битом UCSRC я ошибся, я всё время с ним ошибаюсь (просто у меня старая, но удобная книжка по авр с описанием процов, жалко выбрасывать). Шут с ним, с седьмым битом, не в нём дело, а дело в том, что при инициализации вы ЗАПРЕЩАЕТЕ паритет как класс, тем не менее, в своей программе вы проверяете бит паритета, спрашивается за каким шутом проверять, если вы его запретили принимать? Повторю ещё раз, если внешнее устройство передаёт вам биты с паритетом, а вы его запретили, то МК рассматривает переданные биты паритета как следующие за ними стоп-биты, а это приводит к ошибке FE, если конкретный бит паритета равен 0. Ответьте себе на вопрос, вы на МК передаёте биты с паритетом или нет?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th July 2025 - 08:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01508 секунд с 7
ELECTRONIX ©2004-2016