diff --git a/.cproject b/.cproject
index f19cb80..2f12af9 100644
--- a/.cproject
+++ b/.cproject
@@ -14,7 +14,7 @@
-
+
@@ -22,7 +22,9 @@
-
+
+
+
@@ -101,26 +103,26 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
-
-
-
+
+
-
+
@@ -181,4 +183,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.settings/stm32cubeide.project.prefs b/.settings/stm32cubeide.project.prefs
index 72a6652..ec30d26 100644
--- a/.settings/stm32cubeide.project.prefs
+++ b/.settings/stm32cubeide.project.prefs
@@ -1,3 +1,4 @@
-66BE74F758C12D739921AEA421D593D3=1
+66BE74F758C12D739921AEA421D593D3=2
+8DF89ED150041C4CBC7CB9A9CAA90856=93F4DF6BEDA92BA75FD1174676FB3EF4
DC22A860405A8BF2F2C095E5B6529F12=93F4DF6BEDA92BA75FD1174676FB3EF4
eclipse.preferences.version=1
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6500f9f
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "stm32-for-vscode.openOCDPath": "C:\\USERS\\DASHYFOX\\APPDATA\\ROAMING\\CODE\\USER\\GLOBALSTORAGE\\BMD.STM32-FOR-VSCODE\\@XPACK-DEV-TOOLS\\OPENOCD\\0.12.0-4.1\\.CONTENT\\BIN\\OPENOCD.EXE",
+ "stm32-for-vscode.makePath": "C:\\USERS\\DASHYFOX\\APPDATA\\ROAMING\\CODE\\USER\\GLOBALSTORAGE\\BMD.STM32-FOR-VSCODE\\@XPACK-DEV-TOOLS\\WINDOWS-BUILD-TOOLS\\4.4.1-2.1\\.CONTENT\\BIN\\MAKE.EXE"
+}
\ No newline at end of file
diff --git a/Core/Inc/EEPROM.h b/Core/Inc/EEPROM.h
new file mode 100644
index 0000000..67e70db
--- /dev/null
+++ b/Core/Inc/EEPROM.h
@@ -0,0 +1,52 @@
+#include "stm32f1xx_hal.h"
+
+#define AT24C_ADRESS 0x50 // i2c slave adress EEPROM
+
+#define FLASH_BLOCKSIZE 64
+#define START_ADR_SHOT 0x0000 //00000
+#define START_ADR_PROGRAM 0x3000 //12288
+#define START_ADR_MACRO 0x6000 //24576
+
+#define MAX_NUMBER_MACRO 100
+#define MAX_NUMBER_SHOTS 160
+#define MAX_NUMBER_PROGRAMS 100
+#define MAX_NUMBER_SHOTS_IN_PROGRAMS 31
+#define MAX_NUMBER_PROGRAMS_IN_MACRO 16
+
+struct StructNumberScrewCount{
+ unsigned char number;
+ unsigned char speedScrew;
+ unsigned char countRepeat;
+ unsigned char options;
+ };
+
+struct StructNumberScrew{
+ unsigned char number;
+ unsigned char speedScrew;
+ };
+
+struct StructShot {
+ unsigned char countRepeatShot;
+ unsigned char speedRollerTop;
+ unsigned char speedRollerBottom;
+ unsigned char speedScrew;
+ unsigned char rotationAxial;
+ unsigned char rotationHorizontal;
+ unsigned char rotationVertical;
+ };
+
+struct StructProgram {
+ unsigned char countRepeat;
+ unsigned char options;
+ struct StructNumberScrew numberScrew[MAX_NUMBER_SHOTS_IN_PROGRAMS];
+ };
+
+struct StructMacro {
+ struct StructNumberScrewCount numberScrewCount[MAX_NUMBER_PROGRAMS_IN_MACRO];
+ };
+
+void SaveShot(unsigned char number, struct StructShot* shot);
+void FLASH_WriteBlock(uint8_t *writeAddr, unsigned char *flashWrBufPtr);
+
+struct StructShot GetShot( unsigned char number );
+
diff --git a/Core/Inc/IR.h b/Core/Inc/IR.h
new file mode 100644
index 0000000..d0123f1
--- /dev/null
+++ b/Core/Inc/IR.h
@@ -0,0 +1,19 @@
+#include "stm32f1xx_hal.h"
+
+#define STATUS_START 0
+#define STATUS_COMMAND 1
+#define STATUS_ADDRESS 2
+#define STATUS_REPEAT 3
+#define STATUS_ERROR 10
+
+extern unsigned char IR_Command;
+extern unsigned char IR_Address;
+
+extern unsigned char IR_CommandNumber[3];
+extern unsigned char IRStatus;
+
+void IR_handler(void);
+void ClearIRStatus(void);
+void ClearIRCommand(void);
+void ClearIR(void);
+void SetShiftReg (unsigned char shiftreg[3]);
diff --git a/Core/Inc/Print.h b/Core/Inc/Print.h
new file mode 100644
index 0000000..b81647a
--- /dev/null
+++ b/Core/Inc/Print.h
@@ -0,0 +1,11 @@
+#include "usbd_cdc_if.h"
+#include // Для функции sprintf
+#include
+#include // Для функции strlen
+
+
+#define BUFFER_SIZE 32 // Размер буфера для строки
+
+void print(char* str);
+void int_to_str(int number, char *str, int base);
+void printNumber(long int number);
diff --git a/Core/Inc/pca9685.h b/Core/Inc/pca9685.h
new file mode 100644
index 0000000..11026bf
--- /dev/null
+++ b/Core/Inc/pca9685.h
@@ -0,0 +1,7 @@
+#include "stm32f1xx_hal.h"
+
+extern I2C_HandleTypeDef hi2c1;
+
+void initPCA9685(void);
+void SetServo(uint8_t channel, uint8_t angel);
+
diff --git a/Core/Src/EEPROM.c b/Core/Src/EEPROM.c
new file mode 100644
index 0000000..875356a
--- /dev/null
+++ b/Core/Src/EEPROM.c
@@ -0,0 +1,67 @@
+#include "EEPROM.h"
+#include "pca9685.h"
+#include "usbd_cdc_if.h"
+
+
+void SaveShot(unsigned char number, struct StructShot* shot)
+{
+ uint16_t blockAddr16 = (uint16_t)(START_ADR_SHOT + (uint16_t)(number*FLASH_BLOCKSIZE));
+
+ uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
+
+ unsigned char Buf[FLASH_BLOCKSIZE];
+
+ for( unsigned char i = 0; i < FLASH_BLOCKSIZE; i++ ) Buf[i] = 0;
+
+ Buf[0] = number;
+ Buf[1] = shot->countRepeatShot;
+ Buf[2] = shot->speedRollerTop;
+ Buf[3] = shot->speedRollerBottom;
+ Buf[4] = shot->speedScrew;
+ Buf[5] = shot->rotationAxial;
+ Buf[6] = shot->rotationHorizontal;
+ Buf[7] = shot->rotationVertical;
+
+ // Writes buffer contents to current block
+ FLASH_WriteBlock(blockAddr, Buf);
+}
+
+struct StructShot GetShot( unsigned char number )
+{
+ struct StructShot shot;
+
+ uint16_t blockAddr16 = (uint16_t)(START_ADR_SHOT + (uint16_t)(number*FLASH_BLOCKSIZE));
+
+ uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
+
+ unsigned char Buf[FLASH_BLOCKSIZE];
+
+
+ HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 10);
+ HAL_Delay(1);
+ HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1), Buf, FLASH_BLOCKSIZE, 10);
+ HAL_Delay(1);
+
+ shot.countRepeatShot = Buf[1];
+ shot.speedRollerTop = Buf[2];
+ shot.speedRollerBottom = Buf[3];
+ shot.speedScrew = Buf[4];
+ shot.rotationAxial = Buf[5];
+ shot.rotationHorizontal = Buf[6];
+ shot.rotationVertical = Buf[7];
+
+ return shot;
+}
+
+
+void FLASH_WriteBlock(uint8_t *writeAddr, unsigned char *flashWrBufPtr)
+{
+ unsigned char Buf[FLASH_BLOCKSIZE+2];
+ Buf[0] = writeAddr[0];
+ Buf[1] = writeAddr[1];
+
+ for( unsigned char i = 0; i < (FLASH_BLOCKSIZE); i++ ) Buf[i+2] = flashWrBufPtr[i];
+
+ HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), Buf, (FLASH_BLOCKSIZE + 2), 10);
+ HAL_Delay(1);
+}
diff --git a/Core/Src/IR.c b/Core/Src/IR.c
new file mode 100644
index 0000000..af557d6
--- /dev/null
+++ b/Core/Src/IR.c
@@ -0,0 +1,199 @@
+#include "IR.h"
+#include "usbd_cdc_if.h"
+#include "Print.h"
+
+unsigned char IR_Command;
+unsigned char IR_Address;
+unsigned char IR_OptionsProgram;
+unsigned char IR_IndexBitCommand;
+unsigned char IR_IndexBitAddress;
+
+unsigned int IR_Pulse;
+unsigned int currentIR_Pulse;
+
+unsigned char IR_CommandNumber[3];
+unsigned char IRStatus;
+unsigned char NumberMacroProgramShot;
+unsigned char NumberShot;
+unsigned char NumberProgram;
+unsigned char NumberMacro;
+unsigned char CommandMacroProgramShot;
+
+void IR_handler() // SONY (SIRC) protocol 12 bit (7+5)
+{
+
+ if ((GPIOB->IDR & 0x0002) == 0)
+ {
+ IR_Pulse = SysTick->VAL;
+ // GPIOC->ODR ^= GPIO_PIN_13;
+ }
+ else
+ {
+ {
+ currentIR_Pulse = SysTick->VAL;
+
+ if (currentIR_Pulse > IR_Pulse)
+ {
+ currentIR_Pulse = IR_Pulse + 479999 - currentIR_Pulse;
+ }
+ else
+ {
+ currentIR_Pulse = IR_Pulse - currentIR_Pulse;
+ }
+
+ // if (currentIR_Pulse > 150000 ) currentIR_Pulse = 0xFFFFFFFF - currentIR_Pulse;
+
+ switch (IRStatus)
+ {
+ case STATUS_START:
+ {
+ if ((currentIR_Pulse < 130000) && (currentIR_Pulse > 110000)) // 2,7 ms - 2,3 ms
+ {
+ IRStatus = STATUS_COMMAND; // 129600 - 110400
+ print("STATUS_COMMAND\n");
+ }
+ else
+ {
+ IRStatus = STATUS_ERROR;
+ }
+ }
+ break;
+
+ case STATUS_COMMAND:
+ {
+
+ if (currentIR_Pulse < 37440) // 0.78 ms 37440
+ {
+ IR_Command &= ~((1 << IR_IndexBitCommand) & 0xFF);
+ print("0");
+ }
+ else
+ {
+ IR_Command |= ((1 << IR_IndexBitCommand) & 0xFF);
+ print("1");
+ }
+
+ IR_IndexBitCommand++;
+ if (IR_IndexBitCommand == 7)
+ {
+ IRStatus = STATUS_ADDRESS;
+ print(" STATUS_ADDRESS ");
+ }
+ else
+ {
+ IRStatus = STATUS_COMMAND;
+ }
+ }
+ break;
+
+ case STATUS_ADDRESS:
+ {
+
+ {
+ if (currentIR_Pulse < 37440) // 0.78 ��
+ {
+ IR_Address &= ~((1 << IR_IndexBitAddress) & 0xFF);
+ print("0");
+ }
+ else
+ {
+ IR_Address |= ((1 << IR_IndexBitAddress) & 0xFF);
+ print("1");
+ }
+
+ IR_IndexBitAddress++;
+ if (IR_IndexBitAddress == 5)
+ {
+ IRStatus = STATUS_REPEAT;
+ print("\n\n\n");
+ }
+ else
+ {
+ IRStatus = STATUS_ADDRESS;
+ }
+ }
+ }
+ break;
+ case STATUS_REPEAT:
+ break;
+
+ case STATUS_ERROR:
+ print("STATUS_ERROR\n\n");
+ default:
+ ClearIRStatus();
+
+ break;
+ }
+ }
+ }
+}
+
+void ClearIRStatus()
+{
+ IR_IndexBitCommand = 0x00;
+ IR_IndexBitAddress = 0x00;
+ IRStatus = STATUS_START;
+}
+
+void ClearIRCommand()
+{
+ IR_CommandNumber[0] = 0xFF;
+ IR_CommandNumber[1] = 0xFF;
+ IR_CommandNumber[2] = 0xFF;
+}
+
+void ClearIR()
+{
+ IR_Command = 0x7F;
+ IR_Address = 0x1F;
+ IR_OptionsProgram = 0x00;
+
+ NumberMacroProgramShot = 0xFF;
+ NumberShot = 0xFF;
+ NumberProgram = 0xFF;
+ NumberMacro = 0xFF;
+
+ CommandMacroProgramShot = 0x00;
+
+ ClearIRStatus();
+}
+
+void SetShiftReg(unsigned char shiftreg[3])
+{
+ for (unsigned char i = 0; i < 3; i++)
+ {
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ for (unsigned char j = 0; j < 8; j++)
+ {
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // ��� ��������
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+
+ if (((shiftreg[i] >> j) & 0x01) == 0x01)
+ {
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
+ }
+ else
+ {
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
+ }
+
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // ��� ��������
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ }
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ }
+}
diff --git a/Core/Src/Print.c b/Core/Src/Print.c
new file mode 100644
index 0000000..abf0080
--- /dev/null
+++ b/Core/Src/Print.c
@@ -0,0 +1,53 @@
+/*
+ * Print.c
+ *
+ * Created on: Aug 19, 2024
+ * Author: DashyFox
+ */
+#include "Print.h"
+
+void print(char* str){
+ unsigned int size = 0;
+ while (str[size] != '\0')
+ {
+ size++;
+ }
+ CDC_Transmit_FS((unsigned char*)str, size);
+}
+
+void int_to_str(int number, char *str, int base)
+{
+ static const char digits[] = "0123456789ABCDEF";
+ char buffer[32];
+ char *ptr = buffer + sizeof(buffer) - 1;
+ int is_negative = 0;
+
+ if (number < 0 && base == 10) {
+ is_negative = 1;
+ number = -number;
+ }
+
+ *ptr = '\0';
+ do {
+ *--ptr = digits[number % base];
+ number /= base;
+ } while (number);
+
+ if (is_negative) {
+ *--ptr = '-';
+ }
+
+ strcpy(str, ptr);
+}
+
+void printNumber(long int number)
+{
+ char buffer[BUFFER_SIZE];
+
+ // Преобразование числа в строку
+ int_to_str(number, buffer, 10); // 10 — это основание системы счисления (десятичная система)
+ strcat(buffer, "\r\n"); // Добавление новой строки
+
+ // Отправка строки через USB CDC
+ CDC_Transmit_FS((uint8_t*)buffer, strlen(buffer));
+}
diff --git a/Core/Src/main.c b/Core/Src/main.c
index 1c8f1ff..daee3c7 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -23,6 +23,11 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
+ #include "usbd_cdc_if.h"
+ #include "pca9685.h"
+ #include "IR.h"
+ #include "EEPROM.h"
+#include "Print.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -51,6 +56,40 @@ UART_HandleTypeDef huart3;
/* USER CODE BEGIN PV */
+uint8_t txdata[64];
+uint8_t rxdata[64];
+uint8_t velosety[600];
+uint8_t rxcomlite = 0;
+uint8_t initcomlete = 0;
+
+unsigned char Shiftreg[3];
+
+uint8_t rejim[60]; // 0 - chislo rejimov, 1-6 - rejim1, 7-12 - rejim2...
+uint8_t avto = 0; // vkl/otkl avtomaticheskoi raboti
+uint8_t rejim_number = 1; // nomer tekyshego rejima
+
+uint8_t Vz1 = 100;
+uint8_t Vz2 = 100;
+
+uint16_t vi = 0;
+
+uint16_t timing1 = 0;
+uint16_t timing2 = 0;
+
+
+
+uint8_t MYIR_command = 0;
+
+volatile uint32_t millisCounter = 0;
+ uint32_t previousMillis = 0;
+
+
+ struct StructShot BufShots[MAX_NUMBER_SHOTS];
+ struct StructProgram BufPrograms;
+ struct StructMacro BufMacro;
+
+ extern PCD_HandleTypeDef hpcd_USB_FS;
+
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@@ -94,7 +133,15 @@ int main(void)
SystemClock_Config();
/* USER CODE BEGIN SysInit */
+ // Установка приоритета прерывания
+// NVIC_SetPriority(SysTick_IRQn, 0);
+ // Настройка SysTick таймера на 1 мс
+ SysTick->LOAD = 479999; // 1ms Sys timer
+// SysTick_Config(SystemCoreClock / 1000);
+ __HAL_RCC_USB_FORCE_RESET();
+ HAL_Delay(10);
+ __HAL_RCC_USB_RELEASE_RESET();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
@@ -107,12 +154,151 @@ int main(void)
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
+ HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); //PA8
+ HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); //PA9
+
+ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); //PA0
+ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); //PA1
+ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //PA2
+ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4); //PA3
+
+ initPCA9685();
+
+ //BufShots[0].countRepeatShot = 5;
+ //BufShots[0].speedRollerTop = 120;
+ //BufShots[0].speedRollerBottom = 130;
+ //BufShots[0].speedScrew = 50;
+ //BufShots[0].rotationAxial = 90;
+ //BufShots[0].rotationHorizontal = 90;
+ //BufShots[0].rotationVertical = 90;
+
+ // SaveShot(0, &BufShots[0]);
+
+ // BufShots[1] = GetShot(0);
+
+initcomlete = 1;
+
+ Shiftreg[0] = 0x00; Shiftreg[1] = 0x44; Shiftreg[2] = 0x00; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x00; Shiftreg[1] = 0x66; Shiftreg[2] = 0x00; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x00; Shiftreg[1] = 0x77; Shiftreg[2] = 0x00; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x01; Shiftreg[1] = 0x77; Shiftreg[2] = 0x01; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x03; Shiftreg[1] = 0x77; Shiftreg[2] = 0x03; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x07; Shiftreg[1] = 0x77; Shiftreg[2] = 0x07; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x0F; Shiftreg[1] = 0x77; Shiftreg[2] = 0x0F; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x1F; Shiftreg[1] = 0x77; Shiftreg[2] = 0x1F; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x3F; Shiftreg[1] = 0x77; Shiftreg[2] = 0x3F; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x7F; Shiftreg[1] = 0x77; Shiftreg[2] = 0x7F; SetShiftReg(Shiftreg); HAL_Delay(10);
+ Shiftreg[0] = 0x00; Shiftreg[1] = 0x00; Shiftreg[2] = 0x00; SetShiftReg(Shiftreg); HAL_Delay(10);
+
+
+
+ HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); // ������ �� ������ 1 �6 ������ ��� ��������� �� PA0 PA1
+ HAL_TIM_Base_Start_IT(&htim3);
+ HAL_NVIC_EnableIRQ(TIM3_IRQn);
+
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
+ if (IRStatus == STATUS_REPEAT) {
+ if (IR_Address == 0x01) MYIR_command = IR_Command;
+ CDC_Transmit_FS(&MYIR_command, 1);
+ ClearIRStatus();
+ }
+
+ if (rxcomlite == 1) {
+
+ txdata[0] = 'O'; txdata[1] = 'K'; txdata[2] = '?';
+
+ switch (rxdata[0]) {
+
+ case 1: { SetServo(0, rxdata[1] ); txdata[0] = 'O'; txdata[1] = 'K';
+ txdata[2] = '1'; CDC_Transmit_FS(txdata, 3); break; }
+
+ case 2: { SetServo(1, rxdata[1] ); txdata[0] = 'O'; txdata[1] = 'K';
+ txdata[2] = '2'; CDC_Transmit_FS(txdata, 3); break; }
+
+ case 3: { SetServo(2, rxdata[1] ); txdata[0] = 'O'; txdata[1] = 'K';
+ txdata[2] = '3'; CDC_Transmit_FS(txdata, 3); break; }
+
+ case 4: { SetServo(0, rxdata[1] ); SetServo(1, rxdata[2] ); SetServo(2, rxdata[3] );
+
+ Vz1 = rxdata[4]; //rolic verh 0..200
+ Vz2 = rxdata[5]; //rolic niz 0..200
+ vi = 0;
+
+ //shnek 0..100
+ if (rxdata[6] < 101) { TIM1->CCR1 = 0; TIM1->CCR2 = (uint16_t)(40*rxdata[6]); } else
+ { TIM1->CCR1 = 0; TIM1->CCR2 = 4000;}
+
+ txdata[0] = 'O'; txdata[1] = 'K'; txdata[2] = '4'; CDC_Transmit_FS(txdata, 3); break; }
+
+ case 5: {txdata[0] = LOBYTE(timing1) ; txdata[1] = HIBYTE(timing1) ;
+ CDC_Transmit_FS(txdata, 3); break; }
+ case 6: { CDC_Transmit_FS(velosety, 600); break; }
+
+ case 7: { rejim[0] = rxdata[1];
+ // copy to buffer
+ for (uint8_t i = 0; i < rejim[0]; i++)
+ {
+ rejim[(i*6)+1] = rxdata[(i*6)+2];
+ rejim[(i*6)+2] = rxdata[(i*6)+3];
+ rejim[(i*6)+3] = rxdata[(i*6)+4];
+ rejim[(i*6)+4] = rxdata[(i*6)+5];
+ rejim[(i*6)+5] = rxdata[(i*6)+6];
+ rejim[(i*6)+6] = rxdata[(i*6)+7];
+ }
+ // set rejim #1
+ SetServo(0, rejim[1] );
+ SetServo(1, rejim[2] );
+ SetServo(2, rejim[3] );
+ Vz1 = rejim[4];
+ Vz2 = rejim[5];
+ TIM1->CCR1 = 0; TIM1->CCR2 = (uint16_t)(40*rejim[6]);
+ // set avto
+ rejim_number = 1;
+ avto = 1;
+ break; }
+ case 8: { // stop avto
+ avto = 0; rejim_number = 1;
+ // stop mecanics
+ SetServo(0, 90);
+ SetServo(1, 90);
+ SetServo(2, 90);
+ Vz1 = 100;
+ Vz2 = 100;
+ TIM1->CCR1 = 0; TIM1->CCR2 = 0;
+
+ break; }
+
+ case 9: { txdata[0] = avto ;
+ txdata[1] = rejim_number;
+ CDC_Transmit_FS(txdata, 3);
+
+ break; }
+
+ default: break;
+ }
+
+
+ rxcomlite = 0;
+
+// // HAL_Delay(1000);
+
+ }
+
+
+ uint32_t currentMillis = millisCounter;
+ if (currentMillis - previousMillis >= 500) {
+ previousMillis = currentMillis;
+ GPIOC->ODR ^= GPIO_PIN_13;
+// unsigned char text[] = "Hello\n";
+// printNumber(SysTick->LOAD);
+// CDC_Transmit_FS(text, sizeof(text));
+ }
+
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
@@ -359,7 +545,7 @@ static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
-
+ __HAL_RCC_TIM3_CLK_ENABLE();
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
@@ -463,7 +649,7 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, LED_DATA_Pin|LED_CLK_Pin, GPIO_PIN_RESET);
@@ -518,8 +704,10 @@ void Error_Handler(void)
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
+// GPIOC->ODR &= ~GPIO_PIN_13;
while (1)
{
+
}
/* USER CODE END Error_Handler_Debug */
}
diff --git a/Core/Src/pca9685.c b/Core/Src/pca9685.c
new file mode 100644
index 0000000..fb1fefc
--- /dev/null
+++ b/Core/Src/pca9685.c
@@ -0,0 +1,37 @@
+#include "pca9685.h"
+
+extern I2C_HandleTypeDef hi2c1; // hendl for i2c
+
+#define PCA9685_ADRESS 0x40 // i2c slave adress pca9685
+
+uint8_t PRESCALE_REG[2] = {0xFE,0x79}; // prescale = 121 (50 Hz)
+uint8_t MODE1_REG[2] = {0x00,0x20}; // Auto increment mode, sleep out
+
+void initPCA9685(void)
+{
+ HAL_I2C_Master_Transmit(&hi2c1, (PCA9685_ADRESS << 1), PRESCALE_REG, 2, 10);
+ HAL_Delay(1);
+ HAL_I2C_Master_Transmit(&hi2c1, (PCA9685_ADRESS << 1), MODE1_REG, 2, 10);
+ HAL_Delay(1);
+}
+
+void SetServo(uint8_t channel, uint8_t angel)
+{
+ uint8_t bufer[5];
+ uint16_t A;
+
+ if (angel > 180) { angel = 180;} //check for scale 0..180
+
+ A = 150 + ((angel*15)>>3); //get puls time for servo from min to max
+ // min 150/4095
+ // max 488/4095
+
+ bufer[0] = 6 + channel*4; //channel register adress
+ bufer[1] = 0; //start time for "on" Lowbyte (0..4095)
+ bufer[2] = 0; //start time for "on" HIbyte
+ bufer[3] = A&0xFF; //start time for "off" Lowbyte (0..4095)
+ bufer[4] = A>>8;; //start time for "off" HIbyte
+
+ HAL_I2C_Master_Transmit(&hi2c1, (PCA9685_ADRESS << 1), bufer, 5, 10);
+}
+
diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c
index dc352f0..cc2ec22 100644
--- a/Core/Src/stm32f1xx_it.c
+++ b/Core/Src/stm32f1xx_it.c
@@ -22,6 +22,11 @@
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
+#include "pca9685.h"
+#include "IR.h"
+
+#include "usb_device.h"
+#include "usbd_cdc_if.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -41,17 +46,103 @@
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
+extern volatile uint32_t millisCounter;
+
+uint8_t myi;
+//uint8_t ticktime = 0; //����������-������� ����������� ����� 0,01 �
+uint8_t update1 = 0; //���� ������������ ������� ������� 0 ��� 1
+uint8_t update2 = 0;
+extern uint16_t vi; //������� ���������� ������ ��� �� 0..599
+uint16_t v1[30]; //������ ��������� (�������) [0] - ����� ���������, [1-29] - ������
+uint16_t v2[30];
+
+uint32_t vt1 = 0; //����������� �������� (�� ������� ���������) (�������)
+uint32_t vt2 = 0;
+
+uint16_t vs1[4] = {0,0,0,0}; //������ ����������� �������� �� 3 ���������
+uint16_t vs2[4] = {0,0,0,0}; //[0] - ������� �������� ��������
+ //[1-3] - �������� �� vt
+
+uint32_t vsk1 = 0; //���������� ������� �������� (�������)
+uint32_t vsk2 = 0;
+
+uint16_t Vzad1 = 0; //������� �������� �������� ������
+uint16_t Vupr1 = 0; //������� ��� �������� ������
+
+uint16_t Vzad2 = 0; //������� �������� ������� ������
+uint16_t Vupr2 = 0; //������� ��� ������� ������
+
+
+extern uint8_t rejim[60]; // 0 - chislo rejimov, 1-6 - rejim1, 7-12 - rejim2...
+extern uint8_t avto; // vkl/otkl avtomaticheskoi raboti
+extern uint8_t rejim_number; // nomer tekyshego rejima
+
+
+
+extern uint8_t initcomlete;
+extern uint16_t timing1; //���������� ��������
+extern uint16_t timing2; //���������� ��������
+extern uint8_t velosety[600]; //����� � ������� ��� ��
+
+extern uint8_t Vz1;
+extern uint8_t Vz2;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
-
+int32_t computePID1(uint16_t input, uint16_t setpoint);
+int32_t computePID2(uint16_t input, uint16_t setpoint);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
+int32_t computePID1(uint16_t input, uint16_t setpoint)
+{
+ static int32_t integral = 0, prevErr = 0; // ������������ ������������ � ���������� ������
+ int32_t err = setpoint - input; //1.������
+
+ integral = integral + err/20; //2.������������ ������������ dt = 0.01, ki = 5;
+
+ if (integral > 4000) { integral = 4000;}
+ if (integral < 0) { integral = 0;}
+
+ int32_t D = (err - prevErr); //3.���������������� ������������ dt = 0.01, kd = 0.01
+ if (D > 4000) { D = 4000;}
+ if (D < 0) { D = 0;}
+
+ prevErr = err;
+ //
+ int32_t Rout = ((err * 3)>>1) + integral + D; //4. �=1,5 + �=5 + �=0.01
+ if (Rout > 4000) { Rout = 4000;} //
+ if (Rout < 0) { Rout = 0;} //
+
+ return Rout;
+}
+
+
+int32_t computePID2(uint16_t input, uint16_t setpoint)
+{
+ static int32_t integral = 0, prevErr = 0; // ������������ ������������ � ���������� ������
+ int32_t err = setpoint - input; //1.������
+
+ integral = integral + err/20; //2.������������ ������������ dt = 0.01, ki = 5;
+ if (integral > 4000) { integral = 4000;}
+ if (integral < 0) { integral = 0;}
+
+ int32_t D = (err - prevErr); //3.���������������� ������������ dt = 0.01, kd = 0.01
+ if (D > 4000) { D = 4000;}
+ if (D < 0) { D = 0;}
+
+ prevErr = err;
+ //
+ int32_t Rout = ((err * 3)>>1) + integral + D; //4. �=1,5 + �=5 + �=0.01
+ if (Rout > 4000) { Rout = 4000;} //
+ if (Rout < 0) { Rout = 0;} //
+
+ return Rout;
+}
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
@@ -186,6 +277,95 @@ void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
+ //��������� ������� ��������� ��������� 1
+ if (v1[0] > 0) { //��������� ���� �� ���������� ������ � ������ ���������
+ //������� ������� ��������
+ vt1 = 0;
+ for (uint8_t i = 1; i <= v1[0]; i++) { vt1 += v1[i]; }
+ vt1 = vt1/v1[0];
+ //���� �� ����� ������ ���, �� ����� ��������� ���������� ��������
+ //��������
+ }
+ else {vt1 = timing1; }
+ v1[0] = 0; // �������� ������� ��������� ������� ���������
+ // ������ ������ �������� ������
+
+
+ //��������� ������� ��������� ��������� 2
+ if (v2[0] > 0) { //��������� ���� �� ���������� ������ � ������ ���������
+ //������� ������� ��������
+ vt2 = 0;
+ for (uint8_t i = 1; i <= v2[0]; i++) { vt2 += v2[i]; }
+ vt2 = vt2/v2[0];
+ //���� �� ����� ������ ���, �� ����� ��������� ���������� ��������
+ //��������
+ }
+ else {vt2 = timing2; }
+ v2[0] = 0; // �������� ������� ��������� ������� ���������
+ // ������ ������ �������� ������
+
+
+ //���������� ������� �� 3
+if (vs1[0] < 3) { vs1[vs1[0]+1] = (uint16_t)vt1; vs1[0]++; } else
+ {vs1[0] = 0; vs1[vs1[0]+1] = (uint16_t)vt1; vs1[0]++; }
+
+ vsk1 = (vs1[1]+vs1[2]+vs1[3])/3;
+
+if (vs2[0] < 3) { vs2[vs2[0]+1] = (uint16_t)vt2; vs2[0]++; } else
+ {vs2[0] = 0; vs2[vs2[0]+1] = (uint16_t)vt2; vs2[0]++; }
+
+ vsk2 = (vs2[1]+vs2[2]+vs2[3])/3;
+
+
+ // ������� ������� ����� ���������� � �������� 60*1000000/(�*10)
+ if (vsk1 != 0) {vsk1 = 6000000/vsk1;} else { vsk1 = 0;}
+ if (vsk1 > 10000) vsk1 = 10000;
+ if (vsk1 < 150) vsk1 = 0;
+
+ if (vsk2 != 0) {vsk2 = 6000000/vsk2;} else { vsk2 = 0;}
+ if (vsk2 > 10000) vsk2 = 10000;
+ if (vsk2 < 150) vsk2 = 0;
+
+
+ // ������� ��������� �������� 0 - 200 � -8000 ... 8000 ��./���.
+ if (Vz1 > 100) { Vzad1 = (Vz1 - 100)*80; } else { Vzad1 = (100 - Vz1)*80; }
+ if (Vz2 > 100) { Vzad2 = (Vz2 - 100)*80; } else { Vzad2 = (100 - Vz2)*80; }
+
+ // ���������
+ Vupr1 = (uint16_t)computePID1(vsk1, Vzad1);
+ Vupr2 = (uint16_t)computePID2(vsk2, Vzad2);
+
+ if (Vz1 > 100) { TIM2->CCR2 = 0; TIM2->CCR1 = Vupr1;} else
+ { TIM2->CCR1 = 0; TIM2->CCR2 = Vupr1;}
+
+ if (Vz2 > 100) { TIM2->CCR3 = 0; TIM2->CCR4 = Vupr2;} else
+ { TIM2->CCR4 = 0; TIM2->CCR3 = Vupr2;}
+
+
+ // ������ ���������� �������� � ����� ��� ��
+if (vi < 600) { velosety[vi] = LOBYTE(timing1);
+ velosety[vi+1] = HIBYTE(timing1);
+ velosety[vi+2] = LOBYTE(vsk1);
+ velosety[vi+3] = HIBYTE(vsk1);
+ velosety[vi+4] = LOBYTE(vsk2);
+ velosety[vi+5] = HIBYTE(vsk2);
+ vi = vi + 6; }
+
+ // else
+ // {vi = 0;
+ // velosety[vi] = LOBYTE(timing1);
+ // velosety[vi+1] = HIBYTE(timing1);
+ // velosety[vi+2] = LOBYTE(vt);
+ // velosety[vi+3] = HIBYTE(vt);
+ // velosety[vi+4] = LOBYTE(vsk);
+ // velosety[vi+5] = HIBYTE(vsk);
+ // vi = vi + 6; }
+
+
+
+
+
+ millisCounter+=10; // костыльная примерная коррекция
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
@@ -206,7 +386,17 @@ void SysTick_Handler(void)
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
+ if (avto == 1) { if (rejim_number < rejim[0]) rejim_number++; else rejim_number = 1;
+ SetServo(0, rejim[1 + (rejim_number-1)*6] );
+ SetServo(1, rejim[2 + (rejim_number-1)*6] );
+ SetServo(2, rejim[3 + (rejim_number-1)*6] );
+ Vz1 = rejim[4 + (rejim_number-1)*6];
+ Vz2 = rejim[5 + (rejim_number-1)*6];
+ TIM1->CCR1 = 0; TIM1->CCR2 = (uint16_t)(40*rejim[6 + (rejim_number-1)*6]);
+ vi = 0; // zapis grafika start
+
+ }
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(BALL_EXT_Pin);
/* USER CODE BEGIN EXTI0_IRQn 1 */
@@ -220,7 +410,7 @@ void EXTI0_IRQHandler(void)
void EXTI1_IRQHandler(void)
{
/* USER CODE BEGIN EXTI1_IRQn 0 */
-
+ IR_handler();
/* USER CODE END EXTI1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(IR_EXT_Pin);
/* USER CODE BEGIN EXTI1_IRQn 1 */
@@ -249,6 +439,71 @@ void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
+ static uint32_t prev_capture1 = 0;
+ static uint32_t prev_capture2 = 0;
+
+ uint32_t current_capture1 = 0;
+ uint32_t current_capture2 = 0;
+ uint32_t elapsed_time1 = 0;
+ uint32_t elapsed_time2 = 0;
+
+ /* USER CODE BEGIN TIM3_IRQn 0 */
+
+ // Обработка переполнения таймера
+ if (TIM3->SR & TIM_SR_UIF)
+ {
+ // Сброс флага переполнения
+ TIM3->SR &= ~TIM_SR_UIF;
+ }
+
+ // Обработка захвата сигнала для канала 1
+ if (TIM3->SR & TIM_SR_CC1IF)
+ {
+ current_capture1 = TIM3->CCR1;
+
+ if (current_capture1 >= prev_capture1) {
+ elapsed_time1 = current_capture1 - prev_capture1;
+ } else {
+ // Учёт переполнения таймера
+ elapsed_time1 = (65000 - prev_capture1) + current_capture1 + 1;
+ }
+
+ // Ограничение значения для сохранения в 16-битную переменную
+ if (elapsed_time1 > 65535) {
+ timing1 = 65535; // Максимальное значение
+ } else {
+ timing1 = (uint16_t)elapsed_time1;
+ }
+
+ prev_capture1 = current_capture1;
+ TIM3->SR &= ~TIM_SR_CC1IF; // Сброс флага захвата сигнала
+ update1 = 0;
+ }
+
+ // Обработка захвата сигнала для канала 2
+ if (TIM3->SR & TIM_SR_CC2IF)
+ {
+ current_capture2 = TIM3->CCR2;
+
+ if (current_capture2 >= prev_capture2) {
+ elapsed_time2 = current_capture2 - prev_capture2;
+ } else {
+ // Учёт переполнения таймера
+ elapsed_time2 = (65000 - prev_capture2) + current_capture2 + 1;
+ }
+
+ // Ограничение значения для сохранения в 16-битную переменную
+ if (elapsed_time2 > 65535) {
+ timing2 = 65535; // Максимальное значение
+ } else {
+ timing2 = (uint16_t)elapsed_time2;
+ }
+
+ prev_capture2 = current_capture2;
+ TIM3->SR &= ~TIM_SR_CC2IF; // Сброс флага захвата сигнала
+ update2 = 0;
+ }
+
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
diff --git a/StackSport.ioc b/StackSport.ioc
index 6acc5a9..71b1cd1 100644
--- a/StackSport.ioc
+++ b/StackSport.ioc
@@ -138,9 +138,10 @@ PB7.GPIOParameters=GPIO_Label
PB7.GPIO_Label=SDA
PB7.Mode=I2C
PB7.Signal=I2C1_SDA
-PC13-TAMPER-RTC.GPIOParameters=GPIO_Speed
+PC13-TAMPER-RTC.GPIOParameters=GPIO_Speed,PinState
PC13-TAMPER-RTC.GPIO_Speed=GPIO_SPEED_FREQ_LOW
PC13-TAMPER-RTC.Locked=true
+PC13-TAMPER-RTC.PinState=GPIO_PIN_SET
PC13-TAMPER-RTC.Signal=GPIO_Output
PD0-OSC_IN.Mode=HSE-External-Oscillator
PD0-OSC_IN.Signal=RCC_OSC_IN
@@ -238,7 +239,8 @@ USART3.VirtualMode=VM_ASYNC
USB_DEVICE.APP_RX_DATA_SIZE=64
USB_DEVICE.APP_TX_DATA_SIZE=64
USB_DEVICE.CLASS_NAME_FS=CDC
-USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,APP_RX_DATA_SIZE,APP_TX_DATA_SIZE
+USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,APP_RX_DATA_SIZE,APP_TX_DATA_SIZE,MANUFACTURER_STRING
+USB_DEVICE.MANUFACTURER_STRING=StackSport
USB_DEVICE.VirtualMode=Cdc
USB_DEVICE.VirtualModeFS=Cdc_FS
VP_SYS_VS_Systick.Mode=SysTick
diff --git a/USB_DEVICE/App/usbd_desc.c b/USB_DEVICE/App/usbd_desc.c
index 5f34238..16c563a 100644
--- a/USB_DEVICE/App/usbd_desc.c
+++ b/USB_DEVICE/App/usbd_desc.c
@@ -64,7 +64,7 @@
#define USBD_VID 1155
#define USBD_LANGID_STRING 1033
-#define USBD_MANUFACTURER_STRING "STMicroelectronics"
+#define USBD_MANUFACTURER_STRING "StackSport"
#define USBD_PID_FS 22336
#define USBD_PRODUCT_STRING_FS "STM32 Virtual ComPort"
#define USBD_CONFIGURATION_STRING_FS "CDC Config"