舵輪時鐘-STM32-28路PWM--ESP8266-NTP時間

1.STM32--PWM生成

STM32不具備如此多的PWM,因此采用軟件定時器的方案實現:

使用hal庫實現;

main.c

#include "main.h"#define close1 500#define open 1500#define close 2500// 定時器中斷配置(以TIM2為例)
void TIM2_IRQ_Init(void) {time_init();
}// 初始化舵機GPIO
void Servo_GPIO_Init(void) {GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOA_CLK_ENABLE();                   /* GPIOA時鐘使能 */// 初始化GPIOA PA0-PA7gpio_init_struct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7| GPIO_PIN_8| GPIO_PIN_11;                   /* 引腳 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽輸出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(GPIOA, &gpio_init_struct);       /* 初始化GPIOA引腳 */// 初始化GPIOA PB0-PB15	__HAL_RCC_GPIOB_CLK_ENABLE(); gpio_init_struct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7|GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 |GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;                   /* 引腳 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽輸出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(GPIOB, &gpio_init_struct);       /* 初始化GPIOB引腳 */// 初始化GPIOA PC13-PA15	__HAL_RCC_GPIOB_CLK_ENABLE(); gpio_init_struct.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;                   /* 引腳 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽輸出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(GPIOC, &gpio_init_struct);       /* 初始化GPIOC引腳 */}// 設置舵機脈寬(通道0-29)
void Set_Servo_Pulse(uint8_t ch, uint16_t pulse_us) {if(ch >= SERVO_NUM) return;if(pulse_us < 500) pulse_us = 500;   // 限制最小脈寬if(pulse_us > 2500) pulse_us = 2500; // 限制最大脈寬servo[ch].pulse_us = pulse_us;       // 更新目標脈寬
}uint8_t TIME_HOUR_24h=0;
// 主函數
int main(void) {int XB=0;HAL_Init();                         /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設置時鐘, 72Mhz */delay_init(72);                     /* 延時初始化 */led_init();		//PC13usart_init(115200);				//PA9/PA10// 初始化舵機GPIO結構體(示例部分引腳)servo[0].GPIOx = GPIOB; servo[0].GPIO_Pin = GPIO_PIN_0;servo[1].GPIOx = GPIOB; servo[1].GPIO_Pin = GPIO_PIN_1;servo[2].GPIOx = GPIOB; servo[2].GPIO_Pin = GPIO_PIN_5;servo[3].GPIOx = GPIOB; servo[3].GPIO_Pin = GPIO_PIN_6;servo[4].GPIOx = GPIOB; servo[4].GPIO_Pin = GPIO_PIN_7;servo[5].GPIOx = GPIOB; servo[5].GPIO_Pin = GPIO_PIN_8;servo[6].GPIOx = GPIOB; servo[6].GPIO_Pin = GPIO_PIN_9;servo[7].GPIOx = GPIOB; servo[7].GPIO_Pin = GPIO_PIN_10;servo[8].GPIOx = GPIOB; servo[8].GPIO_Pin = GPIO_PIN_11;servo[9].GPIOx = GPIOB; servo[9].GPIO_Pin = GPIO_PIN_12;servo[10].GPIOx = GPIOB; servo[10].GPIO_Pin = GPIO_PIN_13;servo[11].GPIOx = GPIOB; servo[11].GPIO_Pin = GPIO_PIN_14;servo[12].GPIOx = GPIOB; servo[12].GPIO_Pin = GPIO_PIN_15;servo[13].GPIOx = GPIOA; servo[13].GPIO_Pin = GPIO_PIN_0;servo[14].GPIOx = GPIOA; servo[14].GPIO_Pin = GPIO_PIN_1;servo[15].GPIOx = GPIOA; servo[15].GPIO_Pin = GPIO_PIN_2;servo[16].GPIOx = GPIOA; servo[16].GPIO_Pin = GPIO_PIN_3;servo[17].GPIOx = GPIOA; servo[17].GPIO_Pin = GPIO_PIN_4;servo[18].GPIOx = GPIOA; servo[18].GPIO_Pin = GPIO_PIN_5;servo[19].GPIOx = GPIOA; servo[19].GPIO_Pin = GPIO_PIN_6;servo[20].GPIOx = GPIOA; servo[20].GPIO_Pin = GPIO_PIN_7;servo[21].GPIOx = GPIOA; servo[21].GPIO_Pin = GPIO_PIN_8;servo[22].GPIOx = GPIOA; servo[22].GPIO_Pin = GPIO_PIN_11;// ... 繼續初始化剩余28個舵機的GPIO信息Servo_GPIO_Init();    // 初始化GPIOTIM2_IRQ_Init();      // 配置定時器中斷while(1) {// 在此添加舵機控制邏輯(示例:通道0擺動)switch  (g_usart1_rx_flag){case 0:
//					printf("AT+CWJAP_DEF=\"iPhone\",\"mm123456789\"\r\n");printf("AT+CWJAP=\"Mm\",\"mjmhyw15891443374!\"\r\n");	  		delay_ms(6000);break;case 20:printf("AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\n");delay_ms(1000);break;case 10:printf("AT+CIPSNTPTIME?\r\n");delay_ms(100);break;case 1:printf("AT+CIPSNTPTIME?\r\n");delay_ms(50);if(g_usart1_rx_flag==1){if((TIME_HOUR_24h<7)||(TIME_HOUR_24h>22));else{XB=0;switch (time_min[1]){case 0:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, close);break;case 1:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 2:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 3:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 4:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 5:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 6:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 7:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 8:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 9:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;	default:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;		}XB=1*7;switch (time_min[0]){case 0:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, close);break;case 1:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 2:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 3:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 4:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 5:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 6:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 7:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 8:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 9:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;	default:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;	}	XB=2*7;switch (time_hour[1]){case 0:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, close);break;case 1:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 2:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 3:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, open);break;case 4:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 5:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 6:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 7:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;case 8:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;case 9:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, open);break;	default:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, close);Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;	}	XB=3*7;switch (time_hour[0]){case 0:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, close);//Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, open);Set_Servo_Pulse(XB+4, open);Set_Servo_Pulse(XB+5, open);Set_Servo_Pulse(XB+6, close);break;case 1:Set_Servo_Pulse(XB+0, open);Set_Servo_Pulse(XB+1, open);//Set_Servo_Pulse(XB+2, open);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;default:Set_Servo_Pulse(XB+0, close);Set_Servo_Pulse(XB+1, close);//Set_Servo_Pulse(XB+2, close);Set_Servo_Pulse(XB+3, close);Set_Servo_Pulse(XB+4, close1);Set_Servo_Pulse(XB+5, close1);Set_Servo_Pulse(XB+6, close);break;}}}break;default:break;}	}
}

?main.h

#ifndef __main_H
#define __main_H
#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_it.h"
#include "stdio.h"
//#include "stdarg.h"
#include "string.h"
#include "delay.h"
#include "sys.h"
#include "led.h"
//#include "key.h"
//#include "exti.h"
#include "time.h"
//#include "pwm.h"
//#include "ppm.h"
#include "usart.h"
//#include "adc.h"
//#include "24cxx.h"
//#include "spi.h"
//#include "nrf24l01.h"#endif

?usart.c

#include "main.h"
#include "usart.h"uint8_t g_usart_rx_buf[USART_REC_LEN];
uint16_t g_usart_rx_sta = 0;
uint16_t g_usart1_rx_flag = 0;
uint8_t g_rx_buffer[RXBUFFERSIZE];  /* HAL庫使用的串口接收緩沖 */
UART_HandleTypeDef g_uart1_handle;  /* UART句柄 *//*串口X初始化函數*/
void usart_init(uint32_t BaudRate)
{/*UART 初始化設置*/g_uart1_handle.Instance = USART1;                                       /* USART_UX */g_uart1_handle.Init.BaudRate = BaudRate;                                  /* 波特率 */g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;                      /* 字長為8位數據格式 */g_uart1_handle.Init.StopBits = UART_STOPBITS_1;                           /* 一個停止位 */g_uart1_handle.Init.Parity = UART_PARITY_NONE;                            /* 無奇偶校驗位 */g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;                      /* 無硬件流控 */g_uart1_handle.Init.Mode = UART_MODE_TX_RX;                               /* 收發模式 */HAL_UART_Init(&g_uart1_handle);                                           /* HAL_UART_Init()會使能UART1 *//* 該函數會開啟接收中斷:標志位UART_IT_RXNE,并且設置接收緩沖以及接收緩沖接收最大數據量 */HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, 1); 
}/*usart初始化函數*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef gpio_init_struct;if (huart->Instance == USART1)                            /* 如果是串口1,進行串口1 MSP初始化 */{__HAL_RCC_GPIOA_CLK_ENABLE();                             /* 使能串口TX\RX腳時鐘 */__HAL_RCC_USART1_CLK_ENABLE();                                  /* 使能串口時鐘 */gpio_init_struct.Pin = GPIO_PIN_9;               /* 串口發送引腳號 */gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 復用推挽輸出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* IO速度設置為高速 */HAL_GPIO_Init(GPIOA, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_10;               /* 串口RX腳 模式設置 */gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;    HAL_GPIO_Init(GPIOA, &gpio_init_struct);   /* 串口RX腳 必須設置成輸入模式 */#if USART_EN_RXHAL_NVIC_EnableIRQ(USART1_IRQn);                      /* 使能USART1中斷通道 */HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);              /* 組2,最低優先級:搶占優先級3,子優先級3 */
#endif}
}
uint8_t time_hour[2],time_min[2],time_second[2];
char * recive_s;
char * recive_s1;
//char string_recive1[] = "WIFI CONNECTED\r\nWIFI GOT IP";
char string_recive1[] = "WIFI CONNECTED";
//char string_recive2[39] = "AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\nOK";
char string_recive2[] = "AT+CIPSNTPCFG=1,8,";
//char string_recive22[41] = "AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\n\r\nOK";
char string_recive3[] = "AT+CIPSNTPTIME";
/*串口數據接收回調函數*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1)                    /* 如果是串口1 */{     recive_s = strstr((char*)g_rx_buffer,string_recive1);if (recive_s!=NULL){g_usart1_rx_flag = 20;}recive_s = strstr((char*)g_rx_buffer,string_recive2);if ((recive_s!=NULL)&&((*(recive_s+39)==0X4F)&&(*(recive_s+40)==0X4B))) {g_usart1_rx_flag = 10;}recive_s = strstr((char*)g_rx_buffer,string_recive3);if (/*61字符*/ ((recive_s!=NULL)&&((*(recive_s+57)==0X4F)&&(*(recive_s+58)==0X4B)))||/*60字符*/ ((recive_s!=NULL)&&((*(recive_s+56)==0X4F)&&(*(recive_s+57)==0X4B)))){if( ((*(recive_s+50))==0x31)&& ((*(recive_s+51))==0x39)&& ((*(recive_s+52))==0x37)&& ((*(recive_s+53))==0x30)		//1970年---獲取時間失敗){g_usart1_rx_flag = 0;}else{if(				//必須是有效數字((*(recive_s+50))>=0x30) && ((*(recive_s+50))<=0x39) && ((*(recive_s+51))>=0x30) && ((*(recive_s+51))<=0x39) && ((*(recive_s+52))>=0x30) && ((*(recive_s+52))<=0x39) && ((*(recive_s+53))>=0x30) && ((*(recive_s+53))<=0x39) )g_usart1_rx_flag = 1;//							if(((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30)>=12)
//							{		
//								time_hour[0]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30))-12)/10;
//								time_hour[1]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30))-12)%10;
//							}else{
//								time_hour[0]=(*(recive_s+41))-0x30;
//								time_hour[1]=(*(recive_s+42))-0x30;
//							}if(((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30)>=20)//因為小時的首位只有一個1,因此大于20點默認回歸到12小時制{		time_hour[0]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30))-12)/10;time_hour[1]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30))-12)%10;}else{time_hour[0]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30)))/10;time_hour[1]=((((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30)))%10;}TIME_HOUR_24h = ((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30);time_min[0]=(*(recive_s+44))-0x30;time_min[1]=(*(recive_s+45))-0x30;							time_second[0]=(*(recive_s+47))-0x30;time_second[1]=(*(recive_s+48))-0x30;//							time_hour[0]=(*(recive_s+44))-0x30;
//							time_hour[1]=(*(recive_s+45))-0x30;							
//							time_min[0]=(*(recive_s+47))-0x30;
//							time_min[1]=(*(recive_s+48))-0x30;}}
//			//60個字符
//			if ((recive_s!=NULL)&&((*(recive_s+56)==0X4F)&&(*(recive_s+57)==0X4B)))
//			{
//				
//				if( 
//								((*(recive_s+50))==0x31)&& ((*(recive_s+51))==0x39)&& ((*(recive_s+52))==0x37)&& ((*(recive_s+53))==0x30)		//1970年---獲取時間失敗
//								)
//						{
//							g_usart1_rx_flag = 0;
//						}else{
//							if(				//必須是有效數字
//									 ((*(recive_s+50))>=0x30) && ((*(recive_s+50))<=0x39) 
//								&& ((*(recive_s+51))>=0x30) && ((*(recive_s+51))<=0x39) 
//								&& ((*(recive_s+52))>=0x30) && ((*(recive_s+52))<=0x39) 
//								&& ((*(recive_s+53))>=0x30) && ((*(recive_s+53))<=0x39) 
//							)
//							g_usart1_rx_flag = 1;
//							
//							if(((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30)>=12)
//							{				
//								time_hour[0]=0;
//								time_hour[1]=(((*(recive_s+41))-0x30)*10+((*(recive_s+42))-0x30))-12;
//							}else{
//								time_hour[0]=(*(recive_s+41))-0x30;
//								time_hour[1]=(*(recive_s+42))-0x30;
//							}
//							time_min[0]=(*(recive_s+44))-0x30;
//							time_min[1]=(*(recive_s+45))-0x30;							
//							time_second[0]=(*(recive_s+47))-0x30;
//							time_second[1]=(*(recive_s+48))-0x30;
//							
//						}
//			}}
}void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&g_uart1_handle);   /* 調用HAL庫中斷處理公用函數 */HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);} /* 加入以下代碼, 支持printf函數, 而不需要選擇use MicroLIB */#if 1#if (__ARMCC_VERSION >= 6010050)            /* 使用AC6編譯器時 */
__asm(".global __use_no_semihosting\n\t");  /* 聲明不使用半主機模式 */
__asm(".global __ARM_use_no_argv \n\t");    /* AC6下需要聲明main函數為無參數格式,否則部分例程可能出現半主機模式 */#else
/* 使用AC5編譯器時, 要在這里定義__FILE 和 不使用半主機模式 */
#pragma import(__use_no_semihosting)struct __FILE
{int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling *//* is required. */
};#endif/* 不使用半主機模式,至少需要重定義_ttywrch\_sys_exit\_sys_command_string函數,以同時兼容AC6和AC5模式 */
int _ttywrch(int ch)
{ch = ch;return ch;
}/* 定義_sys_exit()以避免使用半主機模式 */
void _sys_exit(int x)
{x = x;
}char *_sys_command_string(char *cmd, int len)
{return NULL;
}/* FILE 在 stdio.h里面定義. */
FILE __stdout;/* MDK下需要重定義fputc函數, printf函數最終會通過調用fputc輸出字符串到串口 */
int fputc(int ch, FILE *f)
{while ((USART1->SR & 0X40) == 0);     /* 等待上一個字符發送完成 */USART1->DR = (uint8_t)ch;             /* 將要發送的字符 ch 寫入到DR寄存器 */return ch;
}
#endif

