Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 01.06.2015, 01:49  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Подглючивает кольцевой буфер

Доброй ночи.

Был у меня в аврке код кольцевого буфера работало все ОК.

Перенес код в стм началось подглучивание.
Глюк такого характера пропадает один символ. Вернее не пропадает а начинает выводиться с запозданием USART принял 123 символ а выбераеться из буфера 122 и со временем съезжает указатель.
Код:
#define BUFF_SIZE 10



int BuffCount1;
uint16_t *inptA1, *outptA1;	// указатели для записи и чтения в буфер
uint16_t bufferA1[BUFF_SIZE];	// буфер1



void BaseinitBuffAll()
{
inptA1 =  bufferA1;		// указатели
outptA1 = bufferA1;		// на начало буфера
BuffCount1=0; //Общий побайтный счетчик
}





// Буфер 1 прямой USART1
void SetBuff1(uint16_t *BefferRecev)
{
        if (BuffCount1‹BUFF_SIZE)
        {
		*inptA1 = BefferRecev[0];
		inptA1++;
                BuffCount1++;
    	        if (inptA1 ›= bufferA1 + BUFF_SIZE)
    	        {inptA1 = bufferA1;}
        }
}

int GetBuff1(uint16_t *BefferRecev)
{
if (BuffCount1==0) {return 0;}
      BefferRecev[0] =*outptA1;
      outptA1++;
      BuffCount1--;
      if (outptA1 ›= bufferA1 + BUFF_SIZE)//переполнение буфера
      {outptA1 = bufferA1;}
return 1;
}
Такое ощущение что не выполняется BuffCount1++;

ДМА пока не хочу использовать .

Может кто увидит ошибку.
В прерывание USART и в теле программы выгребка содержимого.
Код:
SetBuff2(&data);

                if(GetBuff1(&BaseBufferSend[0]) ==1)
                {
..............
                }
Переносил код в Борланд работает идеально. В чем грабли не могу понять.

За ранее спасибо.
Реклама:
bass1981 вне форума  
Непрочитано 01.06.2015, 03:44  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Вставил отключение прерываний и все запахало...


Код:
int GetBuff1(uint16_t *BefferRecev)
{
  	
if (BuffCount1==0) {return 0;}
__disable_irq();
                BefferRecev[0] =*outptA1;
                outptA1++;
								BuffCount1--;
                         if (outptA1 ›= bufferA1 + BUFF_SIZE)         // переполнение буфера
                        {outptA1 = bufferA1;}
                
//проверка команд
__enable_irq(); 
return 1;
 
}
В чем прикол был не пойму... В борланде в разных потоках все операции производил...
bass1981 вне форума  
Непрочитано 01.06.2015, 13:05  
ForcePoint
Почётный гражданин KAZUS.RU
 
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,792
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
ForcePoint на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Не пропущен-ли где-то тут ELSE?
Сообщение от bass1981 Посмотреть сообщение
Код:
int GetBuff1(uint16_t *BefferRecev)
{
if (BuffCount1==0)
      {return 0;}
else {
      BefferRecev[0] =*outptA1;
      outptA1++;
      BuffCount1--;
      if (outptA1 ›= bufferA1 + BUFF_SIZE)//переполнение буфера
      {outptA1 = bufferA1;}
      return 1;
      }
}
ForcePoint вне форума  
Непрочитано 01.06.2015, 14:10  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Можно и без else {}. Если BuffCount1 == 0 то выйдет по return, иначе не зайдет и выполнит следующий код.
valic вне форума  
Непрочитано 01.06.2015, 14:15  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Сообщение от ForcePoint Посмотреть сообщение
Не пропущен-ли где-то тут ELSE?
Да нет, там возврат стоит return 0. Если сработает конструкция BuffCount1==0 то выскочит из функции и далее код не будет исполняться.
Анализатором смотрел входящий и исходящий поток, глюк как описывал в первом посте. На АВРКЕ и в Борланде из разных потоков работает. Причем в борланде нагружал капитально, все Ок. Наверное без железа вряд ли поможете. Но поставил запрещение прерываний все заработало.
bass1981 вне форума  
Непрочитано 01.06.2015, 14:20  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Получается так:

Входящий поток данных:
10 11 12 13 14 и т.д


Исходящий поток данных:
10 хх 11 12 13 и т.д

хх пропуск пробелы форум убирает.

Меня теперь больше интересует не будет подглючивать USART, а то придут данные в момент отключения прерываний... И будет печалька.

Последний раз редактировалось bass1981; 01.06.2015 в 14:25.
bass1981 вне форума  
Непрочитано 01.06.2015, 14:27  
Yurkin2014
Заблокирован
 
