Jump to content
Smith2007

STM32F103: ADC+DMA

Recommended Posts

Добрый день, уважаемые форумчане.

Столкнулся со странной проблемой в работе связки ADC-DMA

В проекте используется 2 канала DMA1. Канал 1 для циклического чтения регулярных регистров ADC

И канал 4 для вывода буфера в USART. (После добавления этого канала в работу и начались чудеса

ADC по преобразует сигналы и дергает DMA, который последовательно раскладывает значения в буфер uint16_t signal[6]

Все работало длительное время пока я не решил задействовать DMA Для вывода в USART.

Например:

ADC1- Канал1 - записывался в нулевой элемент массива signal[ 0 ]

ADC1- Канал2 - записывался в первый элемент массива signal[ 1 ]

ADC1- Канал3 - записывался во второй элемент массива signal[ 2 ]

После вывода буфера по каналу 4, на канале 1 происходит смещение индекса массива и данные от ADC начинают записываться  по другим адресам.

Например:

ADC1- Канал1 - записывался во второй элемент массива signal[ 2 ]

ADC1- Канал2 - записывался в третий элемент массива signal[ 3 ]

ADC1- Канал3 - записывался во четвертый элемент массива signal[ 4 ]

Каким образом DMA->Канал4 может вносить проблемы на работу DMA->Канал1?

Ниже привожу инит и вывод 

Инициализация и запуск циклического считывания значений в массив  arrSignal[]

void Init_ADC_DMA(void) {

	
	uint32_t pin;
	
	// Включаем тактирование GPIOA, AFIO, ADC1
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_ADC1EN;
		
	RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8;	//Предделитель АЦП 72/6 = 12 МГц
	
	// Очистим настройки пинов. Нулевое значение соответствует Input Analog
	GPIOA->CRL &=  ~(	GPIO_CRL_CNF0 | GPIO_CRL_MODE0
									| GPIO_CRL_CNF1 | GPIO_CRL_MODE1
									| GPIO_CRL_CNF5 | GPIO_CRL_MODE5
									| GPIO_CRL_CNF6 | GPIO_CRL_MODE6
									| GPIO_CRL_CNF7 | GPIO_CRL_MODE7 );
	
	// Настройка DMA1
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;					// Включаем тактирование DMA1
	
	// Deinit DMA1 Channel1
	DMA1_Channel1->CCR &= ~DMA_CCR1_EN;		// Отключаем DMA1 CH1
	//DMA1_Channel1->CCR = 0;								// Reset DMA1 Channel1 control register
	DMA1->IFCR |= DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1; // Reset interrupt pending bits for DMA1 Channel1

	// Настраиваем DMA
	DMA1_Channel1->CNDTR = ADC_COUNT;							// Количество передаваемых данных
	DMA1_Channel1->CPAR = (uint32_t) &(ADC1->DR );// Адрес перифирии
	DMA1_Channel1->CMAR = (uint32_t) arrSignal;		// Адрес памяти
	DMA1_Channel1->CCR 	|= DMA_CCR1_MINC					// Инкремент памяти
											| DMA_CCR1_PSIZE_0				// Режим периферии 16 бит
											| DMA_CCR1_MSIZE_0				// Режим памяти 16 бит
											| DMA_CCR1_PL_1						// Channel Priority level hight
											| DMA_CCR1_CIRC						// Circular mode
											| DMA_CCR1_TEIE;					// Transfer error interrupt enable
  DMA1_Channel1->CCR |= DMA_CCR1_EN;						// Включаем DMA1 Channel3

	// Очистим настройки ADC1
	ADC1->CR1 = 0;
	ADC1->CR2 = 0;
	ADC1->SMPR2 = 0;
	ADC1->SQR1 = 0;
	ADC1->SQR2 = 0;
	ADC1->SQR3 = 0;
	
	// Настраиваем ADC1
	ADC1->CR1 |= ADC_CR1_SCAN;		// Scan mode
	ADC1->CR2 |= ADC_CR2_CONT;		// Continuous Conversion
	ADC1->CR2 |= ADC_CR2_DMA;			// DMA mode
	ADC1->CR2 |= ADC_CR2_TSVREFE;	// Temperature Sensor and VREFINT Enable
	ADC1->CR2 &= ~ADC_CR2_ALIGN;	// Data Alignment
	ADC1->SQR1 |= ((uint32_t)(ADC_COUNT - 1) << 20);			// Сканируем 6 каналов (6-1 = 5)
	
	// Настройка семплирования. Номер канала совпадает с номером пина
	ADC1->SMPR2 |= ADC_SMPR2_SMP0;	// Channel 0 Sample time selection 111: 239.5 cycles
	ADC1->SMPR2 |= ADC_SMPR2_SMP1;	// Channel 1 Sample time selection 111: 239.5 cycles
	ADC1->SMPR2 |= ADC_SMPR2_SMP5;	// Channel 2 Sample time selection 111: 239.5 cycles
	ADC1->SMPR2 |= ADC_SMPR2_SMP6;	// Channel 3 Sample time selection 111: 239.5 cycles
	ADC1->SMPR2 |= ADC_SMPR2_SMP7;	// Channel 4 Sample time selection 111: 239.5 cycles
	ADC1->SMPR1 |= ADC_SMPR1_SMP16;	// Channel 5 Sample time selection 111: 239.5 cycles
	
	// Настройка пинов
	pin = 0x00;
	ADC1->SQR3 |= (pin << (5 * 0));			// Pin0
	pin = 0x01;
	ADC1->SQR3 |= (pin << (5 * 1));			// Pin1
	pin = 0x06;
	ADC1->SQR3 |= (pin << (5 * 2));			// Pin5
	pin = 0x07;
	ADC1->SQR3 |= (pin << (5 * 3));			// Pin6
	pin = 0x05;
	ADC1->SQR3 |= (pin << (5 * 4));			// Pin7
	pin = 0x10;
	ADC1->SQR3 |= (pin << (5 * 5));			// Pin16 - Температурный сенсор
	
	ADC1->CR2 |= ADC_CR2_ADON;		// A/D Converter ON / OFF

	// Обнуляем калибровку
  ADC1->CR2 |= ADC_CR2_RSTCAL; 
  while (ADC1->CR2 & ADC_CR2_RSTCAL);

  //запускаем калибровку и ждем ее завершение
  ADC1->CR2 |= ADC_CR2_CAL; 
  while (ADC1->CR2 & ADC_CR2_CAL);

	ADC1->CR2 |= ADC_CR2_EXTTRIG;		//ADC_CR2_SWSTART;
	ADC1->CR2 |= ADC_CR2_DMA;				// DMA mode
}

 

Вывод буфера в usart 

//##################################################################
// function Передача буфера в USART1 по DMA1 Ch4
// argument buf - указатель на буфер char*
// 					len - длина буфера
// return		void
//##################################################################
void DMA1Ch4_SendBuf8(const char* buf, uint32_t len) {
	
	// Deinit DMA1 Channel4
	DMA1_Channel4->CCR &= ~DMA_CCR4_EN;		// Отключаем DMA1 CH2
	//DMA1_Channel4->CCR = 0;								// Reset DMA1 Channel4 control register
	DMA1->IFCR |= DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4; 	// Reset interrupt pending bits for DMA1 Channel4

	// Настраиваем DMA1 Channel4
	DMA1_Channel4->CNDTR = len;										// Количество передаваемых данных
	DMA1_Channel4->CPAR = (uint32_t) &(USART1->DR);	// Адрес перифирии
	DMA1_Channel4->CMAR = (uint32_t) buf;					// Адрес памяти
	DMA1_Channel4->CCR 	|= DMA_CCR4_MINC					// Инкремент памяти
											//| DMA_CCR4_PL_0						// Channel Priority level Medium
											| DMA_CCR4_DIR						//Data transfer direction. 0 - from peripheria  1 - from memory
											| DMA_CCR4_TCIE;					// Transfer complete interrupt enable
	//DMA1_Channel4->CCR |= DMA_CCR4_TEIE;				// Transfer error interrupt enable
  DMA1_Channel4->CCR |= DMA_CCR4_EN;						// Включаем DMA1 Channel5
}

 

По окончании передачи формируется прерывание в котором просто отключаем DMA1->Channel4

//##################################################################
//function  Прерывание по окончании передачи по DMA CH4            #
//argument  none                                                   #
//return    void                                                   #
//##################################################################
void DMA1_Channel4_IRQHandler(void) {
	if ((DMA1->ISR & DMA_ISR_TCIF4)) { 				// Transfer Complete flag
		DMA1_Channel4->CCR &= ~DMA_CCR4_EN;			// Отключаем DMA.
		DMA1->IFCR |= DMA_IFCR_CTCIF4;					// Channel4 Transfer Complete clear
		usart.Status_Tx = Tx_None;
		xSemaphoreGiveFromISR(mtxUsart, 0);
	}
}

Есть у кого мысли в чем может быть проблема?

Второй день поисков - не дает результата. Понимаю, что можно обойти путем пересинхронизации ADC-DMA после каждого вызова отправки буфера по 4 каналу ДМА. Но это костыль получается.

Edited by Smith2007

Share this post


Link to post
Share on other sites
41 минуту назад, Smith2007 сказал:

DMA1_Channel1->CMAR = (uint32_t) arrSignal;

Уверены что не &arrSignal[0] ?

Туплю да)) Там ок

