Змінюй хід війни! Допомагай ЗСУ!

Электрофлуд :)

  • Автор теми Автор теми RUH
  • Дата створення Дата створення
Що таке радіоелектроніка?
 
⚠ Тільки зареєстровані користувачі бачать весь контент та не бачать рекламу.


интернет не умеет в систематичность, подсказать конкретно по мелкому вопросу это максимум, всё что сложней заходит в дикий блудняк.
 
Ну і правильно. Треба ділом займатись, а не ***нею.
 
чуток увлекся радиоэлектроникой. Подскажите в харькове может курсы какие где есть ?)
Вооружайся книгой комрадов Хоровца и Хилла и вперед. Дальше в зависимости от направления можно еще путевой литературы почитать, ну и вопросов по задавать, главное помнить о том, что правильно поставленный вопрос - уже половина ответа[emoji1]
 
Подскажите, что это за деталь?
 

Вкладення

  • 1.webp
    1.webp
    101.7 КБ · Перегляди: 111
Спасибо. То что в красной рамочке собственно и почернело, я так понимаю что восстановлению не подлежит.
 
Чото мозги у меня уже закипают. Такая с первого взгляда чудесная студия порет полній бред. 100% робочий код не пашет. Написал в кодвижене, перекинул туда заменив типы данных и прочую мелочь. Это **** какая-то.
 
Останнє редагування:
Чото мозги у меня уже закипают. Такая с первого взгляда чудесная студия порет полній бред. 100% робочий код не пашет. Написал в кодвижене, перекинул туда заменив типы данных и прочую мелочь. Это **** какая-то.

Код в студию! :)
 
Все в скинуто в кучу дабы избежать возможных проблем с переназначением переменных и прочей чепухи.
Оно работает в cvavr, но перенесенное в студию з лишь заменой типов данных int -> int16_t и добавлением библиотек с интами и булами, а так же с макросами ISR - болт. И в этом самое противное. Было б что-то серьезное - ладно, а так дрочь какая-то.

Код:
#include <avr/interrupt.h>
#include <stdbool.h>
#include <inttypes.h>

#define oSOLENOID_OFF		PORTD |= 0x04 // PD2 high
#define oSOLENOID_ON		PORTD &= ~0x04 // PD2 low

#define TIMER_ENABLE    WDTCSR = (1<<WDIF); WDTCSR = (1<<WDIE)
#define TIMER_DISABLE   WDTCSR &= ~(1<<WDIE)

#define PLUS    1
#define MINUS   0

#define HOURS               14
#define MINUTES             25

#define COR_STANDART      	40
#define COR_FIRST         	10
#define COR_DIRRECTION      PLUS

#define TICK_TIMER    		197

#define PRESET              1


uint16_t uiPulseTicks = 0;
int8_t cCorrectionFlag = -1;
uint8_t ucTimer = 25;
uint8_t ucSeconds = 55;
uint8_t ucTmpCounter;
bool bMinuteFlag = false;

uint8_t ucMinutes = MINUTES;
uint8_t ucHours = HOURS;

uint8_t ucCorDir = COR_DIRRECTION;
uint8_t ucCorSeconds = COR_STANDART;
uint8_t ucFCorSeconds = COR_FIRST;

uint16_t uiTickTimer = TICK_TIMER;

uint16_t table[] = {  14, 1, 250,
	14, 2, 250,
	14, 3, 250,
	14, 4, 250,
	14, 5, 255,
	14, 6, 250,
	14, 7, 250,
	14, 8, 250,
	14, 9, 250,
	14, 10, 250,
	14, 11, 250,
	14, 12, 250,
	14, 13, 250,
	14, 14, 250,
	14, 15, 255,
	14, 16, 250,
	14, 17, 250,
	14, 18, 250,
	14, 19, 250,
	14, 20, 250,
	14, 21, 250,
	14, 22, 250,
	14, 23, 250,
	14, 24, 250
};



