Если вы белая и пушистая – вам пора в солярий и на эпиляцию.

Меню навигации для мобильных

Цифровое радио (учебно - развлекательная)

Автор zenon, 05 Нояб., 2020, 17:19

« предыдущая - следующая »

zenon

Отвлекаемся от "серьёзных" тем, в целях обучения и развлечения, и схем "выходного дня".
Сыну 15. Кое-что уже сделано, по мере свободного времени что-то творим.
Сейчас в планах по быстрому rda5807m + pro mini, усилитель с темброблоком мы уже сделали, и даже разместили в корпус от коммутатора д-линк.
Схема в аттаче - делали летом, немнго не в тему раздела, но оно пересекается, УНЧ - ВЭФ260 - схема мелькала на коте.
Весь проект с платой если надо выложу, но он сделан на скорую руку, нам нужен был опыт пайки больше.
Библиотека для приемника есть тут (https://github.com/mathertel/Radio).

++
Ну и на очереди вот эти часы (https://radiokot.ru/circuit/digital/game/27/), всё уже есть, кроме своей платы под свои элементы, и датчик надо сделать.
https://github.com/minamonra/

zenon

Собрали тест. Видео (https://youtu.be/xWEQoZh0H1M).
https://github.com/minamonra/

Slabovik

Занятная вещица, но ведь хочется подробностей, так сказать, от первых лиц :)
Ардуиновскую библиотеку готовую, похоже, использовали, не изобретали?
Экранчик, управление?
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Эммм... тут просто скетч для дуины который пишет в регистры rda5807m частоту настройки радиоприёмника по i2c.
Ни экранчика, ни управления. :)
Как вариант находил управление по uart, вэб-морду...
Сама микросхема-то известная и вариантов препараций её много.
#include <Wire.h>              // I2C-Library

double f_ini=102.6;            // Стартовая частота настройки приемника. (Изменяем на нужную).

void setup()                    // Инициализация.
{
  Wire.begin();                // Инициализация двухпроводной шины I2C.
  setFrequency(f_ini);          // Вызываем фукнкцию загрузки частоты настройки в модуль EM5807M.
}

void loop()                    // Основной цикл программы
{
  // Здесь можем написать нашу самую лучшую программу, которая будет работать так как нам нужно.
}
  

void setFrequency(double fmhz)  // Функция загрузки частоты настройки в модуль EM5807M.
{
  int  frequencyB = 4 * (fmhz * 1000000 + 225000) / 32768;
  char frequencyH = frequencyB >> 8;    // Старший байт.
  char frequencyL = frequencyB & 0XFF;  // Накладываем маску 0xFF на младший байт.
  Wire.beginTransmission(0x60);          // Адрес чипа RDA5807M
  Wire.write(frequencyH);                // Старший байт.
  Wire.write(frequencyL);                // Младший байт.
  Wire.write(0xB8);                      // 1011 1000    =Стерео
  Wire.write(0x10);                      // 0001 0000
  Wire.write((byte)0x00);                // 
  Wire.endTransmission();                // формируем I2C-Stop.
} 
Отсюда (https://www.5v.ru/start/em5807m-arduino-nano-30.htm).
Вот ещё (https://tomeko.net/projects/RDA5807M_radio/index.php?lang=en).
И вот этот материал уже интереснее. (https://github.com/mathertel/Radio)
Ну и на коте есть проект.
https://github.com/minamonra/

zenon

Управление rda5807m от stm32f0, перебор забитых в массив станций двумя кнопками на PA4, PA5, i2c на PB6 и PB7.
#include <stm32f0xx.h>
static uint16_t R2H = 0, R3H = 0, R4H = 0, R5H = 0, R6H = 0, R7H = 0, R0AH = 0;
#define CHAN_SHIFT 6
#define FDEL 100
#define RDA5807_OWN_ADDRESS (0x11) // адрес произвольного доступа (порегистровый) I2C_INDX //I2C-Address RDA Chip for Index  Access
//  0x10 // I2C-Address RDA Chip for sequential  Access
//  0x11 // I2C-Address RDA Chip for Index  Access
#define nop()  __NOP()
#define pin_toggle(gpioport, gpios)  do{  \
    register uint32_t __port = gpioport->ODR;  \
    gpioport->BSRR = ((__port & gpios) << 16) | (~__port & gpios);}while(0)
#define pin_set(gpioport, gpios)  do{gpioport->BSRR = gpios;}while(0)
#define pin_clear(gpioport, gpios) do{gpioport->BSRR = ((gpios) << 16);}while(0)
#define pin_read(gpioport, gpios) (gpioport->IDR & (gpios) ? 1 : 0)
#define pin_write(gpioport, gpios)  do{gpioport->ODR = gpios;}while(0)

uint16_t fm_freq_vlg[] = {
  0,
 949, // 0 Радио 7 на семи холмах
 961, // 1 Love Radio
 965, // 2 Комсомольская правда
 972, // 3 Наше радио
 976, // 4 Радио дача
 983, // 5 Радио России
 988, // 6 Радио Energy
 992, // 7 Радио Maximum
1006, // 8 Europa +
1011, // 9 Эхо Москвы
1015, //10 Волгоград FM
1020, //11 Новая Волна
1026, //12 Ретро FM
1031, //13 Авторадио
1036, //14 Дорожное радио
1040, //15 Новое радио
1045, //16 Юмор FM
1051, //17 Радио Спутник
1056  //18 Русское радио
};

char station = 0;
static volatile uint64_t ticks = 0;
uint32_t lticks = 0;
void systick_init(void);
void gpio_init(void);
void i2c_init(void);
void rda5807_write16_reg(uint8_t reg, uint16_t data);
void rda5807_send_reg(uint8_t reg, uint8_t data_h,uint8_t data_l);
uint16_t rda5807_read16_reg(uint8_t reg);
void rda5807_init(uint16_t frequency, char volume, char delay);
void nop_delay(unsigned int i);


int main(void) {
  SystemInit();
  systick_init();
  gpio_init();
  i2c_init();
  rda5807_init(fm_freq_vlg[17], 15, 1);
  while (1) {
    // опрос кнопок раз в 20 ms
    if(lticks > ticks || ticks - lticks > 20) {
      // следующая станция
      if (!pin_read(GPIOA, 1<<4)) {
        if (station > 19) station = 0;
        station++;
        rda5807_init(fm_freq_vlg[station], 15, 1);
      }
      if (!pin_read(GPIOA, 1<<5)) {
        if (station < 1) station = 19; else station--;
        rda5807_init(fm_freq_vlg[station], 15, 1);
      }
    }
  }
} // main(void)

void SysTick_Handler(void) {
  ticks++;
}

void systick_init(void) {
  SystemCoreClockUpdate(); // Make sure SystemCoreClock is up-to-date
  SysTick->LOAD = (SystemCoreClock / 1000) - 1;
  SysTick->VAL = 0;
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}

void gpio_init(void) {
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // включили переферию A
  RCC->AHBENR  |= RCC_AHBENR_GPIOBEN; // B
  // Кнопки на PA4 PA5
  GPIOA->PUPDR = GPIO_PUPDR_PUPDR4_0; // PA4 как вход с подтяжкой вверх
  GPIOA->PUPDR = GPIO_PUPDR_PUPDR5_0; // PA5

}


void nop_delay(unsigned int i) {
  for (; i>0; i--) {
    for (int j = 0; j < FDEL; ++j) {
      __asm__ __volatile__("nop\n\t":::"memory");
    }
  }
}

void i2c_init(void) {
  //RCC->AHBENR  |= RCC_AHBENR_GPIOBEN; в gpio_init
        
  RCC->APB1ENR  |= RCC_APB1ENR_I2C1EN;
  RCC->CFGR3    |= RCC_CFGR3_I2C1SW; 

  GPIOB->AFR[0] |=  (1<<(4*6)) | (1<<(4*7));
  GPIOB->MODER  &= ~(GPIO_MODER_MODER6  | GPIO_MODER_MODER7  );    // PB6 и PB7
  GPIOB->MODER  |=  (GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1);
  GPIOB->OTYPER |=  (GPIO_OTYPER_OT_6    | GPIO_OTYPER_OT_7  );
        
  I2C1->TIMINGR = (uint32_t)0x00B01A4B; 
  I2C1->CR1 = I2C_CR1_PE; 
}
// RDA5807                  STM32F0
// бело-серый  SCL/CLK      PB6      линия тактирования
// черный      SDA/DIO      PB7      линия данных

void rda5807_write16_reg(uint8_t reg, uint16_t data) {
  I2C1->CR2 =  I2C_CR2_AUTOEND | (3<<16) | (RDA5807_OWN_ADDRESS<<1); 

  while (!(I2C1->ISR & I2C_ISR_TXE)); // Check Tx empty

  I2C1->TXDR = reg; // Byte to send
  I2C1->CR2 |= I2C_CR2_START; // Go

  while (!(I2C1->ISR & I2C_ISR_TXIS));
  I2C1->TXDR = (uint8_t)(data>>8); // Byte to send
  
  while (!(I2C1->ISR & I2C_ISR_TXIS));
  I2C1->TXDR = (uint8_t)(data &0x00FF); // Byte to send
}

void rda5807_send_reg(uint8_t reg, uint8_t data_h,uint8_t data_l) {
  I2C1->CR2 =  I2C_CR2_AUTOEND | (3<<16) | (RDA5807_OWN_ADDRESS<<1); 

  while (!(I2C1->ISR & I2C_ISR_TXE)); // Check Tx empty
  I2C1->TXDR = reg; // Byte to send
  I2C1->CR2 |= I2C_CR2_START; // Go

  while (!(I2C1->ISR & I2C_ISR_TXIS));
  I2C1->TXDR = data_h; // Byte to send
  
  while (!(I2C1->ISR & I2C_ISR_TXIS));
  I2C1->TXDR = data_l; // Byte to send
}

uint16_t rda5807_read16_reg(uint8_t reg) {
  uint16_t temp=0;
  I2C1->CR2 =  (1<<16) | (RDA5807_OWN_ADDRESS<<1); 
  while (!(I2C1->ISR & I2C_ISR_TXE));
  I2C1->TXDR = reg; // Byte to send
  I2C1->CR2 |= I2C_CR2_START; // Go
  while (!(I2C1->ISR & I2C_ISR_TC)){};
  I2C1->CR2 =  I2C_CR2_AUTOEND | (2<<16) | 
                (RDA5807_OWN_ADDRESS<<1) |
                          I2C_CR2_RD_WRN |
                            I2C_CR2_NACK; 
  I2C1->CR2 |= I2C_CR2_START; // Go
  while (!(I2C1->ISR & I2C_ISR_RXNE)){};
  temp  = (uint16_t)(I2C1->RXDR <<8);
  while (!(I2C1->ISR & I2C_ISR_RXNE)){};
  temp |=  (uint16_t)I2C1->RXDR; 
  return temp;
}

void rda5807_init(uint16_t frequency, char volume, char delay) {
  if (delay==1) nop_delay(4000);
  
  // R2H = 0, R3H = 0, R4H = 0, R5H = 0, R7H = 0, R0AH = 0;
  // R2H = 0;    0b0000000000000000
  // R2H = R2H | 0b1000000000000000  DHIZ; 
  // R2H = R2H | 0b1000000000000001  ENABLE;

  // регистр 02H
  // DHIZ  (1<<15)
  // DMUTE (1<<14)
  // RENABLE (1<<0)
  // регистр 02H
  //
  R2H = R2H | (1<<15); // DHIZ  (1<<15)
  R2H = R2H | (1<<14); // DMUTE (1<<14)  0 mute, 1 normal operation
  R2H = R2H | (1<<0 ); // ENABLE
  R2H = R2H | (0<<13); // MONO  (0=stereo, 1=mono)
  R2H = R2H | (1<<12); // BASS  (0=disable, 1=enable bass boost)
  R2H = R2H | (0<<2 ); // NEW_METHOD (New  Demodulate Method Enable,  can  improve the receive sensitivity about 1dB)
  R2H = R2H | (0<<11); // RCLK NON-CALIBRATEMODE  0=RCLK clock is always supply 1=RCLK  clock  isnot  always  supply  when  FM work
  // Биты 6:4 CLK_MODE[2:0] кварц 000 = 32.768 он у нас и стоит, менять ничего не надо
 
  rda5807_write16_reg(0x02, R2H); // пишем регистр 02H

  // регистр 03H
  // BAND = 00 (87..108МГц), STEP = 00 (100кГц)
  // 3:2 BAND[1:0]Band Select.  00=87–108 MHz US/Europe 01=76–91 MHz Japan 10=76–108 MHz worldwide 11=65–76 MHz East Europe or 50-65MHz
  // выбор канала, зависит от BAND
  // BAND = 0: частота = интервал между каналами (кГц) * CHAN + 87.0 МГц.
  // BAND = 1 или 2: частота = интервал между каналами (кГц) * CHAN + 76.0 МГц.
  // BAND = 3: частота = интервал между каналами (кГц) * CHAN + 65.0 МГц.
  // частота 10 бит!
  R3H = (frequency - 870) << CHAN_SHIFT;  // chan = (frequency - band) << сдвиг на 6
  R3H = R3H | (1<<4);                    // TUNE после установки частоты установить TUNE бит!!

  rda5807_write16_reg(0x03, R3H);
  // регистр 05H
  R5H  = rda5807_read16_reg(0x05);
  R5H &= ~0x000F; // 0b0000000000001111
  R5H |= volume << 0; // Устанавливаем новую громкость
  rda5807_write16_reg(0x05, R5H);
}

https://github.com/minamonra/

zenon

Измочалил свой девбоард для stm, думал какую плату сделать... вышел гибрид для тестов с радиоприёмником, в основном для освоения...
На схеме всё приблизительно.
По хорошему другой контроллер надо бы сюда, но я ни разу не пробовал ни DS1307 ни память I2C...
5 кнопок, энкодер, выход на пищалку, один выход на реле...
https://github.com/minamonra/

Slabovik

#6
Однако наворочено :)
Но я побрюзжу на пользу дела: обратил внимание, что средняя точка для ОУ организована как-то не очень. Она без фильтрации, что значит, что все помехи с питания VCC1 будут на выходе ОУ с коэффициентом усиления 2.
И ФНЧ килогерц на 15 хорошо бы иметь в дополнение к emphasis коррекции (в вещании на УКВ используется подъём ВЧ с постоянной времени фильтра 50 мкс, следовательно, в приёмнике надо иметь ФНЧ с аналогичными параметрами).
Про LM358 ты и сам знаешь  ;)

А всё-таки вопросик у меня есть: антенну как считал?
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#7
Плату сделал. Спешка наше всё... Наворотил вроде немного, хочется со всем этим разобраться...
ds1307 по напряжению то не подходит, ну ладно надо поискать ds1338, она вроде пин-то-пин.
Как на stm общаться с rtc по i2c пытаюсь разобраться, пока никак.
С кодом для тюнера вроде всё работает, кроме поиска станций (тут засада, вроде пытаюсь сделать как в даташите, подробнее позже напишу), подсматривал реализацию для avr тут (https://github.com/WiseLord/fm7segm/tree/master/src).
ФНЧ да, надо, может предложишь повторитель/усилитель с однополярным питание сюда? Хотя выход у приюмника сам по себе не слабый и необходимость в ОУ сомнительна, хотя...
Антенну - не рассчитывал.
Вообще надо ещё раз подумать и какой нибудь другой приёмник, качеством получше поискать.
Кстати, при включении через бит ENABLE раздражает щелчок довольно сильный, и похоже это "фича" этой микросхемы, также как и нарастающая громкость после смены частоты.
Такс... eeprom у меня 24cXX надо тоже посмотреть как они с 3.3 вольт дружат.
Часовой кварц откуда-то выдернул, маленких конденсаторов для него в 0805 формате не оказалось под рукой.
Ещё подтяжку i2c разместил в не удачном месте...
Сумбурно написал, весь в ремонте (в кватире ремонт).
//
ы. Появились у меня ещё:
STM32G070RBT6, STM32G030K6T6, STM32G030C8T6, STM32G030F6P6.
Хватит на долгие вечера... :))))