Минусы в том что не видно объявления переменной)

Edited by DrobyshevAlex

Share this post


Link to post
Share on other sites

Во время отправки по USART работа первого DMA отключается?

 

Share this post


Link to post
Share on other sites

Особенности схемотехники и трассировки печатных плат для STM32WB55

Разработка новых устройств на базе беспроводного микроконтроллера STM32WB от STMicroelectronics может быть сделана в короткий срок, если выполнять некоторые важные правила и воспользоваться готовыми конструктивными решениями и рекомендациями инженеров ST.

Читать статью

39 минут назад, DrobyshevAlex сказал:

Уверены что не &arrSignal[0] ?

С этим асе нормально.

Объявлен массив

Uint16t arrSignal[6]

Этот вариант работает довольно давно и до подключения канала1 ни каких сбоев не замечал

14 минут назад, BARS_ сказал:

Во время отправки по USART работа первого DMA отключается?

 

Нет. Не отключаю.

Думал об этом. Возможно надо приостановить ADC. 

Единственный общий ресурс, который я меняю это регистр

DMA1->IFCR

Когда произвожу сброс флага по окончании обработки прерывания

(Окончание передачи)

Edited by Smith2007
Правка

Share this post


Link to post
Share on other sites

Попробуйте приостановить выборку данных из ADC. Ну и не совсем понятно, зачем для передачи 4 байт гонять DMA. Выигрыша по времени практически никакого.

