Mi proyecto se basa en el MSP430F5529. De la guía de usuario de la familia MSP430x5xx :
NOTA: la configuración rápida de la velocidad de transmisión
Para calcular la configuración correcta correcta para la generación de velocidad en baudios, realice estos pasos:
Calcule N = fBRCLK / velocidad en baudios [si N > 16 continúe con el paso 3, de lo contrario con el paso 2]
OS16 = 0, UCBRx = INT (N) [continuar con el paso 4]
OS16 = 1, UCBRx = INT (N / 16), UCBRFx = INT ([(N / 16) - INT (N / 16)] × 16)
Se puede encontrar UCBRSx buscando la parte fraccionaria de N (= N - INT (N)) en la tabla Tabla 39-4
Si se eligió OS16 = 0, TI recomienda realizar un cálculo de error detallado.
Actualmente estoy calculando las configuraciones de registro para 230.4 kbps con un reloj de 16 MHz. Mis cálculos son los siguientes:
- N = (16000000/230400) = 69.4444 ....
- N / A
- OS16 = 1 (modo de sobremuestreo), UCBRx = (int) (69.4444 / 16) = 4 , UCBRFx = (int) ([(69.4444 / 16) - (int) (69.4444 / 16)] * 16) = 5
- De acuerdo con la Tabla 39-4 (abajo), N- (int) N = 69.4444-69 = 0.4444 = > UCBRSx = 0x55
Ahoraaquíestálaparteconfusa.SiconsultalaTabla36-5enlapágina954,verálassiguientesconfiguracionesrecomendadaspara16MHza230.4kbpsconOS16=1:
Notequesesugiere"5" para UCBRSx y se sugiere "3" para UCBRFx. Como puede ver, estos números claramente no coinciden con los cálculos. Cuando uso los valores calculados y el valor para UCBRSx de la tabla de búsqueda, el UART no siempre se comporta correctamente, especialmente a las tasas de bits bajas (< 9600 bps) y las altas (> 115200 bps). Necesito poder calcular los valores de registro del generador de velocidad en baudios sobre la marcha para 300 bps a 230400 bps, y esta discrepancia en la hoja de datos hace que esto sea muy difícil.
Si no puedo confiar en los cálculos, ¿cuál es la forma correcta de determinar los valores de registro? Tal vez estoy malinterpretando esto? También he usado esta herramienta para calcular la configuración y los resultados coinciden con la Tabla 36-5 en la hoja de datos, aunque los cálculos mencionados en la página arrojan los resultados que obtuve de mis propios cálculos.
Veo que sugieren hacer un cálculo de error detallado para diferentes opciones, pero esto se refiere al ajuste de la velocidad en baudios de baja frecuencia (OS16 = 0) o si se seleccionan valores entre 0 y 7 para UCBRSx. Esto parece ser diferente de la Tabla 39-4, ya que la tabla sugiere que podrían usarse valores entre 0x00 y 0xFF.
Mi código es el siguiente:
void uartConfig(uint32_t frequency, uint32_t baud) {
float divFactor;
uint16_t UCBRx;
uint8_t oversampling;
uint8_t UCBRFx;
uint8_t UCBRSx;
// Calculate baud rate modulation register values
divFactor = (float)((float)frequency/(float)baud);
// High frequency mode
oversampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION; // High frequency baud rate generation
UCBRx = (uint16_t)(divFactor/16); // Calculate integer part of N divided by 16
UCBRFx = round(((divFactor/16) - (uint16_t)(divFactor/16)) * 16); // Calculate first modulation stage
// Found from table for N-INT(N); See slau208q Pg. 1037 for details
UCBRSx = getUCBRSxValue(divFactor); // Second modulation register
uartParams.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
uartParams.clockPrescalar = UCBRx;
uartParams.firstModReg = UCBRFx;
uartParams.secondModReg = UCBRSx;
uartParams.parity = USCI_A_UART_NO_PARITY;
uartParams.msborLsbFirst = USCI_A_UART_LSB_FIRST;
uartParams.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
uartParams.uartMode = USCI_A_UART_MODE;
uartParams.overSampling = oversampling;
}
Y la "tabla de búsqueda" (ish):
// Lookup table for UCBRSx values
uint8_t getUCBRSxValue(float factor) {
uint16_t frac = (factor - (uint16_t)factor) * 10000;
if (frac < 529) {
return 0x00;
} else if ((frac >= 529) && (frac < 715)) {
return 0x01;
} else if ((frac >= 715) && (frac < 835)) {
return 0x02;
} else if ((frac >= 835) && (frac < 1001)) {
return 0x04;
} else if ((frac >= 1001) && (frac < 1252)) {
return 0x08;
} else if ((frac >= 1252) && (frac < 1430)) {
return 0x10;
} else if ((frac >= 1430) && (frac < 1670)) {
return 0x20;
} else if ((frac >= 1670) && (frac < 2147)) {
return 0x11;
} else if ((frac >= 2147) && (frac < 2224)) {
return 0x21;
} else if ((frac >= 2224) && (frac < 2503)) {
return 0x22;
} else if ((frac >= 2503) && (frac < 3000)) {
return 0x44;
} else if ((frac >= 3000) && (frac < 3335)) {
return 0x25;
} else if ((frac >= 3335) && (frac < 3575)) {
return 0x49;
} else if ((frac >= 3575) && (frac < 3753)) {
return 0x4A;
} else if ((frac >= 3753) && (frac < 4003)) {
return 0x52;
} else if ((frac >= 4003) && (frac < 4286)) {
return 0x92;
} else if ((frac >= 4286) && (frac < 4378)) {
return 0x53;
} else if ((frac >= 4378) && (frac < 5002)) {
return 0x55;
} else if ((frac >= 5002) && (frac < 5715)) {
return 0xAA;
} else if ((frac >= 5715) && (frac < 6003)) {
return 0x6B;
} else if ((frac >= 6003) && (frac < 6254)) {
return 0xAD;
} else if ((frac >= 6254) && (frac < 6432)) {
return 0xB5;
} else if ((frac >= 6432) && (frac < 6667)) {
return 0xB6;
} else if ((frac >= 6667) && (frac < 7001)) {
return 0xD6;
} else if ((frac >= 7001) && (frac < 7147)) {
return 0xB7;
} else if ((frac >= 7147) && (frac < 7503)) {
return 0xBB;
} else if ((frac >= 7503) && (frac < 7861)) {
return 0xDD;
} else if ((frac >= 7861) && (frac < 8004)) {
return 0xED;
} else if ((frac >= 8004) && (frac < 8333)) {
return 0xEE;
} else if ((frac >= 8333) && (frac < 8464)) {
return 0xBF;
} else if ((frac >= 8464) && (frac < 8572)) {
return 0xDF;
} else if ((frac >= 8572) && (frac < 8751)) {
return 0xEF;
} else if ((frac >= 8751) && (frac < 9004)) {
return 0xF7;
} else if ((frac >= 9004) && (frac < 9170)) {
return 0xFB;
} else if ((frac >= 9170) && (frac < 9288)) {
return 0xFD;
} else if (frac >= 9288) {
return 0xFE;
}
return 0x00;
}