?usart.h

#ifndef __USART_H
#define __USART_H#define USART_REC_LEN               200         /* 定義最大接收字節數 200 */
#define USART_EN_RX                 1           /* 使能(1)/禁止(0)串口1接收 */
#define RXBUFFERSIZE   100                        /* 緩存大小 */extern UART_HandleTypeDef g_uart1_handle;       /* HAL UART句柄 */
extern uint8_t  g_usart_rx_buf[USART_REC_LEN];  /* 接收緩沖,最大USART_REC_LEN個字節.末字節為換行符 */
extern uint16_t g_usart_rx_sta;                 /* 接收狀態標記 */
extern uint8_t g_rx_buffer[RXBUFFERSIZE];       /* HAL庫USART接收Buffer */
extern uint16_t g_usart1_rx_flag ;              /*數據接收標志*/      extern uint8_t time_hour[2],time_min[2],time_second[2];void usart_init(uint32_t BaudRate);                /* 串口初始化函數 */extern uint16_t g_usart1_rx_flag;
extern uint8_t TIME_HOUR_24h;
#endif

time.c

#include "main.h"TIM_HandleTypeDef g_timx_handle;  /* 定時器句柄 */void time_init(void)
{g_timx_handle.Instance = TIM2;                        /* 通用定時器4 */g_timx_handle.Init.Prescaler = 72-1;                /* 設置預分頻系數 */g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;  /* 遞增計數模式 */g_timx_handle.Init.Period = TIMER_TICK;                   /* 自動裝載值 */HAL_TIM_Base_Init(&g_timx_handle);HAL_TIM_Base_Start_IT(&g_timx_handle);         /* 使能定時器x及其更新中斷 */
}void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM2){__HAL_RCC_TIM2_CLK_ENABLE();            /* 使能TIM時鐘 */HAL_NVIC_SetPriority(TIM2_IRQn, 1, 3); /* 搶占1,子優先級3,組2 */HAL_NVIC_EnableIRQ(TIM2_IRQn);         /* 開啟ITM3中斷 */}
}
uint16_t tim_cnt;
void TIM2_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_timx_handle); /* 定時器中斷公共處理函數 */
}Servo_Ctrl servo[SERVO_NUM];  // 舵機控制數組void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) /*定時器更新中斷回調函數*/
{static uint16_t global_counter = 0;if (htim->Instance == TIM2){
//			ADC_PPM();if(tim_cnt>=g_usart1_rx_flag*500){tim_cnt = 0;LED0_TOGGLE();}else{tim_cnt++;}//pwm生成for(uint8_t i=0; i<SERVO_NUM; i++) {if(global_counter == 0) {  // 新周期開始時拉高所有引腳//        GPIO_SetBits(servo[i].GPIOx, servo[i].GPIO_Pin);HAL_GPIO_WritePin(servo[i].GPIOx,servo[i].GPIO_Pin , GPIO_PIN_SET);servo[i].counter = 0;} else {servo[i].counter += TIMER_TICK;if(servo[i].counter >= servo[i].pulse_us) {  // 達到脈寬時間后拉低//          GPIO_ResetBits(servo[i].GPIOx, servo[i].GPIO_Pin);HAL_GPIO_WritePin(servo[i].GPIOx,servo[i].GPIO_Pin , GPIO_PIN_RESET);}}}global_counter += TIMER_TICK;if(global_counter >= PWM_PERIOD) {global_counter = 0;  // 周期復位}}
}

?time.h

#ifndef __TIME_H
#define __TIME_H#include "main.h"#define SERVO_NUM  23   // 舵機數量
#define PWM_PERIOD  20000 // 20ms周期(單位:us)
#define TIMER_TICK  100    // 定時器中斷間隔(單位:us)// 舵機控制結構體
typedef struct {GPIO_TypeDef* GPIOx;  // GPIO端口uint16_t GPIO_Pin;    // GPIO引腳uint16_t pulse_us;    // 當前脈寬(單位:us)uint16_t counter;     // 內部計時器
} Servo_Ctrl;extern Servo_Ctrl servo[SERVO_NUM];  // 舵機控制數組void time_init(void);
#endif

2.esp8266鏈接網絡時間采用NTP時間為基準;

鏈接wifi:

AT+CWJAP="xxxxxx","*************"

鏈接NTP:

AT+CIPSNTPCFG=1,8,"ntp1.aliyun.com"

發送時間請求:

AT+CIPSNTPTIME?

3.舵輪時鐘圖紙:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/87850.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/87850.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/87850.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis的單線程和多線程(單Worker線程)

Redis的單線程和多線程 Redis6.0之前是單線程的&#xff0c;6.0之后是多線程的&#xff0c;我們先了解6.0版本之前的單線程Redis。但其實無論6.0之前還是6.0之后&#xff0c;redis用于工作的線程也只有一個&#xff0c;所以也可以說redis一直是單線程的。 Redis單線程 Redis 6.…

OSPFv3基礎

文章目錄 OSPFv3基礎OSPFv3的改進OSPFv2 v3相同OSPFv2 v3不同 &#x1f3e1;作者主頁&#xff1a;點擊&#xff01; &#x1f916;Datacom專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2025年07月07日22點31分 OSPFv3基礎 OSPFv3協議號依然為89&#xff0c;在I…

前端篇——HTML知識點體系

目錄 一、基礎結構與文本 1. 文檔基礎 2. 文本元素 二、多媒體元素 1. 圖像 2. 音頻 3. 視頻 三、列表系統 1. 無序列表 2. 有序列表 3. 定義列表 四、表格系統 1. 表格結構 2. 合并單元格 五、表單系統 1. 輸入控件 2. 表單元素 3. 高級表單特性 六、布局系…

產品需求管理文檔中,需求模塊是怎么界定的

產品需求文檔中&#xff0c;需求模塊的界定方式主要包括&#xff1a;1、基于業務流程的功能劃分、2、按用戶角色使用場景分類、3、根據系統架構與技術邊界拆解、4、對數據實體和功能點進行組合聚類、5、結合未來演進節奏設置獨立迭代單元。 其中&#xff0c;“基于業務流程的功…

國內免代理免費使用Gemini大模型實戰

文章目錄 一、免費申請Gemini API密鑰二、使用openai-gemini1、在github上找到openai-gemini2、將openai-gemini部署到Netlify3、在Cherry Studio中配置和使用gemini的模型1&#xff09;在Cherry Studio中配置gemini API2&#xff09;在Cherry Studio中使用gemini 的模型 4、在…

day46-tomcat-java業務部署

1. ?選型1.1. &#x1f3af;中間件java web中間件說明tomcat組件&#xff0c;功能多jetty精簡&#xff0c;功能少一些......weblogic使用oracle數據庫配合weblogic(商業)國產&#xff1a;東方通(TongWEB)1.2. &#x1f4cc;jdkjdk選型說明jdk(oracle jdk)商業版&#xff0c;jd…

[netty5: HttpServerCodec HttpClientCodec]-源碼分析

在閱讀該篇文章之前&#xff0c;推薦先閱讀以下內容&#xff1a; [netty5: ChannelHandler & ChannelHandlerAdapter]-源碼解析[netty5: HttpObjectEncoder & HttpObjectDecoder]-源碼解析 HttpServerCodec HttpServerCodec 是一個 Netty 編解碼器&#xff0c;結合 …

華為OD機試 2025B卷 - 數組組成的最小數字(C++PythonJAVAJSC語言)

2025B卷目錄點擊查看: 華為OD機試2025B卷真題題庫目錄|機考題庫 + 算法考點詳解 2025B卷 100分題型 最新華為OD機試 真題目錄:點擊查看目錄 華為OD面試真題精選:點擊立即查看 2025華為od 機試2025B卷-華為機考OD2025年B卷 題目描述 給定一個整型數組,請從該數組中選…

Ubuntu下Tomcat的配置

進入Tomcat的conf目錄下 1 備份配置文件 cp server.xml server.xml.2下載server.xml&#xff0c;用notepad文本編輯器打開 2 修改Tomcat的端口號 找到如下內容<Connector port"8080" protocol"HTTP/1.1"connectionTimeout"20000"redirectPort…

Docker部Ollama安裝、本地大模型配置與One-API接入

Docker 安裝 Ollama Ollama 支持 Docker 安裝,極大簡化了部署流程。以下是具體步驟: 創建ollama文件夾 創建 docker-compose.yaml 文件新建一個 docker-compose.yaml 文件,內容如下: 編輯文件 …

ABB焊接機器人智能節氣儀

在現代焊接工業中&#xff0c;ABB焊接機器人憑借其高精度、高效率等優勢被廣泛應用。而在焊接過程中&#xff0c;節氣是一個重要的考量因素&#xff0c;這就凸顯出ABB焊接機器人智能節氣儀的重要性。ABB焊接機器人節氣是提高焊接生產效益的關鍵環節。傳統的焊接過程中&#xff…

攝影后期:使用Photoshop進行暗角控制

方法一&#xff1a;ctrlshiftR調出鏡頭校正工具&#xff0c;調整暈影 方法二&#xff1a;

pyhton基礎【24】面向對象進階五

目錄 十五.多繼承的繼承順序 - mro 調用父類方式不同導致結果不同 單繼承中的super 簡單總結 面試題 十六.魔術方法 魔術方法概述 魔術方法概覽 __getattribute__屬性 __getattribute__注意事項 常用的魔術方法 __doc__ __module__和__class__ __init__ __del__…

如何保障MySQL客戶端連接數據庫安全更安全

公司員工或外協人員&#xff0c;直接使用業務賬號或高權限賬號連接MySQL服務器&#xff0c;如同讓數據在連接時減少風險——賬號密碼易泄露、操作行為難追溯、安全風險陡增&#xff01;尤其是在客戶端連接環節&#xff0c;如何確保每一個接入點都安全可控&#xff0c;每一次操作…

機器學習入門:線性回歸詳解及Scikit-learn API使用指南

一、線性回歸概述線性回歸是統計學和機器學習領域中最基礎、最廣泛應用的預測建模技術之一。自19世紀初由弗朗西斯高爾頓(Francis Galton)首次提出以來&#xff0c;線性回歸已成為數據分析的核心工具&#xff0c;在經濟學、社會科學、生物統計學、工程學等眾多領域發揮著重要作…

高斯牛頓法求解三維變換矩陣的數學推導

目錄一、問題定義二、李代數基礎三、雅可比矩陣推導四、高斯牛頓迭代1. 整體雅可比矩陣2. 正規方程構建3. 參數更新4. 李代數更新五、理論優勢分析一、問題定義 給定兩組三維點云&#xff1a;源點云 P{pi∈R3}i1NP \{p_i \in \mathbb{R}^3\}_{i1}^NP{pi?∈R3}i1N?&#xff0…

JAVA 商城系統為什么受歡迎?ZKmall開源商城靈活定制 + 插件接入適配市場

在電商系統開發這塊&#xff0c;技術選得好不好&#xff0c;直接關系到平臺穩不穩定、能不能擴展、適配能力強不強。JAVA 語言因為 “跨平臺性突出、安全性高、可擴展性好” 這些特點&#xff0c;成了企業級電商系統的首選技術。而 ZKmall 商城基于 JAVA 開發的商城系統&#x…

【數據結構之哈夫曼樹與編碼實現】

文章目錄 前言一、哈夫曼樹與哈夫曼編碼簡介1. 什么是哈夫曼樹&#xff1f;2. 為什么需要哈夫曼編碼&#xff1f; 二、哈夫曼編碼原理三、哈夫曼樹的構建步驟詳解1. 統計字符頻率2. 定義哈夫曼樹節點3. 最小堆&#xff08;優先隊列&#xff09;的構造4. 合并節點&#xff0c;構…

基于Hadoop的京東廚具商品數據分析及商品價格預測系統的設計與實現

文章目錄有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主項目介紹數據采集用戶界面系統展示管理員界面每文一語有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主 項目介紹 本項目圍繞“京東廚具數據分析系統的設計與實…

深入解析TCP:可靠傳輸的核心機制與實現邏輯(三次握手、四次揮手、流量控制、滑動窗口、擁塞控制、慢啟動、延時應答、面向字節流、粘包問題)

Linux系列 文章目錄 Linux系列一、TCP連接的建立與斷開1.1 TCP 三次握手1.2 TCP四次揮手1. TCP連接的本質是應用層間的通信通道2. 斷開連接的核心是終止應用層通信3. 常見誤解澄清 二、TCP協議的機制2.1 流量控制2.2 滑動窗口2.2.1 滑動窗口的工作原理2.2.2 基于滑動窗口快重傳…