Share this post


Link to post
Share on other sites
                     

CoolGaN - на предельной скорости коммутации!

Решения на галлий-нитриде (GaN) обладают фундаментальными преимуществами перед кремнием. В частности, имея более высокую критическую напряжённость электрического поля, в сравнении с традиционными кремниевыми транзисторами, транзисторы на основе галлий-нитрида обладают выдающимися динамическими характеристиками, что позволяет коммутировать их на высоких частотах. Семейство CoolGaN™ – это именно то, что необходимо, чтобы поднять ваши устройства на принципиально новый уровень. Мы собрали все самые интересные материалы по данной теме на одной странице.

Читать статьи

Только что, Smith2007 сказал:

С этим асе нормально.

Ну на вид проблема с указателем, я даже не вчитывался в код, но потом понял что раз без канала 4 работало, то дело скорей всего не в этом.

Он пишет просто смещая указатель ? то есть идут показания подряд но не с первого элемента массива?

А что происходит с последним каналом? куда он пишет? За пределы же не должен массива, должен тогда упасть с ошибкой код, или в мк нет ошибки типа segmentation fault?

Как вы вообще определили что пишет не верно? Может лог выводит не верно? Например ДМА АДЦ перетирает данные быстрей чем улетают 

А может быть такое что пока ДМА читает байт, новый писать не может и из за этого глюк, типа к одной ячейки памяти доступ ток одного канала в один момент.

Можно подумать в сторону прерывания по половине данных, только нужно скорости отправки/чтения учесть тогда, что бы когда половина массива записана, начинало слать в UART с начала, а АЦП как раз допишет до конца и пойдет с начала когда в порт улетать будет уже конец.

 

 

 

Share this post


Link to post
Share on other sites
7 минут назад, BARS_ сказал:

. Ну и не совсем понятно, зачем для передачи 4 байт гонять DMA. Выигрыша по времени практически никакого.

Преобразования по 6ти каналам uint16.

Т.е не 4 байта, а 12.

Но дело даже не в этом...

Настроил adc-dma однажды и забыл. Когда нужно просто забираем данные из массива. Проц не участвует в чтении и сохранении данных adc. 

 

И просто такой конфиг работал очень долго, пока не подключил канал4

Share this post


Link to post
Share on other sites
5 минут назад, DrobyshevAlex сказал:

За пределы же не должен массива, должен тогда упасть с ошибкой код, или в мк нет ошибки типа segmentation fault?

На самом деле тут зависит от везения, точнее от того, что хранится в памяти за областью расположения массива. Если ничего жизненно важного нет, то программа может работать неопределенно долго.

1 минуту назад, Smith2007 сказал:

Т.е не 4 байта, а 12.

Я про передачу по USART.

 

2 минуты назад, Smith2007 сказал:

И просто такой конфиг работал очень долго, пока не подключил канал4

Тогда надо засинхронить работу DMA. Сначала дождаться, пока заполнится весь массив, затем остановить ADC и выплюнуть данные в USART. После чего запустить ADC.

Share this post


Link to post
Share on other sites
8 минут назад, DrobyshevAlex сказал:

Он пишет просто смещая указатель ? то есть идут показания подряд но не с первого элемента массива?

Данные загружаются в массив но со смещением (циклическим)

Т.е нулевой канал перескочил с нулевого элемента массива на первый элемент. А пятый канал стал грузиться не в пятый элемент массива, а в нулевой.

Проверял как в отладчике так и в памяти. Так же делал вывод массива в юсарт.

Ощущение, что во время операций с каналом 4, на канале1 происходит пропуск запроса на чтение , поступившего от adc.

При этом само смещение в массиве постоянно меняется. Может на 1 позицию сместиться, может на 2,3 и т.д.

 

Share this post


Link to post
Share on other sites

Ну и опять же, надо проверить, реально ли пишутся данные криво или же криво идет отправка.

Share this post


Link to post
Share on other sites
5 минут назад, BARS_ сказал:

Я про передачу по USART

Передача по юсарт может быть несколько килобайт.

За границы массива точно не выхожу. 

Я смотрел память.

И смотрел элементы массива отладчиком

1 минуту назад, BARS_ сказал:

Ну и опять же, надо проверить, реально ли пишутся данные криво или же криво идет отправка.

Данные пишутся верно по всем каналам, но смещается номер элемента массива.

Ставлю заглушку на вывод в юсарт по дма - проблема исчезает.

Понимаю, что можно каждый раз пересинхронизировать adc-dma. Но это же костыль будет

Share this post


Link to post
Share on other sites
6 минут назад, Smith2007 сказал:

Т.е нулевой канал перескочил с нулевого элемента массива на первый элемент. А пятый канал стал грузиться не в пятый элемент массива, а в нулевой.

Ну тут напрашиваются вариант как я писал выше

19 минут назад, DrobyshevAlex сказал:

А может быть такое что пока ДМА читает байт, новый писать не может и из за этого глюк, типа к одной ячейки памяти доступ ток одного канала в один момент.

 

8 минут назад, Smith2007 сказал:

Ощущение, что во время операций с каналом 4, на канале1 происходит пропуск запроса на чтение , поступившего от adc.

Как раз вы тоже об этом думаете)

Вообщем как вам уже посоветовали, попробуйте просто выключать дма-ацп пока идет отправка, видимо блокировка ячейки памяти. так как слать по половинкам думаю будет сложно подгадать какая ячейка сейчас отправляется...

 

Share this post


Link to post
Share on other sites
4 минуты назад, DrobyshevAlex сказал:

попробуйте просто выключать дма-ацп пока идет отправка,

Это может быть очень большим временем.

Если отправить в медленный юсарт буфер в пару килобайт....

 

Попробую при входе в прерывание по окончанию передачи в юсарт приостановить adc

По крайней мере это всего несколько тактов

Share this post


Link to post
Share on other sites
1 минуту назад, Smith2007 сказал:

Если отправить в медленный юсарт буфер в пару килобайт.

