This commit is contained in:
DashyFox 2024-09-10 01:09:10 +03:00
parent 8aed06aa9c
commit c85e6aca95
6 changed files with 268 additions and 333 deletions

View File

@ -6,25 +6,25 @@
#define AT24C_ADRESS 0x50 // i2c slave adress EEPROM #define AT24C_ADRESS 0x50 // i2c slave adress EEPROM
#define START_ADR_STAT 0x0000 //00000 #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 SHOT_BLOCKSIZE 10
#define MAX_NUMBER_SHOTS 255 #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 PROGRAM_BLOCKSIZE 203
#define MAX_NUMBER_PROGRAMS 100 #define MAX_NUMBER_PROGRAMS 100
#define MAX_NUMBER_SHOTS_IN_PROGRAMS \ #define MAX_NUMBER_SHOTS_IN_PROGRAMS \
(PROGRAM_BLOCKSIZE-sizeof(ProgramHeader)) /sizeof(ProgramShot) // 100 (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 MACRO_BLOCKSIZE 81
#define MAX_NUMBER_MACRO 100 #define MAX_NUMBER_MACRO 100
#define MAX_NUMBER_PROGRAMS_IN_MACRO \ #define MAX_NUMBER_PROGRAMS_IN_MACRO \
(MACRO_BLOCKSIZE-sizeof(MacroHeader)) /sizeof(MacroProgram) // 20 (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 { typedef enum MemoryStatus {
EEPROM_FAIL, EEPROM_FAIL,
@ -103,16 +103,20 @@ typedef struct HardwareInit_t{
}HardwareInit_t; }HardwareInit_t;
typedef struct Statistics{ typedef struct Statistics{
uint16_t totalShots; uint32_t totalShots;
uint16_t totalPrograms; uint32_t totalPrograms;
uint16_t totalMacros; uint32_t totalMacros;
}Statistics; }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 saveShot(unsigned char number, Shot *shot);
MemoryStatus getShot(unsigned char number, Shot *shot); MemoryStatus getShot(unsigned char number, Shot *shot);

View File

@ -6,172 +6,138 @@
MemoryStatus saveShot(unsigned char number, Shot* shot) 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_OK;
} }
return EEPROM_FAIL; return EEPROM_FAIL;
} }
MemoryStatus getShot(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; return EEPROM_FAIL;
} }
if(!shot->isExist){ if (!shot->isExist) {
return EEPROM_MISSING_ELEMENT; return EEPROM_MISSING_ELEMENT;
} }
return EEPROM_OK; return EEPROM_OK;
} }
MemoryStatus saveProg(unsigned char number, Program* prog) MemoryStatus saveProg(unsigned char number, Program* prog)
{ {
MemoryStatus result = EEPROM_OK; MemoryStatus result = EEPROM_OK;
for(uint16_t i = 0; i < MAX_NUMBER_SHOTS_IN_PROGRAMS; ++i){ for (uint16_t i = 0; i < MAX_NUMBER_SHOTS_IN_PROGRAMS; ++i) {
Shot shot; Shot shot;
MemoryStatus stat = getShot(prog->shots[i].id, &shot); MemoryStatus stat = getShot(prog->shots[i].id, &shot);
if(!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)){ if (!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)) {
return EEPROM_FAIL; return EEPROM_FAIL;
} }
if(!shot.isExist){ if (!shot.isExist) {
//todo: add to shotRequest order // todo: добавить в запросы для загрузки снимков
result = EEPROM_MISSING_ELEMENT; result = EEPROM_MISSING_ELEMENT;
} }
} }
if(FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)prog) != EEPROM_OK){
return EEPROM_FAIL; if (FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)prog, PROGRAM_BLOCKSIZE) != EEPROM_OK) {
} return EEPROM_FAIL;
return result; }
return result;
} }
MemoryStatus getProg( 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; return EEPROM_FAIL;
} }
if(!prog->header.isExist){ if (!prog->header.isExist) {
return EEPROM_MISSING_ELEMENT; return EEPROM_MISSING_ELEMENT;
} }
return EEPROM_OK; return EEPROM_OK;
} }
MemoryStatus saveMacro(unsigned char number, Macro* macro) MemoryStatus saveMacro(unsigned char number, Macro* macro)
{ {
MemoryStatus result = EEPROM_OK; MemoryStatus result = EEPROM_OK;
for (uint16_t i = 0; i < MAX_NUMBER_PROGRAMS_IN_MACRO; ++i) { for (uint16_t i = 0; i < MAX_NUMBER_PROGRAMS_IN_MACRO; ++i) {
Program prog; Program prog;
MemoryStatus stat = getProg(macro->programs[i].id, &prog); MemoryStatus stat = getProg(macro->programs[i].id, &prog);
if(!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)){ if (!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)) {
return EEPROM_FAIL; return EEPROM_FAIL;
} }
if(!prog.header.isExist){ if (!prog.header.isExist) {
result = EEPROM_MISSING_ELEMENT; 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 EEPROM_FAIL;
} }
return result; return result;
} }
MemoryStatus getMacro( unsigned char number, Macro* macro)
MemoryStatus getMacro(unsigned char number, Macro* macro)
{ {
if(FLASH_ReadBlock(START_ADR_PROGRAM, number, (uint8_t*)&macro) != EEPROM_OK){ if (FLASH_ReadBlock(START_ADR_MACRO, number, (uint8_t*)macro, MACRO_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL; return EEPROM_FAIL;
} }
if(!macro->header.isExist){ if (!macro->header.isExist) {
return EEPROM_MISSING_ELEMENT; return EEPROM_MISSING_ELEMENT;
} }
return EEPROM_OK; 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; 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)
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)); // Проверка на корректность входных данных
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)}; 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;
}
unsigned char Buf[dataSize+2]; uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number * dataSize));
memset(Buf, 0x00, sizeof(Buf)); uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
Buf[0] = blockAddr[0];
Buf[1] = blockAddr[1]; unsigned char Buf[dataSize + 2];
memset(Buf, 0x00, sizeof(Buf));
for( unsigned char i = 0; i < (dataSize); i++ ) Buf[i+2] = writeData[i]; Buf[0] = blockAddr[0];
Buf[1] = blockAddr[1];
result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), Buf, (dataSize + 2), 10);
HAL_Delay(1); for (unsigned char i = 0; i < dataSize; i++) Buf[i + 2] = writeData[i];
return result;
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; HAL_StatusTypeDef result;
// 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)
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); // Проверка на корректность входных данных
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;
}
uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number*dataSize)); memset(readData, 0x00, dataSize);
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 10); uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number * dataSize));
HAL_Delay(1); uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
result = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1), readData, dataSize, 10);
HAL_Delay(1); result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 10);
return result; HAL_Delay(1);
result = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1), readData, dataSize, 10);
HAL_Delay(1);
return result;
} }

View File

