Генерировать все частоты от 5 до 8 кГц с шагом 1 Гц
Можно ли генерировать все частоты в диапазоне от 5000 до 8000 Гц с интервалом в 1 Гц с помощью ATmega328? Когда я создаю программу на языке C вне среды Arduino IDE для расчета частот с помощью формулы, приведенной в техническом описании, я пропускаю несколько частот, в верхней части с разницей в 4 Гц.
Есть ли какой-нибудь трюк, чтобы получить лучшее разрешение?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
// ICR = ( FCPU / ( prescaler * desiredFrequency ) ) - 1
// desiredFrequency = FCPU / ( (ICR1 + 1) * prescaler );
int main() {
FILE *fp = fopen( "/home/somebody/Desktop/freqlist.txt", "w+" );
uint32_t freq_found[3000];
int p = -1;
int found;
uint32_t FCPU = 16000000;
uint32_t prescalers[] = { 1, 8, 64, 256, 1024 };
fprintf( fp, "ICR1\tPresc.1\tFreq.Timer1\n" );
for( uint32_t ptr1 = 0; ptr1 < 5; ptr1++ ) { // pointer to prescalers array for timer1
for( uint32_t ICR1 = 0; ICR1 < 65536; ICR1++ ) {
uint32_t F1 = FCPU / ( ( ICR1 + 1 ) * prescalers[ptr1] );
if( F1 >= 5000 && F1 <= 8000 ) { // required frequency range between 5000 and 8000 Hz
found = 0;
for( int i = p; i > -1; i-- ) {
if( F1 == freq_found[i] ) { // found in array
found = 1;
break;
}
}
if( ! found ) {
printf( "%d ", F1 );
fprintf( fp, "%d\t%d\t%d\n", ICR1, prescalers[ptr1], F1 );
freq_found[++p] = F1;
}
}
}
}
fclose( fp );
return 0;
}
Вот рассчитанные частоты, всего 1200:
8000 7996 7992 7988 7984 7980 7976 7972 7968 7964 7960 7956 7952 7948 7944 7940 7936 7932 7928 7924 7920 7916 7912 7909 7905 7901 7897 7893 7889 7885 7881 7877 7874 7870 7866 7862 7858 7854 7850 7846 7843 7839 7835 7831 7827 7823 7820 7816 7812 7808 7804 7801 7797 7793 7789 7785 7782 7778 7774 7770 7766 7763 7759 7755 7751 7748 7744 7740 7736 7733 7729 7725 7722 7718 7714 7710 7707 7703 7699 7696 7692 7688 7684 7681 7677 7673 7670 7666 7662 7659 7655 7651 7648 7644 7640 7637 7633 7629 7626 7622 7619 7615 7611 7608 7604 7600 7597 7593 7590 7586 7582 7579 7575 7572 7568 7565 7561 7557 7554 7550 7547 7543 7540 7536 7532 7529 7525 7522 7518 7515 7511 7508 7504 7501 7497 7494 7490 7487 7483 7480 7476 7473 7469 7466 7462 7459 7455 7452 7448 7445 7441 7438 7434 7431 7428 7424 7421 7417 7414 7410 7407 7403 7400 7397 7393 7390 7386 7383 7380 7376 7373 7369 7366 7363 7359 7356 7352 7349 7346 7342 7339 7336 7332 7329 7326 7322 7319 7315 7312 7309 7305 7302 7299 7295 7292 7289 7285 7282 7279 7276 7272 7269 7266 7262 7259 7256 7252 7249 7246 7243 7239 7236 7233 7230 7226 7223 7220 7216 7213 7210 7207 7203 7200 7197 7194 7191 7187 7184 7181 7178 7174 7171 7168 7165 7162 7158 7155 7152 7149 7146 7142 7139 7136 7133 7130 7126 7123 7120 7117 7114 7111 7107 7104 7101 7098 7095 7092 7089 7085 7082 7079 7076 7073 7070 7067 7064 7060 7057 7054 7051 7048 7045 7042 7039 7036 7032 7029 7026 7023 7020 7017 7014 7011 7008 7005 7002 6999 6996 6993 6989 6986 6983 6980 6977 6974 6971 6968 6965 6962 6959 6956 6953 6950 6947 6944 6941 6938 6935 6932 6929 6926 6923 6920 6917 6914 6911 6908 6905 6902 6899 6896 6893 6890 6887 6884 6881 6878 6875 6872 6869 6866 6864 6861 6858 6855 6852 6849 6846 6843 6840 6837 6834 6831 6828 6825 6823 6820 6817 6814 6811 6808 6805 6802 6799 6796 6794 6791 6788 6785 6782 6779 6776 6773 6771 6768 6765 6762 6759 6756 6753 6751 6748 6745 6742 6739 6736 6734 6731 6728 6725 6722 6719 6717 6714 6711 6708 6705 6702 6700 6697 6694 6691 6688 6686 6683 6680 6677 6675 6672 6669 6666 6663 6661 6658 6655 6652 6650 6647 6644 6641 6639 6636 6633 6630 6628 6625 6622 6619 6617 6614 6611 6608 6606 6603 6600 6597 6595 6592 6589 6587 6584 6581 6578 6576 6573 6570 6568 6565 6562 6560 6557 6554 6552 6549 6546 6543 6541 6538 6535 6533 6530 6527 6525 6522 6519 6517 6514 6512 6509 6506 6504 6501 6498 6496 6493 6490 6488 6485 6482 6480 6477 6475 6472 6469 6467 6464 6462 6459 6456 6454 6451 6449 6446 6443 6441 6438 6436 6433 6430 6428 6425 6423 6420 6417 6415 6412 6410 6407 6405 6402 6400 6397 6394 6392 6389 6387 6384 6382 6379 6377 6374 6371 6369 6366 6364 6361 6359 6356 6354 6351 6349 6346 6344 6341 6339 6336 6334 6331 6329 6326 6324 6321 6319 6316 6314 6311 6309 6306 6304 6301 6299 6296 6294 6291 6289 6286 6284 6281 6279 6276 6274 6272 6269 6267 6264 6262 6259 6257 6254 6252 6250 6247 6245 6242 6240 6237 6235 6232 6230 6228 6225 6223 6220 6218 6216 6213 6211 6208 6206 6203 6201 6199 6196 6194 6191 6189 6187 6184 6182 6179 6177 6175 6172 6170 6168 6165 6163 6160 6158 6156 6153 6151 6149 6146 6144 6142 6139 6137 6134 6132 6130 6127 6125 6123 6120 6118 6116 6113 6111 6109 6106 6104 6102 6099 6097 6095 6092 6090 6088 6085 6083 6081 6079 6076 6074 6072 6069 6067 6065 6062 6060 6058 6056 6053 6051 6049 6046 6044 6042 6040 6037 6035 6033 6030 6028 6026 6024 6021 6019 6017 6015 6012 6010 6008 6006 6003 6001 5999 5997 5994 5992 5990 5988 5985 5983 5981 5979 5976 5974 5972 5970 5967 5965 5963 5961 5959 5956 5954 5952 5950 5947 5945 5943 5941 5939 5936 5934 5932 5930 5928 5925 5923 5921 5919 5917 5914 5912 5910 5908 5906 5904 5901 5899 5897 5895 5893 5891 5888 5886 5884 5882 5880 5878 5875 5873 5871 5869 5867 5865 5862 5860 5858 5856 5854 5852 5850 5847 5845 5843 5841 5839 5837 5835 5833 5830 5828 5826 5824 5822 5820 5818 5816 5813 5811 5809 5807 5805 5803 5801 5799 5797 5795 5792 5790 5788 5786 5784 5782 5780 5778 5776 5774 5772 5769 5767 5765 5763 5761 5759 5757 5755 5753 5751 5749 5747 5745 5743 5740 5738 5736 5734 5732 5730 5728 5726 5724 5722 5720 5718 5716 5714 5712 5710 5708 5706 5704 5702 5700 5698 5695 5693 5691 5689 5687 5685 5683 5681 5679 5677 5675 5673 5671 5669 5667 5665 5663 5661 5659 5657 5655 5653 5651 5649 5647 5645 5643 5641 5639 5637 5635 5633 5631 5629 5627 5625 5623 5621 5619 5617 5616 5614 5612 5610 5608 5606 5604 5602 5600 5598 5596 5594 5592 5590 5588 5586 5584 5582 5580 5578 5576 5574 5572 5571 5569 5567 5565 5563 5561 5559 5557 5555 5553 5551 5549 5547 5545 5544 5542 5540 5538 5536 5534 5532 5530 5528 5526 5524 5522 5521 5519 5517 5515 5513 5511 5509 5507 5505 5503 5502 5500 5498 5496 5494 5492 5490 5488 5486 5485 5483 5481 5479 5477 5475 5473 5471 5470 5468 5466 5464 5462 5460 5458 5457 5455 5453 5451 5449 5447 5445 5444 5442 5440 5438 5436 5434 5432 5431 5429 5427 5425 5423 5421 5420 5418 5416 5414 5412 5410 5409 5407 5405 5403 5401 5399 5398 5396 5394 5392 5390 5389 5387 5385 5383 5381 5379 5378 5376 5374 5372 5370 5369 5367 5365 5363 5361 5360 5358 5356 5354 5352 5351 5349 5347 5345 5344 5342 5340 5338 5336 5335 5333 5331 5329 5328 5326 5324 5322 5320 5319 5317 5315 5313 5312 5310 5308 5306 5305 5303 5301 5299 5298 5296 5294 5292 5291 5289 5287 5285 5284 5282 5280 5278 5277 5275 5273 5271 5270 5268 5266 5264 5263 5261 5259 5257 5256 5254 5252 5251 5249 5247 5245 5244 5242 5240 5239 5237 5235 5233 5232 5230 5228 5227 5225 5223 5221 5220 5218 5216 5215 5213 5211 5210 5208 5206 5204 5203 5201 5199 5198 5196 5194 5193 5191 5189 5188 5186 5184 5183 5181 5179 5177 5176 5174 5172 5171 5169 5167 5166 5164 5162 5161 5159 5157 5156 5154 5152 5151 5149 5148 5146 5144 5143 5141 5139 5138 5136 5134 5133 5131 5129 5128 5126 5124 5123 5121 5120 5118 5116 5115 5113 5111 5110 5108 5106 5105 5103 5102 5100 5098 5097 5095 5093 5092 5090 5089 5087 5085 5084 5082 5080 5079 5077 5076 5074 5072 5071 5069 5068 5066 5064 5063 5061 5060 5058 5056 5055 5053 5052 5050 5048 5047 5045 5044 5042 5040 5039 5037 5036 5034 5033 5031 5029 5028 5026 5025 5023 5021 5020 5018 5017 5015 5014 5012 5010 5009 5007 5006 5004 5003 5001 5000
@hennep, 👍1
1 ответ
Я предполагаю, что вы используете ATmega как в Arduino, т.е. тактируется на частоте 16 МГц.
Во-первых, нет смысла использовать другое значение делителя частоты, кроме
×1. Единичный предделитель частоты обеспечивает наилучшее временное разрешение.
(разрешение одного цикла) и с 16-битным таймером может дать вам
частота всего лишь F_CPU/216 ≈ 244 Гц.
Далее, вам нужно помнить, что, поскольку микроконтроллер В данном случае время изменяется дискретными шагами, равными одному циклу ЦП. Затем вы нужно преобразовать желаемые частоты в количество тактов процессора. Четыре диапазон, который вас интересует, преобразования дают:
| частота (Гц) | период (мкс) | Циклов ЦП |
|---|---|---|
| 5000 | 200.000 | 3200.00 |
| 5001 | 199.960 | 3199.36 |
| ... | ||
| 7999 | 125.016 | 2000.25 |
| 8000 | 125.000 | 2000.00 |
Большинство этих частот потребовали бы определенного количества циклов ЦП, не целое число. Микроконтроллер не может этого сделать. Мы можем спросить вопрос в обратном направлении: в заданном диапазоне тактов ЦП (от 2000 до 3200), какие частоты можно достичь:
| Циклов ЦП | период (мкс) | частота (Гц) |
|---|---|---|
| 2000 | 125.000 | 8000.00 |
| 2001 | 125.063 | 7996.00 |
| ... | ||
| 3199 | 199.938 | 5001.56 |
| 3200 | 200.000 | 5000.00 |
Это примерно то, что дала вам ваша программа, с парой дополнительных цифры для частот.
Тем не менее, если вас не смущает небольшая нервозность, вы можете
достичь произвольных средних частот. Например, если вы сохраните
период таймера в 2000 циклов ЦП (ICR1 = 1999) для трех циклов таймера,
затем вы устанавливаете его на 2001 цикл ЦП для одного цикла таймера, затем повторяете...
В итоге вы получаете средний период 2000,25 циклов ЦП, что является
Частота почти точно 7999 Гц. Эта схема может быть реализована
обновление ICR1 в рамках ISR(TIMER1_OVF_vect).
Редактировать: Вот реализация этой схемы. Идея в том, чтобы написать
вниз по периоду сигнала как 32-битное число в единицах
2−16 тактов ЦП (наш «квант времени», около 0,95 пс).
Старшие 16 бит (целое число циклов ЦП) используются для установки ICR1.
Нижние 16 бит добавляются в аккумулятор в каждом периоде сигнала.
Когда аккумулятор достигает 216 (что соответствует полному
(цикл ЦП) мы увеличиваем длительность этого цикла сигнала на один цикл ЦП. Это
дает разрешение по частоте в десятки микрогерц:
| кванты времени | Циклов ЦП | период (мкс) | частота (Гц) |
|---|---|---|---|
| 131072000 | 2000.000000 | 125.000000000 | 8000.000000 |
| 131072001 | 2000.000015 | 125.000000954 | 7999.999939 |
| ... | |||
| 209715199 | 3199.999985 | 199.999999046 | 5000.000024 |
| 209715200 | 3200.000000 | 200.000000000 | 5000.000000 |
Вот реализация:
volatile uint32_t signal_period; // единица измерения: 1/(F_CPU*2^16)
ISR(TIMER1_OVF_vect)
{
static uint16_t accumulator;
uint32_t this_period = signal_period + accumulator;
ICR1 = (this_period >> 16) - 1;
accumulator = this_period; // усечено до 16 бит
}
static void set_frequency(float f)
{
uint32_t period = round(F_CPU * 65536.0 / f);
uint16_t ocr1a = (period >> 17) - 1;
noInterrupts();
signal_period = period;
OCR1A = ocr1a;
interrupts();
}
Обратите внимание, что фактическое разрешение по частоте здесь ограничено float
Тип данных примерно до 0,5 МГц. И точность ограничена гораздо сильнее.
значительно керамический резонатор тактирует Arduino.
И тестовый код:
void setup()
{
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
set_frequency(5000); // установить начальную частоту
ICR1 = (signal_period >> 16) - 1;
DDRB |= _BV(PB1); // PB1 = контакт 9 как выход
TIMSK1 = _BV(TOIE1); // включить прерывание TIMER1_OVF
TCCR1A = _BV(COM1A1) // неинвертирующий ШИМ на OC1A = PB1 = вывод 9
| _BV(WGM11); // режим 14: быстрый ШИМ, TOP = ICR1
TCCR1B = _BV(WGM12) // то же самое...
| _BV(WGM13) // то же самое...
| _BV(CS10); // тактовая частота F_CPU
// Немного остроумия, затем измени частоту.
delay(2000);
set_frequency(7998);
}
void loop() {}
- Генерация стабильной частоты
- Таймер 2 «Очистить OC2B при сравнении совпадений» не работает в режиме CTC
- Генерация импульса 200 кГц на Arduino Uno в обычном режиме
- Прерывание сравнения Timer2 не работает должным образом
- Изменчивая переменная не обновляется с таймера ISR
- Точность синхронизации Arduino nano
- ATmega328P - проблема с использованием таймера 2 для генерации тона
- Настройка таймера ATMega328p (Arduino)
Спасибо, Эдгар, но мне очень нужен шаг в 1,0 Гц. Я решил попробовать более быстрый контроллер. Возможно, это будет контроллер STM32 на 72 МГц, который также доступен для Arduino IDE., @hennep
@hennep: Схема, которую я здесь показываю, дает вам шаг в один герц, если вы этого хотите:
set_ frequency(5000)дает 5000 Гц,set_ frequency(5001)дает 5001 Гц,set_ frequency(5002)дает 5002 Гц и т. д., @Edgar Bonet