给CC1101写寄存器,根据用户指定的Frequency deviation,按公式计算
反反推DEVIATION_M和DEVIATION_E的值,
写入DEVIATN,寄存器描述如下:
借ChatGPT生成的代码,把f_dev定义为了double,测试了下,是可用的
#include <stdio.h>
#include <math.h>
#include <float.h> // For DBL_MAX
#define FXOSC 27000000 // 27 MHz
int find_deviation_parameters(double f_dev, int *DEVIATION_M, int *DEVIATION_E) {
// Calculate the constant K
double K = (f_dev * pow(2, 17)) / FXOSC;
// Initialize variables to find the closest match
double closest_f_dev_diff = DBL_MAX;
int best_DEVIATION_M = -1, best_DEVIATION_E = -1;
// Iterate over possible values of DEVIATION_E
for (int DEVIATION_E_local = 0; DEVIATION_E_local < 8; DEVIATION_E_local++) {
// Calculate the potential DEVIATION_M value
double potential_M = K / pow(2, DEVIATION_E_local) - 8;
// Check if potential_M is within the valid range (0 to 7)
if (potential_M >= 0 && potential_M < 8) {
// Calculate the actual deviation frequency for this pair
double actual_f_dev = (FXOSC / pow(2, 17)) * (8 + (int)potential_M) * pow(2, DEVIATION_E_local);
double f_dev_diff = fabs(f_dev - actual_f_dev);
// Check if this is the closest match so far
if (f_dev_diff < closest_f_dev_diff) {
closest_f_dev_diff = f_dev_diff;
best_DEVIATION_M = (int)potential_M;
best_DEVIATION_E = DEVIATION_E_local;
}
// If potential_M is an integer within the valid range (0 to 7), we have an exact match
if (floor(potential_M) == potential_M) {
*DEVIATION_M = (int)potential_M;
*DEVIATION_E = DEVIATION_E_local;
return 1; // Success with an exact match
}
}
}
// If no exact valid pair is found, return the closest match
if (best_DEVIATION_M != -1 && best_DEVIATION_E != -1) {
*DEVIATION_M = best_DEVIATION_M;
*DEVIATION_E = best_DEVIATION_E;
return 1; // Success with the closest match
}
// If no valid pair is found at all, return 0 to indicate failure
return 0;
}
int main() {
double f_dev = 5000; // Example frequency deviation
int DEVIATION_M, DEVIATION_E;
if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
} else {
printf("No valid DEVIATION_M and DEVIATION_E found.\n");
}
return 0;
}
但是有些小问题,具体表现为当输入的f_dev精度不一样是,计算出的寄存器值差了一个数。
I test with the double-f_dev version function find_deviation_parameters, when the input f_dev is 4943.848, the result is "DEVIATION_M: 4, DEVIATION_E: 1", however when I change the f_dev to 4943.84, the result is "DEVIATION_M: 3, DEVIATION_E: 1". there can be some glitches, please improve it.
这是不可接受的,所以问了下ChatGPT,给我改善了下
To improve the precision and consistency of the results for the floating-point version, we need to ensure that small changes in the input
f_dev
do not lead to disproportionate changes in the output parameters. This can be achieved by ensuring that all calculations are performed with high precision and by carefully managing rounding.Here is an improved version of the function to handle floating-point inputs more accurately:
#include <stdio.h>
#include <math.h>
#include <float.h> // For DBL_MAX
#define FXOSC 27000000.0 // 27 MHz
int find_deviation_parameters(double f_dev, int *DEVIATION_M, int *DEVIATION_E) {
// Calculate the constant K
double K = (f_dev * pow(2.0, 17)) / FXOSC;
// Initialize variables to find the closest match
double closest_f_dev_diff = DBL_MAX;
int best_DEVIATION_M = -1, best_DEVIATION_E = -1;
// Iterate over possible values of DEVIATION_E
for (int DEVIATION_E_local = 0; DEVIATION_E_local < 8; DEVIATION_E_local++) {
// Calculate the potential DEVIATION_M value
double potential_M = K / pow(2.0, DEVIATION_E_local) - 8.0;
// Check if potential_M is within the valid range (0 to 7)
if (potential_M >= 0 && potential_M < 8) {
// Calculate the actual deviation frequency for this pair
double actual_f_dev = (FXOSC / pow(2.0, 17)) * (8 + floor(potential_M + 0.5)) * pow(2.0, DEVIATION_E_local);
double f_dev_diff = fabs(f_dev - actual_f_dev);
// Check if this is the closest match so far
if (f_dev_diff < closest_f_dev_diff) {
closest_f_dev_diff = f_dev_diff;
best_DEVIATION_M = (int)floor(potential_M + 0.5);
best_DEVIATION_E = DEVIATION_E_local;
}
// If potential_M is an integer within the valid range (0 to 7), we have an exact match
if (fabs(potential_M - floor(potential_M + 0.5)) < DBL_EPSILON) {
*DEVIATION_M = (int)floor(potential_M + 0.5);
*DEVIATION_E = DEVIATION_E_local;
return 1; // Success with an exact match
}
}
}
// If no exact valid pair is found, return the closest match
if (best_DEVIATION_M != -1 && best_DEVIATION_E != -1) {
*DEVIATION_M = best_DEVIATION_M;
*DEVIATION_E = best_DEVIATION_E;
return 1; // Success with the closest match
}
// If no valid pair is found at all, return 0 to indicate failure
return 0;
}
int main() {
double f_dev = 4943.848; // Example frequency deviation
int DEVIATION_M, DEVIATION_E;
if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
} else {
printf("No valid DEVIATION_M and DEVIATION_E found.\n");
}
// Test with a slightly different frequency deviation
f_dev = 4943.84;
if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
} else {
printf("No valid DEVIATION_M and DEVIATION_E found.\n");
}
return 0;
}
其实就是转换的问题,导致了误差的累积,精度丢失了。这涉及到 (int)转换, floor函数,还有(int)floor函数的用法,另开一篇写吧。