@ -14,10 +14,7 @@
enum IR_MENU { enum IR_MENU {
IR_MENU_Home, IR_MENU_Home,
IR_MENU_SHOT, IR_MENU_SHOT, IR_MENU_PROGR, IR_MENU_MACRO, IR_MENU_,
IR_MENU_PROGR,
IR_MENU_MACRO,
IR_MENU_,
}; };
@ -30,13 +27,13 @@ extern uint16_t inputParam; // current input parameter
extern IRData data; extern IRData data;
// () // ()
extern void NullFunc(); // null func for paramEnter(NullFunc); extern void NullFunc(); // null func for paramEnter(NullFunc);
extern void paramEnter(void(*onEnter_)()); // setParamFunc for enter extern void paramEnter(void (*onEnter_)()); // setParamFunc for enter
void IR_ShotPrepared(); void IR_ShotPrepared();
void onSelectShot(){ void onSelectShot() {
if(prepareShot(inputParam)){ if (prepareShot(inputParam)) {
InputHandler = IR_ShotPrepared; InputHandler = IR_ShotPrepared;
} else { } else {
paramEnter(onSelectShot); paramEnter(onSelectShot);
@ -45,8 +42,6 @@ void onSelectShot(){
} }
} }
unsigned char b1 = 1; unsigned char b1 = 1;
unsigned char b2 = 1; unsigned char b2 = 1;
unsigned char b3 = 1; unsigned char b3 = 1;
@ -96,92 +91,96 @@ void IR_Home_Process() {
break; break;
case IR_PAUSE: case IR_PAUSE:
{
uint8_t buf[32];
uint16_t blockAddr16 = 0; // Начальный адрес блока в EEPROM
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)}; // Адрес в формате 2 байта
// Отправляем адрес в EEPROM
if (HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 1000) == HAL_OK) {
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");
char buffer[16];
snprintf(buffer, sizeof(buffer), "%02X ", buf[i]); // Преобразуем байт в шестнадцатеричную строку
CDC_Transmit_FS((uint8_t*)buffer, strlen(buffer));
}
} else {
print("Read Error EEPROM\n");
}
} else {
print("Address TX Error EEPROM\n");
}
}
break;
case IR_DEBUG:
{ {
uint8_t i2c_address; uint8_t buf[128]; // Буфер для чтения данных размером 128 байт
HAL_StatusTypeDef result; 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;
print("Scan\n"); do {
// Отправляем адрес в EEPROM
// Перебираем все возможные адреса на шине I2C (7 бит, от 0x08 до 0x77) status = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 1000);
for (i2c_address = 0x08; i2c_address <= 0x77; i2c_address++) { if (status != HAL_OK) {
// Отправляем запрос на указанный адрес (HAL_I2C_Master_Transmit без данных) HAL_Delay(5); // Задержка перед повтором
result = HAL_I2C_IsDeviceReady(&hi2c1, (i2c_address << 1), 1, 100); attempts++;
continue; // Переход к следующей попытке
if (result == HAL_OK) {
// Если устройство отвечает, выводим его адрес
print("Found I2C at: ");
printNumber(i2c_address);
print("\n");
} else {
// Если устройство не отвечает, продолжаем сканирование
print(".");
} }
HAL_Delay(10); // Задержка для стабильности сканирования
}
print("\nScanning completed.\n"); HAL_Delay(1); // Небольшая задержка
// Читаем 128 байт данных из EEPROM
status = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, buf, sizeof(buf), 1000);
if (status == HAL_OK) {
// Данные успешно считаны, выводим их
char buffer[16];
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++;
}
} while (attempts < max_attempts);
if (status != HAL_OK) {
print("Failed to read EEPROM after multiple attempts\n");
}
}
break;
case IR_DEBUG: {
uint8_t i2c_address;
HAL_StatusTypeDef result;
print("Scan\n");
// Перебираем все возможные адреса на шине I2C (7 бит, от 0x08 до 0x77)
for (i2c_address = 0x08; i2c_address <= 0x77; i2c_address++) {
// Отправляем запрос на указанный адрес (HAL_I2C_Master_Transmit без данных)
result = HAL_I2C_IsDeviceReady(&hi2c1, (i2c_address << 1), 1, 100);
if (result == HAL_OK) {
// Если устройство отвечает, выводим его адрес
print("Found I2C at: ");
printNumber(i2c_address);
print("\n");
} else {
// Если устройство не отвечает, продолжаем сканирование
print(".");
}
HAL_Delay(10); // Задержка для стабильности сканирования
}
print("\nScanning completed.\n");
} }
break; break;
case IR_NUM_1: case IR_NUM_1:
setRollersSpeed(speedUP+=1, speedDown);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_2: case IR_NUM_2:
setScrewkSpeed(screwSpeed+=1);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_3: case IR_NUM_3:
setRollersSpeed(speedUP, speedDown+=1);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_7: case IR_NUM_7:
setRollersSpeed(speedUP-=1, speedDown);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_8: case IR_NUM_8:
setScrewkSpeed(screwSpeed-=1);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_9: case IR_NUM_9:
setRollersSpeed(speedUP, speedDown-=1);
onHoldRepeat = IR_Home_Process;
break; break;
case IR_NUM_5: case IR_NUM_5:
setRollersSpeed(100,100);
break; break;
case IR_STOP: case IR_STOP:
@ -191,20 +190,62 @@ void IR_Home_Process() {
stopShooting(); stopShooting();
break; 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: default:
break; break;
} }
} }
void IR_ShotPrepared(){ void IR_ShotPrepared() {
InputHandler = IR_ShotPrepared; InputHandler = IR_ShotPrepared;
switch (data.command) { switch (data.command) {
case IR_START: case IR_START:
startShooting(); startShooting();
break; break;
default: default:
InputHandler(); InputHandler();
break; break;
} }
} }

