ViKo 1 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба В 31.08.2022 в 01:45, RusikOk сказал: чем закончилась эпопея? удалось калибровать? Обошлось без калибровки. Принцип связи поменялся, подстраивать тактовый генератор уже не нужно было. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 15 часов назад, RusikOk сказал: чем закончилась эпопея? удалось калибровать? В 17.06.2021 в 11:36, ViKo сказал: Мне хватит точности часового резонатора. Смысл калибровки - обеспечить тактовую частоту, достаточную для последовательной связи. ps - для широкого диапазона температур не пойдет, если RC не термокомпенсирован. Для тактирования UART от RC генератора (DCO), на 115200 без кварца на MSP430F2618 (в нем нет FLL) выполнялась следующая процедура: 1. Подключался кварц 32768, выставлялся частотометром / подстроечным конденсатором. 2. Запускалась небольшая утилита из application (Ti) notes на ASM, которая подгоняла корректирующие константы для DCO. Утилита без интерфейса, соотв-но требуется по #define прописать туда требуемую частоту DCO, на которую будет настройка - компиляция. Утилита отрабатывала за время до 1с. 3. Все. Утилита сама прописывала корректирующие коэффициенты в соотв-ие ячейки коррекции DCO в MSP430F2618 --------- С переходом на MSP430F5438 эти танцы с бубном стали не нужны. https://d1.amobbs.com/bbs_upload782111/files_47/ourdev_697186XQW2VI.pdf Обеспечение точности генератора в MSP430 Спойлер #include <msp430.h> #define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz unsigned char CAL_DATA[8]; // Temp. storage for constants volatile unsigned int i; int j; char *Flash_ptrA; // Segment A pointer void Set_DCO(unsigned int Delta); int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization P1OUT = 0x00; // Clear P1 output latches P1DIR = 0x01; // P1.0 output P2SEL |= 0x02; // P2.1 SMCLK output P2DIR |= 0x02; // P2.1 output j = 0; // Reset pointer Set_DCO(DELTA_16MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_12MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_8MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_1MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j < 8; j++) *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit while (1) { P1OUT ^= 0x01; // Toggle LED for (i = 0; i < 0x4000; i++); // SW Delay } } void Set_DCO(unsigned int Delta) // Set DCO to selected frequency { unsigned int Compare, Oldcapture = 0; BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8 TACCTL2 = CM_1 + CCIS_1 + CAP; // CAP, ACLK TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear while (1) { while (!(CCIFG & TACCTL2)); // Wait until capture occured TACCTL2 &= ~CCIFG; // Capture occured, clear flag Compare = TACCR2; // Get current captured SMCLK Compare = Compare - Oldcapture; // SMCLK difference Oldcapture = TACCR2; // Save current captured SMCLK if (Delta == Compare) break; // If equal, leave "while(1)" else if (Delta < Compare) { DCOCTL--; // DCO is too fast, slow it down if (DCOCTL == 0xFF) // Did DCO roll under? if (BCSCTL1 & 0x0f) BCSCTL1--; // Select lower RSEL } else { DCOCTL++; // DCO is too slow, speed it up if (DCOCTL == 0x00) // Did DCO roll over? if ((BCSCTL1 & 0x0f) != 0x0f) BCSCTL1++; // Sel higher RSEL } } TACCTL2 = 0; // Stop TACCR2 TACTL = 0; // Stop Timer_A BCSCTL1 &= ~DIVA_3; // ACLK = LFXT1CLK } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться