G1KuL1N

Moderators
  • Публикации

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

  • Посещение

Репутация

100 Хороший

О G1KuL1N

  • Звание
    ♣Гитароломатель♣
  • День рождения 16.12.1982

Информация

  • Пол
    Мужчина
  • Город
    Москва

Электроника

  • Стаж в электронике
    Не связан с электроникой

Посетители профиля

29 572 просмотра профиля
  1. Программный I2C для STM32

    Пины аппартаного I2C заняты плата разведена, FRAM навесом
  2. Программный I2C для STM32

    Уважаемый MasterElectric я выше уже ответил по этому поводу, не спорю с таймером лучше, но если ценим процессорное время - юзаем аппаратный I2C, и нет больше никаких "самых лучших вариантов". Во-вторых когда мне понадобился срочно программный I2C, если-б я залез сюда на форум, наткнулся бы на Ваш пост с программным I2C с таймерами и бит-бандингом, я бы включил его себе с мыслью: вот чел молодец какой, выложил не поленился, спасибо ему. Так что как есть, так есть.
  3. Программный I2C для STM32

    Это решение "в лоб", но работает, просто и быстро, написано за 20 минут так как горело, и с ходу рабочего решения не нашел. Задержку на таймере конечно лучше но необязательно, для ценителей программного времени там переделать 10 минут на таймер (хотя тот кто считает такты никогда в здравом уме не будет использовать программный i2C, когда есть аппаратный ). На HAL так как это встроено в большую программу которая работает с HAL. Понадобилось просто подвесить в проект FRAM но уже все было готово и переделывать было бы долго и нудно.
  4. Программный I2C для STM32

    В общем понадобилось тут подвесить FRAM к STM32, а пины аппаратных I2C были уже заняты, ну решил не менять пины, а добавить себе на вооружение на всякий, программный I2C. То что удалось нагуглить либо работало криво, либо приходилось допиливать и допиливать. Ну и написал свой с блекджеком и ш.. Так как в сети примеров мало программного I2C на STM32 то решил поделиться. Вдруг кому пригодится. Работает с библиотекой HAL, поправить нужно только под свой камень и свои порты и все работает. I2C.h #ifndef __I2C_H_H__ #define __I2C_H_H__ // G1KuL1N // ПОДКЛЮЧИТЬ БИБЛИОТЕКУ СВОЕГО КОНТРОЛЛЕРА #include "stm32f4xx_hal.h" // В CUBE MX порты I2C настроить на выход (либо в main.c вручну подать тактирование на нужны GPIO) //---подключение шины к пинам----------------------------------------------------- #define SCL_I HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15); #define SDA_I HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14); #define SCL_O HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET); #define SDA_O HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); //-------------------------------------------------------------------------------- void i2c_init (void); // Инициализация шины void i2c_start_cond (void); // Генерация условия старт void i2c_restart_cond (void); // Генерация условия рестарт void i2c_stop_cond (void) ; // Генерация условия стоп uint8_t i2c_send_byte (uint8_t data) ; //Передать байт (вх. аргумент передаваемый байт) (возвращает 0 - АСК, 1 - NACK) uint8_t i2c_get_byte (uint8_t last_byte) ; //Принять байт (если последний байт то входной аргумент = 1, если будем считывать еще то 0)(возвращает принятый байт) //-------------------------------------------------------------------------------- // ПРИМЕР ИСПОЛЬЗОВАНИЯ //========================================================================================= // Запись uint16_t во внешнюю еепром (FRAM FM24CL64) или любой другой 24LC памяти, // две ячейки, указывается адрес первой ячейки, следующая идет adr++ //========================================================================================= // //void FRAM_W_INT(uint16_t adr, uint16_t dat){ //i2c_start_cond (); //i2c_send_byte (0xA2); //адрес чипа + что будем делать (записывать) //i2c_send_byte ((adr & 0xFF00) >> 8); //i2c_send_byte (adr & 0x00FF); //i2c_send_byte ((dat & 0xFF00) >> 8); //i2c_send_byte (dat & 0x00FF); //i2c_stop_cond(); //} //========================================================================================= // Считывание uint16_t из внешней еепром (FRAM FM24CL64) или любой другой 24LC памяти, // две ячейки, указывается адрес первой ячейки, следующая идет adr++ //========================================================================================= //uint16_t FRAM_R_INT(uint16_t adr){ //uint16_t dat; //i2c_start_cond (); //i2c_send_byte (0xA2); //i2c_send_byte ((adr & 0xFF00) >> 8); //i2c_send_byte (adr & 0x00FF); //i2c_restart_cond (); //i2c_send_byte (0xA3); //dat = i2c_get_byte(0); //dat <<= 8; //dat |= i2c_get_byte(1); //i2c_stop_cond(); //return dat; //} // G1KuL1N #endif /* __I2C_H_H__ */ i2C.c #include "I2C.h" volatile uint8_t i2c_frame_error=0; //----------------------------------------------------------- __STATIC_INLINE void Delay_us (uint32_t __IO us) //Функция задержки в микросекундах us { us *=(SystemCoreClock/1000000)/5; while(us--); } //---------------------------------------------------- void SCL_in (void) //функция отпускания SCL в 1, порт на вход (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } //---------------------------------------------------- void SCL_out (void) //функция притягивания SCL в 0 (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); SCL_O; } //---------------------------------------------------- void SDA_in (void) //функция отпускания SDA в 1, порт на вход (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } //---------------------------------------------------- void SDA_out (void) //функция притягивания SDA в 0 (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); SDA_O } //---------------------------------------------------- void i2c_stop_cond (void) // функция генерации условия стоп { uint16_t SCL, SDA; SCL_out(); // притянуть SCL (лог.0) Delay_us(10); SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SDA_in(); // отпустить SDA (лог.1) Delay_us(10); // проверка фрейм-ошибки i2c_frame_error=0; // сброс счётчика фрейм-ошибок SCL=SCL_I; SDA=SDA_I; if (SCL == 0) i2c_frame_error++; // проберяем, чтобы на ноге SDA была лог.1, иначе выдаём ошибку фрейма if (SDA == 0) i2c_frame_error++; // проберяем, чтобы на ноге SCL была лог.1, иначе выдаём ошибку фрейма Delay_us(40); } void i2c_init (void) // функция инициализации шины { i2c_stop_cond(); // стоп шины i2c_stop_cond(); // стоп шины } //---------------------------------------------------- void i2c_start_cond (void) // функция генерации условия старт { SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } //---------------------------------------------------- void i2c_restart_cond (void) // функция генерации условия рестарт { SDA_in(); // отпустить SDA (лог.1) Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } //---------------------------------------------------- uint8_t i2c_send_byte (uint8_t data) // функция отправки байта { uint8_t i; uint8_t ack=1; //АСК, если АСК=1 – произошла ошибка uint16_t SDA; for (i=0;i<8;i++) { if (data & 0x80) { SDA_in(); // лог.1 } else { SDA_out(); // Выставить бит на SDA (лог.0 } Delay_us(10); SCL_in(); // Записать его импульсом на SCL // отпустить SCL (лог.1) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) data<<=1; // сдвигаем на 1 бит влево } SDA_in(); // отпустить SDA (лог.1), чтобы ведомое устройство смогло сгенерировать ACK Delay_us(10); SCL_in(); // отпустить SCL (лог.1), чтобы ведомое устройство передало ACK Delay_us(10); SDA=SDA_I; if (SDA==0x00) ack=1; else ack=0; // Считать ACK SCL_out(); // притянуть SCL (лог.0) // приём ACK завершён return ack; // вернуть ACK (0) или NACK (1) } //---------------------------------------------------- uint8_t i2c_get_byte (uint8_t last_byte) // функция принятия байта { uint8_t i, res=0; uint16_t SDA; SDA_in(); // отпустить SDA (лог.1) for (i=0;i<8;i++) { res<<=1; SCL_in(); // отпустить SCL (лог.1) //Импульс на SCL Delay_us(10); SDA_in(); SDA=SDA_I; if (SDA==1) res=res|0x01; // Чтение SDA в переменную Если SDA=1 то записываем 1 SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } if (last_byte==0){ SDA_out();} // притянуть SDA (лог.0) // Подтверждение, ACK, будем считывать ещё один байт else {SDA_in();} // отпустить SDA (лог.1) // Без подтверждения, NACK, это последний считанный байт Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); SDA_in(); // отпустить SDA (лог.1) return res; // вернуть считанное значение }
  5. Делаем ЦАП

    А что стандартный QFP44 использовать или свой нарисовать большая проблема? Зачем именно SPICE нужен? no comments. Забудьте слово P-CAD... навсегда,
  6. Делаем ЦАП

    Вместо TL431 лучше TL1431. Михаил рекомендую посмотреть на ADR525 (550) по цене очень подъемные, я в такие регуляторы только их применяю последнее время. Да и генераторы я бы запитал от такого же регулятора
  7. Питание Педали

    Ну да в таком случае шумодав не нужен. Блок питания по ссылке конечно для хайгеновых примочек не подходит ни разу. Соберите стабилизатор на 7809 или LM317. Если будете покупать все же новый БП главное что бы он был не импульсный, даже если на нем написано, что он стабилизированный.
  8. Питание Педали

    Вообще как бы должно фонить, это все таки дисторшн. Причем зависит и от типа звукоснимателя, и от качества БП, и от того куда втыкается. Можно поступить радикально и купить BOSS NS-2 например.
  9. Предусилитель Для Электро Гитары

    Коллектор, Тебе тогда нужен либо RIVERA knucklehead, либо ORANGE rockerverb, лучше всего канеш AXE FX2 сразу. после просмотра цен на данные аппараты собери что то типа ENGL E530, тем разжеванных полно.
  10. Jlh Headphone Amplifiers

    Наткнулся на эту тему месяц назад. О JLH для наушников слышал но не обращал внимания, а вот схема 2005-го года меня заинтересовала, решил собрать ради интереса. Усь хороший, субъективно мне больше понравился всяких лехманов, панд и пр. на TPA и AD, даже звено от предварительного усилителя Вадима(waso) не так живо звучит, разве что бете22 проиграл. Недостаток один - это постоянка на выходе, которая лечиться интегратором, либо ждать, у меня есть усь по подобной топологии, так там защита отщелкивается через 15-20 минут после включения. Транзисторы BC550/560 2SC5171, ток покоя 140мА. Если кому нужно платку которую накидал добавил + пару фото. PCB.rar
  11. Автор тут, но появляюсь сейчас немного реже, времени мало. Любые вопросы естессно нужно писать сразу в тему.
  12. Шикарный Подарок Электронщику

    Блин ну китайцы дают, уже и на этом делают деньги, и покупают же. У меня таких линеек полно валяется, даже выкидываю - бесплатно, их разные производители ПП, как рекламные материалы каждый год присылают.
  13. Делаем ЦАП

    Вот как раз, я только думал до этого ему такие же схемки подкинуть, только все равно воткнуть ADR525 для 5в и ADR530 для -12, соответственно резюки 8,9, 17,18 пересчитать.
  14. Делаем ЦАП

    to scare1987 в рогове фнч на резисторе лучше заменить на Бесселя третьего порядка, 390пф, 2.7mH, 2100пф, звук гораздо лучше чем с резистором. Питание да лучше сделать как у Андронникова, референс-ОУ-транзистор, для цифры можно и 317/337
  15. Делаем ЦАП

    до 96кГц по СПДИФУ, там AD1896. и 44.1 по I2S, на больше нужны переключаемые генераторы. Не стал возиться, да и для PCM63 не нужно больше ИМХО