int main(void)
{
	unsigned int i;
	

	PIND  |= (1<<PD2);			// PD2 out
	PORTD |= (1<<PD1);;		    // pull up for PD1
	
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);

	oSOLENOID_OFF;

	// TIMER0
	TCCR0A = 0x00;
	TCCR0B = 0x03;    //prescaller clk/1024
	TCNT0  = 0xB1;    //5ms interrupt on ovf
	TIMSK0 = 0x01;    //OVF Interrupt Enabled

	PCICR  = 0x04;   // PCINT 2 channel( e_ints 16-23) ON.
	// Our IN 31st pin PD1 is PCINT17.
	
	WDTCSR |= (1<<WDCE) | (1<<WDE);      // setting WDT to interrupt every 8sec
	WDTCSR = (1<<WDP3) | (1<<WDP0);
	sei();

	while(1)
    {
        if(bMinuteFlag)
        {
            bMinuteFlag = false; 
            

            for(ucTmpCounter=0; ucTmpCounter<sizeof(table)/6; ucTmpCounter++)
            {
              if(table[ucTmpCounter*3] == ucHours) 
              {
                if(table[ucTmpCounter*3 + 1] == ucMinutes) 
                {
                  oSOLENOID_ON;
                  uiPulseTicks += table[ucTmpCounter*3 + 2] *2;
                  PCIFR |= (1<<PCIF2);                          // clear PCINT2 flag
                  PCMSK2 |= (1<<PCINT17);                       // turn on PCINT17  
                  break;
                }
              }
            }
            

            if(ucHours == 14)
            {
              if(ucMinutes == 3)
              {
                if(cCorrectionFlag)
                {
                  if(cCorrectionFlag > 0) 
                  {                                           
                    if(ucCorDir) ucSeconds = ucCorSeconds;              
                    else                                       
                    {
                      ucSeconds = 60 - ucCorSeconds;
                      ucMinutes--;
                    } 
                  }  
                  else 
                  {                                         
                    if(ucCorDir) ucSeconds = ucFCorSeconds;  
                    else                                   
                    {                                        
                      ucSeconds = 60 - ucFCorSeconds;
                      ucMinutes--;
                    }
                  } 
                  cCorrectionFlag = 0; 
                  TIMER_ENABLE;
                }
              }
            }  
        }		
    }
}



ISR(PCINT2_vect)
{
	if(uiPulseTicks > 0) uiPulseTicks--;
	else
	{
		oSOLENOID_OFF;
		PCMSK2 &= ~(1<<PCINT17);        // turn off PCINT17
	}
}

ISR(TIMER0_OVF_vect)
{
	TCNT0  = 0xB1;    //5ms interrupt on ovf

	if(uiTickTimer > 0) uiTickTimer--;
	else
	{
		uiTickTimer = TICK_TIMER;
		ucSeconds++;
		if(ucSeconds > 59)
		{
			ucSeconds = 0;
			ucMinutes++;
			bMinuteFlag = true;
			if(ucMinutes > 59)
			{
				ucMinutes = 0;
				ucHours++;
				if(ucHours > 23) ucHours = 0;
			}
		}
	}
}

ISR(WDT_vect)                // wdt interrupt routline, happens every 8 sec.
{
	ucTimer--;
	if(!ucTimer)
	{
		TIMER_DISABLE;
		ucTimer = 25;
		cCorrectionFlag = 1;
	}
}
 
Останнє редагування:
Все в скинуто в кучу дабы избежать возможных проблем с переназначением переменных и прочей чепухи.
Оно работает в cvavr, но перенесенное в студию з лишь заменой типов данных int -> int16_t и добавлением библиотек с интами и булами, а так же с макросами ISR - болт. И в этом самое противное. Было б что-то серьезное - ладно, а так дрочь какая-то.

Код:
#include <avr/interrupt.h>
#include <stdbool.h>
#include <inttypes.h>

#define oSOLENOID_OFF		PORTD |= 0x04 // PD2 high
#define oSOLENOID_ON		PORTD &= ~0x04 // PD2 low

#define TIMER_ENABLE    WDTCSR = (1<<WDIF); WDTCSR = (1<<WDIE)
#define TIMER_DISABLE   WDTCSR &= ~(1<<WDIE)

#define PLUS    1
#define MINUS   0

#define HOURS               14
#define MINUTES             25

#define COR_STANDART      	40
#define COR_FIRST         	10
#define COR_DIRRECTION      PLUS

#define TICK_TIMER    		197

#define PRESET              1


uint16_t uiPulseTicks = 0;
int8_t cCorrectionFlag = -1;
uint8_t ucTimer = 25;
uint8_t ucSeconds = 55;
uint8_t ucTmpCounter;
bool bMinuteFlag = false;