Регистрация: 21.01.2014
Сообщений: 589
Сказал спасибо: 7
Сказали Спасибо 267 раз(а) в 206 сообщении(ях)
Yurkin2014 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Сообщение от bass1981 Посмотреть сообщение
Вставил отключение прерываний
Как я понял, переменная int BuffCount1 при приёме увеличивается на 1, а при передаче - уменьшается. Если приём и передача происходят отдновременно, то может инкремент прерваться декрементом и запишется ошибочное значение в BuffCount1.
Я предлагаю выкинуть эту BuffCount1 совсем. Не нужна эта BuffCount1.
Просто при приёме тупо сдвигать указатель inptA1, при достижении границы буфера - сбрасывать на начало. То же самое при передаче - двигаем указатель outptA1.
Получается, что указатель чтения буфера как бы всё время догоняет указатель записи в буфер.
Проверку пустой ли буфер заменяем на
Код:
if (outptA1 == inptA1) {return 0;}
Так как указатели изменяются только в своих процедурах, то никакой путаницы не будет.

И потом, такое ощущение, что у Вас пользуется только половина буфера. Дело в том, что значения двухбайтные, то есть при BUFF_SIZE =10 буфер занимает 20 байт памяти, а определение границы только по 10 байтам
Код:
if (inptA1 ›= bufferA1 + BUFF_SIZE)
Я думаю, надо бы так
Код:
if (inptA1 ›= bufferA1 + BUFF_SIZE * 2)
Yurkin2014 вне форума  
Сказали "Спасибо" Yurkin2014
bass1981 (01.06.2015)
Непрочитано 01.06.2015, 15:22  
Hives
Гражданин KAZUS.RU
 
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
Hives на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

нда, костыли на роликах, ролики на костылях...
вот пример нормальной реализации буфера:
Код:
// файл заголовков

#define BUF_SIZE        256                     // размер буфера приема UART
#define BUF_MASK        (BUF_SIZE - 1)          // маска размера буфера

typedef struct
{
__IO int Head;
int Tail;
__IO unsigned char Buffer[BUF_SIZE];
} TFifo;

extern TFifo Fifo;
//==================================================  ==============================

// файл исходников

TFifo Fifo;

// очистка буфера приема
void FifoClear (void)
{
Fifo.Tail = 0;
Fifo.Head = 0;
}

// наличие данных в буфере приема
bool FifoDataAvail (void)
{
int Head = Fifo.Head;
int Tail = Fifo.Tail;
return (Head != Tail);
}

// размер данных в буфере приема
int FifoDataSize (void)
{
int Head = Fifo.Head;
int Tail = Fifo.Tail;
int Count = Head - Tail;
if (Count ‹ 0) Count += BUF_SIZE;
return Count;
}

// чтение данных из буфера приема
unsigned char FifoGetByte (void)
{
int Head = Fifo.Head;
int Tail = Fifo.Tail;
if (Head == Tail) return 0;
unsigned char Data = Fifo.Buffer[Tail];
Fifo.Tail = (++Tail) & BUF_MASK;
return Data;
}

// чтение порта при приеме
void Обработчик_прерываний_порта (void)
{
// чтение порта...
unsigned char Data = ...;

int Head = Fifo.Head;
int Tail = Fifo.Tail;
int NextHead = (Head + 1) & BUF_MASK;
if (NextHead != Tail)
  {
  Fifo.Buffer[Head] = Data;
  Fifo.Head = NextHead;
  }
}
//==================================================  ==============================
Hives вне форума  
Сказали "Спасибо" Hives
bass1981 (01.06.2015)
Непрочитано 01.06.2015, 15:32  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Сообщение от Yurkin2014 Посмотреть сообщение
Проверку пустой ли буфер заменяем на
Код:
if (outptA1 == inptA1) {return 0;}
Так как указатели изменяются только в своих процедурах, то никакой путаницы не будет.
Попробую, не додумался так сделать.
Действительно все в своих процедурах.

Сообщение от Yurkin2014 Посмотреть сообщение
И потом, такое ощущение, что у Вас пользуется только половина буфера. Дело в том, что значения двухбайтные, то есть при BUFF_SIZE =10 буфер занимает 20 байт памяти, а определение границы только по 10 байтам
Код:
if (inptA1 ›= bufferA1 + BUFF_SIZE)
Я думаю, надо бы так
Код:
if (inptA1 ›= bufferA1 + BUFF_SIZE * 2)
А вот на счет половины буфера не ошиблись ли ???
У меня 9 ти битный USART и поэтому были буфера 16 бит а не восьми.
bass1981 вне форума  
Непрочитано 01.06.2015, 15:57  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Подглючивает кольцевой буфер

Сообщение от Hives Посмотреть сообщение
нда, костыли на роликах, ролики на костылях...
вот пример нормальной реализации буфера:
Да в данном коде производиться вычитание при заборе(определении занятости буфера) все выполняется в своих функциях..

Последний раз редактировалось bass1981; 01.06.2015 в 15:59.
bass1981 вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подскажите 8-канальный параллельный буфер для светодиодов chapa TTL и CMOS логика 8 26.03.2013 23:02
Счетчик-таймер на ATtiny Dimitrij Микроконтроллеры, АЦП, память и т.д 45 10.09.2011 13:36
Кольцевой буфер uart code-by Микроконтроллеры, АЦП, память и т.д 46 18.01.2011 19:33
Нужна помощь: буфер FIFO NETPOZYVNOGO Микроконтроллеры, АЦП, память и т.д 3 29.09.2007 10:21


Часовой пояс GMT +4, время: 11:02.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot