Страница 200 из 280

Re: Proteus: вопросы и ответы

Добавлено: Вс мар 29, 2015 23:21:03
CB1
Доброго времени суток! Поддерживаю вопрос Valeriy L по поводу можно ли сделать видными скрытые выводы микроконтроллеров (в моем случае AVR )... Видел графу где можно в письменном виде задать контакт к которому присоединить скрытый вывод, но что то это не то... Пробовал писать к примеру резистор, после этого под микроконтроллером появилась надпись VCC-R10 -следовательно появилась связь между выводом VCC и резистором R10... Но в данном случае не понятно с каким из выводов резистора VCC соединилось?

Re: Proteus: вопросы и ответы

Добавлено: Пн мар 30, 2015 21:46:13
Halex
Valeriy L писал(а):как сделать активными выводы питания Vdd и GND для PIC12F629. Что-бы я их мог использовать в проекте.
CB1 писал(а):Поддерживаю вопрос Valeriy L по поводу можно ли сделать видными скрытые выводы микроконтроллеров (в моем случае AVR )...
Тэкс, кто третьим будет??? В стопитьсотый раз повторюсь, в том числе и здесь на Коте - не парьте себе и другим мосК. Видимость выводов МК никаких преимуществ Вам не даст, поскольку использовать их как активные, т.е. управлять через них питанием МК Вы не сможете. Так задуманы и реализованы модели. Если про Пики в хелпе Лабцентр об этом скромно умолчал, то для AVR чётко прорисано (см. раздел AVR MODEL HELP -> General Model Limitations):
Power supply voltage changing is not supported.
Там есть и другие ограничения, касающиеся питания, в частности BOR. Я уже неоднократно и объяснял, как такое обойти - есть вывод RESET (у PIC - MCLR) - вот на него "тумблер" на землю - им и гасите, эффект практически тот же.

Можно ли верить Proteus'у ?

Добавлено: Пт апр 03, 2015 19:26:38
Ellissar
Начал изучать микроконтроллеры и решил освоить прерывания, хочу сделать задержку без delay_ms().
У меня появился вопрос насколько точно работает осциллограф в протеусе? Можно ли доверять ему?
Хочу сделать таймер на прерывании как можно точнее.
Приведу два примера: один с использованием delay_ms() второй с использованием прерывания.

С использование delay_ms()
Изображение

Код: Выделить всё

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
	DDRC |= (1<<5);
	PORTC |= (1<<5);
	
    while(1)
    {
		_delay_ms(20);
        PORTC ^= (1<<5);
		
    }
}
С использованием прерывания
Изображение

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>

unsigned long long millis = 0; //От 0 до 18 446 744 073 709 551 615
unsigned long long prevMillis = 0;

ISR (TIMER2_COMP_vect)
{
	millis++; //миллисекунды
}


void timer2_init (void)
{
	//*** Настройки для 8MHz ***//
	TCCR2 |= (1<<1) | (1<<0); //установка предделителя = 64
	TIMSK |= (1<<7); //разрешает прерывания по событию совпадение
	TCCR2 |= (1<<3); //сброс при совпадении TCNT2 с OCR2
	OCR2 = 249; //подгонялось вручную для 8MHz
	TCNT2 = 0b00000000; //т.к. счетчик уже считает, то сброс счетчика после настройки.
}

void port_init (void)
{
	DDRC |= (1<<5);
	PORTC |= (1<<5);
}


int main(void)
{
	timer2_init(); //настройка таймера2 для подсчета миллисекунд
	port_init(); //настройка портов
	
	sei(); //разрешение прерываний
	
    while(1)
    {
		if (millis - prevMillis > 20)
		{
			prevMillis = millis;
			PORTC ^= (1<<5); //инверсия одного бита
		}
    }
}

Re: Можно ли верить Proteus'у ?

Добавлено: Пт апр 03, 2015 20:47:30
Аlex

Код: Выделить всё

   millis++; //миллисекунды

..............
..............

      if (millis - prevMillis > 20)
Плохой подход.
1. Никогда не забывайте об атомарном доступе к многобайтным переменным.
2. Представьте, что произойдёт, когда переменная millis переполнится.
Можно ли доверять ему?
Можно. По крайней мере, до десятых (а может и сотых) микросекунд точно будет мерить.

ЗЫ: В протеусе, для таких случаев, есть инструмент - COUNTER TIMER. Им можно мерить длину импульса с разрешением в 1 us.
ЗЫЗЫ: А вообще, по протеусу, так то, уже существует тема. Давайте туда "переедем" ?

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 04:46:50
Ellissar
ЗЫЗЫ: А вообще, по протеусу, так то, уже существует тема. Давайте туда "переедем" ?
Понял, буду задавать вопросы в той теме.
Плохой подход.
1. Никогда не забывайте об атомарном доступе к многобайтным переменным.
2. Представьте, что произойдёт, когда переменная millis переполнится.
Может быть я не правильно рассчитал переполнение переменной? Но вроде бы она очень не скоро должна переполниться, разве нет? unsigned long long millis переполнится через 5849,42 лет верно?

Каким образом тогда можно выполнить задержку без _delay_ms() и ей подобных ф-й?

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 08:32:30
Аlex
Но вроде бы она очень не скоро должна переполниться, разве нет?
Если она 8 байт, то действительно что-то очень долго получается. Контроллер успеет сгнить 1000 раз :))
Тогда всё нормально. Только об атомарном доступе позаботьтесь и всё.

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 09:58:43
Ellissar
Тогда всё нормально. Только об атомарном доступе позаботьтесь и всё.
Можно запретить прерывания. Я правильно понимаю?

Код: Выделить всё

    while(1)
    {
		cli()
		if ((millis - prevMillis) > 20)
		{
			prevMillis = millis;
			PORTC ^= (1<<5); //инверсия одного бита
			
		}
		sei()
    }
Почитал сейчас про атомарный доступ код для компилятора IAR.

Код: Выделить всё

__monitor unsigned long get_system_timer(void)
{
    return system_timer;
}
Хотелось бы сделать такую же функцию в Atmel Studio. Как это можно сделать?

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 10:03:20
Аlex
Можно запретить прерывания. Я правильно понимаю?
Правильно.
Только прерывания достаточно запрещать на время работы с переменной, используемой в прерывании. На весь кусок запрещать нет смысла.
Хотелось бы сделать такую же функцию в Atmel Studio. Как это можно сделать?
Просто создайте функцию, запрещающую прерывание на время чтения переменной и возвращающую это значение.

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 10:39:32
Ellissar
Аlex писал(а):Просто создайте функцию, запрещающую прерывание на время чтения переменной и возвращающую это значение.
Так можно сделать?

Код: Выделить всё

unsigned long long get_millis(void)
{
	cli();
	return millis;
	sei();
}

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 10:42:13
Аlex
Неужели попробовать будет дольше, чем ждать ответа на форуме ? :)

ЗЫ: После return, дальше, программа не выполняется. Вот и думайте, можно так или нет :)

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 10:52:36
Ellissar
Аlex писал(а):Неужели попробовать будет дольше, чем ждать ответа на форуме ? :)
ЗЫ: После return, дальше, программа не выполняется. Вот и думайте, можно так или нет :)
Попробовать конечно не сложно, только у меня из-за return и появился вопрос. Тогда может быть так?

Код: Выделить всё

unsigned long long get_millis(void)
{
	cli();
	unsigned long long tmp = millis;
	sei();
	return tmp
}
Вопросы у меня появляются потому, что я не знаю как узнать при отладке когда прерывания разрешены/запрещены :(

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 10:54:08
Аlex
Но при отладке видно же докуда (не)доходит программа.

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 11:02:46
Ellissar
Аlex писал(а):Но при отладке видно же докуда (не)доходит программа.
Действительно)

Мой последний кусок кода будет правильным?

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 11:15:37
Ellissar
Я наверное задаю вопросы быстрее чем думаю :))
Нашел в Atmel studio окошко Processor там есть Status register и 7-й бит Global interrupt enable :)

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 11:17:48
ARV
Ellissar писал(а):Хотелось бы сделать такую же функцию в Atmel Studio. Как это можно сделать?
изучить документацию на WinAVR и использовать макрос ATOMIC_BLOCK:

Код: Выделить всё

#include <ulil/atomic.h>

ATOMIC_BLOCK(ATOMIC_RESTORE_STATE){
   // тут пишется код, который будет выполнен атомарно
}

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 11:56:25
Ellissar
ATOMIC_BLOCK интересная штука, но в неё тоже нельзя включить return millis;. Поэтому решил использовать cli() и sei().

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 12:20:10
ARV
в нее можно включать return что угодно!!!

а вот ваш вариант с cli-sti может дать побочный эффект, потому как уже вам нужно будет контролировать, были ли разрешены прерывания перед обращением к вашей функции или нет, потому как ваша функция всегда БУДЕТ разрешать прерывания, или наоборот, БУДЕТ их запрещать.

ATOMIC_BLOCK в показанном мной варианте использования всегда восстановит то состояние прерываний, которое было до обращения к нему. вдумайтесь :)))

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 12:36:57
Ellissar
ARV писал(а):в нее можно включать return что угодно!!!
пробую так:

Код: Выделить всё

unsigned long long get_millis(void)
{
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
		return millis;
	};
}
только при выходе из функции прерывания должны быть разрешенными(разрешаю прерывания в ф-и main), а они запрещены. Я что-то делаю не так?
Работает нормально только в таком виде

Код: Выделить всё

unsigned long long get_millis(void)
{
	unsigned long long tmp;
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
		tmp = millis;
	};
	return tmp;
}

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 12:39:59
Аlex
ATOMIC_BLOCK в показанном мной варианте использования всегда восстановит то состояние прерываний, которое было до обращения к нему. вдумайтесь
Не, ну всегда же можно прочитать состояние, а потом восстановить.
"Горшки тоже не боги обжигают" (с) :)

Re: Можно ли верить Proteus'у ?

Добавлено: Сб апр 04, 2015 12:44:48
Аlex
Я что-то делаю не так?
Аlex писал(а): После return, дальше, программа не выполняется !
А макрос тоже "человек", ему тоже хочется закончиться до конца :)

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