diff --git a/.cproject b/.cproject index f19cb80..2f12af9 100644 --- a/.cproject +++ b/.cproject @@ -14,7 +14,7 @@ - + + + + + + + + + \ 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"