经过大半年 努力拼搏 认识了一群志同道合的兄弟 很开心 ,
比赛完 又忙着期末 考试 忙的要死 终于考完试 了 在这里总结一下 嘚瑟一下 战果 并记下学习笔记 记录人生的精彩
话不多说先上图
有个各性小眼神 组委会要求使用大屏 所以为了醒目 我们使用了 北京 某某 串口屏幕 stm32
串口通信 总结经验
void Send_data(USART_TypeDef * USARTx,u8 *s)
{
while(*s!='\0')
{
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET);
USART_SendData(USARTx,*s);
s++;
}
}
主函数变量发送
sprintf(buf,"DS64(64,100,' %d',1);\r\n",er);
轱辘是怎么转起来的呢
#include "motor.h"
void Motor_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructureB; //后轮
GPIO_InitTypeDef GPIO_InitStructureC; //后轮
GPIO_InitTypeDef GPIO_InitStructureE; //前轮
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructureB.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5; //端口配置
GPIO_InitStructureB.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructureB.GPIO_Speed = GPIO_Speed_50MHz; //50M
GPIO_Init(GPIOB, &GPIO_InitStructureB); //根据设定参数初始化GPIOB
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PB端口时钟
GPIO_InitStructureC.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //端口配置
GPIO_InitStructureC.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructureC.GPIO_Speed = GPIO_Speed_50MHz; //50M
GPIO_Init(GPIOC, &GPIO_InitStructureC); //根据设定参数初始化GPIOB
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能PE端口时钟
GPIO_InitStructureE.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; //端口配置
GPIO_InitStructureE.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructureE.GPIO_Speed = GPIO_Speed_50MHz; //50M
GPIO_Init(GPIOE, &GPIO_InitStructureE); //根据设定参数初始化GPIOB
}
void PWM_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<3; //TIM5时钟使能
RCC->APB2ENR|=1<<2; //PORTA时钟使能
GPIOA->CRL&=0XFFFF0000; //PORTA0,1,2,3复用输出
GPIOA->CRL|=0X0000BBBB; //PORTA0,1,2,3复用输出
TIM5->ARR=arr;//设定计数器自动重装值
TIM5->PSC=psc;//预分频器不分频
TIM5->CCMR1|=6<<4; //CH1 PWM1模式
TIM5->CCMR1|=6<<12;//CH2 PWM1模式
TIM5->CCMR2|=6<<4; //CH3 PWM1模式
TIM5->CCMR2|=6<<12;//CH4 PWM1模式
TIM5->CCMR1|=1<<3; //CH1预装载使能
TIM5->CCMR1|=1<<11;//CH2预装载使能
TIM5->CCMR2|=1<<3; //CH3预装载使能
TIM5->CCMR2|=1<<11;//CH4预装载使能
TIM5->CCER|=1<<0; //CH1输出使能
TIM5->CCER|=1<<4; //CH2输出使能
TIM5->CCER|=1<<8; //CH3输出使能
TIM5->CCER|=1<<12; //CH4输出使能
TIM5->CR1=0x8000; //ARPE使能
TIM5->CR1|=0x01; //使能定时器3
}
void Set_Motor(int MotorA,int MotorB,int MotorC,int MotorD)
{
if(MotorA>0)
{
AIN1=0, AIN2=1;
PWMA=MotorA;
}
else
{
AIN1=1, AIN2=0;
PWMA=-MotorA;
}
/
if(MotorB>0)
{
BIN1=0, BIN2=1;
PWMB=MotorB;
}
else
{
BIN1=1, BIN2=0;
PWMB=-MotorB;
}
///
if(MotorC>0)
{
CIN1=1, CIN2=0;
PWMC=MotorC;
}
else
{
CIN1=0; CIN2=1;
PWMC=-MotorC;
}
/
if(MotorD>0)
{
DIN1=1; DIN2=0;
PWMD=MotorD;
}
else
{
DIN1=0, DIN2=1;
PWMD=-MotorD;
}
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
#include "encoder.h"
int Encoder[4];
void Encoder_Init(void)
{
Encoder_Init_TIM8();
Encoder_Init_TIM2();
Encoder_Init_TIM3();
Encoder_Init_TIM4();
}
/**************************************************************************
函数功能:把TIM1初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM8(void)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB2ENR|=1<<13; //TIM8时钟使能
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOC->CRL&=0X00FFFFFF;//PC6,7
GPIOC->CRL|=0X44000000;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM8->PSC = 0;//预分频器
TIM8->ARR = 0xFFFF-1;//设定计数器自动重装值
TIM8->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM8->CCMR1 |= 0xC<<4; //输入滤波器
TIM8->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM8->CCMR1 |= 0xC<<12; //输入滤波器
TIM8->CCER |= 0<<1; //IC1不反向
TIM8->CCER |= 0<<5; //IC2不反向
TIM8->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM8->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:把TIM2初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM2(void)
{
//TIM2的输入端口已经重新映射
//部分重映射,CH1---PA15,CH2---PB3
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOA->CRH&=0X0FFFFFFF;//PA15
GPIOA->CRH|=0X40000000;//浮空输入
GPIOB->CRL&=0XFFFF0FFF;//PB3
GPIOB->CRL|=0X00004000;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM2->PSC = 0;//预分频器
TIM2->ARR = 0xFFFF-1;//设定计数器自动重装值
TIM2->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM2->CCMR1 |= 0xC<<4; //输入滤波器
TIM2->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM2->CCMR1 |= 0xC<<12; //输入滤波器
TIM2->CCER |= 0<<1; //IC1不反向
TIM2->CCER |= 0<<5; //IC2不反向
TIM2->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM2->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:把TIM2初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM3(void)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB1ENR|=1<<1; //TIM3时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0X00FFFFFF;//PA6 PA7
GPIOA->CRL|=0X44000000;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM3->PSC = 0;//预分频器
TIM3->ARR = 0xFFFF-1;//设定计数器自动重装值
TIM3->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM3->CCMR1 |= 0xC<<4; //输入滤波器
TIM3->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM3->CCMR1 |= 0xC<<12; //输入滤波器
TIM3->CCER |= 0<<1; //IC1不反向
TIM3->CCER |= 0<<5; //IC2不反向
TIM3->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM3->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:把TIM4初始化为编码器接口模式
入口参数:无
返回 值:无
**************************************************************************/
void Encoder_Init_TIM4(void)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB1ENR|=1<<2; //TIM4时钟使能
RCC->APB2ENR|=1<<3; //使能PORTb时钟
GPIOB->CRL&=0X00FFFFFF;//PB6 PB7
GPIOB->CRL|=0X44000000;//浮空输入
/* 把定时器初始化为编码器模式 */
TIM4->PSC = 0;//预分频器
TIM4->ARR = 0xFFFF-1;//设定计数器自动重装值
TIM4->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM4->CCMR1 |= 0xC<<4; //输入滤波器
TIM4->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM4->CCMR1 |= 0xC<<12; //输入滤波器
TIM4->CCER |= 0<<1; //IC1不反向
TIM4->CCER |= 0<<5; //IC2不反向
TIM4->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效
TIM4->CR1 |= 0x01; //CEN=1,使能定时器
}
/**************************************************************************
函数功能:单位时间读取编码器计数
入口参数:定时器
返回 值:速度值
**************************************************************************/
void Read_Encoder(void)
{
Encoder[0]= (short)TIM2 -> CNT; TIM2 -> CNT=0;//前左轮
Encoder[1]= (short)TIM8 -> CNT; TIM8 -> CNT=0;//前右轮
Encoder[2]= (short)TIM3 -> CNT; TIM3 -> CNT=0;//后左轮
Encoder[3]= (short)TIM4 -> CNT; TIM4 -> CNT=0;//后右轮
}
、、、
这一堆代码 看着难受 海底找手册 、、、、、】】】】】辛苦些吧、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
就这样就 编码器 我men 用的是140转的 那么pid呢
就是这啦//定时器6中断服务程序
void TIM6_IRQHandler(void)
{
delay5ms++;
if(TIM6->SR&0X0001)//溢出中断
{
USART_SendData(USART1,FF);
Contorl_stick++;
if(Contorl_stick==4)
{
Contorl_stick=0;
Read_Encoder();//读编码器
encoder_1+=Encoder[1];
// OLED_ShowNum(30,4,encoder_1,6,16);
for(nmr=0;nmr<4;nmr++)
{
PID_Motor[nmr].error=Encoder[nmr]-Motor_Speed[nmr];
//输出的P值
PID_Motor[nmr].pout = PID_Motor[nmr].Pdat * PID_Motor[nmr].error;
//输出的I值
PID_Motor[nmr].iout += (PID_Motor[nmr].Idat*0.05) * PID_Motor[nmr].error;
PID_Motor[nmr].iout = Get_MxMi(PID_Motor[nmr].iout,200,-200);//判读I是否超出范围
//输出的D值
PID_Motor[nmr].dout = PID_Motor[nmr].Ddat*0.05*(PID_Motor[nmr].error-PID_Motor[nmr].Last_error);
PID_Motor[nmr].Last_error=PID_Motor[nmr].error;
//PID三个值融合
PID_Motor[nmr].OUT += PID_Motor[nmr].pout + PID_Motor[nmr].iout +PID_Motor[nmr].dout;P,I,D值相加
PID_Motor[nmr].OUT=Get_MxMi(PID_Motor[nmr].OUT,7199,-7199);
}
Set_Motor(PID_Motor[0].OUT, PID_Motor[1].OUT, PID_Motor[2].OUT, PID_Motor[3].OUT);
}
}
TIM6->SR&=~(1<<0);//清除中断标志位
}
void Car_Control(int Y_Move,int X_Move,int Yaw0)
{
Motor_Speed[0] = (-Y_Move + X_Move + Yaw0); Motor_Speed[3] = (Y_Move - X_Move + Yaw0);
Motor_Speed[2] = (-Y_Move - X_Move + Yaw0); Motor_Speed[1] = (Y_Move + X_Move + Yaw0);
}
void PID_Init(void)
{
PID_Motor[0].Pdat=-16; PID_Motor[0].Idat=0; PID_Motor[0].Ddat=-4;
PID_Motor[1].Pdat=16; PID_Motor[1].Idat=0; PID_Motor[1].Ddat=4;
PID_Motor[2].Pdat=16; PID_Motor[2].Idat=0; PID_Motor[2].Ddat=4;
PID_Motor[3].Pdat=-16; PID_Motor[3].Idat=0; PID_Motor[3].Ddat=-4;
PID_Motor[0].iout=0;
PID_Motor[1].iout=0;
PID_Motor[2].iout=0;
PID_Motor[3].iout=0;
PID_Motor[0].OUT=0;
PID_Motor[1].OUT=0;
PID_Motor[2].OUT=0;
PID_Motor[3].OUT=0;
PID_Motor[0].error=0;
PID_Motor[1].error=0;
PID_Motor[2].error=0;
PID_Motor[3].error=0;
PID_Motor[0].Last_error=0;
PID_Motor[1].Last_error=0;
PID_Motor[2].Last_error=0;
PID_Motor[3].Last_error=0;
}
float Get_MxMi(float num,float max,float min)
{
if(num>max)
return max;
else if(num<min)
return min;
else
return num;
}
int encoder(int ax)
{
motor1_d=encoder_1-ax*3500;
// if(-motor1_d<2000)
// {
// motor1_b=(3000+motor1_d)/50;
// motor1_b=Get_MxMi(motor1_b,65,45);
// }
// OLED_ShowNum(30,4,-motor1_d,6,16);
if(motor1_d<0)
{
flag_mm=0;
if(motor1_d>=-800)
flag_mm= 2;
}
if(motor1_d>0)
flag_mm= 1;
return flag_mm;
}
int encoder1(int ax)
{
motor1_d=-encoder_1-ax*3100;
if(motor1_d<0)
{
flag_mm=0;
if(motor1_d>=-2600)
flag_mm= 2;
}
if(motor1_d>0)
flag_mm= 1;
return flag_mm;
}
int encoder2(int ax)
{
motor1_d=-encoder_1-ax*2800;
if(motor1_d<0)
{
flag_mm=0;
if(motor1_d>=-1500)
flag_mm= 2;
}
if(motor1_d>0)
flag_mm= 1;
return flag_mm;
}
int encoder3(int ax)
{
motor1_d=encoder_1-ax*2958;
if(motor1_d<0)
{
flag_mm=0;
if(motor1_d>=-1500)
flag_mm= 2;
}
if(motor1_d>0)
flag_mm= 1;
return flag_mm;
}
这些核心的 东西 搞好 搞稳 路径就好写 但是 我们的目的不是参与奖 而是特等奖 我们需要更加稳定的巡线算法 于是 某个大神高出了 pid 横向 巡线
**************************************/
void Lxunji_pid(int v)
{
a0=ARED1;
a1=ARED3;
error=a1-a0-flagREDL;
if(error<0)
error=-error;
pout = Pdat * error;//输出的P值
iout += (Idat*0.05) * error;//输出的I值
iout = Get_MxMi(iout,10,-10);//判读I是否超出范围
dout = Ddat*0.05*(error-Last_error); //输出的D值
Last_error=error;
OUT += pout +dout;P,I,D值相加 //PID三个值融合
if(OUT<100)
LEFT(v,v,v,v);
else
{
// OLED_ShowNum(30,6,OUT/10,6,16);
OUT=Get_MxMi(OUT,v+10,v);
if(a1<a0)
LEFT(OUT,v,v,v);
else if(a1>a0)
LEFT(v,v,OUT,v);
}
if(DRED3==0&&DRED1==1) //数字量保险回线
{
LEFT(v-10,v+10,v+10,v-10);
}
if(DRED3==1&&DRED1==0) //数字量保险回线
{
LEFT(v+10,v-10,v-10,v+10);
}
}保证 车正 线直 于是效果很完美
这些 过后路径只要是思路清晰的话就很好写的 我就不上 了 上了也没啥大用
然后 我们就顺利的 进入了决赛 经过 一晚上努力付出 终于把临场的任务写完
无非就是 改改路径 罢了
但是加了wifi 模组 udp 连接模式 比赛当晚 出了些问题好在最后解决了
对于8266我用了三种 首先放弃了at 命令 之后 用了arduino for 8266
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "GXDS2019";
const char* password = "xnsq2019";
unsigned long previousMillis = 0; //毫秒时间记录
const long interval = 100; //时间间隔
WiFiUDP Udp;
unsigned int localUdpPort = 9050; // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char replyPacket[] = " Got the message)"; // a reply string to send back
void setup()
{
pinMode(2, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting %s ");
WiFi.mode(WIFI_STA);
WiFi.setAutoConnect(false);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
digitalWrite(2, HIGH);
delay(500);
//Serial.print(".");
digitalWrite(2, LOW);
}
Serial.println(" connected");
Udp.begin(localUdpPort);
//Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}
void loop()
{
// unsigned long currentMillis = millis(); //读取当前时间
// if (currentMillis - previousMillis >= interval) //如果和前次时间大于等于时间间隔
// {
//
// previousMillis = currentMillis; //更新时间记录
//
// }
digitalWrite(2, LOW);
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
// Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
Serial.printf(incomingPacket);
// send back a reply, to the IP address and port we got the packet from"UDP packet contents: %s\n",
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
// Udp.beginPacket("192.168.137.255",Udp.remotePort());
Udp.write(replyPacket);
Udp.endPacket();
}
}
但是 我怕比赛时候出事啊 于是又有了第三种方案
AIthink 的sdk
// 头文件引用
//==================================================================================
#include "user_config.h" // 用户配置
#include "driver/uart.h" // 串口
#include "driver/oled.h" // OLED
//#include "at_custom.h"
#include "c_types.h" // 变量类型
#include "eagle_soc.h" // GPIO函数、宏定义
#include "ip_addr.h" // 被"espconn.h"使用。在"espconn.h"开头#include"ip_addr.h"或#include"ip_addr.h"放在"espconn.h"之前
#include "espconn.h" // TCP/UDP接口
//#include "espnow.h"
#include "ets_sys.h" // 回调函数
//#include "gpio.h"
#include "mem.h" // 内存申请等函数
#include "os_type.h" // os_XXX
#include "osapi.h" // os_XXX、软件定时器
//#include "ping.h"
//#include "pwm.h"
//#include "queue.h"
//#include "smartconfig.h"
//#include "sntp.h"
//#include "spi_flash.h"
//#include "upgrade.h"
#include "user_interface.h" // 系统接口、system_param_xxx接口、WIFI、RateContro
//==================================================================================
// 宏定义
//==================================================================================
#define ProjectName "STA_UDP_Client" // 工程名宏定义
#define ESP8266_STA_SSID "GXDS2019" // 接入的WIFI名
#define ESP8266_STA_PASS "xnsq2019" // 接入的WIFI密码
#define LED_ON GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0) // LED亮
#define LED_OFF GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1) // LED灭
//==================================================================================
// 全局变量
//==================================================================================
os_timer_t OS_Timer_1; // 定义软件定时器
struct espconn ST_NetCon; // 网络连接结构体
//==================================================================================
// 毫秒延时函数
//===========================================
void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
{ for(;C_time>0;C_time--)
os_delay_us(1000);
}
//===========================================
// ESP8266_STA初始化
//==============================================================================
void ICACHE_FLASH_ATTR ESP8266_STA_Init_JX()
{
struct station_config STA_Config; // STA参数结构体
struct ip_info ST_ESP8266_IP; // STA信息结构体
// 设置ESP8266的工作模式
//------------------------------------------------------------------------
wifi_set_opmode(0x01); // 设置为STA模式,并保存到Flash
/*
// 设置STA模式下的IP地址【ESP8266默认开启DHCP Client,接入WIFI时会自动分配IP地址】
//--------------------------------------------------------------------------------
wifi_station_dhcpc_stop(); // 关闭 DHCP Client
IP4_ADDR(&ST_ESP8266_IP.ip,192,168,8,88); // 配置IP地址
IP4_ADDR(&ST_ESP8266_IP.gw,192,168,8,1); // 配置网关地址
IP4_ADDR(&ST_ESP8266_IP.netmask,255,255,255,0); // 配置子网掩码
wifi_set_ip_info(STATION_IF,&ST_ESP8266_IP); // 设置STA模式下的IP地址
*/
// 结构体赋值,配置STA模式参数
//-------------------------------------------------------------------------------
os_memset(&STA_Config, 0, sizeof(struct station_config)); // STA参数结构体 = 0
os_strcpy(STA_Config.ssid,ESP8266_STA_SSID); // 设置WIFI名
os_strcpy(STA_Config.password,ESP8266_STA_PASS); // 设置WIFI密码
wifi_station_set_config(&STA_Config); // 设置STA参数,并保存到Flash
// wifi_station_connect(); // ESP8266连接WIFI
}
//=========================================================================================
// 成功发送网络数据的回调函数
//==========================================================
void ICACHE_FLASH_ATTR ESP8266_WIFI_Send_Cb_JX(void *arg)
{
//os_printf("\nESP8266_WIFI_Send_OK\n");
}
//==========================================================
// 成功接收网络数据的回调函数【参数1:网络传输结构体espconn指针、参数2:网络传输数据指针、参数3:数据长度】
//=========================================================================================================
void ICACHE_FLASH_ATTR ESP8266_WIFI_Recv_Cb_JX(void * arg, char * pdata, unsigned short len)
{
struct espconn * T_arg = arg; // 缓存网络连接结构体指针
remot_info * P_port_info = NULL; // 定义远端连接信息指针
// 根据数据设置LED的亮/灭
//-------------------------------------------------------------------------------
os_printf("#%s\r\n",pdata); // 串口打印接收到的数据
OLED_ShowString(32,6,pdata);
// 获取远端信息【UDP通信是无连接的,向远端主机回应时需获取对方的IP/端口信息】
//------------------------------------------------------------------------------------
if(espconn_get_connection_info(T_arg, &P_port_info, 0)==ESPCONN_OK) // 获取远端信息
{
T_arg->proto.udp->remote_port = P_port_info->remote_port; // 获取对方端口号
T_arg->proto.udp->remote_ip[0] = P_port_info->remote_ip[0]; // 获取对方IP地址
T_arg->proto.udp->remote_ip[1] = P_port_info->remote_ip[1];
T_arg->proto.udp->remote_ip[2] = P_port_info->remote_ip[2];
T_arg->proto.udp->remote_ip[3] = P_port_info->remote_ip[3];
//os_memcpy(T_arg->proto.udp->remote_ip,P_port_info->remote_ip,4); // 内存拷贝
}
//--------------------------------------------------------------------
OLED_ShowIP(16,4,T_arg->proto.udp->remote_ip); // 显示远端主机IP地址
//--------------------------------------------------------------------
//espconn_send(T_arg,"ESP8266_WIFI_Recv_OK",os_strlen("ESP8266_WIFI_Recv_OK")); // 向对方发送应答
}
//=========================================================================================================
// 定义espconn型结构体
//-----------------------------------------------
//struct espconn ST_NetCon; // 网络连接结构体
// 初始化网络连接(UDP通信)
//==================================================================================================
void ICACHE_FLASH_ATTR ESP8266_NetCon_Init_JX()
{
// 结构体赋值
//--------------------------------------------------------------------------
ST_NetCon.type = ESPCONN_UDP; // 设置通信协议为UDP
ST_NetCon.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); // 开辟内存
// 此处需要设置目标IP/端口(ESP8266作为Client,需要预先知道Server的IP/端口)
//--------------------------------------------------------------------------
ST_NetCon.proto.udp->local_port = 9050 ; // 设置本地端口
ST_NetCon.proto.udp->remote_port = 9050; // 设置目标端口
ST_NetCon.proto.udp->remote_ip[0] = 192; // 设置目标IP地址
ST_NetCon.proto.udp->remote_ip[1] = 168;
ST_NetCon.proto.udp->remote_ip[2] = 3;
ST_NetCon.proto.udp->remote_ip[3] = 50;
//u8 remote_ip[4] = {192,168,8,47}; // 目标ip地址
//os_memcpy(ST_NetCon.proto.udp->remote_ip,remote_ip,4); // 拷贝内存
// 注册回调函数192.168.3.50
//-------------------------------------------------------------------------------------------
espconn_regist_sentcb(&ST_NetCon,ESP8266_WIFI_Send_Cb_JX); // 注册网络数据发送成功的回调函数
espconn_regist_recvcb(&ST_NetCon,ESP8266_WIFI_Recv_Cb_JX); // 注册网络数据接收成功的回调函数
// 调用UDP初始化API
//-----------------------------------------------
espconn_create(&ST_NetCon); // 初始化DUP通信
// 主动向Server发起通信
//----------------------------------------------------------------------------
//espconn_send(&ST_NetCon,"Hello,I am ESP8266",os_strlen("Hello,I am ESP8266"));
}
//==================================================================================================
// 软件定时的回调函数
//=========================================================================================================
void ICACHE_FLASH_ATTR OS_Timer_1_cb(void)
{
u8 C_LED_Flash = 0; // LED闪烁计次
struct ip_info ST_ESP8266_IP; // ESP8266的IP信息
u8 ESP8266_IP[4]; // ESP8266的IP地址
// 成功接入WIFI【STA模式下,如果开启DHCP(默认),则ESO8266的IP地址由WIFI路由器自动分配】
//-------------------------------------------------------------------------------------
if( wifi_station_get_connect_status() == STATION_GOT_IP ) // 判断是否获取IP
{
wifi_get_ip_info(STATION_IF,&ST_ESP8266_IP); // 获取STA的IP信息
ESP8266_IP[0] = ST_ESP8266_IP.ip.addr; // IP地址高八位 == addr低八位
ESP8266_IP[1] = ST_ESP8266_IP.ip.addr>>8; // IP地址次高八位 == addr次低八位
ESP8266_IP[2] = ST_ESP8266_IP.ip.addr>>16; // IP地址次低八位 == addr次高八位
ESP8266_IP[3] = ST_ESP8266_IP.ip.addr>>24; // IP地址低八位 == addr高八位
// 显示ESP8266的IP地址
//-----------------------------------------------------------------------------------------------
//os_printf("ESP8266_IP = %d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);
OLED_ShowIP(16,2,ESP8266_IP); // OLED显示ESP8266的IP地址
//-----------------------------------------------------------------------------------------------
// 接入WIFI成功后,LED快闪3次
//----------------------------------------------------
for(; C_LED_Flash<=5; C_LED_Flash++)
{
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),(C_LED_Flash%2));
delay_ms(100);
}
os_timer_disarm(&OS_Timer_1); // 关闭定时器
ESP8266_NetCon_Init_JX(); // 初始化网络连接(UDP通信)
}
}
//=========================================================================================================
// 软件定时器初始化(ms毫秒)
//=====================================================================================
void ICACHE_FLASH_ATTR OS_Timer_1_Init_JX(u32 time_ms, u8 time_repetitive)
{
os_timer_disarm(&OS_Timer_1); // 关闭定时器
os_timer_setfn(&OS_Timer_1,(os_timer_func_t *)OS_Timer_1_cb, NULL); // 设置定时器
os_timer_arm(&OS_Timer_1, time_ms, time_repetitive); // 使能定时器
}
//=====================================================================================
// LED初始化
//=============================================================================
void ICACHE_FLASH_ATTR LED_Init_JX(void)
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4); // GPIO4设为IO口
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1); // IO4 = 1
}
//=============================================================================
// user_init:entry of user application, init user function here
//==============================================================================
void ICACHE_FLASH_ATTR user_init(void)
{
uart_init(115200,115200); // 初始化串口波特率
os_delay_us(10000); // 等待串口稳定
//os_printf("\r\n=================================================\r\n");
//os_printf("\t Project:\t%s\r\n", ProjectName);
//os_printf("\t SDK version:\t%s", system_get_sdk_version());
//os_printf("\r\n=================================================\r\n");
// OLED显示初始化
//--------------------------------------------------------
OLED_Init(); // OLED初始化
//OLED_ShowString(0,0,"ESP8266"); // ESP8266模式
OLED_ShowString(0,2,"I:"); // ESP8266_IP地址
OLED_ShowString(0,4,"P:"); // 远端主机模式
OLED_ShowString(0,6,"Rec:"); // 远端主机IP地址
//--------------------------------------------------------
LED_Init_JX(); // LED初始化
ESP8266_STA_Init_JX(); // ESP8266_STA初始化
OS_Timer_1_Init_JX(1000,1); // 1秒定时
}
//==============================================================================
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR user_rf_pre_init(void){}
好复杂 好多代码 去球 反正成功了 再给看个效果图
再后来 我们就比赛 了 期间 出了小意外 但是 不好意思了 我们特等奖 嘚瑟一下嘿嘿i
然后给你men 看看我们的奖牌,妥妥的
嘻嘻
马上就大四 准备找工作了 加油吧 少年