舵轮时钟-STM32-28路PWM--ESP8266-NTP时间

发布于:2025-07-04 ⋅ 阅读:(19) ⋅ 点赞:(0)

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-PA7
  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_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();		//PC13
	 usart_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();    // 初始化GPIO
  TIM2_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_RX
        HAL_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.舵轮时钟图纸:


网站公告

今日签到

点亮在社区的每一天
去签到