:: добавлено 05 Март, 2023, 14:41
Мысли-коромысли... :)
В tqfp-32 корпусе нет выводов для часового кварца и vbat.
Зато, как оказалось, stm32f030 превращается в stm32f031 простым подключением библиотек от f031 камня, те f030=f031, подсказали на коте, после этого смог подключить IR на TIM2, высвободив TIM3 на энкодер.
фото:
https://github.com/minamonra/

Slabovik

Фильтрация секретов не представляет. Например, здесь (https://anklab.ru/forum/index.php?topic=84.0) я вставлял аж четвёртый порядок. Совершенно не зря, мне понравился звук.

Уровни для всего этого пучка интерфейсов можно согласовывать через TXS0108 (https://anklab.ru/forum/index.php?action=dlattach;topic=128.0;attach=4134) - занятная микросхемка. У нас в магазине такие не продавались, зато продавались готовые платки типа "преобразователь уровня для Ардуины" с этой микросхемкой. забрал все :)
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#9
В попытка вникнуть в регистры stm32 терплю пока сплошные неудачи, каша в голове никак не систематизируется.
Даташит на 24C16N есть (https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjsnPKOl8r9AhURrosKHR1TCFoQFnoECAkQAQ&url=http%3A%2F%2Fpdf.datasheet.live%2Fdatasheets-1%2Fatmel%2FAT24C16N-10SA-2.7C.pdf&usg=AOvVaw0kekRKy6KGi2FNyVPgEuTP). референс мануал на F0 есть.
Но чтение/запись из eeprom получилась методом "тыка".
Наиболее подробно процесс нашёл на этом форуме (http://mcu.goodboard.ru/viewtopic.php?id=14#p266). Но там для F4, соответственно регистры в CMSIS тоже не так называются.
С инитом проблем нет, тайминги там только загвоздка, но они уже везде посчитаны.
У меня так:
void i2c_init (void)
{
  RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
      
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  RCC->CFGR3 |= RCC_CFGR3_I2C1SW;
      
  GPIOB->AFR[0] |= (1<<(4*6)) |(1<<(4*7));
  GPIOB->MODER &= ~(GPIO_MODER_MODER6 |GPIO_MODER_MODER7);
  GPIOB->MODER |= (GPIO_MODER_MODER6_1 |GPIO_MODER_MODER7_1);
  GPIOB->OTYPER |=(GPIO_OTYPER_OT_6 |GPIO_OTYPER_OT_7);
  I2C1->TIMINGR = (uint32_t)0x00B01A4B;
  I2C1->CR1 = I2C_CR1_PE;
}


Чтение eeprom страницей сделал так:
void zeeprom_read_i2c (uint8_t addr, uint8_t *data, uint8_t nbytes) {
  uint8_t i;  // 

  I2C1->CR2 = (1 << 16) | I2C_CR2_START | addr;

  while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
  I2C1->TXDR = 0;
  while((I2C1->ISR & I2C_ISR_TC) != I2C_ISR_TC);
  I2C1->CR2  = I2C_CR2_AUTOEND | (nbytes << 16) | I2C_CR2_RD_WRN | addr;
  I2C1->CR2 |= I2C_CR2_START;

  for(i = 0; i < nbytes; i++) {
    while((I2C1->ISR & I2C_ISR_RXNE) != I2C_ISR_RXNE);
    *data++ = I2C1->RXDR;
  }
  delay_us(5);
}

nbytes тут 16 (по числу байт на странице, можно и константой сделать), а вот адресация страниц получилась странная, если читать передавая адрес 0xA0, то читается 1-ая страница, 0xA1 - вторая итд до 16-ой. Читаются правильно. Но как-то не правильно вроде так адресовать страницы.
Эмм от какого момента я до этого дошёл,... просто попробовал написать сканер для i2c ну и увидел адреса:
...OK!i: 32
...OK!i: 33
...OK!i: 34
...OK!i: 35

...OK!i: 160  0xA0
...OK!i: 161  0xA1
...OK!i: 162  0xA2
...OK!i: 163  0xA3
...OK!i: 164  0xA4
...OK!i: 165  0xA5
...OK!i: 166  0xA6
...OK!i: 167  0xA7
...OK!i: 168  0xA8
...OK!i: 169  0xA9
...OK!i: 170  0xAA
...OK!i: 171  0xAB
...OK!i: 172  0xAC
...OK!i: 173  0xAD
...OK!i: 174  0xAE
...OK!i: 175  0xAF



...OK!i: 192
...OK!i: 193


:: добавлено 08 Март, 2023, 00:04
Так... запись, а вот запись страницы выглядит сейчас так:
void zeeprom_write_i2c (uint8_t addr, uint8_t *data, uint8_t nbytes)  {
  uint8_t i = 0;
  I2C1->CR2 = I2C_CR2_RELOAD | (1 << 16) | I2C_CR2_START | addr;
  while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
    
  I2C1->TXDR = 0;
    
  while((I2C1->ISR & I2C_ISR_TCR) != I2C_ISR_TCR);
  //I2C1->CR2 = I2C_CR2_AUTOEND | (EEPROM_PAGE_SIZE << 16) | addr;
  I2C1->CR2 = I2C_CR2_AUTOEND | (nbytes<<16) | addr | 1 |  I2C_CR2_RD_WRN;
//I2C1->CR2 = addr | 1 | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN;    
  for(i = 0; i < nbytes; i++)
  {
    while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
    I2C1->TXDR = data[i];
  }
  delay_us(5);
}
Но пишет неправильно, сразу две страницы заполняет, например выполнив zeeprom_write_i2c(0xA0, gDB, 16);, значения массива gDB будут в адресе 0xA0 и точно такие же в 0xA1.
https://github.com/minamonra/

zenon

#10
В общем с eeprom поступил так:
static uint8_t 
EEaddr [8] = { 160, // 0
               162, // 1
               164, // 2
               166, // 3
               168, // 4
               170, // 5
               172, // 6
               174  // 7
             }; 

Сделал чтение при загрузке параметров из eeprom, настройка ручная, регулировка громкости.
Сохраняются текущие настройки пока кнопкой.
Отображение громкости с включенным усилением баса vbXX, с выключенным voXX.
Меню сохранения станций додумаю и вроде на этой плате всё.
Реализацию часов уже на другой плате, будет или PCF8563T, которые едут, или поставлю камень из новых STM32G030K6T6, он почти такой же, но пины по другому сделали, ножки на питание сократили, есть выводы для часового кварца, так что для часов он лучше, не нужна лишняя микросхема.
За столом у меня приём ужасный, на самом деле принимает лучше.



аааа! Индикатор этот меня подвел! Нет в нём точек. Только двоеточие, точки есть у 14-ти пиновых, у 12 - нет, надо было сразу смотреть, так что при покупке надо лишний раз обращать внимание.
https://github.com/minamonra/

zenon

ы. а с антенной засада, те на плате её не знаю как на УКВ сделать. Только на свежем воздухе эта нормально работает... :)
https://github.com/minamonra/

zenon

Так конечно адреса чётными будут блин, на 1 заканчивается адрес если это запись... дошло таки.
https://github.com/minamonra/

zenon

#13
В общем победил лень.
Запустил анализатор (дешёвый китайский).
Про 24c16.
Объём всего 16 Кбит, те 2 Кбайт. Те 2048 ячейки по 8 бит.
Исходя из DS память организованна в 128 страниц по 16 ячеек.
Запись страницы = передать адрес кратный 16-ти, передать адрес ячейки, передать 16 байт, стоп.
Чтения страницы отдельной операцией нет, только последовательное чтение по адресу из 8 банков по 256 байт максимум.
Сделал чтение 16-ти байт для того чтобы было красиво.
Собственно чтение (адрес передаётся кратным 16, от 0 до 2032):
uint8_t ee24c16read_page (uint16_t addr, uint8_t* buff) {
  cntr = ttms;
  uint8_t addr_tmp = EE16ADDR + (addr/255<<1);

  I2C1->CR2 = 1<<16 | I2C_CR2_START | addr_tmp;
  while((I2C1->ISR & I2C_ISR_TXIS)==0) { if(ttms - cntr > I2CWAIT) return 0; }

  I2C1->TXDR = (uint8_t) addr;
  while((I2C1->ISR & I2C_ISR_TC)==0) { if(ttms - cntr > I2CWAIT) return 0; }

  I2C1->CR2 = 16<<16 | I2C_CR2_START | addr_tmp | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN;
  for(uint8_t i=0; i<=16-1; i++) {
    while((I2C1->ISR & I2C_ISR_RXNE)==0) { if(ttms - cntr > I2CWAIT) return 0; }
    *(buff+i) = (uint8_t)I2C1->RXDR;
    buff[i]  = I2C1->RXDR ;
  }
  return 1;
}


Запись:
uint8_t ee24c16write_page (uint16_t addr, uint8_t *buff)
{
  uint8_t addr_tmp = EE16ADDR + (addr/255<<1);
  
  cntr = ttms;
  I2C1->CR2 = I2C_CR2_AUTOEND | (17<<16) | (addr_tmp) | I2C_CR2_START;
  while (!(I2C1->ISR & I2C_ISR_TXE))  { if(ttms - cntr > I2CWAIT) return 0; }; // TXE регистр данных передачи пуст (буфер передачи пуст)

  I2C1->TXDR =(uint8_t) addr;  
  while (!(I2C1->ISR & I2C_ISR_TXIS)) { if(ttms - cntr > I2CWAIT) return 0; };
  
  cntr = ttms;
  for (uint8_t i = 0; i <= 16 - 1; i++) {
    while (!(I2C1->ISR & I2C_ISR_TXIS))  // TXIS // ждем пока TXDR станет пустым и готовым к новым данным
    if(ttms - cntr > I2CWAIT) return 0;  //
    I2C1->TXDR = buff[i] ; //
  }
  while((I2C1->ISR & I2C_ISR_STOPF)==0) {}; // не знаю нужна проверка?
  return 1;
}
EE16ADDR      (0xA0)
ttms - из прерывания системного тикера (1/1000).
Вроде нормально работает?
В архиве сэйвы логгера.
Постранично:
uint8_t ee24c16rp(uint8_t page, uint8_t* buff)
{
  uint8_t addr = page * 16;
  return ee24c16read_page (addr, buff);
}

uint8_t ee24c16wp(uint8_t page, uint8_t *buff)
{
  uint8_t addr = page * 16;
  return ee24c16write_page(addr, buff);
}
В памяти 24c32/64 организация другая - по 32 байта странички, и для передачи нужен адрес из двух байт.
Чуть позже выложу тоже.
https://github.com/minamonra/

Slabovik

Уу, слона-то я и не заметил. Смотрел в код, а видел фигу, т.к. надо подпрограммы расколупывать, бррр...
Поздравляю с удачной отладкой :)

А по антенне маленько грустно. Для нормального приёма нужен штырь сантиметров 70-80, ну хотя бы 50, и противовес, в качестве которого можно использовать проводящий корпус-общий провод. Ибо суть антенны - собрать как можно больше распределённой по пространству энергии волн, а лучше всего это делают антенны, соизмеримые с размерами самих волн. Поэтому такие маленькие - это уже на гигагерцы. Честно говоря, я их считать не умею, потому и спросил про расчёт.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Ну да L/4, я помню...
Где-то проскакивало про фильтр простейший, прицепил, и! однако стало лучше.
Усилитель какой может попробовать? Хотя чувствительность у него и так не плохая.
Присматриваюсь к вот такому экземпляру TEF6686 (https://aliexpress.ru/item/1005004600166150.html?spm=a2g2w.cart.cart_split.26.4ea44aa67gI1cr&sku_id=12000029783044527).
Не знаю как на него с кодом...
Что-то меня на радиоприём потянуло...
Не замахнуться ли нам на что-нибудь с синтезатором? Но не слишком уж сложное, ёмкости маленькие и настройка контуров пугает...
https://github.com/minamonra/

zenon

#16
Почти все цели достигнуты.
С RTC всё оказалось просто, будильники осталось.
Не дождался модулей с али, взял ds3231.
Естественно некоторые вещи не выдумывал, подглядел... на то он и гитхаб. :)
i2c:
void i2c_init (void) {
  RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
      
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  RCC->CFGR3 |= RCC_CFGR3_I2C1SW;
      
  GPIOB->AFR[0] |= (1<<(4*6)) |(1<<(4*7));
  GPIOB->MODER &= ~(GPIO_MODER_MODER6 |GPIO_MODER_MODER7);
  GPIOB->MODER |= (GPIO_MODER_MODER6_1 |GPIO_MODER_MODER7_1);
  GPIOB->OTYPER |=(GPIO_OTYPER_OT_6 |GPIO_OTYPER_OT_7);
  I2C1->TIMINGR = (uint32_t)0x00B01A4B;
  I2C1->CR1 = I2C_CR1_PE;
}

uint8_t i2c_write(uint8_t addr, uint8_t *data, uint8_t nbytes) {
  cntr = ttms;
  while(I2C1->ISR & I2C_ISR_BUSY) { if(ttms - cntr > I2C_TIMEOUT) return 0; }

  cntr = ttms;
  I2C1->CR2 = (nbytes << 16) | addr | I2C_CR2_AUTOEND | I2C_CR2_START; // autoend // now start transfer
  while(I2C1->CR2 & I2C_CR2_START) { if(ttms - cntr > I2CWAIT) return 0; }
    
  for(int i = 0; i < nbytes; ++i){
    cntr = ttms;
    while(!(I2C1->ISR & I2C_ISR_TXIS)){ if(ttms - cntr > I2CWAIT) return 0; }
    I2C1->TXDR = data[i]; // send data
  }
  while(I2C1->ISR & I2C_ISR_BUSY){ if(ttms - cntr > I2CWAIT) break; } // wait for data gone
  return 1;
}

uint8_t i2c_read(uint8_t addr, uint8_t *data, uint8_t nbytes) {
  cntr = ttms;
  while (I2C1->ISR & I2C_ISR_BUSY) { if(ttms - cntr > I2CWAIT) return 0; }
  cntr = ttms;
  while (I2C1->CR2 & I2C_CR2_START) { if(ttms - cntr > I2CWAIT) return 0; }
  // read N bytes
  I2C1->CR2 = (nbytes<<16) | addr | 1 | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN;
  I2C1->CR2 |= I2C_CR2_START;

  for (uint8_t i = 0; i < nbytes; ++i) {
    cntr = ttms;
    while (!(I2C1->ISR & I2C_ISR_RXNE)) { if(ttms - cntr > I2CWAIT) return 0; }
    *data++ = I2C1->RXDR;
  }
  return 1;
}

Запись/чтение в/из rda5807:
static uint8_t rda5807writeI2C(uint8_t nbytes) {
  cntr = ttms;
  I2C1->CR2 = (nbytes << 16) | RDA5807M_I2C_ADDR | I2C_CR2_AUTOEND | I2C_CR2_START;
  while(I2C1->CR2 & I2C_CR2_START) { if(ttms - cntr > I2C_TIMEOUT) return 0; }

  for (int i = 0; i < nbytes; ++i){
    cntr = ttms;
    while(!(I2C1->ISR & I2C_ISR_TXIS)) { if(ttms - cntr > I2CWAIT) return 0; };
    I2C1->TXDR = wrBuf[i]; // wrBuff[14]
  }
  
  while(I2C1->ISR & I2C_ISR_BUSY) { if(ttms - cntr > I2CWAIT) break; } // wait for data gone
  return 1;
}


uint8_t *rda580xReadStatus (void) {
  uint8_t i;
  i2c_read(RDA5807M_I2C_ADDR, rdBuf, sizeof(rdBuf));  //rdBuf[12];
  return rdBuf;
}

ds3231.h:
struct ds3231_calendar {
    uint8_t second;
    uint8_t minute;
    uint8_t hour;
    uint8_t dayWeek;
    uint8_t dayMonth;
    uint8_t month;
    uint8_t year;
};

#define DS3231_I2C_ADDR_WRITE                     (uint8_t)0xD0
#define DS3231_I2C_ADDR_READ                      (uint8_t)0xD1

#define DS3231_SEC_ADDR                           (uint8_t)0x0
#define DS3231_MIN_ADDR                           (uint8_t)0x1
#define DS3231_HOUR_ADDR                          (uint8_t)0x2
#define DS3231_DAY_WEEK_ADDR                      (uint8_t)0x3
#define DS3231_DAY_MONTH_ADDR                     (uint8_t)0x4
#define DS3231_MONTH_ADDR                         (uint8_t)0x5
#define DS3231_YEAR_ADDR                          (uint8_t)0x6
#define DS3231_A1M1_ADDR                          (uint8_t)0x7
#define DS3231_A1M2_ADDR                          (uint8_t)0x8
#define DS3231_A1M3_ADDR                          (uint8_t)0x9
#define DS3231_A1M4_ADDR                          (uint8_t)0xA
#define DS3231_CONTROL_ADDR                       (uint8_t)0xE
#define DS3231_CON_STAT_ADDR                      (uint8_t)0xF

void ds3231init();
void ds3231get(struct ds3231_calendar*);
void ds3231set(struct ds3231_calendar*);
ds3231.c:
void ds3231init() {
  uint8_t init[3] = {DS3231_CONTROL_ADDR, 0x0, 0x0};
  i2c_write(DS3231_I2C_ADDR_WRITE, init, 3);
}

// получение даты и времени из RTC
void ds3231get(struct ds3231_calendar* cal) {
  uint8_t date[7] = {0};
  uint8_t addr = 0;
  i2c_write(DS3231_I2C_ADDR_WRITE, &addr, 1);
  i2c_read(DS3231_I2C_ADDR_READ, date, 7);        
  cal->second=date[0];
  cal->minute=date[1];
  cal->hour=date[2];
  cal->dayWeek=date[3];
  cal->dayMonth=date[4];
  cal->month=date[5];
  cal->year=date[6];
}

// записать дату и время в RTC
void ds3231set(struct ds3231_calendar* cal) {
  uint8_t new_data[8] = {
    DS3231_SEC_ADDR, 
    cal->second,
    cal->minute,
    cal->hour,
    cal->dayWeek,
    cal->dayMonth,
    cal->month,
    cal->year
  };
  i2c_write(DS3231_I2C_ADDR_WRITE, new_data, 8);
}
ы. Напомню всё для F0 серии.

:: добавлено 05 Апр., 2023, 14:13
И 24c32/64:
Тут уже есть операция чтения страницы (не как в 24c16 только последовательное чтение).
addr тут кратен 32-ум.
uint8_t eeprom24c64pgread(uint16_t addr, uint8_t* buff, uint8_t nbytes) {
  I2C1->CR2 = (1 << 16) | I2C_CR2_START | (EEADDR << 1); // пишем 1 байт, старт, адрес ведомого
  while((I2C1->ISR & I2C_ISR_TXE) != I2C_ISR_TXE) {}; // ждем передачи

  I2C1->CR2 = (2 << 16) | (EEADDR << 1);
  while (!(I2C1->ISR & I2C_ISR_TXE)) {};
  cntr = ttms;
  I2C1->TXDR = (uint8_t) (addr >> 8); // Byte to send
  I2C1->CR2 |= I2C_CR2_START; // Go
  while (!(I2C1->ISR & I2C_ISR_TXIS)) { if(ttms - cntr > I2CWAIT) return 0; } // check start

  I2C1->TXDR = (uint8_t)(addr & 0x00FF); // Byte to send 
  while (!(I2C1->ISR & I2C_ISR_TC)) {};

  //          атостоп           
  I2C1->CR2 = I2C_CR2_AUTOEND | (nbytes<<16) | (EEADDR<<1) | I2C_CR2_RD_WRN | I2C_CR2_NACK;
  I2C1->CR2 |= I2C_CR2_START; // Go

  cntr = ttms;
  for (uint8_t i = 0; i <= nbytes - 1; i++) {
    while (!(I2C1->ISR & I2C_ISR_RXNE))  // wait for data
    if(ttms - cntr > I2CWAIT) { return 0; break; }
    buff[i]  = I2C1->RXDR ;
  }
  return 1;
}

uint8_t eeprom24c64pgwrite(uint16_t addr, uint8_t *buff, uint8_t nbytes) {
  I2C1->CR2 =  I2C_CR2_AUTOEND | ((2+nbytes)<<16) | (EEADDR<<1);
  while (!(I2C1->ISR & I2C_ISR_TXE)) {}; // TXE регистр данных передачи пуст (буфер передачи пуст) // Check Tx empty
   
  I2C1->TXDR =(uint8_t) (addr>>8); // младшая часть адреса страницы (при присвоении к 8-ми битной переменной, старший байт сам улетит)
  I2C1->CR2 |= I2C_CR2_START; // Go
      
  while (!(I2C1->ISR & I2C_ISR_TXIS)) {}; //TXIS
  I2C1->TXDR = (uint8_t)(addr & 0x00FF); // старшая часть адреса страницы
  
  cntr = ttms;
  for (uint8_t i = 0; i <= nbytes - 1; i++) {
    while (!(I2C1->ISR & I2C_ISR_TXIS)) //TXIS // ждем пока TXDR станет пустым и готовым к новым данным
    if(ttms - cntr > I2CWAIT) return 4;  // return 0;  // check busy
    I2C1->TXDR = buff[i] ; // Byte to send
  }
  return 1;
}
ыы. Да, пободаться i2c в stm32 заставил... зато сейчас вроде как всё встало на свои места. :)
https://github.com/minamonra/

Slabovik

Синтезаторы можно попробовать TEA7001, TSA6057. Правда, они довольно старые и и надо пятивольтовое питание. А вот по логическим уровням SDA SCL трёхвольтовое управление должно вроде вписаться, при условии, что управляющие сигналы КМОП-уровней (с этим у STM проблем нет - они КМОП от рождения). Надо только подумать (а лучше почитать), как их к радиочасти прикрутить. Но там не сложно, можно использовать и микросхемы "всё а одном". Отличие только в том, что настройкой гетеродинного контура будет синтезатор управлять, подавая напряжение на его варикапы, а не пользователь.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#18
Самые доступные сейчас модули на Si5351A. AD9834 как-то не для экспериментов.
А аналоговая часть?
Сейчас поглядываю на SI4735... Ещё FMdx хочу понять что из себя представляет, пощупать надо этот TEF.
ы. Зашёл на гитхаб поиск по TEF6686 выдал кучу результатов, что уже радует.
https://github.com/minamonra/

Slabovik

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

Цифровая же микросхема - это всё внутри, обработка тоже цифровая. Управлять просто, а как оно внутри.... тут мои знания дают пробел. По крайней мере я точно знаю, что повлиять на то, что внутри, уже не получится...
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#20
Цитата: Slabovik от 06 Апр., 2023, 17:43Я цифровых приёмников до сих пор не собирал совсем.
Будем пробовать 4735?
Сегодня заказал на пробу тут (https://aliexpress.ru/item/1005003147639640.html?spm=a2g2w.orderdetail.0.0.4ce34aa6BG8jFW&sku_id=12000024356825873).
Из МК думаю расчехлить из новых какой-нибудь G030/G070.
Дисплеи есть 1.77TFT (https://aliexpress.ru/item/1005001621932172.html?spm=a2g2w.orderdetail.0.0.6b564aa6rQa79R&sku_id=12000018917906810).
ы. Набрёл на статью в хакере (https://xakep.ru/2021/07/22/diy-si473x/).

:: добавлено 07 Апр., 2023, 17:22
Добавлю схему и проект в segger на текущий проект.
Многое не оптимально, есть функции которые только для эксперимента.
Управление только с пульта (с энкодером ещё предстоит разобраться), установка времени по длинному нажатию utf, добавление в память станций по длинному mode.
Программу управления дисплей+пульт писал впервые, поэтому вышло не айс, но работает, надо бы переделать получше обдумав алгоритм, но пока так.
Работает норм, станции с кнопок 0...9 (можно расширить до двухзнаков, но не знаю), вкл/выкл баса, mute, настройка на частоту ручная.
rds естественно нет, куда ж его выведешь в данном исполнении? :)
f031_radioclock - проект в KiCad.
z137rcc - проект в Segger.
https://github.com/minamonra/

Slabovik

#21
Чувствую, что я за тобой просто не успею...
зы: а Хакер не даёт прочитать статью полностью :(
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#22
:)  ;)
Прицепил статью.

:: добавлено 12 Апр., 2023, 21:58
https://github.com/minamonra/

zenon

Доехал до меня модуль PCF8563, убираю не глядя DS2331, подключаю новый...
Пытаюсь запустить... ну блин лажа какая-то... ну нет чтобы на адреса посмотреть... у 24C16 они уже заняты (0xA3 и 0xA2), так ещё она и припаяна под индикатором и просто так её не снять.. Пришлось пока обратно всё верстать.
Да, разводка у этого китайского модуля не очень, часовой кварц не припаян к массе и дороги как антенны.
https://github.com/minamonra/

zenon

Фильтр который был спаян навесом показал себя хорошо, на столе заметно уменьшились помехи от всего импульсного.
Реализация взята отсюда (http://dedclub.blogspot.com/2018/02/fm-875-108.html).
Схема радио-часов сейчас приобретает такой вид:
https://github.com/minamonra/

Slabovik

Фильтр - это реально нужная штука. Фильтр на LC - одобряю. Для ленивых могу рекомендовать кварцевые полосовые фильтры, но результат хуже, чем при настроенном LC (но намного лучше, чем при не настроенном). Чуток ликбеза: https://www.changpuak.ch/electronics/ceramic_bandpass_filter (https://www.changpuak.ch/electronics/ceramic_bandpass_filter.php)

Вот, например LPF88 (https://www.endrich.com/sixcms/media.php/2/Ceramic%20.pdf), его можно купить, но дороговат. Murata'вские заметно дешевле, но я забыл название... нашёл, правда другой. Написано на нём BP87108...
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#26
Надо подумать насчёт готового фильтра...
Но тут если хочется добротности при ручном изготовлении - размеры сразу больше.
Оттуда же где и фильтр решил попробовать интересную схему с усилителем.
Транзистор малошумящий надо поискать BFR181 не знаю найду или нет.
В общем чуть ещё переделал схему.
Регулировка громкости у RDA5807 реально забодала как и щелчки при вкл/выкл.
Вопрос Q3, Q4 перебросить на выход PT2257 или так оставить?
https://github.com/minamonra/

Slabovik

По-хорошему, надо коммутатор ставить. 74HC4056 (561КП1), 74HC4066 (561КТ3) и т.п.
В качестве дешёвого решения можно применить маломощные J-fet, но напряжение управления должно быть достаточно высокое т.к. у них будет эффект модуляции сопротивления канала от напряжения на истоке. Он не страшен, когда сопротивление закрытого канала >> сопротивления шунтируемого источника, но эффект вносит (в виде искажений).

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

zenon

#28
Да, при включении "mute" щелчков нет. Только при вкл/выкл приёмника (посылка = RDA580X_ENABLE / &= ~RDA580X_ENABLE).
А громкость родная у него при каждом изменении сначала приглушается почти до минимума, потом выставляется на заданную громкость, именно это причина по которой думаю поставить PT2257.
ы. R24/R25 для измерения напряжения питания, если будет аккумулятор то не помешает, ещё тогда на всю периферию ключ на выкл питания неплохо добавить.
ыы. По-хорошему надо переразвести, схема уже изменялась не один раз, но наверное сделаю такой вариант, и ещё помучаю её. :)
Плата 165x67.
https://github.com/minamonra/

zenon

#29
↓ спойлер ↓
[свернуть]
Забыл совсем поменять транзисторы на те, которые советовал, а у полевиков в sot-23 другая цоколёвка.
На прикрепленной плате уже всё правильно, только разъём SMA не точно, у меня их ещё нет.
Транзистор в антенном усилителе BFR93 стоит (при номиналах на схеме потребляет 2-3мА, питание 2S лития), на самом деле не понятна эффективность усилителя, а вот фильтров - однозначно.
На даче попробую.
https://github.com/minamonra/

zenon

#30
Приехали китайские HT16K33, я так понимаю VK16K33 это их копия, информация о такой не гуглится.
Сам индикатор 14 пин, те, по идее должны быть и точки и двоеточие (0,56"). Правда индикатор красный.
Второй 14 сегментов размер 0,54", но для часов двоеточия нет, взял посмотреть, как в живую смотрятся, свечение оранжевое.
Вариант платы под это дело получается примерно такой.
https://github.com/minamonra/

zenon

О, забыл отчитаться, вариант с антенным усилителем и фильтром на даче показал прекрасные результаты, - уверенно поймал всё что можно в FM диапазоне.
Так что я доволен. Рядом бумбокс Panasonic половину станций ловит неуверенно и постоянно приходится вертеть антенну, а на моём - кусок провода.

https://github.com/minamonra/

zenon

Ну а как там приёмникостроение?
Вот так.
Верхний без фильтра, индикатор TM1637.
Нижний с фильтром на двух ОУ, индикатор HT16K33. Плюс УНЧ (ещё не запаял, на плате он на нижнем слое меди).
Программатор сейчас использую DAP Link, бонусом на его борту USART, удобно. Segger его понимает сразу как J-Link.
Никак не могу придумать алгоритм управления с кнопок, те сам код есть, а вот как сделать управление удобным - тут завис.
Пока четыре кнопки частота/громкость в режиме 0, пятая "режим" по кругу 0..X длинное нажатие, короткое отображает режим на пару секунд.
//
Вот тут кстати (https://count-zero.ru/2022/debugger/) хорошо про отладчики написано.
ы. Просьба название темы, если можно переименовать в что-то типа RDA5807, всё равно тут в основном вокруг неё, пробовал si4703 уже, но думаю лучше в отдельную тему.
https://github.com/minamonra/

zenon

Включил с усилителем, - ну я ждал этого честно говоря... Гудит индикатор (HT16K33) по питанию сильно.
Сообразил фильтр, навесом пока, на 100 мкГн индуктивностях (готовые размер 1210 smd (https://aliexpress.ru/item/32981310345.html?spm=a2g2w.orderdetail.0.0.339f4aa6xjXiOY&sku_id=66768777151)).
Стало лучше, но всё-равно в наушниках, если убрать громкость в 0 - слышен гул ШИМ.
LM4863 тоже сидит на 7805 стабилизаторе, я как-то не сразу сообразил что 2S литий её прибьёт. :)
https://github.com/minamonra/

Slabovik

У 2S напряжение маловато, чтобы 7805 питать, ибо ей нужно довольно большое превышение напряжения для нормальной работы (если правильно помню, там минимум вольта полтора). Надо хотя бы что-либо типа LM317 (ЕН21/ЕН22).

Индуктивность в земляном проводе imho лишняя. Возможно, индикатор через отдельный стабилизатор запитать было бы неплохо, а индуктивность расположить перед стабилизатором. В таком случае её можно сделать побольше. Не смотрел осликом, на какой частоте помеха идёт? Если частота низкая, индуктивность нужна большая.

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

А не смотрел, какой уровень сигнала (размах) выходит с RDA?

И ещё.... возможно, помеха пролазит через R58-R60 (R59-R61). Попробуй сделать развязку, как у меня в оригинале.

p.s. А 4863 она вообще на 1S рассчитана, даже 6 вольт ей скорее всего смерть...
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#35
У меня 78M05 прижилась, потому как их лента целая в TO-252 (DPAK).
Так-то надо два напряжения 3,3 и 5 для индикатора.
Отдельный стабилизатор для индикатора я пробовал (плюс в точку подключения питания к плате), она (помеха) по земле где-то виляет...
Надо минус тоже попробовать так же, ну и перед LM-кой тоже фильтр + посмотреть что с минусом.
Частота довольно низкая, на слух герц 100.
Посмотреть надо попробовать.

:: добавлено 29 Май, 2023, 17:26
Цитата: Slabovik от 29 Май, 2023, 15:45Попробуй сделать развязку, как у меня в оригинале.
Упс, не вижу как.  :(
А, конденсаторы параллельно R58, R59 по моей схеме?
https://github.com/minamonra/

Slabovik

Примерно вот так

R6R12.png

резисторы R6 R12 делают делитель и совместно с C5 фильтр с частотой среза герц на 12 (надо меньше - увеличь резисторы, скажем, до 22 кОм, либо конденсатор).

А попробуй оторвать землю индикатора и подсоединить в точке питания всей схемы. Чтобы ток через полигон не шёл, вихляясь. Ну, или поискать точку подключения...
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Да, землю индикатора оторвал, всё равно слышу.
Самый лучший вариант пока - две трухольных индуктивности нашёл по 2 мГн и между ними ёмкость на 100 мкФ, почти не слышно, но чуть есть.... блин...
https://github.com/minamonra/

Slabovik

Там скорее всего комплекс мер надо. Я посмотрел разводку. Земля просто полигоном налита. Полигон надо делить, чтобы узлы сидели на своих кусках, не пересекаясь токами. С питанием в общем-то то же самое, но тут проще - его можно отделять резисторами малого сопротивления и индуктивностями. С индуктивностями тоже может быть фишка - они умеют наводить наводку друг на друга, что при неудачном взаиморасположении тоже даст эффект (можно вспомнить АрВид-1051).

Шину I2C смотрел осликом. Не звенит, случаем? Данные по ней изредка гоняешь, или постоянно? Если есть звон, тоже надо отделять. Звон гасится резисторами малого сопротивления в цепь и конденсаторами малой ёмкости (тут могу посоветовать глянуть схемы всяких клавиатур или PC-портов - там эти меры применяются).

А вообще, чисто цифровые схемы не критичны к разводке земли, но вот когда дело касается аудио - встаёт в полный рост :)
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Ха, "комплекс мер" помог.
Отдельный стабилизатор 78M05 + 2 индуктивности (без земляной), и отрыв земли индикатора, идеальная тишина, учитывая задранный Кус у LM (20k/20k надо, я для попробовать поставил 10k/20k).
Вот, по поводу УНЧ - тут я его не планировал, второй этаж хотел сделать, но взгляд упал на LM, которые валялись без дела пару лет, ну а почему бы не добавить его для ушей, тем более качество у него достойное.
А второй этаж в виде пары модулей D класса может быть.
https://github.com/minamonra/

zenon

#40
Разбираюсь потихоньку с кнопками, энкодером.
Добавил измерение напряжения питания. АЦП в STM - те ещё приключения.
Читаю АЦП медленно, при включении на видео видно наполнение массива АЦП (10).
Верх-право платы то самое временное решение от фона.
HT16K33 для совместимости подключил на ногодрыгательную линию I2C, на плату можно установить либо TM1637 модуль, либо этот.
Те, один I2C у меня хардварный, другой через паузы.
На крайней схеме энкодер не правильно подключен. Его выход "C" надо на землю посадить, я его по ошибке к PB1 подключил, но это плюс ещё одна свободная нога, как раз можно на выключение питания.
↓ спойлер ↓
[свернуть]
https://github.com/minamonra/

zenon

Продолжил пытаться разобраться с Qucs-s, нашёл примеры, которые идут с программой, подглядывая в примеры, а в частности в "Signetics NE520 broadband amplifier", нарисовалась модель фильтра, что прикручивал к приёмнику, честно говоря интерпретировать не совсем получается.
В общем вот.
https://github.com/minamonra/

Slabovik

Для начала хорошо бы узнать, как ты сам интерпретируешь это. Что за измерения производишь и что ожидаешь, почему?
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#43
Пики, это же резонансы фильтров, так?
А вот почему на входе у меня сигнал по форме похож на усииленный v.Out?
Задача стояла ослабить всё что ниже и выше вещательного FM диапазона.
На сколько хорошо это получилось смоделировать/воплотить?
ы. Воплотить-то конечно только косвенно можно проверить без анализатора спектра :_), хотя можно генератор+вольтметр попробовать.
По самому моделированию становиться понятно, как легко уйти из хотелок, индуктивности надо довольно точно соблюсти, а такую мелюзгу ещё умудриться надо измерить.
ыы. Попутно узнал о NE5204, и кстати искали низковольтный ОУ, NE5230 от 1,8 вольт работает, плюс малошумящий.
ыыы. О забыл спросить роль L4C5?
https://github.com/minamonra/

Slabovik

Ну, по порядку.
По схеме. 13 витков и 2 витка - мне видится, что разница в индуктивностях поболее будет. Но тут могу быть не прав, конечно, это я чисто на глаз...

R6, C7, C5, L4 роли не играют и могут быть удалены вовсе. Если очень хочется поиграться с DC, R6 и конденсатор один можно оставить, как на исходной схеме, 0.1 где-нибудь.

По процессу. Тут вообще много взаимовлияющего, из-за чего сложно ориентироваться. Рекомендую для начала отцепить транзистор и подать сигнал на левый вывод C4, посмотреть, что там получится. Выходное сопротивление генератор конечно надо сделать хотя бы примерно равным выходному сопротивлению каскада на транзисторе.

Второй этап - то же самое сделать с входными цепями, но выход смотреть на их выходе - базе транзистора.

Ну и третье - соединить уже воедино.

Самое неприятное - в реальности будет ещё и взаимовлияние катушек и всего остального, но считать это всё-равно, что на квасу гадать.

Если показывает вот это, что у тебя, значит, моделька таки работает. Два острых резонансных пика, похоже работаю на входном каскаде резонаторов т.к. на этих частотах "нули" на In. Полоса вполне, усиление есть
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

На счёт генератора - не понял как сделать, поудалял, отцепил, у самого фильтра полоса такая примерно же вышла.
График в децибелах информативнее выглядит.
https://github.com/minamonra/

Slabovik

Ага, всё верно. Вот в такой конфигурации можно поиграться с номиналами элементов, чтобы посмотреть, что на что влияет.
Резонансных частоты две - это да, но ведь и контур там не один.
Первый резонанс похоже последовательный - на его частоте просадка Vin, второй параллельный - там подъём, но рядом тоже ещё пик просадки, чуть выше по частоте.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

#47
И по сути пришли к
ы. Раз уж начал, посмотрел и первый вариант собранного фильтра.
По сути такие изыски наверное не очень нужны, для нынешних условий, для FM приёмника хватит отсечь всё, что ниже 60-70 МГц.
https://github.com/minamonra/

Slabovik

Ммм. Не знаю. Мы же вроде хотели модель посмотреть и понять, что на что и как влияет... Не?
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Ну да, это я что-то не в ту сторону пойдём... :_)
По первой схеме (filtr+amp-FM_v01) три вопроса
1. C1C2C3L1L2L3
2. L4C5R5
3. R3
+++
Тут вот какая опция есть, если по правому щелчку деактивировать компонент, то первый раз (красное перекрести) он исключается из моделирования, если ещё раз нажать - зелёное перекрестие - замыкаются его выводы.
И вот второй скрин, при удалении L4 усиления нет?
https://github.com/minamonra/

Slabovik

Честно говоря, я не понял, в чём вопрос с C1 C2 C3 etc...

А когда коллектор транзистора, с которого должен сниматься усиленный сигнал, замкнут через источник питания на землю, вполне логично, что усиления не будет. Сигнала-то нет...

Не, вообще конечно C1, C2 C3 - это три связанных между собой контура, чертовски сильно взаимовлияющих друг на друга.

И да, L4 всё-таки рекомендую не ставить. Там в оригинале в коллекторе резистор один. Усиление меньше, но и проблем меньше. На таких частотах взаимовлияние ппц какое сильное, особенно для близкорасположенных проводников. Ну хотя бы прикинь Z для ёмкости 1 пФ...
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

L4 немного выравнивает АЧХ при симуляции, влияния L3 практически нет.
Ну C1, C3 если еще более менее понятно - развязывают по постоянному, а L1L2C2?
R5 сразу не уведел, что это часть усилительного каскада.
R3-то зачем?
https://github.com/minamonra/

Slabovik

Ну, я попробую ещё раз намекнуть, что при плотном монтаже ты настолько офигеешь о того, что компоненты вдруг неожиданно не только "ушли" по параметрам, но ещё и имеют огромное взаимовлияние друг на друга, что ни о какой "коррекции ачх" уже и думать не будешь. Желание будет только одно - хоть как-то поднастроить, чтобы оно хотя бы работало. Вот для этой ситуации и нужно понимание, какой компонент за какой полюс отвечает, чтобы при настройке знать, какой конденсатор крутить и какую катушку в какую сторону раздвигать.

Здесь R6 работает только для обеспечения ООС каскада по постоянному току. Чтобы транзистор при смене комнаты на улицу и обратно из режима не вываливался. Коллекторная нагрузка по переменному току - резистор R5, он же обеспечивает согласование с последующим каскадом контуров. Ну хотя бы приблизительное... Хочешь корректировать индуктивностями - будь добр обеспечить согласование. Нет согласования - получаешь непонятку. Хочешь большее усиление - на тебе обратку с виде неопознанной ёмкостно-индуктивной связи от катушки L4 в х.з. куда...

И т.д....

А R3 уменьшает добротность контура, чтобы он звенел меньше и всё хозяйство было больше похоже на полосовой фильтр, а не на частотный, т.е. на одну частоту.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Не, я намёк понял, я же говорил про модель.
Остаётся вопрос, почему каскад усиления сначала, а не после фильтра.
https://github.com/minamonra/

Slabovik

Потому что здесь два фильтра.
Транзистор компенсирует потерю сигнала в них.
Между поставить удобнее всего, потому что первый равномерно нагружен, второй правильно питается.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Ну тогда можно так оставить?
Для стационарного использования лучше сообразить простейщий диполь из двух кусков по 75см и около них поставить.
С платы приёмника лучше уберу.
Тут ещё пару вариантов на глаза попались.
http://electronics-diy.com/vhf-fm-antenna-booster.php
https://www.robkalmeijer.nl/techniek/electronica/radiotechniek/hambladen/hr/1986/09/page30/index.html
https://github.com/minamonra/

Slabovik

Ну да.
По-хорошему, чтобы настраивать эти штуки, АЧХометр надо сооружать. Или найти что-нибудь. Вот такой (https://chaplin-lounge.ru/pribor-h1-7-shema-harakteristiki/) был у меня. И сейчас есть, только работать перестал. Радиотракты очень удобно настраивать - всё видно. А иначе совершенно непонятно, что и куда крутить, т.к. на слух вообще ничего не очевидно, тем более, что АРУ в тракте...
И радиочастотные цепи делить, каждый каскад в свой кузов экранированный. Иначе они друг на друга светят, и наводка прямо с эфира на тракт тоже идёт. Именно по этой причине сейчас бытовые радиоприёмники на АМ в городе вообще не работают - уровень помех такой, что наводками забивает тракт ПЧ, не говоря уже о входных цепях.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

zenon

Можно попробовать как-нибуть способ с детекторной головкой.
Ради интереса набросал схему с ОБ, потом вспомнилось, по току-то передача никакая (точнее сначала увидел, что при высокоомной нагрузке всё ок, уменьшаешь - нет), ну и повторитель туда, нуууу .... каракули в общем :_)
https://github.com/minamonra/

Slabovik

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