uint8_t ucMinutes = MINUTES;
uint8_t ucHours = HOURS;

uint8_t ucCorDir = COR_DIRRECTION;
uint8_t ucCorSeconds = COR_STANDART;
uint8_t ucFCorSeconds = COR_FIRST;

uint16_t uiTickTimer = TICK_TIMER;

uint16_t table[] = {  14, 1, 250,
	14, 2, 250,
	14, 3, 250,
	14, 4, 250,
	14, 5, 255,
	14, 6, 250,
	14, 7, 250,
	14, 8, 250,
	14, 9, 250,
	14, 10, 250,
	14, 11, 250,
	14, 12, 250,
	14, 13, 250,
	14, 14, 250,
	14, 15, 255,
	14, 16, 250,
	14, 17, 250,
	14, 18, 250,
	14, 19, 250,
	14, 20, 250,
	14, 21, 250,
	14, 22, 250,
	14, 23, 250,
	14, 24, 250
};



int main(void)
{
	unsigned int i;
	

	PIND  |= (1<<PD2);			// PD2 out
	PORTD |= (1<<PD1);;		    // pull up for PD1
	
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);
	oSOLENOID_OFF;
	for(i=0xffff; i>0; i--);
	oSOLENOID_ON;
	for(i=0xffff; i>0; i--);

	oSOLENOID_OFF;

	// TIMER0
	TCCR0A = 0x00;
	TCCR0B = 0x03;    //prescaller clk/1024
	TCNT0  = 0xB1;    //5ms interrupt on ovf
	TIMSK0 = 0x01;    //OVF Interrupt Enabled

	PCICR  = 0x04;   // PCINT 2 channel( e_ints 16-23) ON.
	// Our IN 31st pin PD1 is PCINT17.
	
	WDTCSR |= (1<<WDCE) | (1<<WDE);      // setting WDT to interrupt every 8sec
	WDTCSR = (1<<WDP3) | (1<<WDP0);
	sei();

	while(1)
    {
        if(bMinuteFlag)
        {
            bMinuteFlag = false; 
            

            for(ucTmpCounter=0; ucTmpCounter<sizeof(table)/6; ucTmpCounter++)
            {
              if(table[ucTmpCounter*3] == ucHours) 
              {
                if(table[ucTmpCounter*3 + 1] == ucMinutes) 
                {
                  oSOLENOID_ON;
                  uiPulseTicks += table[ucTmpCounter*3 + 2] *2;
                  PCIFR |= (1<<PCIF2);                          // clear PCINT2 flag
                  PCMSK2 |= (1<<PCINT17);                       // turn on PCINT17  
                  break;
                }
              }
            }
            

            if(ucHours == 14)
            {
              if(ucMinutes == 3)
              {
                if(cCorrectionFlag)
                {
                  if(cCorrectionFlag > 0) 
                  {                                           
                    if(ucCorDir) ucSeconds = ucCorSeconds;              
                    else                                       
                    {
                      ucSeconds = 60 - ucCorSeconds;
                      ucMinutes--;
                    } 
                  }  
                  else 
                  {                                         
                    if(ucCorDir) ucSeconds = ucFCorSeconds;  
                    else                                   
                    {                                        
                      ucSeconds = 60 - ucFCorSeconds;
                      ucMinutes--;
                    }
                  } 
                  cCorrectionFlag = 0; 
                  TIMER_ENABLE;
                }
              }
            }  
        }		
    }
}



ISR(PCINT2_vect)
{
	if(uiPulseTicks > 0) uiPulseTicks--;
	else
	{
		oSOLENOID_OFF;
		PCMSK2 &= ~(1<<PCINT17);        // turn off PCINT17
	}
}

ISR(TIMER0_OVF_vect)
{
	TCNT0  = 0xB1;    //5ms interrupt on ovf

	if(uiTickTimer > 0) uiTickTimer--;
	else
	{
		uiTickTimer = TICK_TIMER;
		ucSeconds++;
		if(ucSeconds > 59)
		{
			ucSeconds = 0;
			ucMinutes++;
			bMinuteFlag = true;
			if(ucMinutes > 59)
			{
				ucMinutes = 0;
				ucHours++;
				if(ucHours > 23) ucHours = 0;
			}
		}
	}
}

