void Path_Analysis(char *path, uint8_t mode);
uint8_t Quick_reading_FS(uint8_t linked_list);
char path1[] = {"B7,B6,B4,B2,D2,F2,F4,F6,D2,B6,B7"};
//路径保存变量,在此更新任务路径,路径点需为地图中连续的点,用英文逗号隔开
Path_Analysis(path1, 0);
/*函数名称:Path_Analysis
输入参数:path ,mode ,dir_bef(*path 任务路径指针,mode模式<0,1> 开始方向)
*path为传入的循迹坐标
mode=0:为有任务循迹模式
mode=1:无任务循迹模式
返回参数:空
说明:通过选择模式来现在是否做任务*/
void Path_Analysis(char *path, uint8_t mode);
char *p = path;
uint8_t check_mode = 0; // 循迹模式
check_mode = mode;
uint8_t Special_Tpg_Flag; //特殊地形标准位
typedef struct
{
char Cd_X; // 坐标的字母
char Cd_Y; // 坐标的数字
int k; // 任务的序号
int vernier; // 下一个坐标
} Statick[50];
static int linked_list = 0; // 结点编号
Statick link;
//路径读取到坐标数组中
do
{
link[linked_list].Cd_X = *p;
link[linked_list].Cd_Y = *(p + 1);
link[linked_list].k = linked_list;
link[linked_list].vernier = linked_list + 1;
linked_list++;
p = p + 3;
/*
linked_list = 0 ---
link[0].Cd_X = *p;
link[0].Cd_Y = *(p + 1);
link[0].k = 0;
link[0].vernier = 0 + 1;
linked_list ++;
p = p + 3; // 跳过,分隔的逗号,跳到下一个坐标的字母
*/
} while (*(p - 1) == ',');
// 路径解析完以后最后一个结点设置为结束符号
link[linked_list].Cd_X = '\0';
link[linked_list].Cd_Y = '\0';
/************************************************************************
函数名称:Quick_reading_FS
参数:linked_list
返回值:uint8_t choose
作用:判断相对的位置
************************************************************************/
uint8_t Quick_reading_FS(uint8_t linked_list)
{
// 例如B7 , B6
// B == B
uint8_t choose; // 当前车的朝向
// 当前结点(也就是坐标)与下一个结点(也就是坐标)的字母进行比较
// 如果当前结点(也就是坐标)的 字母 大于 下一个结点(也就是坐标)的字母(如 D > B)
// 说明下一个结点(也就是坐标)在当前结点(也就是坐标)的右边(按图排列)
if (link[ linked_list ].Cd_X > link[ link[ linked_list ].vernier ].Cd_X) choose = 1;
// 左边
else if (link[linked_list].Cd_X < link[link[linked_list].vernier].Cd_X) choose = 2;
else
// 当前结点(也就是坐标)的字母,与下一个结点(也就是坐标)的字母相同,即同一条线,则判断数字
{
// 当前结点(也就是坐标)的数字与下一个结点(也就是坐标)的数字进行比较
// 如果当前结点(也就是坐标)的数字 的 数字 小于 下一个结点(也就是坐标)的数字(如6 < 7)
// 说明下一个结点(也就是坐标)在当前结点(也就是坐标)的上方
if (link[ linked_list ].Cd_Y < link[ link[ linked_list ].vernier ].Cd_Y) choose = 3;
// 下方
else choose = 4;
}
return choose;
}
/***********************************************************************
调整车头方向函数
函数名 Change_dir
功能:根据下一个点位置方位及 当前车头方向 调整 新的车头方向
输入参数: dir_b 当前方向 dir_a 调整后方向
输出参数:无
************************************************************************/
// dir_bef 初始化为0,即开始的时候车头朝上
Change_dir(dir_bef, 0);
void Change_dir(int dir_b,int dir_a)
{
// int dir_bef ;//初始化当前车头方向,0向上,1向右,2向下,3向左
// 例如 dir_b = 0, dir_a = 0
// 即要调整的方向在上方
if((dir_b%2) == (dir_a%2))//判断当前方向与调整后方向是否在一条直线上
// if(2 == 2)
{
if(dir_b != dir_a)//方向不一致则调头
// if (0 != 0) 不调头
Turn_Reverse(2);
// else//方向一致直行
// printf("直行\n");
}
else//不在一条直线上则左转或右转
{
if((dir_a-dir_b== 1) || (dir_a-dir_b == -3))
Turn_Right(2);
else
Turn_Left(2);
}
}
void Turn_Reverse(uint8_t mode)//调头函数
{
// 往右转两次,调头
// mode 是右转的模式
// 使用 mode = 2
/* 暂时不看 */
Turn_Right(mode);
Turn_Right(mode);
}
/************************************************************************
函数名称:Turn_Right
参数:mode (右转模式)
返回值:空
作用:右转函数的功能实现
*************************************************************************/
void Turn_Right(uint8_t mode)//右转函数
{
uint16_t gd = 0xFFFF;
if(mode == 0)//模式0按时间延迟转向
{
LSpeed=80;
RSpeed=-80;
Send_UpMotor(LSpeed,RSpeed);
delay_ms(500);//延迟时间需精确调整
delay_ms(420);//延迟时间需精确调整直线行驶转向550,循迹转向420
Send_UpMotor(0,0);
}
else if(mode == 2)//模式2按保险右转向
{
int Mp_Value=0;
LSpeed = wheel_SpeedR;
RSpeed = -wheel_SpeedR;
Send_UpMotor(LSpeed,RSpeed);
while(1)//中间那个灯不灭则继续转向
{
gd = Get_Host_UpTrack(TRACK_H8);//获取循迹数据
if((gd==0xef||gd==0xe7)&&Mp_Value>50)
break;
else
Mp_Value++;
delay_ms(10);
}
Send_UpMotor(0,0);//中间那个灯灭则停止转向
//判断小车转90度还是180度.
//等待数据
if(Mp_Value>150)//判断出寻到白线
{
if(countL!=0)
Turn_Left(4); //智能左转90
else
Turn_Left(3);//关闭循迹,定时左转90
}
else
{
if(countR==0)
countR=Mp_Value;
}
}
else if(mode == 3)
{
int Mp_Value=0;
LSpeed=85;
RSpeed=-85;
Send_UpMotor(LSpeed,RSpeed);
while(1)//中间那个灯不灭则继续转向
{
gd = Get_Host_UpTrack(TRACK_H8);//获取循迹数据
if(Mp_Value>110)
{
break;
}
else
{
Mp_Value++;
}
delay_ms(10);
}
Send_UpMotor(0,0);//中间那个灯灭则停止转向
}
else if(mode==4)//智能右转
{
int Mp_Value=countR;
LSpeed=wheel_SpeedR;
RSpeed=-wheel_SpeedR;
Send_UpMotor(LSpeed,RSpeed);
while(Mp_Value>0)
{
delay_ms(10);
--Mp_Value;
}
Send_UpMotor(0,0);
}
}
//自动循迹函数
void Auto_Track(uint8_t mode)
{
/* 暂时不看 */
uint16_t gd;
Go_Flag = 0;
Stop_Flag = 0;
Track_Flag = 1;
RFID_SpecialTerrain=0;
Roadway_mp_syn();//码盘同步
Encoder_values[0]=Roadway_mp_Get();//获取码盘值
while(Track_Flag == 1)//开始循迹
{
gd = Get_Host_UpTrack(TRACK_H8);
delay_ms(10);
ComparisonOTracking(gd,0);
//ComparisonOTracking(gd,mode);
}
}
/******************************************************************
函数名称:Intersection_behavior
参数:RFID_Flag
返回值:空
作用:判断十字路口行为
*******************************************************************/
void Intersection_behavior(uint8_t RFID_Flag)
{
if(RFID_Flag)
{
Go_Along(50,450);//到了循迹线再走一段
delay_ms(100);
}
}
// 进行两个结点(也就是坐标)的行进,如果结点(也就是坐标)有任务,则做任务
for(linked_list=0; link[linked_list].Cd_X != '\0'; linked_list=link[linked_list].vernier)
{
RFID_Flag = 1;
ReadCard_Flag = 2;//更新读卡任务标准位
RFID_Location_Flag = 0;//RFID位置标准位置
/****************做任务*******************/
#if 0
Task(link[linked_list].k);//执行本点对应任务
#endif
/******************end********************/
if(link[ link[ linked_list ].vernier ].Cd_X) // 当前结点的,下一个结点的,字母,不为空,即有下一个结点
{
uint8_t choose = Quick_reading_FS(linked_list);//判断相对的位置
if (choose==2)//判断列坐标大小,如果后者大于前者,则后者在前者左边,调整后方向为3
{
RFID_special[0]=dir_bef;
Change_dir(dir_bef, 3);//调整车头方向
dir_bef = 3;
RFID_special[1]=dir_bef;
Auto_Track(0);//循迹
delay_ms(100);
//判断是否是十字路口
Intersection_behavior(RFID_Flag);
}
else if (choose==1)//判断列坐标大小,如果后者小于前者,则后者在前者右边,调整后方向为1
{
RFID_special[0]=dir_bef;
Change_dir(dir_bef, 1);//调整车头方向
dir_bef = 1;
RFID_special[1]=dir_bef;
Auto_Track(0);//循迹
//判断是否是十字路口
Intersection_behavior(RFID_Flag);
}
else if (choose==4)//后者行坐标小于前者,则后者在前者下方,调整后方向为2
{
RFID_special[0]=dir_bef;
Change_dir(dir_bef, 2);//调整车头方向
dir_bef = 2;
RFID_special[1]=dir_bef;
Auto_Track(0);//循迹
delay_ms(100);
//判断是否是十字路口
Intersection_behavior(RFID_Flag);
}
else if (choose==3)//后者行坐标大于前者,则后者在前者上方,调整后方向为0
{
// int dir_bef;//初始化当前车头方向,0向上,1向右,2向下,3向左
RFID_special[0]=dir_bef;
Change_dir(dir_bef, 0);
dir_bef = 0;
RFID_special[1]=dir_bef;
Auto_Track(0);//循迹
delay_ms(100);
//判断是否是十字路口
Intersection_behavior(RFID_Flag);
}
}
}
//执行任务函数
/* 暂时不看 */
void Task(uint8_t Task_ID)
{
extern uint8_t Infrared_Tab[6]; //红外数据存放数组
uint8_t TL=0;
int i=0;
extern uint8_t MOKE;
#if 1
switch(Task_ID)
{
case 0:
//开始计时
LED_display(1);
delay_s(1);
//开启无线
Send_ZigbeeData_To_Fifo(Wir_C,8);
break;
case 1:
dir_bef=3;
Turn_Right(2);
delay_s(1);
A72_TraffiIdentification();
break;
case 2:
break;
case 3:
//采集数据
RecordedData();
TL=0;
//从车启动
while(Stop_Flag!=0xA2&&TL<5)
{
Send_ZigbeeData_To_Fifo(CCQd1,8);
Master_slave_interaction();
delay_ms(500);
TL++;
}
break;
case 4:
//超声波测距
Go_Back(50,450);
Ultrasonic_LED();
A72_IdentificationQCode();
Go_Along(50,400);
delay_s(1);
break;
case 5:
//智能路灯
int number=(disa[2]/60);
int nasdfas=1;
for(int i=0;i<number;i++)
{
if(nasdfas>4)
{
nasdfas%=4;
}
else
nasdfas*=number;
}
nasdfas%=4;
Turn_Right(2);
delay_s(1);
Street_lamp(nasdfas+1);
delay_s(1);
Turn_Left(2);
//TFT识别
Send_ZigbeeData_To_Fifo(H_X,8);//图片下翻
//接收从车数据
#if 1
ReceivTslaveCar();
#endif
break;
case 6:
break;
case 7:
//从车地址点
if(RFID_stop==SET)
{
PathAnalysis(READ_RFID);
delay_s(1);
while(Stop_Flag!=0xA2)
{
Send_ZigbeeData_To_Fifo(CCQd2,8);
Master_slave_interaction();
delay_s(1);
}
}
delay_s(2);
Turn_Left(2);
dir_bef=0;
TL=0;
Send_ZigbeeData_To_Fifo(DZ_H,8);
delay_ms(400);
Send_ZigbeeData_To_Fifo(DZ_Q,8);
while(Stop_Flag!=0x07&&TL<5)
{
Send_ZigbeeData_To_Fifo(DZ_H,8);
delay_ms(400);
Send_ZigbeeData_To_Fifo(DZ_Q,8);
delay_ms(500);
DZ_on_of();
TL++;
}
break;
case 8:
Turn_Right(2);
SYN_7318_One_test(1,0);
Turn_Left(2);
break;
case 9:
Turn_half_Left(2);
Infrared_Send(Ster_SD,6);
Turn_half_Ringht(2);
break;
case 10:
break;
case 11:
switch(RFID_Position[0])
{
case 'E':
numberOTgarage=2;
break;
case 'D':
numberOTgarage=3;
break;
case 'C':
numberOTgarage=4;
break;
}
Car_Deal(numberOTgarage,0);
break;
case 12:break;
case 13:break;
case 14:break;
case 15:break;
case 16:break;
case 17:break;
}
#endif
#if 0
switch(Task_ID)
{
case 1:
Turn_Right(2);
dir_bef=3;
A72_TraffiIdentification();
delay_s(2);
break;
case 4:
A72_IdentificationQCode();
delay_s(2);
break;
case 5:
A72_vehiclLPlatRecognition();
delay_s(2);
break;
}
#endif
}
每个通用 I/O 端口包括 4 个 32 位配置寄存器 ( GPIOx_MODER、 GPIOx_OTYPER、GPIOx_OSPEEDR 和 GPIOx_PUPDR)、 2 个 32 位数据寄存器(GPIOx_IDR 和GPIOx_ODR)、 1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、 1 个 32 位锁定寄存器(GPIOx_LCKR) 和 2 个 32 位复用功能选择寄存器( GPIOx_AFRH 和 GPIOx_AFRL)。
根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口 位分别配置为多种模式:
每个 I/O 端口位均可自由编程,但 I/O 端口寄存器必须按 32 位字、半字或字节进行访问。 GPIOx_BSRR 寄存器旨在实现对 GPIO ODR 寄存器进行原子读取/修改访问。这样便可确保 在读取和修改访问之间发生中断请求也不会有问题。
在复位期间及复位刚刚完成后,复用功能尚未激活, I/O 端口被配置为输入浮空模式。 复位后,调试引脚处于复用功能上拉/下拉状态:
当引脚配置为输出后,写入到输出数据寄存器 (GPIOx_ODR) 的值将在 I/O 引脚上输出。可 以在推挽模式下或开漏模式下使用输出驱动器(输出 0 时仅激活 N-MOS)。 输入数据寄存器 (GPIOx_IDR) 每隔 1 个 AHB1 时钟周期捕获一次 I/O 引脚的数据。 所有 GPIO 引脚都具有内部弱上拉及下拉电阻,可根据 GPIOx_PUPDR 寄存器中的值来打 开/关闭。
微控制器 I/O 引脚通过一个复用器连接到板载外设/模块,该复用器一次仅允许一个外设的复 用功能 (AF) 连接到 I/O 引脚。这可以确保共用同一个 I/O 引脚的外设之间不会发生冲突。 每个 I/O 引脚都有一个复用器,该复用器采用 16 路复用功能输入( AF0 到 AF15) ,可通过 GPIOx_AFRL(针对引脚 0 到 7)和 GPIOx_AFRH(针对引脚 8 到 15)寄存器对这些输入 进行配置:
除了这种灵活的 I/O 复用架构之外,各外设还可以将复用功能映射到不同 I/O 引脚,这可以 优化小型封装中可用外设的数量
将 I/O 连接到 AF0,然后根据所用功能进行配置: — JTAG/SWD:在各器件复位后,会将这些引脚指定为专用引脚,可供片上调试模块立即使用(不受 GPIO 控制器控制)。 — RTC_REFIN:此引脚应配置为输入浮空模式。 — MCO1 和 MCO2:这些引脚必须配置为复用功能模式。
在 GPIOx_MODER 寄存器中将所需 I/O 配置为输出或输入。
对于 ADC 和 DAC,在 GPIOx_MODER 寄存器中将所需 I/O 配置为模拟通道。 对于其它外设: — 在 GPIOx_MODER 寄存器中将所需 I/O 配置为复用功能 — 通过 GPIOx_OTYPER、 GPIOx_PUPDR 和 GPIOx_OSPEEDER 寄存器,分别选 择类型、上拉/下拉以及输出速度 — 在 GPIOx_AFRL 或 GPIOx_AFRH 寄存器中,将 I/O 连接到所需 AFx
配置用于输出 Cortex-M4F EVENTOUT 信号的 I/O 引脚(通过将其连接到 AF15) 注意: EVENTOUT 不会映射到以下 I/O 引脚: PC13、 PC14、 PC15、 PH0、 PH1 和 PI8。 有关系统和外设的复用功能 I/O 引脚映射的详细信息,请参见数据手册中的“复用功能 映射”表。
每个 GPIO 有 4 个 32 位存储器映射的控制寄存器( GPIOx_MODER、 GPIOx_OTYPER、GPIOx_OSPEEDR、 GPOIx_PUPDR), 可配置多达 16 个 I/O。 GPIOx_MODER 寄存器用于选择 I/O 方向(输入、输出、 AF、模拟)。 GPIOx_OTYPER 和 GPIOx_OSPEEDR 寄存器分别用于选择输出类型(推挽或开漏)和速度 (无论采用哪种 I/O 方向,都会直接将 I/O 速度引 脚连接到相应的 GPIOx_OSPEEDR 寄存器位)。无论采用哪种 I/O 方向, GPIOx_PUPDR 寄存器都用于选择上拉/下拉。
每个 GPIO 都具有 2 个 16 位数据寄存器:输入和输出数据寄存器( GPIOx_IDR 和GPIOx_ODR)。 GPIOx_ODR 用于存储待输出数据,可对其进行读/写访问。通过 I/O 输入的数据存储到输入数据寄存器 (GPIOx_IDR) 中, 它是一个只读寄存器。 有关寄存器说明的详细信息,请参见第 7.4.5 节: GPIO 端口输入数据寄存器 (GPIOx_IDR) (x = A..I) 和第 7.4.6 节: GPIO 端口输出数据寄存器 (GPIOx_ODR) (x = A..I)。
置位复位寄存器 (GPIOx_BSRR) 是一个 32 位寄存器,它允许应用程序在输出数据寄存器(GPIOx_ODR) 中对各个单独的数据位执行置位和复位操作。 置位复位寄存器的大小是GPIOx_ODR 的二倍。 GPIOx_ODR 中的每个数据位对应于 GPIOx_BSRR 中的两个控制位: BSRR(i) 和BSRR(i+SIZE)。 当写入 1 时, BSRR(i) 位会置位对应的 ODR(i) 位。当写入 1 时,BSRR(i+SIZE) 位会清零 ODR(i) 对应的位。 在 GPIOx_BSRR 中向任何位写入 0 都不会对 GPIOx_ODR 中的对应位产生任何影响。 如果在 GPIOx_BSRR 中同时尝试对某个位执行置位和清零操作,则置位操作优先。 使用 GPIOx_BSRR 寄存器更改 GPIOx_ODR 中各个位的值是一个“单次”操作,不会锁定GPIOx_ODR 位。 随时都可以直接访问 GPIOx_ODR 位。 GPIOx_BSRR 寄存器提供了一种执行原子按位处理的方法。 在对 GPIOx_ODR 进行位操作时,软件无需禁止中断:在一次原子 AHB1 写访问中,可以修改一个或多个位。
通过将特定的写序列应用到 GPIOx_LCKR 寄存器,可以冻结 GPIO 控制寄存器。冻结的寄存器包括 GPIOx_MODER、 GPIOx_OTYPER、 GPIOx_OSPEEDR、 GPIOx_PUPDR、GPIOx_AFRL 和 GPIOx_AFRH。 要对 GPIOx_LCKR 寄存器执行写操作,必须应用特定的写/读序列。当正确的 LOCK 序列应用到此寄存器的第 16 位后, 会使用 LCKR[15:0] 的值来锁定 I/O 的配置(在写序列期间,LCKR[15:0] 的值必须相同)。 将 LOCK 序列应用到某个端口位后,在执行下一次复位之前,将无法对该端口位的值进行修改。 每个 GPIOx_LCKR 位都会冻结控制寄存器 (GPIOx_MODER、GPIOx_OTYPER、 GPIOx_OSPEEDR、 GPIOx_PUPDR、 GPIOx_AFRL 和 GPIOx_AFRH)中的对应位。 LOCK 序列(参见第 7.4.8 节: GPIO 端口配置锁定寄存器 (GPIOx_LCKR) (x = A..I))只能通过对 GPIOx_LCKR 寄存器进行字( 32 位长)访问的方式来执行, 因为 GPIOx_LCKR 的第 16 位必须与 [15:0] 位同时置位。 有关详细信息,请参见第 7.4.8 节: GPIO 端口配置锁定寄存器 (GPIOx_LCKR) (x = A..I) 中的 LCKR 寄存器说明。
所有端口都具有外部中断功能。要使用外部中断线,必须将端口配置为输入模式,请参见 第 10.2 节:外部中断/事件控制器 (EXTI)和第 10.2.3 节:唤醒事件管理。
对 I/O 端口进行编程作为输入时:
图 20 说明了 I/O 端口位的输入配置
本节对 GPIO 寄存器进行了详细介绍。 有关寄存器位、寄存器偏移地址和复位值的汇总,请参见表 32。 可通过字节( 8 位)、半字( 16 位)或字( 32 位)对 GPIO 寄存器进行访问。
static uint8_t Car_1[8]={0x55,0x0D,0x01,0x01,0x00,0x00,0x02,0xBB}; //到达第一层
static uint8_t Car_2[8]={0x55,0x0D,0x01,0x02,0x00,0x00,0x03,0xBB}; //到达第二层
static uint8_t Car_3[8]={0x55,0x0D,0x01,0x03,0x00,0x00,0x04,0xBB}; //到达第三层
static uint8_t Car_4[8]={0x55,0x0D,0x01,0x04,0x00,0x00,0x05,0xBB}; //到达第四层
static uint8_t Car_R_F[8]={0x55,0x0D,0x02,0x01,0x00,0x00,0x03,0xBB};//请求回传立体车库所在层数
static uint8_t Car_R_I[8]={0x55,0x0D,0x02,0x02,0x00,0x00,0x04,0xBB};//请求回传立体车库前后侧红外状态
typedef struct _Fifo_Drv_Struct
{
uint32_t ml;
uint32_t rp;
uint32_t wp;
uint8_t *buf;
}Fifo_Drv_Struct;
Fifo_Drv_Struct Fifo_ZigbTx;
// 结构体初始化
void FifoDrv_Init(Fifo_Drv_Struct *p,uint8_t c)
{
if(p != _NULL)
{
if(p->ml > 1)
{
p->wp = 0;
p->rp = p->ml-1;
memset(p->buf,c,p->ml);
}
}
}
// 例如发送
//
Send_ZigbeeData_To_Fifo(Car_1,8); // go.c -> 1484 line
/**
函数功能:将数据发送至ZigBee模块
参 数:无
返 回 值:无
*p = Car_1, len = 8
*/
void Send_ZigbeeData_To_Fifo(u8 *p, u8 len)
{
FifoDrv_BufWrite(&Fifo_ZigbTx, p, len);
// FifoDrv_Bufwrite(&Fifo_ZigbTx, Car_1, 8);
}
/*
往特定地址写入数据
*/
uint32_t FifoDrv_BufWrite(Fifo_Drv_Struct *p,uint8_t *buf,uint32_t l)
{
// *p = Fifo_ZigbTx, *buf = Car_1, l = 8
// 函数调用等于 FifoDrv_Bufwrite(Fifo_ZigbTx, Car_1, 8);
uint32_t Rt = 0;
int i=l;
// int i = 8;
while(l--)
{
if(Rt==6&&8==i)
{
buf[6]=((buf[5]+buf[4]+buf[3]+buf[2]))%256;
// 做校验和的计算
}
// 一个一个数据写入
if(FifoDrv_WriteOne(p,buf[Rt]) == 0)
break;
Rt++;
}
// 返回写入了多少位数据
return Rt;
}
// 一个一个数据写入
uint8_t FifoDrv_WriteOne(Fifo_Drv_Struct *p,uint8_t d)
{
// *p = Fifo_ZigbTx, d = buf[Rt] -> {buf[0], buf[1], buf[2]}
// 函数调用等于 FifoDrv_WriteOne(Fifo_ZigbTx, Car_1[x])
uint8_t Rt = 0;
// 如果可用返回1
if(FifoDrv_CheckWriteEn(p))
{
p->buf[p->wp++] = d;
if(p->wp >= p->ml)
p->wp = 0;
Rt = 1;
}
// 写入成功返回1
return Rt;
}
// 检查结构体是否可用
uint8_t FifoDrv_CheckWriteEn(Fifo_Drv_Struct *p)
{
// *p = Fifo_ZigbTx
// 函数调用等于 FifoDrv_CheckWriteEn(Fifo_ZigbTx);
uint8_t Rt = 0;
if(FifoDrv_StructCheck(p))
{
if(p->wp != p->rp)
Rt = 1;
}
// 如果可用返回1
return Rt;
}
/*
// 检查结构体是否可用
*/
uint8_t FifoDrv_StructCheck(Fifo_Drv_Struct *p)
{
// *p = Fifo_ZigbTx
// 函数调用等于 FifoDrv_StructCheck(Fifo_ZigbTx);
uint8_t Rt = 0;
if(p != _NULL)
{
if(p->ml > 1)
{
if((p->buf != _NULL)
&&(p->wp < p->ml)
&&(p->rp < p->ml)
)
Rt = 1;
}
}
// 如果可用返回1
return Rt;
}
// Can总线数据监测
void CanP_CanTx_Check(void)
{
uint8_t tmbox, i, f = 1;
while (f)
{
f = 0;
i = FifoDrv_BufRead(&Fifo_Info, ctbuf, 8); // 调试信息
if (i)
{
CanDrv_WhaitTxEmpty();
CanDrv_TxData(ctbuf, i, CAN_SID_HL(ID_DISP, 0), 0, &tmbox);
f = 1;
}
i = FifoDrv_BufRead(&Fifo_WifiTx, ctbuf, 8); // wifi信息
if (i)
{
CanDrv_WhaitTxEmpty();
CanDrv_TxData(ctbuf, i, CAN_SID_HL(ID_WIFI, 0), 0, &tmbox);
f = 1;
}
i = FifoDrv_BufRead(&Fifo_ZigbTx, ctbuf, 8); // Zigbee信息
if (i)
{
CanDrv_WhaitTxEmpty();
// 发送到Can总线里面
CanDrv_TxData(ctbuf, i, CAN_SID_HL(ID_ZIGBEE, 0), 0, &tmbox);
f = 1;
}
}
}
// 请求回传立体车库所在层数
Send_ZigbeeData_To_Fifo(Car_R_F,8);
// 获取当前车库状态
Can_ZigBeeRx_carport();
int Stereo_loop=1;
//判断车库在第几层,并发指令降到第一层
int i=0;
while(Stop_Flag!=0x09)
{
delay_ms(400);
Send_ZigbeeData_To_Fifo(Car_R_F,8);
delay_ms(400);
Can_ZigBeeRx_carport();
delay_ms(400);
// 发送降到第一层的指令
Send_ZigbeeData_To_Fifo(Car_1,8);
}
//倒车
Go_Back(100,2000);
//标准入库
// 请求回传立体车库所在层数
Send_ZigbeeData_To_Fifo(Car_R_F,8);
// 获取当前车库状态
Can_ZigBeeRx_carport();
// 发送降到第一层的指令
Send_ZigbeeData_To_Fifo(Car_1,8);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。