И все пару килобайт данные из DMA? Если так, то завести второй буфер, в который будут перекладываться данные после наполнения буфера отсчетов. Это будет быстро. А уже этот буфер передавать. Соответственно, пока идет запись или передача, буфер больше никто не должен трогать.

Share this post


Link to post
Share on other sites
7 минут назад, BARS_ сказал:

то завести второй буфер, в который будут перекладываться данные после наполнения буфера отсчетов.

Буфер adc и буфер для usart не пересекаются.

Просто из отрывков кода это не видно.

Я искал зацепку в даташите, но ничего вразумительного не нашел.

Вероятно это глюк самого контроллера, а точнее его периферии.

Поэкспериментирую еще сегодня.

Результат отпишу.

Share this post


Link to post
Share on other sites
Только что, Smith2007 сказал:

Буфер adc и буфер для usart не пересекаются.

А как данные перекладываются из одного буфера в другой?

Share this post


Link to post
Share on other sites

Если буфер ДМА для АЦП пару КБ пишет и потом шлет за раз то это один момент, а вот если у вас буфер для UART формирутеся где то в другом месте, и туда помещаются  всего 12 байт, то

или на момент помещения выключайте ДМА АЦП

или просто делайте по прерыванию ДМА АЦП когда буфер заполнен просто копирование ваших 12 байт в другой массив временный и все.

Но опять же, если формировать буфер для UART процем а в это время ДМА сработает прерывание, у вас опять данные могут быть битые

 

Вариант еще, выставляете флаг 

bool completed = false;

 

в прерывании дма по АЦП 

if (!complited) {

    completed = true;

    копируте буфер дма во временный

}


в цикле 

if (completed) {

    копируте из временного буфера в буфер usart

    completed = false

}

 

Edited by DrobyshevAlex

Share this post


Link to post
Share on other sites

таким образом вы получите не битый буфер, если конечно не будет еще конфликта прерываний)) но думаю заполнять буфер нужно не в прерывании а в основном цикле а значит не будет

 

Share this post


Link to post
Share on other sites
16 минут назад, BARS_ сказал:

А как данные перекладываются из одного буфера в другой?

На уарт терминал висит. В него идет как отладочная инфа так и служебная.

Есть строковые константы. Есть даже большие.

Ацп считывает данные с датчиков, а дальше они пройдут через медианные фильтры, нормированы и будут использованы в отдельной задаче.

 

Share this post


Link to post
Share on other sites
1 минуту назад, Smith2007 сказал:

На уарт терминал висит. В него идет как отладочная инфа так и служебная.

Ну так значит буферы все таки пересекаются.

Share this post


Link to post
Share on other sites
19 минут назад, DrobyshevAlex сказал:

просто делайте по прерыванию ДМА АЦП когда буфер заполнен просто копирование ваших 12 байт в другой массив временный и все.

Я подозреваю, что дело не в массиве, а в том, что при операциях с регистрами дма1 канал4, каким-то образом происходит пропуск запроса на чтение.

Т.е ацп дергает дма - читай, у меня готовы данные для элемента1.

А дма1 тем временем очень занят и пропустил мимо ушей эту инфу.

 

2 минуты назад, BARS_ сказал:

Ну так значит буферы все таки пересекаются

Нет буферы не пересекаются.

Если я преобразую int в ascii, я это делаю в отдельном статическом буфере

Share this post


Link to post
Share on other sites
5 минут назад, Smith2007 сказал:

А дма1 тем временем очень занят и пропустил мимо ушей эту инфу.

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

То есть я понимаю пропустил, это он просто не записал новое значение канала 1 в первый элемент массива

Или же я бы понял если он с задержкой записал, и тайминги сбились, типа занят, пока не могу записать.

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

Не понятно куда тогда пишет последний канал. Может вы случайно где то размер сбили? Например у вас 4 канала а указано 5 и он по кругу со смещение бегает :) Или еще что... просто как то странно это все

Share this post


Link to post
Share on other sites
13 минут назад, DrobyshevAlex сказал:

То есть я понимаю пропустил, это он просто не записал новое значение канала 1 в первый элемент массива

Смещение индекса произвольное.

Без канала4 дма - все работает верно.

13 минут назад, DrobyshevAlex сказал:

Ладно бы пропустил, но у вас сдвиг счетчика происходит а запись нет судя оп вашему