ISR(WDT_vect)                // wdt interrupt routline, happens every 8 sec.
{
	ucTimer--;
	if(!ucTimer)
	{
		TIMER_DISABLE;
		ucTimer = 25;
		cCorrectionFlag = 1;
	}
}

Так а что именно не работает? Как это проявляется?
 
Не работает. Глубоко не копал. В прерывания вваливается. В них провереная логика, но результата нет.
 
Останнє редагування:
Не работает. Глубоко не копал. В прерывания вваливается. В них провереная логика, но результата нет.

Я уже и не помню точно, так как с АВР-ми и их студией не работал долго, -
но по-моему, изначально, нужно определить работу порта либо на вход, либо на выход, и для этого использовался макрос DDRx, где х - было имя порта. А уже PORTx или PINx, в зависимости от использования, либо переключали, либо "слушали" состояние самого порта.
 
Я у тебя этого здесь не увидел. Возможно студия, по-умолчанию, конфигурирует все порты как вход, а кодевижн, по умолчанию - как выход.
 
Теоретически возможно, асм листинг не смотрел. Но практически никогда такого не видел. Пишешь в регистры порта - замечательно, нет - нет, по умолчанию останется высокоомным входом.
Попробую, мало ли чо они там намутили.

Кстати как-то отталкивает студия. Вроде скооперировались с мс, на движке визуал студии построили свой продукт, автоподстановку реализовали на уровне студии, но элементарной визуализации структуры кода нет.
 
Останнє редагування:
Теоретически возможно, асм листинг не смотрел. Но практически никогда такого не видел. Пишешь в регистры порта - замечательно, нет - так нет, по умолчанию останется высокоомным входом.

Помоему, у АВР фишка в следующем - если твой порт был сконфигурирован на вход , к примеру как, DDRD = 0x0;
а потом ты хочешь, к примеру, установить 0 пин в 1 думая, что порт настроен как выход, - PORTD |= (1 << 0);
то этим самым ты включиш, банально, на нулевом пине подтягивающий резистор, потому как для прослушивания порта существует иной макрос - PIND
По-моему так, если память не подводит..
 
Логично. Но у меня всего один выход, запутаться с которым сложно. В начале ставится входом и все.

А для чтения реального физического значения порта таки PIN используется.

Самое обидное когда заместь работы занимаешься вот таким вздрочем. И cvavr уважаю сильно как раз за отсутствие вздрочей. Понятные библиотеки, некоторые плюшки типо встроеных макросов, например возвожность писать PORTA.[index] = 1; и быть понятым.
 
Останнє редагування:
И cvavr уважаю сильно как раз за отсутствие вздрочей. Понятные библиотеки, некоторые плюшки типо встроеных макросов, например возвожность писать PORTA.[index] = 1; и быть понятым.

А я вот наоборот, считаю, что их библиотеки не очень то и классные, потому как они и есть именно библиотеки, а не open source модули. Мне пришлось перепедаливать, в свое время, некоторые именно за то, что в них что-то не устраивало.
Ну, а макросы, типа PORTD.1 = 1; дело пяти минут. Один раз для себя написать, если так удобно, а потом портировать беспроблемно куда угодно.
Сколько людей, столько и мнений. :)
 
Я уже и не помню точно, так как с АВР-ми и их студией не работал долго, -
но по-моему, изначально, нужно определить работу порта либо на вход, либо на выход, и для этого использовался макрос DDRx, где х - было имя порта. А уже PORTx или PINx, в зависимости от использования, либо переключали, либо "слушали" состояние самого порта.
Проспался и нашел таки то, про что ты говорил. Да, порт изначально не настроил перепутав ДДР с ПИН. То есть выход был входом, но будучи поцепленым на мосфет с затвором притянутым через резистор к земле и так нормально работало - 50к внутренней подтяжки вверх как-то открывали его, а 100к вниз закрывали назад при переходе пина в высокоомное состояние.
Но сути то неработы не меняет :(
 
А виснет в прерывании или в основном цикле? Попробуй поклацать релюхой через задержку, закомментив прерывания. Может в имени обработчика прерывания ошибка есть, и он виснет улетев куда-то в никуда?
 
Назад
Зверху Знизу