-
Постов
76 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Блоги
Сообщения, опубликованные Kostyanskiy
-
-
3 часа назад, Starichok сказал:
а еще проблема в том, что ты нам не нарисовал, как подключен светодиод к порту.
А в чем проблема, катод к минусу, анод к плюсу
0 -
Здравствуйте, решил в своем проекте подключить кнопку, но МК странно себя ведет, создал отдельный проект, подумал, что что-то в моем основном коде не так, но нет, этот код не работает и в отрыве от основного, что странно. Вот:
#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
0 -
@IMXO помогите с кодом пожалуйста, а то у меня немного руки кривые
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); } }
0 -
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); }
Проблема была еще и в контактах, а когда припаял провода - все заработало
0 -
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 сказал:Не страшно что индусы! Берете их поделие и строчка за строчкой приводите к человеческому виду. Потом рефакторинг чтобы выкинуть ту часть библиотеки, которая посвящена восхвалению Кришны (по желанию можно заменить на восхваление Ктулху или Омниссии), рисованию логотипа производителя или другие не относящиеся к делу куски.
Да, лучше всего делать это прямо на Ардуине, чтобы и исходный код запускался, и ваша интерпретация. Ну а когда доведете работу до конца (то есть разделите платформо-зависимую часть от логики), уже можно переносить и на другие контроллеры если надо.
Хаха, спасибо за совет, этим уже занимаюсь
0 -
Только что, Starichok сказал:
на индусском языке, что ли?
Возможно...
0 -
14 минут назад, hasl сказал:
Возьмите либу от ардуино на данное железо и посмотрите, что делаете не так
В том то и проблема, что в либу под ардуино писали индусы, и там ничего не понятно.
0 -
Здравствуйте, пишу либу для 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); }
0 -
Спасибо, за объяснение господа, сделав перерыв в 1 день и толком все обмозговав, я понял как это работает
0 -
9 часов назад, Yurkin2015 сказал:
Ну, сбросили в ноль, а следующее прерывание от ножки пришло через 5 секунд, например, обороты ну очень маленькие, таймер успеет переполнится пару раз.
Наконец-то дошло как это работает, но зачем тогда первые 16 бит инкрементировать, почему не просто timer++?
11 часов назад, Kostyanskiy сказал:11 часов назад, IMXO сказал:T = SumNew - SumLast
И если посмотреть с другой стороны, то это не совсем период, это разность времени между 2 оборотами, зачем нам эта разность если это не период ?
0 -
20 минут назад, Yurkin2015 сказал:
тогда счётчик много раз переполнится между прерываниями от оборотов. На этот случай и делается учёт переполнений.
А что нам мешает каждый раз в прерывании от ножки сбрасывать счетчик в 0?
0 -
19 минут назад, IMXO сказал:
10*2^16
небольшое уточнение, почему 2 в степени 16 и умноженное на 10?
32 минуты назад, IMXO сказал:T = SumNew - SumLast
Я понял почему здесь так, из-за нелинейности движения измер. колеса разное время движения точки измерения, но почему мы тогда просто не ограничемся счетчиком TCNT1 зачем нам еще и переполнение по прерыванию таймера и как оно играет на конечный результат?
0 -
3 минуты назад, Yurkin2015 сказал:
плавающей запятой заменяем на быстрое и лёгкое целочисленное деление, всего одна операция
Я понял, но при чем здесь
13 минут назад, Kostyanskiy сказал:16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит
И какая зависимость скорости колеса измерения, предделителя таймера и переменной которая инкрементируется в прерывании по переполнению таймера?
0 -
тогда volatile uint32_t timer = 0;
ISR(TIMER1_COMPA_vect)
{
(timer << 16)++;
}Или как?
59 минут назад, IMXO сказал:обычно запускается 16-и битный таймер, в прерывании по переполнению таймера инкриминируется переменная тайм 32бит
в прерывании от ногадрыга читается таймер и складывается с тайм , полученная сумма вычитается из предыдущего значения суммы и получается значение периода в тактах таймера.Можете пожалуйста поподробней рассказать почему так? Или дайте источники где про это можно почитать
0 -
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; } }
То есть, вот так?
0 -
Только что, Yuriy.pv сказал:
Для этого есть нога ICP
Я знаю, я просто хочу разобраться в алгоритме, и решил сделать все более, для себя, наглядней
0 -
Здравствуйте уважаемые, стоит задача: сделать бесконтактный тахометр на 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 бит данных } } }
0 -
Укажите напряжение питания усилителя
0 -
Как уже и сказали выше:
04.04.2021 в 23:34, SLACKBAYN TM сказал:А как можно доказать то что VD3 компенсирует падание на VD1 и VD2? Извиняюсь за такие вопросы, просто я совсем зеленый!
Диод VD3 стоит в цепи обратной связи ОУ, но по большей части, задавать коэффициент обратной связи будет резистор R5 и R2=R3, R4. На диоде VD3 упадет 0,6 - 0,8В. Он наоборот будет гасить часть сигнала и пропустит только положительный сигнал, а отрицательный проигнорирует, и обратная связь будет немножко кастрированная.
0 -
17 минут назад, Kostyanskiy сказал:
как это было предложено выше
Скажите, а где написано, что я предложил использовать данный транзистор при напряжении 300В, я даже напряжение не указывал в схеме
0 -
8 минут назад, oleg korotkov сказал:
Так, все таки, Rн2 100 или 200 ом то так, то эдак???
9 минут назад, sanya110 сказал:Очень интересное решение. Но если интересует правильное, писать лучше сразу сюда: https://forum.cxem.net/index.php?/forum/15-вакансии-и-разовая-работа/. И заодно привести все исходные данные, чтобы случайно не применить КТ3102 при напряжении на нагрузке 300 В, как это было предложено выше.
А что не так с этим транзистором, и при чем здесь 300В?
0 -
-
Где данный усилитель будет применяться?
0 -
Благодарю за самое понятное объяснение
rd = adc_read(0) * echo_level; buf[i] = rd;
Я так понимаю, что в этом примере мы просто перезаписываем каждый раз сигнал без наложения
0
PINxn Atmega328 не работает
в МК для начинающих
Опубликовано
Оговорочка, анод к ножке PD0