Я думаю, что как раз происходит пропуск чтения и соответственно не инкрементируется счетчик.

Т.е.

Ацп пнул дма, а дма пропустил.

Ацп перешел к следующему каналу - снова пнул дма. Дма щагрузил.

Потом еще несколько циклов и несколько прпусков.

Это как раз объясняет тот факт, что смещение индекса постоянно меняется

13 минут назад, DrobyshevAlex сказал:

Не понятно куда тогда пишет последний канал.

В нулевой элемент массива или в любой другой в зависимости от сиещения

Зв. Движек форумя тяжел для смартфона.

 

Edited by Smith2007
Правка

Share this post


Link to post
Share on other sites
2 часа назад, Smith2007 сказал:

Ацп пнул дма, а дма пропустил.

Ацп перешел к следующему каналу - снова пнул дма. Дма щагрузил.

Потом еще несколько циклов и несколько прпусков.

так это была бы ругая ситуация по идеи... 

АЦП пнул ДМА, ДМА пропустил, АЦП пнул бы уже с новым каналом ДМА по идеи...

странно это все, выходит что дма счетчик сдвинул, а ацп как раз не отдал данные так как он перенес их в новый канал. Вы хе написали что данные с АЦП канал 1 идут потом на ДМА в ячейку 2, то есть данные не пропущены просто не туда записаны...

 

 

Share this post


Link to post
Share on other sites
3 часа назад, DrobyshevAlex сказал:

странно это все, выходит что дма счетчик сдвинул, а ацп как раз не отдал данные так как он перенес их в новый канал. Вы хе написали что данные с АЦП канал 1 идут потом на ДМА в ячейку 2, то есть данные не пропущены просто не туда записаны...

Я думаю, что ДМА счетчик не сдвинул как раз. Пропустил запрос от ADC. 

Следующий запрос от ADC к DMA:  DMA принял, но данные поместил уже не во второй элемент массива, а в первый.

Затем ADC шлет еще и еще запросы и некоторые из них DMA вновь пропускает. И количество пропусков *считай смещений) может составлять от 1 до 6.  Вот это и объясняет, что сдвиг данных всегда на разную величину происходит.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • http://www.alfarzpp.ru/rus/sc/153ud1-3.pdf примерно одно и то же ... ставь - пойдет аж бегом
    • @IMXO Схему в Протеусе не рисовал, а те, что были - давно утеряны. Да там схема-то особо и не нужна. RB3 - вход (последовательный 1 wire), все остальные - выходы на сегменты и выбор знака. В проекте Протеуса подтянул RB3 к питанию, остальные - выходы, в никуда. При этом на первую секунду зажигаются все сегменты (нули), потом индицируется " - - " (только два нуля) и без последовательного кода на входе не меняется. Линии выбора знака индикатора должны меняться с частотой примерно 60 Гц.
    • элементарно. сигнал усилить в усилителем в 20раз и пропустить через триггер Шмитта на компараторе , подать на вход INT МК и включить прерывание по нарастающему фронту, запустить любой таймер на тик 1мс , по отработке таймера инкриминировать беззнаковый счетчик разрядностью 16 бит  по отработке прерывания по фронту из нового значения счетчика вычесть старое значение счетчика = период с точностью +/-1мс новое значение счетчика сохранить как старое.
    • @IMXO , вот например, дешифратор динамического семисегментного индикатора. Написан в 2003-м под pic16c, для pic16f исправлен OPTION в 2015-м в MPLab 8.40. В ASM есть коментарии. RB3 - вход (последовательный 1 wire), все остальные - выходы на сегменты и выбор знака. С этим проектом с единственным из всех Протеус запустил заново созданный проект (даже ещё без имени и не сохранённый), открылось окно окно Sourse Code и может долго шагать по шагам, дважды вызвав подпрограмму. Но всё равно если RUN, то вылетает с той же ошибкой в DLL на совершенно безобидной операции то ли RLC, то ли MOVE (по которым он уже дважды прошёл), - не отловил, т.к. при вылете в ошибку закрываются все окна Sourse Code. DC_BAG1.rar
    • @KRAB а 153 в металле не аналоги 553?,а есть несколько корпусов..попробовать..не совсем..сам уже посмотрел..
×
×
  • Create New...