413 lines
8.2 KiB
C
413 lines
8.2 KiB
C
#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;
|
||
//
|
||
//}
|
||
|