舵轮时钟-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?