Перейти к содержанию

Kostyanskiy

Members
  • Постов

    76
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Kostyanskiy

  1. Здравствуйте, решил в своем проекте подключить кнопку, но МК странно себя ведет, создал отдельный проект, подумал, что что-то в моем основном коде не так, но нет, этот код не работает и в отрыве от основного, что странно. Вот:

    #include <avr/io.h>
    
    int main(void)
    {
    	DDRD |= (1<<0); //Выход
    	DDRD &=~ (1<<3); //Вход
       
        
    	while (1)
        {
    	    if(PIND & 0b00001000) PORTD |= (1<<0);
    	     else PORTD &=~ (1<<0);
        }
    }

    Проблема в том, что когда у меня лог. 1 на 3 порте, то светодиод гаснет, а по логике как бы должно быть (0b00001000 & 0b00001000) - подать лог. 1 на пин 0,

    (0b00000000 & 0b00001000) - подать лог. 0 на пин 0

     

  2. @IMXO помогите с кодом пожалуйста, а то у меня немного руки кривые :unsure:

    volatile uint32_t timer = 0;
    volatile unsigned int T = 0;
    volatile unsigned int SumNew = 0;
    volatile unsigned int SumLast = 0;
    volatile unsigned int RPM = 0;
    
    
    ISR(TIMER1_COMPA_vect)
    {
    	timer+=(1<<16);
    }
    
    ISR(INT0_vect)
    {
    	SumNew = (TCNT1 + timer);
    	T = SumNew - SumLast;
    	SumLast = SumNew;
    }
    
    
    
    int main(void)
    {
    	ST7789_Init(3);
    	LCD_Fill(BLACK);
    	GICR|=(1<<INT0); //разрешаем прерывание по INT0
    	MCUCR |= (0<<ISC00)|(0<<ISC01); //прерывание по фронту сигнала на INT0
    	TCCR1B = (1<<CS12)|(1<<WGM12); // /256, 8*10^6 / 256 = 31250 KHz // 1/31250 = 0,000032 sec
    	TIMSK = (1<<OCIE1A);
    	OCR1A = 65535; // на переполнении 
    	sei();
      
      while(1)
    	{  
    	   RPM = 60/T;
    	   TFTDrawValue(0, 16, WHITE, BLACK, RPM);
    	  
    	}
    	
    }

     

  3. 21.07.2021 в 13:26, COKPOWEHEU сказал:

    Не страшно что индусы! Берете их поделие и строчка за строчкой приводите к человеческому виду. Потом рефакторинг чтобы выкинуть ту часть библиотеки, которая посвящена восхвалению Кришны (по желанию можно заменить на восхваление Ктулху или Омниссии), рисованию логотипа производителя или другие не относящиеся к делу куски.

    Да, лучше всего делать это прямо на Ардуине, чтобы и исходный код запускался, и ваша интерпретация. Ну а когда доведете работу до конца (то есть разделите платформо-зависимую часть от логики), уже можно переносить и на другие контроллеры если надо.

    Хаха, спасибо за совет, уже получилось, вот результат

    void ST7789_Init()
    {
    		SPI_Init();		
    		
    		RESET_HIGH;
    		_delay_ms(200);
    		RESET_LOW;
    		_delay_ms(200);
    		RESET_HIGH;
    		
    		ST7789_SendCommand(0x01);//Software Reset
    		_delay_ms(1000);
            ST7789_SendCommand(0x11);
            ST7789_SendCommand(0x3A);
    		ST7789_SendData(0x05);
    		ST7789_SendCommand(0x36);
            ST7789_SendData(0x20);
            ST7789_SendData(0x10);
    		ST7789_SendData(0x04);
    		ST7789_SendData(0x08);
    		ST7789_SendCommand(0x21);
    		ST7789_SendCommand(0x29);
    		ST7789_SendCommand(0x2C);
    		
       LCD_Fill(BLACK);
    }

    Проблема была  еще и в контактах, а когда припаял провода - все заработало

  4.  

    21.07.2021 в 14:53, Alex сказал:

    Покажите этот индусский код, который Вам непонятен. И скажите, что конкретно в нём не понятно.

    static const uint8_t PROGMEM
      cmd_240x240[] = {                 		// Initialization commands for 7789 screens
        10,                       				// 9 commands in list:
        ST7789_SWRESET,   ST_CMD_DELAY,  		// 1: Software reset, no args, w/delay
          150,                     				// 150 ms delay
        ST7789_SLPOUT ,   ST_CMD_DELAY,  		// 2: Out of sleep mode, no args, w/delay
          255,                    				// 255 = 500 ms delay
        ST7789_COLMOD , 1+ST_CMD_DELAY,  		// 3: Set color mode, 1 arg + delay:
          0x55,                   				// 16-bit color
          10,                     				// 10 ms delay
        ST7789_MADCTL , 1,  					// 4: Memory access ctrl (directions), 1 arg:
          0x00,                   				// Row addr/col addr, bottom to top refresh
        ST7789_CASET  , 4,  					// 5: Column addr set, 4 args, no delay:
          0x00, ST7789_240x240_XSTART,          // XSTART = 0
    	  (ST7789_TFTWIDTH+ST7789_240x240_XSTART) >> 8,
    	  (ST7789_TFTWIDTH+ST7789_240x240_XSTART) & 0xFF,   // XEND = 240
        ST7789_RASET  , 4,  					// 6: Row addr set, 4 args, no delay:
          0x00, ST7789_240x240_YSTART,          // YSTART = 0
          (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) >> 8,
    	  (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) & 0xFF,	// YEND = 240
        ST7789_INVON ,   ST_CMD_DELAY,  		// 7: Inversion ON
          10,
        ST7789_NORON  ,   ST_CMD_DELAY,  		// 8: Normal display on, no args, w/delay
          10,                     				// 10 ms delay
        ST7789_DISPON ,   ST_CMD_DELAY,  		// 9: Main screen turn on, no args, w/delay
        255 };                  				// 255 = 500 ms delay

    Вот это можете мне пояснить, может я чего то не понимаю, ну, я и поэтому пришел сюда.

    21.07.2021 в 13:26, COKPOWEHEU сказал:

    Не страшно что индусы! Берете их поделие и строчка за строчкой приводите к человеческому виду. Потом рефакторинг чтобы выкинуть ту часть библиотеки, которая посвящена восхвалению Кришны (по желанию можно заменить на восхваление Ктулху или Омниссии), рисованию логотипа производителя или другие не относящиеся к делу куски.

    Да, лучше всего делать это прямо на Ардуине, чтобы и исходный код запускался, и ваша интерпретация. Ну а когда доведете работу до конца (то есть разделите платформо-зависимую часть от логики), уже можно переносить и на другие контроллеры если надо.

    Хаха, спасибо за совет, этим уже занимаюсь 

  5. 14 минут назад, hasl сказал:

    Возьмите либу от ардуино на данное железо и посмотрите, что делаете не так

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

  6. Здравствуйте, пишу либу для ST7789 проблемы с инициализацией, помогите пожалуйста.

    Вот код

    #define F_CPU 8000000UL
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include <stdio.h>
    #include <stdlib.h>
    //==========================================================================================
    #define RGB565(r, g, b)         (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
    #define RGB16(color) (unsigned int)(((color&0xF80000)>>8)|((color&0x00FC00)>>5)|((color&0x0000F8)>>3))
    //==========================================================================================
    #define DDR_DC	    DDRB	// Порт на котором будет DC
    #define DDR_RES		DDRB	// Порт на котором будет RES
    //==========================================================================================
    #define PORT_DC     PORTB	// Порт на котором будет DC
    #define PORT_RES	PORTB	// Порт на котором будет RES
    //==========================================================================================
    #define LCD_DC 1    //Command/Data
    #define LCD_RESET 2 //LCD Reset
    #define LCD_MISO 4
    #define LCD_MOSI 3
    #define LCD_SCK 5
    //==========================================================================================
    #define DC_HIGH        PORT_DC |=  (1<<DC);
    #define DC_LOW         PORT_DC &=~ (1<<DC);
    #define RESET_HIGH     PORT_RES |=  (1<<RES);
    #define RESET_LOW      PORT_RES &=~ (1<<RES);
    //==========================================================================================
    void SPI_Init()
    {
    	DDRB |=  (1<<LCD_SCK)|(1<<LCD_MISO)|(1<<LCD_MOSI);
    	DDR_DC |= (1<<LCD_DC);
    	DDR_RES |= (1<<LCD_RESET);
    	PORT_DC &=~(1<<LCD_DC);
    	
    	SPCR |= (1<<SPE)|(1<<MSTR);// 8MHz/2
    	SPSR |= (1<<SPI2X);
    }
    //==========================================================================================
    void ST7789_SendData(char Data)
    {
    	DC_HIGH;
    	SPDR = Data;
    	while (! (SPSR & ( 1 << SPIF)));
    	
    }
    //==========================================================================================
    void ST7789_SendCommand(char Data)
    {
    	DC_LOW;
    	SPDR = Data;
    	while (! (SPSR & ( 1 << SPIF)));
    	
    }
    //==========================================================================================
    void ST7789_Init()
    {
    		// Инициализация SPI
    		SPI_Init();
    		_delay_ms(100);
    		RESET_HIGH;
    		_delay_ms(100);
    		RESET_LOW;
    		_delay_ms(100);
    		ST7789_SendCommand(0x01);
    		_delay_ms(100);
    		
    		ST7789_SendCommand(0x3A);
    		ST7789_SendData(0x50);
    		ST7789_SendData(0x05);
    		_delay_ms(10);
    		ST7789_SendCommand(0x11);  
    		_delay_ms(10);
    		ST7789_SendCommand(0x36);
    		ST7789_SendData(0x20);
    		ST7789_SendData(0x08);
    		ST7789_SendData(0x10);
    		ST7789_SendData(0x04);
    	    _delay_ms(10);
    		ST7789_SendCommand(0x21);
    		ST7789_SendCommand(0x29);
    		_delay_ms(10);
    }

     

  7. 9 часов назад, Yurkin2015 сказал:

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

    Наконец-то дошло как это работает, но зачем тогда первые 16 бит инкрементировать, почему не просто timer++?

    11 часов назад, Kostyanskiy сказал:
    11 часов назад, IMXO сказал:

    T = SumNew - SumLast

     

    И если посмотреть с другой стороны, то это не совсем период, это разность времени между 2 оборотами, зачем нам эта разность если это не период ?

  8. 20 минут назад, Yurkin2015 сказал:

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

    А что нам мешает каждый раз в прерывании от ножки сбрасывать счетчик в 0?

  9. 19 минут назад, IMXO сказал:

    10*2^16

    небольшое уточнение, почему 2 в степени 16 и умноженное на 10?

    32 минуты назад, IMXO сказал:

    T = SumNew - SumLast

    Я понял почему здесь так, из-за нелинейности движения измер. колеса разное время движения точки измерения, но почему мы тогда просто не ограничемся счетчиком TCNT1 зачем нам еще и переполнение по прерыванию таймера и как оно играет на конечный результат?

     

     

     

  10. 3 минуты назад, Yurkin2015 сказал:

    плавающей запятой заменяем на быстрое и лёгкое целочисленное деление, всего одна операция

    Я понял, но при чем здесь

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

    16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит

    И какая зависимость скорости колеса измерения, предделителя таймера и переменной которая инкрементируется в прерывании по переполнению таймера?

  11. тогда volatile uint32_t timer = 0;

    ISR(TIMER1_COMPA_vect)
    {
        (timer << 16)++;
    }

    Или как?

    59 минут назад, IMXO сказал:

    обычно запускается 16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит
    в прерывании от ногадрыга читается таймер и складывается с тайм , полученная сумма вычитается из предыдущего значения суммы и получается значение периода в тактах таймера.

    Можете пожалуйста поподробней рассказать почему так? Или дайте источники где про это можно почитать

  12. ISR(TIMER1_COMPA_vect)
    {
    	timer++;
    }
    //=============================================================================================================
    ISR(INT0_vect)
    {
       SumNew = (TCNT1 + timer) - SumLast;
       T = SumNew;
       SumLast = SumNew; 
       TCNT1 = 0;
       
    }
    int main(void)
    {  
      //инициализация переферии 
    	
    	while (1) 
        {
        
    	RPM = 60/T;
        }
    }

    То есть, вот так?

  13. Здравствуйте уважаемые, стоит задача: сделать бесконтактный тахометр на Atmega8,  вывод данных на дисплей.

    Идея какая: мерить время каждого оборота - Т, с помощью прерывания на ножке PD3 и запускать таймер на отчет времени, и когда прерывание срабатывает повторно останавливать таймер и записать в переменную timer значение TCNT1 и отключить таймер до следующего прерывания. Чтоб узнать период одного оборота измерительного колеса, нужно знать время одного тика таймера, что составляет 1 / (частота МК / предделитель) и значение регистра TCNT1 за один оборот измерительного колеса которое записано в переменную timer. Произведение данных величин можно записать так: T = (timer * tодного тика). Чтобы узнать частоту измерительного колеса в секунду, нужно 1/T. Частота - это произведение количества оборотов на время. Чтобы преобразовать в об/мин, нужно подставить 60. Результат: f = RPM/60,   f = 1/T,  RPM/60 = 1/T.  в итоге: RPM = 60/T

    Конечная формула: RPM = 60/(timer * tодного тика)

    Проблема с кодом, уважаемые, скажите, что здесь не так:

    char buff [0];
    volatile unsigned int change = 0;
    volatile unsigned int timer = 0;
    float T = 0;
    unsigned int RPM = 0; 
    unsigned int Frec = 0;
    
    
    ISR(INT0_vect)
    {
    
    	if(change == 0)
    	{
    		TCNT1 = 0;
    		asm("nop");
    		TIMSK = (1<<OCIE1A);
    		timer = 0;
    	    
    	} 
    	if(change == 1)
    	{
    	   timer = TCNT1; 	
    	   asm("nop");
    	   TIMSK = (0<<OCIE1A);
    	}
      
    
    
       if(change == 0) change = 1;
         else change = 0;
    
    }
    
    
    int main(void)
    {
       //записываем это значение в верхнюю часть регистра  (8 бит из 11)
       UBRRH = (unsigned char) (51 >> 8);
       
       // записываем оставшуюся часть регистра
       UBRRL = (unsigned char) 51;
       
       // задействуем передатчик и приемник
       UCSRB = (1 << RXEN) | (1 << TXEN);
       
       //устанавливаем 2 стоповых бита и 8-битную длину передаваемого символа
       UCSRC = (1 << USBS) | (3 << UCSZ0);
       
       
       GICR|=(1<<INT0); //разрешаем прерывание по INT0
       MCUCR |= (0<<ISC00)|(0<<ISC01); //прерывание по фронту сигнала на INT0
       TCCR1B = (1<<CS12)|(1<<WGM12); // /256, 8*10^6 / 256 = 31250 KHz // 1/31250 = 0,000032 sec
       OCR1A = 32768;
       sei();
       
    	
    	while (1) 
        {
        
    	T = timer * 0,000032; // perod 1 RPM, 0,000032 время одного тика 
    //     Frec = 1/T;
    //     RPM = Frec*60;
    	RPM = 60 / T;
    	
    	
    	sprintf(buff, "%5d", RPM);
    	
    	while (! (UCSRA & (1 << UDRE)) );
    	{
    		UDR = buff;//когда передатчик готов посылаем 8 бит данных
    	}
      
        }
    }

     

  14. Как уже и сказали выше:

    04.04.2021 в 23:34, SLACKBAYN TM сказал:

    А как можно доказать то что VD3 компенсирует падание на VD1 и VD2? Извиняюсь за такие вопросы, просто я совсем зеленый!

     Диод VD3 стоит в цепи обратной связи ОУ, но по большей части, задавать коэффициент обратной связи будет резистор R5 и R2=R3, R4. На диоде VD3 упадет 0,6 - 0,8В. Он наоборот будет гасить часть сигнала и пропустит только положительный сигнал, а отрицательный проигнорирует, и обратная связь будет немножко кастрированная. 

  15. 8 минут назад, oleg korotkov сказал:

    Так, все таки, Rн2  100 или 200 ом  то так, то эдак???

    Пардон, ошибся photo_2021-04-08_12-56-58.thumb.jpg.eb18b156f899c61831885f65dc2c479c.jpg

    9 минут назад, sanya110 сказал:

    Очень интересное решение. Но если интересует правильное, писать лучше сразу сюда: https://forum.cxem.net/index.php?/forum/15-вакансии-и-разовая-работа/. И заодно привести все исходные данные, чтобы случайно не применить КТ3102 при напряжении на нагрузке 300 В, как это было предложено выше.

    А что не так с этим транзистором, и при чем здесь 300В?

     classificationKT3102-1.png.b95cbc9305b56d259183b4f212e17afa.png

  16. Благодарю за самое понятное объяснение

    rd = adc_read(0) * echo_level;
    
    buf[i] = rd;

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

×
×
  • Создать...