#include "basic.h" int led_flag = 0 ; int Mode_turn = 0 ; //安全栅模式/电流模式切换 float temp = 0; //温度 float length = 0; //长度 float zero_length; //零点位置长度 float act_length = 0;//实际长度 float v = 0; //电压设定值 int ts= 0,te = 0; int n = 0; int adc_num = 0; u8 array[8] = {0x02,0x03,0x00,0x00,0x00,0x02,0xC4,0x38};//位移传感器读命令 u16 Tstar[20] = {0};//启动延时时间 u8 Terror[20] = {0};//错误信号持续时间 u16 T_flag[20] = {0}; //系统初始化 void Sys_Init() { //SysTick_Init(); //初始化串口 usart_Init(); //串口数据初始化 InitUart_Data(); //ADC初始化 ADC_AllInit(); //初始化定时器3 TIM3_Configuration(); //TIM8_IC_Init(); //初始化DAC,开始DAC转换 DAC_Config(); //安全栅端口初始化 safe_gpio_Init(); Gpio_Init(); EXTI_Key_Config(); //SPI通讯初始化 MAX31865_Init(); MAX31865_Cfg(); //串口3相关 UART_Receive_flg = 0; TIM4_PWM_Init(1999,90); } //LED灯闪烁 void led() { if(it_1s_flag == 1) { it_1s_flag = 0; GPIO_ToggleBits(GPIOG,GPIO_Pin_1); //LED电平翻转 } } int u = 0; //主程序运行函数 void main_do() { switch(Mode_Flag) { case 1: mode_one(); break; case 2: mode_two(); break; case 3: mode_thr(); break; default: break; } Deal_Uart_Data_For_Module(); //处理接收的数据 v = (((float)(Set_Vol - 10 ) / 100) - 5 ) / 2; DAC1_SetVol(v); //DAC输出电压 } /***************************************************** *函数名称: mode_one *函数功能: 模式1,控制电机转动,实现置零,实现位移数据收集 *参数说明: *****************************************************/ void mode_one() { u++; if(u>50) { ADC_SoftwareStartConv(ADC1); //触发ADC转换 get_adcnum(); //ADC滤波 u=0; } if(zero_flag == 2) Deal_Motor(); //根据接收的数据控制电机 else set_zero(); //设置零点 if(UART_Receive_flg) { UART_Receive_flg = 0; } if(it_100ms_flag == 1) { it_100ms_flag = 0; temp = MAX31865_GetTemp(); //软件模拟spi读取max31865合成温度 Uart3_SendStr(array,8); //发送命令,是位移传感器回传数据 } get_state(); //得到安全栅状态 if(zero_length == 0) { act_length = length - zero_length; //转化为实际距离 } else { act_length = zero_length - length; //转化为实际距离 } data_deal(send_data,V_Channel,act_length,temp); //ADC数据、温度、位移数据整理打包 } /***************************************************** *函数名称: mode_two *函数功能: 模式2,计算传感器的启动延时时间以及错误信号持续时间 *参数说明: *****************************************************/ void mode_two() { ADC_SoftwareStartConv(ADC1); //触发ADC转换 if(get_time_flag == 1) { if(it_100ms_flag == 1) { it_100ms_flag = 0; //temp = MAX31865_GetTemp(); //软件模拟spi读取max31865合成温度 Uart3_SendStr(array,8); //发送命令,是位移传感器回传数据 } //get_state(); //得到安全栅状态 if(zero_length == 0) { act_length = length - zero_length; //转化为实际距离 } else { act_length = zero_length - length; //转化为实际距离 } if(act_length > dis) FWD(); else REV(); motor_start(); motor_mov_slow(); if(act_length < (dis + 0.05f) && act_length > (dis - 0.05f)) { motor_stop(); for(int i= 0;i<20;i++) { T_flag[i] = 0; Tstar[i] = 0; //启动延时时间 Terror[i] = 0; //错误信号持续时间 V_time_test[i] = ((uint16_t)(ADC_ConvertedValue[0][num_array[i]])*10000/4096) ; //当前位置稳定电流V_Channel[i] } GPIO_ResetBits(GPIOF,GPIO_Pin_11); //关闭使能,ADC掉电 adc_num = 0; get_time_flag = 2; } } if(get_time_flag == 4) { get_time_flag = 0; deal_time(); //时间数据整合 send_set_resp(0xF002, OBJ_DEVICE_ADDR, 60, time_data);//数据发送 Mode_Flag = 1; } } /***************************************************** *函数名称: mode_thr *函数功能: 模式3,控制无刷电机,实现装置频率测试 *参数说明: *****************************************************/ void mode_thr() { u++; if(u>10) { ADC_SoftwareStartConv(ADC1); //触发ADC转换 u=0; } frequency_test(); //频率测试 if(it_100ms_flag == 1) //&& Run_State == 1 { it_100ms_flag = 0; Fre_data[0] = (((uint16_t)MOT_Fre) & 0xff00) >> 8; Fre_data[1] = ((uint16_t)MOT_Fre) & 0x00ff; Fre_data[2] = (((uint16_t)ADC_Fre) & 0xff00) >> 8; Fre_data[3] = ((uint16_t)ADC_Fre) & 0x00ff; send_set_resp(0xF003, OBJ_DEVICE_ADDR, 4, Fre_data);//数据发送 if(ADC_Fre > 1000 && MOT_Fre > 1000) Run_State = 0; } } /***************************************************** *函数名称: get_length *函数功能: 位移数据处理 *参数说明: *****************************************************/ char get_length_flag = 0; unsigned int data = 0; float d = 0; void get_length(uint8_t *D_array) { get_length_flag = 1; /* 位移数据正常情况为 00 02 03 起始 偶有 00 A0 20 起始 两种情况位移数据位置不同 */ if(D_array[1] == 0x02 && D_array[2] == 0x03) { data = D_array[6] << 8; data |= D_array[7]; d = ((float)data) / 1000; } else if(D_array[1] == 0xA0 && D_array[2] == 0x20) { data = D_array[5] << 8; data |= D_array[6]; d = ((float)data) / 1000; } length = d; } //启动延时时间和错误信号持续时间计算 void time_test(int i) { //启动延时时间指ADC数据达到掉电前稳定数据的±5%所需时间,为避免错误信号的影响,设定其最小值为0.3ms if(((uint16_t)(ADC_ConvertedValue[0][num_array[i]])*10000/4096) <= (V_time_test[i]* 105 /100) && ((uint16_t)(ADC_ConvertedValue[0][num_array[i]])*10000/4096) >= (V_time_test[i]* 95 /100) && Tstar[i] == 0 && ts > 3) { Tstar[i] = ts;///10 } else { ts++; if(ts > 30000) ts = 0xffff; } //错误信号持续时间指上电后过高瞬时电压的持续时间,这里以超过稳定电压的105%为阈值 if(((uint16_t)(ADC_ConvertedValue[0][num_array[i]])*10000/4096) >(V_time_test[i]* 105 /100) && T_flag[i] == 0) { T_flag[i] = 1; } if(T_flag[i] == 1) { if(((uint16_t)(ADC_ConvertedValue[0][num_array[i]])*10000/4096) <= (V_time_test[i]* 105 /100) && Terror[i] == 0) { T_flag[i] = 2; Terror[i] = te;///10 } else { if(te > 255) te = 0xff; else te++; } } } //时间测试 void get_time() { GPIO_SetBits(GPIOF,GPIO_Pin_11); //打开使能,ADC上电 if(it_100us_flag == 1) { it_100us_flag = 0; n++; //每个传感器设定1s的时间来计算 if(n > 10000) { adc_num++; n = 0; ts = 0; te = 0; if(adc_num >= 20) { get_time_flag = 4; adc_num = 0; } else get_time_flag = 3; } else { time_test(adc_num); } } } //整理时间测试数据 void deal_time() { //启动延时时间 for(int i= 0;i<20;i++) { time_data[2*i] = (Tstar[i] & 0xff00) >> 8; time_data[2*i+1] = Tstar[i] & 0x00ff; } //错误信号持续时间 for(int i=0;i < 20;i++) { time_data[i+40] = Terror[i]; } } /***************************************************** *函数名称: data_deal *函数功能: 整合处理数据 *参数说明: *****************************************************/ void data_deal(unsigned char *send_array,uint16_t *V_array,float l,float t) { if(Mode_turn == 0) { //ADC电流 //由20个传感器电流值、总电流值和设定电压值组成 for(int i = 0,j = 0;i < 22;i++,j+=2) { send_array[j] = (V_Channel[i] & 0xff00) >> 8; send_array[j+1] = V_Channel[i] & 0x00ff; } } else { //安全栅状态 //由20个安全栅状态决定,规定安全栅断开(0)时,电流数值定为3mA,否则为0.5mA //使用安全栅时ADC不可用,总电流和设定电压规定为0 for(int i = 0,j = 0;i < 20;i++,j+=2) { if(state[i] == 0) { send_array[j] = (0x0BB8 & 0xff00) >> 8; send_array[j+1] =0x0BB8 & 0x00ff; } else { send_array[j] = 0x01; send_array[j+1] =0xF4; } } for(int i = 40;i < 44;i++) send_array[i] = 0; } //温度 if(t >= 0)//零上 { send_array[44] = 00; send_array[45] = (((uint16_t)(t*100)) & 0xff00) >> 8; send_array[46] = ((uint16_t)(t*100)) & 0x00ff; } else//零下 { send_array[44] = 01; t = fabsf(t); send_array[45] = (((uint16_t)(t*100)) & 0xff00) >> 8; send_array[46] = ((uint16_t)(t*100)) & 0x00ff; } //位移 send_array[47] = (((uint16_t)(l*1000)) & 0xff00) >> 8;; send_array[48] = ((uint16_t)(l*1000)) & 0x00ff; //发送成功标志,为上位机服务 send_array[49] = 01; } //float A1 = 0,A2 = 0,A3 = 0,A4 = 0; //int zero_deal() //{ // if(get_length_flag == 1) // { // get_length_flag = 0; // A4 = A3; // A3 = A2; // A2 = A1; // A1 = length; // } // if(fabsf(A3-A2)<0.03f && fabsf(A2-A1)<0.02f) // return 1; // else // return 0; // //}