mirror of
https://github.com/DashyFox/StackSport.git
synced 2025-05-04 07:10:17 +00:00
upd
This commit is contained in:
parent
8aed06aa9c
commit
c85e6aca95
@ -6,25 +6,25 @@
|
||||
#define AT24C_ADRESS 0x50 // i2c slave adress EEPROM
|
||||
|
||||
#define START_ADR_STAT 0x0000 //00000
|
||||
#define STAT_BLOCKSIZE 20
|
||||
#define STAT_BLOCKSIZE sizeof(InfoBlock)
|
||||
|
||||
#define START_ADR_SHOT (START_ADR_STAT+STAT_BLOCKSIZE) // 0x0014 = 20
|
||||
#define START_ADR_SHOT (START_ADR_STAT+STAT_BLOCKSIZE)
|
||||
#define SHOT_BLOCKSIZE 10
|
||||
#define MAX_NUMBER_SHOTS 255
|
||||
|
||||
#define START_ADR_PROGRAM (START_ADR_SHOT + (SHOT_BLOCKSIZE*MAX_NUMBER_SHOTS)) // 0x0A0A = 2570
|
||||
#define START_ADR_PROGRAM (START_ADR_SHOT + (SHOT_BLOCKSIZE*MAX_NUMBER_SHOTS))
|
||||
#define PROGRAM_BLOCKSIZE 203
|
||||
#define MAX_NUMBER_PROGRAMS 100
|
||||
#define MAX_NUMBER_SHOTS_IN_PROGRAMS \
|
||||
(PROGRAM_BLOCKSIZE-sizeof(ProgramHeader)) /sizeof(ProgramShot) // 100
|
||||
|
||||
#define START_ADR_MACRO (START_ADR_PROGRAM + (PROGRAM_BLOCKSIZE*MAX_NUMBER_PROGRAMS)) // 0x5956 = 22870
|
||||
#define START_ADR_MACRO (START_ADR_PROGRAM + (PROGRAM_BLOCKSIZE*MAX_NUMBER_PROGRAMS))
|
||||
#define MACRO_BLOCKSIZE 81
|
||||
#define MAX_NUMBER_MACRO 100
|
||||
#define MAX_NUMBER_PROGRAMS_IN_MACRO \
|
||||
(MACRO_BLOCKSIZE-sizeof(MacroHeader)) /sizeof(MacroProgram) // 20
|
||||
|
||||
#define MEMORY_END (START_ADR_MACRO + (MACRO_BLOCKSIZE*MAX_NUMBER_MACRO)) // 0x78FA = 30970
|
||||
#define MEMORY_END (START_ADR_MACRO + (MACRO_BLOCKSIZE*MAX_NUMBER_MACRO))
|
||||
|
||||
typedef enum MemoryStatus {
|
||||
EEPROM_FAIL,
|
||||
@ -103,16 +103,20 @@ typedef struct HardwareInit_t{
|
||||
}HardwareInit_t;
|
||||
|
||||
typedef struct Statistics{
|
||||
uint16_t totalShots;
|
||||
uint16_t totalPrograms;
|
||||
uint16_t totalMacros;
|
||||
uint32_t totalShots;
|
||||
uint32_t totalPrograms;
|
||||
uint32_t totalMacros;
|
||||
}Statistics;
|
||||
|
||||
typedef struct InfoBlock{
|
||||
HardwareInit_t hwInfo;
|
||||
Statistics statInfo;
|
||||
}InfoBlock;
|
||||
|
||||
|
||||
MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number, uint8_t *writeData, uint8_t dataSize);
|
||||
MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, uint8_t *readData, uint8_t dataSize);
|
||||
|
||||
MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number,
|
||||
uint8_t *writeData);
|
||||
MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number,
|
||||
uint8_t *outData);
|
||||
|
||||
MemoryStatus saveShot(unsigned char number, Shot *shot);
|
||||
MemoryStatus getShot(unsigned char number, Shot *shot);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
MemoryStatus saveShot(unsigned char number, Shot* shot)
|
||||
{
|
||||
if(FLASH_WriteBlock(START_ADR_SHOT, number, (uint8_t*)shot) == EEPROM_OK){
|
||||
if (FLASH_WriteBlock(START_ADR_SHOT, number, (uint8_t*)shot, SHOT_BLOCKSIZE) == EEPROM_OK) {
|
||||
return EEPROM_OK;
|
||||
}
|
||||
return EEPROM_FAIL;
|
||||
@ -14,7 +14,7 @@ MemoryStatus saveShot(unsigned char number, Shot* shot)
|
||||
|
||||
MemoryStatus getShot(unsigned char number, Shot* shot)
|
||||
{
|
||||
if(FLASH_ReadBlock(START_ADR_SHOT, number, (uint8_t*)&shot) != EEPROM_OK){
|
||||
if (FLASH_ReadBlock(START_ADR_SHOT, number, (uint8_t*)shot, SHOT_BLOCKSIZE) != EEPROM_OK) {
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
if (!shot->isExist) {
|
||||
@ -33,11 +33,12 @@ MemoryStatus saveProg(unsigned char number, Program* prog)
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
if (!shot.isExist) {
|
||||
//todo: add to shotRequest order
|
||||
// todo: добавить в запросы для загрузки снимков
|
||||
result = EEPROM_MISSING_ELEMENT;
|
||||
}
|
||||
}
|
||||
if(FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)prog) != EEPROM_OK){
|
||||
|
||||
if (FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)prog, PROGRAM_BLOCKSIZE) != EEPROM_OK) {
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
return result;
|
||||
@ -45,7 +46,7 @@ MemoryStatus saveProg(unsigned char number, Program* prog)
|
||||
|
||||
MemoryStatus getProg(unsigned char number, Program* prog)
|
||||
{
|
||||
if(FLASH_ReadBlock(START_ADR_PROGRAM, number, (uint8_t*)&prog) != EEPROM_OK){
|
||||
if (FLASH_ReadBlock(START_ADR_PROGRAM, number, (uint8_t*)prog, PROGRAM_BLOCKSIZE) != EEPROM_OK) {
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
|
||||
@ -67,20 +68,21 @@ MemoryStatus saveMacro(unsigned char number, Macro* macro)
|
||||
}
|
||||
if (!prog.header.isExist) {
|
||||
result = EEPROM_MISSING_ELEMENT;
|
||||
//todo: add to programRequest order
|
||||
// todo: добавить в запросы для загрузки программ
|
||||
}
|
||||
}
|
||||
|
||||
if(FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)macro) != EEPROM_OK){
|
||||
if (FLASH_WriteBlock(START_ADR_MACRO, number, (uint8_t*)macro, MACRO_BLOCKSIZE) != EEPROM_OK) {
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MemoryStatus getMacro(unsigned char number, Macro* macro)
|
||||
{
|
||||
if(FLASH_ReadBlock(START_ADR_PROGRAM, number, (uint8_t*)¯o) != EEPROM_OK){
|
||||
if (FLASH_ReadBlock(START_ADR_MACRO, number, (uint8_t*)macro, MACRO_BLOCKSIZE) != EEPROM_OK) {
|
||||
return EEPROM_FAIL;
|
||||
}
|
||||
|
||||
@ -90,34 +92,16 @@ MemoryStatus getMacro( unsigned char number, Macro* macro)
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number, uint8_t *writeData)
|
||||
|
||||
MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number, uint8_t *writeData, uint8_t dataSize)
|
||||
{
|
||||
HAL_StatusTypeDef result;
|
||||
uint8_t dataSize;
|
||||
// protect and select
|
||||
switch (startAddr) {
|
||||
case START_ADR_STAT:
|
||||
number = 0;
|
||||
dataSize = STAT_BLOCKSIZE;
|
||||
break;
|
||||
case START_ADR_SHOT:
|
||||
dataSize = SHOT_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_SHOTS)
|
||||
|
||||
// Проверка на корректность входных данных
|
||||
if ((startAddr == START_ADR_SHOT && number > MAX_NUMBER_SHOTS) ||
|
||||
(startAddr == START_ADR_PROGRAM && number > MAX_NUMBER_PROGRAMS) ||
|
||||
(startAddr == START_ADR_MACRO && number > MAX_NUMBER_MACRO)) {
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
case START_ADR_PROGRAM:
|
||||
dataSize = PROGRAM_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_PROGRAMS)
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
case START_ADR_MACRO:
|
||||
dataSize = MACRO_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_MACRO)
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
default:
|
||||
return EEPROM_WRONG_STARTADDR;
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number * dataSize));
|
||||
@ -128,40 +112,22 @@ MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number, uint8_t *write
|
||||
Buf[0] = blockAddr[0];
|
||||
Buf[1] = blockAddr[1];
|
||||
|
||||
for( unsigned char i = 0; i < (dataSize); i++ ) Buf[i+2] = writeData[i];
|
||||
for (unsigned char i = 0; i < dataSize; i++) Buf[i + 2] = writeData[i];
|
||||
|
||||
result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), Buf, (dataSize + 2), 10);
|
||||
HAL_Delay(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, uint8_t *readData){
|
||||
MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, uint8_t *readData, uint8_t dataSize)
|
||||
{
|
||||
HAL_StatusTypeDef result;
|
||||
uint8_t dataSize;
|
||||
// protect and select
|
||||
switch (startAddr) {
|
||||
case START_ADR_STAT:
|
||||
number = 0;
|
||||
dataSize = STAT_BLOCKSIZE;
|
||||
break;
|
||||
case START_ADR_SHOT:
|
||||
dataSize = SHOT_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_SHOTS)
|
||||
|
||||
// Проверка на корректность входных данных
|
||||
if ((startAddr == START_ADR_SHOT && number > MAX_NUMBER_SHOTS) ||
|
||||
(startAddr == START_ADR_PROGRAM && number > MAX_NUMBER_PROGRAMS) ||
|
||||
(startAddr == START_ADR_MACRO && number > MAX_NUMBER_MACRO)) {
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
case START_ADR_PROGRAM:
|
||||
dataSize = PROGRAM_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_PROGRAMS)
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
case START_ADR_MACRO:
|
||||
dataSize = MACRO_BLOCKSIZE;
|
||||
if(number > MAX_NUMBER_MACRO)
|
||||
return EEPROM_OUT_OF_RANGE;
|
||||
break;
|
||||
default:
|
||||
return EEPROM_WRONG_STARTADDR;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(readData, 0x00, dataSize);
|
||||
|
@ -14,10 +14,7 @@
|
||||
enum IR_MENU {
|
||||
IR_MENU_Home,
|
||||
|
||||
IR_MENU_SHOT,
|
||||
IR_MENU_PROGR,
|
||||
IR_MENU_MACRO,
|
||||
IR_MENU_,
|
||||
IR_MENU_SHOT, IR_MENU_PROGR, IR_MENU_MACRO, IR_MENU_,
|
||||
|
||||
};
|
||||
|
||||
@ -45,8 +42,6 @@ void onSelectShot(){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char b1 = 1;
|
||||
unsigned char b2 = 1;
|
||||
unsigned char b3 = 1;
|
||||
@ -97,37 +92,52 @@ void IR_Home_Process() {
|
||||
|
||||
case IR_PAUSE:
|
||||
{
|
||||
uint8_t buf[32];
|
||||
|
||||
uint16_t blockAddr16 = 0; // Начальный адрес блока в EEPROM
|
||||
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)}; // Адрес в формате 2 байта
|
||||
uint8_t buf[128]; // Буфер для чтения данных размером 128 байт
|
||||
uint16_t blockAddr16 = 0; // Начальный адрес EEPROM
|
||||
uint8_t blockAddr[2] = { (uint8_t)(blockAddr16 >> 8), (uint8_t)(blockAddr16 & 0xFF) }; // Адрес в формате 2 байта
|
||||
int max_attempts = 15; // Максимальное количество попыток для операции
|
||||
int attempts = 0; // Счетчик попыток
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
do {
|
||||
// Отправляем адрес в EEPROM
|
||||
if (HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 1000) == HAL_OK) {
|
||||
status = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 1000);
|
||||
if (status != HAL_OK) {
|
||||
HAL_Delay(5); // Задержка перед повтором
|
||||
attempts++;
|
||||
continue; // Переход к следующей попытке
|
||||
}
|
||||
|
||||
HAL_Delay(1); // Небольшая задержка
|
||||
|
||||
// Читаем данные из EEPROM
|
||||
if (HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1), buf, sizeof(buf), 1000) == HAL_OK) {
|
||||
// Выводим считанные данные
|
||||
for (int i = 0; i < sizeof(buf); ++i) {
|
||||
if (!(i % 8)) print(" ");
|
||||
if (!(i % 32)) print("\n");
|
||||
|
||||
// Читаем 128 байт данных из EEPROM
|
||||
status = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, buf, sizeof(buf), 1000);
|
||||
if (status == HAL_OK) {
|
||||
// Данные успешно считаны, выводим их
|
||||
char buffer[16];
|
||||
snprintf(buffer, sizeof(buffer), "%02X ", buf[i]); // Преобразуем байт в шестнадцатеричную строку
|
||||
for (int i = 0; i < sizeof(buf); ++i) {
|
||||
if (i % 8 == 0) print(" ");
|
||||
if (i % 32 == 0) print("\n");
|
||||
|
||||
// snprintf(buffer, sizeof(buffer), "%02X ", buf[i]); // Преобразуем байт в шестнадцатеричную строку
|
||||
CDC_Transmit_FS((uint8_t*)buffer, strlen(buffer));
|
||||
}
|
||||
break; // Выход из попыток, если чтение успешно
|
||||
} else {
|
||||
print("Read Error EEPROM\n");
|
||||
HAL_Delay(5); // Задержка перед повтором
|
||||
attempts++;
|
||||
}
|
||||
} else {
|
||||
print("Address TX Error EEPROM\n");
|
||||
} while (attempts < max_attempts);
|
||||
|
||||
if (status != HAL_OK) {
|
||||
print("Failed to read EEPROM after multiple attempts\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IR_DEBUG:
|
||||
{
|
||||
|
||||
case IR_DEBUG: {
|
||||
uint8_t i2c_address;
|
||||
HAL_StatusTypeDef result;
|
||||
|
||||
@ -155,33 +165,22 @@ void IR_Home_Process() {
|
||||
break;
|
||||
|
||||
case IR_NUM_1:
|
||||
setRollersSpeed(speedUP+=1, speedDown);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
|
||||
break;
|
||||
case IR_NUM_2:
|
||||
setScrewkSpeed(screwSpeed+=1);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
case IR_NUM_3:
|
||||
setRollersSpeed(speedUP, speedDown+=1);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
|
||||
break;
|
||||
|
||||
case IR_NUM_7:
|
||||
setRollersSpeed(speedUP-=1, speedDown);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
case IR_NUM_8:
|
||||
setScrewkSpeed(screwSpeed-=1);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
case IR_NUM_9:
|
||||
setRollersSpeed(speedUP, speedDown-=1);
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_NUM_5:
|
||||
setRollersSpeed(100,100);
|
||||
break;
|
||||
|
||||
case IR_STOP:
|
||||
@ -191,6 +190,48 @@ void IR_Home_Process() {
|
||||
stopShooting();
|
||||
break;
|
||||
|
||||
case IR_TEMPO_INC:
|
||||
if (screwSpeed < 100) {
|
||||
setScrewkSpeed(++screwSpeed);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_TEMPO_DEC:
|
||||
if (screwSpeed > 0) {
|
||||
setScrewkSpeed(--screwSpeed);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_ENGINE_UP_INC:
|
||||
if (speedUP < 200) {
|
||||
setRollersSpeed(++speedUP, speedDown);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_ENGINE_UP_DEC:
|
||||
if (speedUP > 0) {
|
||||
setRollersSpeed(--speedUP, speedDown);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_ENGINE_DOWM_INC:
|
||||
if (speedDown < 200) {
|
||||
setRollersSpeed(speedUP, ++speedDown);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
case IR_ENGINE_DOWM_DEC:
|
||||
if (speedDown > 0) {
|
||||
setRollersSpeed(speedUP, --speedDown);
|
||||
}
|
||||
onHoldRepeat = IR_Home_Process;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -52,6 +52,10 @@ HardwareInit_t hwSettings = {
|
||||
extern int16_t Vz1;
|
||||
extern int16_t Vz2;
|
||||
|
||||
int16_t map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) {
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
void doShot(Shot *shot) {
|
||||
SetServo(0, shot->rotationHorizontal);
|
||||
SetServo(1, shot->rotationVertical);
|
||||
@ -99,13 +103,10 @@ void startShooting() {
|
||||
void stopShooting() {
|
||||
isShooting = 0;
|
||||
isPause = 0;
|
||||
|
||||
setScrewkSpeed(0);
|
||||
setRollersSpeed(100, 100);
|
||||
setPosDefault();
|
||||
Vz1 = 100;
|
||||
Vz2 = 100;
|
||||
TIM1->CCR1 = 0;
|
||||
TIM1->CCR2 = 0;
|
||||
}
|
||||
|
||||
void doShotForever(uint8_t number) {
|
||||
@ -135,16 +136,18 @@ void setPos(uint8_t axial, uint8_t horizontal, uint8_t vertical) {
|
||||
SetServo(SERVO_VERTICAL, vertical); // Vertical
|
||||
}
|
||||
void setPosDefault() {
|
||||
SetServo(0, 90); // Axial
|
||||
SetServo(1, 90); // Horizontal
|
||||
SetServo(2, 90); // Vertical
|
||||
SetServo(SERVO_AXIAL, hwSettings.servos[SERVO_AXIAL].def); // Axial
|
||||
SetServo(SERVO_HORIZONTAL, hwSettings.servos[SERVO_HORIZONTAL].def); // Horizontal
|
||||
SetServo(SERVO_VERTICAL, hwSettings.servos[SERVO_VERTICAL].def); // Vertical
|
||||
}
|
||||
|
||||
// 0 .. 100
|
||||
void setScrewkSpeed(uint8_t speed) {
|
||||
|
||||
if(speed && speed < hwSettings.motors.speed_Screw_min)
|
||||
speed = hwSettings.motors.speed_Screw_min;
|
||||
// if(speed < 0) speed = 0;
|
||||
if(speed > 100) speed = 100;
|
||||
|
||||
speed = map(speed, 0, 100, hwSettings.motors.speed_Screw_min, 100);
|
||||
|
||||
TIM1->CCR1 = 0;
|
||||
TIM1->CCR2 = (uint16_t)(40 * speed);
|
||||
@ -153,6 +156,18 @@ void setScrewkSpeed(uint8_t speed) {
|
||||
//(-v) 0 .. 100(stop) .. 200(+v)
|
||||
void setRollersSpeed(uint8_t up, uint8_t down) {
|
||||
|
||||
if(up < 100){
|
||||
up = map(up, 0, 100, 0, 100-hwSettings.motors.speed_Screw_min);
|
||||
} else {
|
||||
up = map(up, 0, 100, 0, 100+hwSettings.motors.speed_Screw_min);
|
||||
}
|
||||
|
||||
if(down < 100){
|
||||
map(down, 0, 100, 0, 100-hwSettings.motors.speed_Screw_min);
|
||||
} else {
|
||||
map(down, 0, 100, 0, 100+hwSettings.motors.speed_Screw_min);
|
||||
}
|
||||
|
||||
Vz1 = 200-up; // invert
|
||||
Vz2 = down;
|
||||
}
|
||||
|
@ -204,7 +204,9 @@ initcomlete = 1;
|
||||
/* USER CODE BEGIN WHILE */
|
||||
|
||||
Shot testShot;
|
||||
memset(&testShot, 0x00, sizeof(Shot));
|
||||
getShot(3, &testShot);
|
||||
|
||||
if(!testShot.isExist){
|
||||
testShot.countRepeatShot = 1;
|
||||
testShot.speedRollerTop = 200;
|
||||
|
97
TODO.md
97
TODO.md
@ -8,7 +8,7 @@ IR:
|
||||
V Добавить press and hold
|
||||
|
||||
Проверка железа:
|
||||
Проверить все PWM
|
||||
V Проверить все PWM
|
||||
Проверить функции управления железом
|
||||
setRollersSpeed
|
||||
setScrewkSpeed
|
||||
@ -17,7 +17,7 @@ IR:
|
||||
doShot
|
||||
|
||||
Логика работы:
|
||||
Ограничение минимальных скоростей!
|
||||
V Ограничение минимальных скоростей!
|
||||
Правильное переключение выстрелов с учётом repeatCount
|
||||
Переключение выстрелов в программе
|
||||
Переключение программ в макро
|
||||
@ -39,96 +39,3 @@ IR:
|
||||
Ошибки:
|
||||
В некоторый момент PID регулятор выдаёт 0 и двигатель не запускается не зависимо от входного значенияPWM
|
||||
|
||||
|
||||
|
||||
uint32_t GetTimerClockFrequency(TIM_TypeDef *TIMx) {
|
||||
uint32_t clock_frequency = 0;
|
||||
uint32_t sysclk_frequency = 0;
|
||||
uint32_t hclk_frequency = 0;
|
||||
uint32_t apb1_frequency = 0;
|
||||
uint32_t apb2_frequency = 0;
|
||||
|
||||
// Определяем источник системного тактирования (SYSCLK)
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS) {
|
||||
case RCC_CFGR_SWS_HSI: // HSI используется как системный клок
|
||||
sysclk_frequency = 8000000; // HSI - 8 MHz
|
||||
break;
|
||||
case RCC_CFGR_SWS_HSE: // HSE используется как системный клок
|
||||
sysclk_frequency = HSE_VALUE; // Предположим, что значение HSE_VALUE определено
|
||||
break;
|
||||
case RCC_CFGR_SWS_PLL: // PLL используется как системный клок
|
||||
// Получаем значение входного тактового сигнала PLL
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC_HSI_DIV2) {
|
||||
sysclk_frequency = 4000000; // HSI/2 - 4 MHz
|
||||
} else {
|
||||
sysclk_frequency = HSE_VALUE; // HSE_VALUE определено как 8 или 16 MHz
|
||||
}
|
||||
|
||||
// Получаем множитель PLL
|
||||
uint32_t pll_mul = ((RCC->CFGR & RCC_CFGR_PLLMULL) >> 18) + 2;
|
||||
sysclk_frequency *= pll_mul;
|
||||
break;
|
||||
default:
|
||||
sysclk_frequency = 8000000; // По умолчанию HSI
|
||||
break;
|
||||
}
|
||||
|
||||
// Определяем частоту шины AHB (HCLK)
|
||||
uint32_t ahb_prescaler = (RCC->CFGR & RCC_CFGR_HPRE) >> 4;
|
||||
if (ahb_prescaler < 8) {
|
||||
hclk_frequency = sysclk_frequency;
|
||||
} else {
|
||||
hclk_frequency = sysclk_frequency >> ((ahb_prescaler - 7));
|
||||
}
|
||||
|
||||
// Определяем частоту шины APB1
|
||||
uint32_t apb1_prescaler = (RCC->CFGR & RCC_CFGR_PPRE1) >> 8;
|
||||
if (apb1_prescaler < 4) {
|
||||
apb1_frequency = hclk_frequency;
|
||||
} else {
|
||||
apb1_frequency = hclk_frequency >> ((apb1_prescaler - 3));
|
||||
}
|
||||
|
||||
// Определяем частоту шины APB2
|
||||
uint32_t apb2_prescaler = (RCC->CFGR & RCC_CFGR_PPRE2) >> 11;
|
||||
if (apb2_prescaler < 4) {
|
||||
apb2_frequency = hclk_frequency;
|
||||
} else {
|
||||
apb2_frequency = hclk_frequency >> ((apb2_prescaler - 3));
|
||||
}
|
||||
|
||||
// Определяем частоту для конкретного таймера
|
||||
if (TIMx == TIM1 || TIMx == TIM8) { // Таймеры на шине APB2
|
||||
clock_frequency = (apb2_prescaler == 0 ? apb2_frequency : apb2_frequency * 2);
|
||||
} else { // Таймеры на шине APB1
|
||||
clock_frequency = (apb1_prescaler == 0 ? apb1_frequency : apb1_frequency * 2);
|
||||
}
|
||||
|
||||
return clock_frequency;
|
||||
}
|
||||
|
||||
// Функция для вычисления целевого значения
|
||||
uint32_t CalculateTargetCount(TIM_TypeDef *TIMx, uint32_t freq) {
|
||||
// Проверяем, что частота не равна нулю
|
||||
if (freq == 0) return 0xFFFFFFFF; // Защита от деления на ноль
|
||||
|
||||
// Получаем частоту тактового генератора для данного таймера
|
||||
uint32_t clock_frequency = GetTimerClockFrequency(TIMx);
|
||||
|
||||
// Получаем значение предделителя (PSC) и ARR таймера
|
||||
uint32_t psc = TIMx->PSC;
|
||||
uint32_t arr = TIMx->ARR;
|
||||
|
||||
// Вычисляем частоту работы таймера
|
||||
uint32_t timer_frequency = clock_frequency / ((psc + 1) * (arr + 1));
|
||||
|
||||
// Вычисляем целевое значение счетчика для заданной частоты
|
||||
uint32_t target_count = timer_frequency / freq;
|
||||
|
||||
return target_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user