View File

@ -52,6 +52,10 @@ HardwareInit_t hwSettings = {
extern int16_t Vz1; extern int16_t Vz1;
extern int16_t Vz2; 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) { void doShot(Shot *shot) {
SetServo(0, shot->rotationHorizontal); SetServo(0, shot->rotationHorizontal);
SetServo(1, shot->rotationVertical); SetServo(1, shot->rotationVertical);
@ -99,13 +103,10 @@ void startShooting() {
void stopShooting() { void stopShooting() {
isShooting = 0; isShooting = 0;
isPause = 0; isPause = 0;
setScrewkSpeed(0); setScrewkSpeed(0);
setRollersSpeed(100, 100); setRollersSpeed(100, 100);
setPosDefault(); setPosDefault();
Vz1 = 100;
Vz2 = 100;
TIM1->CCR1 = 0;
TIM1->CCR2 = 0;
} }
void doShotForever(uint8_t number) { 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 SetServo(SERVO_VERTICAL, vertical); // Vertical
} }
void setPosDefault() { void setPosDefault() {
SetServo(0, 90); // Axial SetServo(SERVO_AXIAL, hwSettings.servos[SERVO_AXIAL].def); // Axial
SetServo(1, 90); // Horizontal SetServo(SERVO_HORIZONTAL, hwSettings.servos[SERVO_HORIZONTAL].def); // Horizontal
SetServo(2, 90); // Vertical SetServo(SERVO_VERTICAL, hwSettings.servos[SERVO_VERTICAL].def); // Vertical
} }
// 0 .. 100 // 0 .. 100
void setScrewkSpeed(uint8_t speed) { void setScrewkSpeed(uint8_t speed) {
if(speed && speed < hwSettings.motors.speed_Screw_min) // if(speed < 0) speed = 0;
speed = hwSettings.motors.speed_Screw_min; if(speed > 100) speed = 100;
speed = map(speed, 0, 100, hwSettings.motors.speed_Screw_min, 100);
TIM1->CCR1 = 0; TIM1->CCR1 = 0;
TIM1->CCR2 = (uint16_t)(40 * speed); TIM1->CCR2 = (uint16_t)(40 * speed);
@ -153,6 +156,18 @@ void setScrewkSpeed(uint8_t speed) {
//(-v) 0 .. 100(stop) .. 200(+v) //(-v) 0 .. 100(stop) .. 200(+v)
void setRollersSpeed(uint8_t up, uint8_t down) { 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 Vz1 = 200-up; // invert
Vz2 = down; Vz2 = down;
} }

View File

@ -204,7 +204,9 @@ initcomlete = 1;
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
Shot testShot; Shot testShot;
memset(&testShot, 0x00, sizeof(Shot));
getShot(3, &testShot); getShot(3, &testShot);
if(!testShot.isExist){ if(!testShot.isExist){
testShot.countRepeatShot = 1; testShot.countRepeatShot = 1;
testShot.speedRollerTop = 200; testShot.speedRollerTop = 200;

97
TODO.md
View File

@ -8,7 +8,7 @@ IR:
V Добавить press and hold V Добавить press and hold
Проверка железа: Проверка железа:
Проверить все PWM V Проверить все PWM
Проверить функции управления железом Проверить функции управления железом
setRollersSpeed setRollersSpeed
setScrewkSpeed setScrewkSpeed
@ -17,7 +17,7 @@ IR:
doShot doShot
Логика работы: Логика работы:
Ограничение минимальных скоростей! V Ограничение минимальных скоростей!
Правильное переключение выстрелов с учётом repeatCount Правильное переключение выстрелов с учётом repeatCount
Переключение выстрелов в программе Переключение выстрелов в программе
Переключение программ в макро Переключение программ в макро
@ -38,97 +38,4 @@ IR:
Ошибки: Ошибки:
В некоторый момент PID регулятор выдаёт 0 и двигатель не запускается не зависимо от входного значенияPWM В некоторый момент 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;
}