feat: add STM32 four-channel weighing firmware
This commit is contained in:
@@ -0,0 +1,421 @@
|
||||
/*************************** (C) COPYRIGHT 2017 CXHY ****************************
|
||||
* 文件名 :UltrasonicWave.c
|
||||
* 描 述 :HC-SR04超声波驱动代码
|
||||
* 版 本 :V1.0
|
||||
* 作 者 :XuZhongPing
|
||||
* 日 期 :2017/08/04
|
||||
*********************************************************************************/
|
||||
#include "IR_Distancer.h"
|
||||
#include "timer.h"
|
||||
#include "delay.h"
|
||||
#include "adc.h"
|
||||
#include "my_math.h"
|
||||
#include "data_typedef.h"
|
||||
|
||||
#define IR_AdcValSize 100
|
||||
uint16_t IR_AdcValBuf_1[IR_AdcValSize];
|
||||
uint16_t IR_AdcVal_1 = 0;
|
||||
|
||||
uint16_t IR_AdcValBuf_2[IR_AdcValSize];
|
||||
uint16_t IR_AdcVal_2 = 0;
|
||||
|
||||
uint8_t IR_GetAdcValMake = 0;
|
||||
|
||||
#define IR_GetDataCount 5
|
||||
|
||||
uint8_t ir_Distance1 = 0;
|
||||
uint8_t ir_dataOutState1 = 0;
|
||||
uint8_t ir_Distance2 = 0;
|
||||
uint8_t ir_dataOutState2 = 0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: show
|
||||
* 功能说明: 以十六进制显示数组里的内容
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
***********************************************************************
|
||||
*/
|
||||
void showBuf(uint16_t num[], uint8_t n)
|
||||
{
|
||||
uint8_t i;
|
||||
printf("\r\n");
|
||||
for(i=0; i<n; i++)
|
||||
{
|
||||
printf("%04d ",num[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: IR_GetAdcVal_1
|
||||
* 功能说明: 获取红外测距传感器ADC值
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
***********************************************************************
|
||||
*/
|
||||
void IR_GetAdcVal_1(void)
|
||||
{
|
||||
Data_collection(IR_AdcValBuf_1, IR_AdcValSize, ADC_Channel_11);
|
||||
sort_16(IR_AdcValBuf_1, IR_AdcValSize); //对存在缓存中的采集数据进行排序
|
||||
IR_AdcVal_1 = average_16(IR_AdcValBuf_1, IR_AdcValSize, 20); //去掉头和尾后,求平均数
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: IR_GetAdcVal_2
|
||||
* 功能说明: 获取红外测距传感器ADC值
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
***********************************************************************
|
||||
*/
|
||||
void IR_GetAdcVal_2(void)
|
||||
{
|
||||
Data_collection(IR_AdcValBuf_2, IR_AdcValSize, ADC_Channel_10);
|
||||
sort_16(IR_AdcValBuf_2, IR_AdcValSize); //对存在缓存中的采集数据进行排序
|
||||
IR_AdcVal_2 = average_16(IR_AdcValBuf_2, IR_AdcValSize, 20); //去掉头和尾后,求平均数
|
||||
}
|
||||
|
||||
uint8_t distanceMap[] = { 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150};
|
||||
float voltageMap[14] = {2.49, 1.95, 1.51, 1.21, 1.01, 0.86, 0.76, 0.69, 0.61, 0.53, 0.45, 0.40, 0.34, 0.25};
|
||||
// float voltageMap[14] = {2.50, 1.95, 1.50, 1.20, 1.00, 0.88, 0.77, 0.69, 0.60, 0.55, 0.49, 0.44, 0.38, 0.30};
|
||||
|
||||
// float voltageMap[14] = {2.44, 1.94, 1.50, 1.20, 1.00, 0.85, 0.74, 0.67, 0.60, 0.52, 0.48, 0.44, 0.39, 0.33};
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: LookupTable
|
||||
* 功能说明: 查表得出对应的距离值
|
||||
* 形 参:无
|
||||
* 返 回 值: 对应的距离
|
||||
***********************************************************************
|
||||
*/
|
||||
float LookupTable(float vIn, float vMap1, float vMap2, uint8_t disMap1, uint8_t disMap2)
|
||||
{
|
||||
uint8_t disDifVal; //区间的电压差值
|
||||
float vDifVal; //区间的距离差值
|
||||
float vLtscale; //区间距离比例因子
|
||||
float vIntervalVal; //区间电压值
|
||||
float intervalDistance; //区间的距离
|
||||
|
||||
disDifVal = disMap2 - disMap1;
|
||||
vDifVal = vMap1 - vMap2;
|
||||
vLtscale = disDifVal/vDifVal;
|
||||
|
||||
vIntervalVal = vMap1 - vIn;
|
||||
intervalDistance = vIntervalVal*vLtscale;
|
||||
|
||||
// printf("\r\ndisDif = %d\r\n", disDifVal);
|
||||
// printf("\r\nvDif = %.2f\r\n", vDifVal);
|
||||
// printf("\r\nvLtscale = %.2f\r\n", vLtscale);
|
||||
// printf("\r\nvIntervalVal = %.2f\r\n", vIntervalVal);
|
||||
// printf("\r\nvInvalVal = %.2f\r\n", intervalDistance);
|
||||
|
||||
return disMap1 + intervalDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: IR_GetDistanceData
|
||||
* 功能说明: 取得一次测距值
|
||||
* 形 参:num -> 对应哪个通道
|
||||
* 返 回 值: 当前通道的测距值
|
||||
***********************************************************************
|
||||
*/
|
||||
uint8_t IR_GetDistanceData(uint8_t num)
|
||||
{
|
||||
float distanceTemp;
|
||||
float adToVdcVal;
|
||||
int index = 0;
|
||||
|
||||
switch(num)
|
||||
{
|
||||
case 1:
|
||||
IR_GetAdcVal_1();
|
||||
|
||||
if(IR_AdcVal_1 < 120)
|
||||
{
|
||||
return 255;
|
||||
}else{
|
||||
adToVdcVal = IR_AdcVal_1/4096.0 * 3.34;
|
||||
// printf("\r\nV1 = %1.2f, ADC1 = %d ", adToVdcVal, IR_AdcVal_1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
IR_GetAdcVal_2();
|
||||
|
||||
if(IR_AdcVal_2 < 120)
|
||||
{
|
||||
return 255;
|
||||
}else{
|
||||
adToVdcVal = IR_AdcVal_2/4096.0 * 3.34;
|
||||
// printf("\r\nV2 = %1.2f, ADC2 = %d ", adToVdcVal, IR_AdcVal_2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// printf("ADC = %4d, %4d, V = %1.2f\r\n", IR_AdcVal_1, IR_AdcVal_2, adToVdcVal);
|
||||
|
||||
for(index = 0; index < 14; index++)
|
||||
{
|
||||
if(adToVdcVal >= voltageMap[index])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// printf("\r\nindex = %d\r\n", index);
|
||||
if(index == 0)
|
||||
{
|
||||
distanceTemp = 20;
|
||||
}else if(index == 14){
|
||||
distanceTemp = 150;
|
||||
}else{
|
||||
distanceTemp = LookupTable(adToVdcVal, voltageMap[index-1], voltageMap[index], distanceMap[index-1], distanceMap[index]);
|
||||
}
|
||||
|
||||
// printf("D = %d cm\r\n", (uint8_t)distanceTemp);
|
||||
|
||||
return distanceTemp;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: ULT_DataProcessing
|
||||
* 功能说明: 对采集到缓存的数据处理(对其进行排序后求平均数)
|
||||
* 形 参:
|
||||
* *p: 需要处理的数组指针
|
||||
* n: 数组的长度
|
||||
* 返 回 值: 返回最终处理过后的结果
|
||||
***********************************************************************
|
||||
*/
|
||||
uint8_t IR_DataProcessing(uint8_t *p, uint16_t n, uint8_t discardVal)
|
||||
{
|
||||
uint8_t retData = 0;
|
||||
|
||||
sort_8(p, n); //对存在缓存中的采集数据进行排序
|
||||
retData = average_8(p, n, discardVal); //去掉头和尾后,求平均数
|
||||
// printf("\r\nValue = %d\r\n", retData);
|
||||
return retData;
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: IR_GetDistanceTask_01
|
||||
* 功能说明: 获取红外测距任务
|
||||
* 形 参:无
|
||||
* 返 回 值: 数据处理状态 1:已处理完成可以输出、0:尚未处理完成
|
||||
***********************************************************************
|
||||
*/
|
||||
void IR_GetDistanceTask_01(void)
|
||||
{
|
||||
static uint8_t step = 0x00;
|
||||
static uint8_t getDataCnt = 0x00;
|
||||
|
||||
static uint8_t newValue = 0x00;
|
||||
static uint8_t oleValue = 0x00;
|
||||
static uint8_t IR_DistanceDataBuf[IR_GetDataCount];
|
||||
|
||||
static timer waitingTimer;
|
||||
static uint8_t timer_ok = 0;
|
||||
|
||||
if(timer_ok == 0)
|
||||
{
|
||||
timer_ok = 1;
|
||||
timer_set(&waitingTimer, 1);
|
||||
}
|
||||
|
||||
switch(step)
|
||||
{
|
||||
case 0x00:
|
||||
if(timer_expired(&waitingTimer))
|
||||
{
|
||||
newValue = IR_GetDistanceData(1);
|
||||
// printf("\r\nValue = %3.1f cm\r\n",(float)newValue);
|
||||
step = 0x01;
|
||||
timer_restart(&waitingTimer);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
if(DifferenceCompare(newValue, oleValue, 10)) //比较新旧值的差值,(当前值 - 之前值)> 设定值时重新采集数据
|
||||
{
|
||||
getDataCnt = 0;
|
||||
}
|
||||
// printf("\r\nCnt1 = %d, newValue = %d, oleValue = %d\r\n", getDataCnt, newValue, oleValue);
|
||||
oleValue = newValue;
|
||||
|
||||
IR_DistanceDataBuf[getDataCnt] = newValue;
|
||||
getDataCnt++;
|
||||
if(IR_GetDataCount == getDataCnt) //IR_GetDataCount次数据都相差不大,则认为数据已经稳定可以输出
|
||||
{
|
||||
getDataCnt = 0;
|
||||
step = 0x02; //转到数据处理输出
|
||||
}else{
|
||||
step = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
ir_Distance1 = IR_DataProcessing(IR_DistanceDataBuf, IR_GetDataCount, 0);
|
||||
// printf("\r\nNo1 ---> %3.1f cm\r\n",(float)ir_Distance1);
|
||||
ir_dataOutState1 = 1;
|
||||
step = 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
step = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* 函 数 名: IR_GetDistanceTask_02
|
||||
* 功能说明: 获取红外测距任务
|
||||
* 形 参:无
|
||||
* 返 回 值: 数据处理状态 1:已处理完成可以输出、0:尚未处理完成
|
||||
***********************************************************************
|
||||
*/
|
||||
void IR_GetDistanceTask_02(void)
|
||||
{
|
||||
static uint8_t step = 0x00;
|
||||
static uint8_t getDataCnt = 0x00;
|
||||
|
||||
static uint8_t newValue = 0x00;
|
||||
static uint8_t oleValue = 0x00;
|
||||
static uint8_t IR_DistanceDataBuf[IR_GetDataCount];
|
||||
|
||||
static timer waitingTimer;
|
||||
static uint8_t timer_ok = 0;
|
||||
|
||||
if(timer_ok == 0)
|
||||
{
|
||||
timer_ok = 1;
|
||||
timer_set(&waitingTimer, 1);
|
||||
}
|
||||
|
||||
switch(step)
|
||||
{
|
||||
case 0x00:
|
||||
if(timer_expired(&waitingTimer))
|
||||
{
|
||||
newValue = IR_GetDistanceData(2);
|
||||
// printf("\r\nValue = %3.1f cm\r\n",(float)newValue);
|
||||
step = 0x01;
|
||||
timer_restart(&waitingTimer);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
if(DifferenceCompare(newValue, oleValue, 10)) //比较新旧值的差值,(当前值 - 之前值)> 设定值时重新采集数据
|
||||
{
|
||||
getDataCnt = 0;
|
||||
}
|
||||
// printf("\r\nCnt2 = %d, newValue = %d, oleValue = %d\r\n", getDataCnt, newValue, oleValue);
|
||||
oleValue = newValue;
|
||||
|
||||
IR_DistanceDataBuf[getDataCnt] = newValue;
|
||||
getDataCnt++;
|
||||
if(IR_GetDataCount == getDataCnt) //10次数据都相差不大,则认为数据已经稳定可以输出
|
||||
{
|
||||
getDataCnt = 0;
|
||||
step = 0x02; //转到数据处理输出
|
||||
}else{
|
||||
step = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
ir_Distance2 = IR_DataProcessing(IR_DistanceDataBuf, IR_GetDataCount, 0);
|
||||
// printf("\r\nNo2 ---> %3.1f cm\r\n",(float)ir_Distance2);
|
||||
ir_dataOutState2 = 1;
|
||||
step = 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
step = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// /*
|
||||
// ***********************************************************************
|
||||
// * 函 数 名: IR_GetDistanceTask
|
||||
// * 功能说明: 红外测距任务
|
||||
// * 形 参:无
|
||||
// * 返 回 值: 无
|
||||
// ***********************************************************************
|
||||
// */
|
||||
// void IR_GetDistanceTask(void)
|
||||
// {
|
||||
// static uint8_t ULT_getDataStatus = 0x00;
|
||||
//
|
||||
// static uint8_t distance_1 = 255;
|
||||
// static uint8_t distance_2 = 255;
|
||||
//
|
||||
// static timer waitingTimer;
|
||||
// static timer responsTimer;
|
||||
// static uint8_t timer_ok = 0;
|
||||
//
|
||||
// if(timer_ok == 0)
|
||||
// {
|
||||
// timer_ok = 1;
|
||||
// timer_set(&waitingTimer, CLOCK_SECOND*2);
|
||||
// timer_set(&responsTimer, 3);
|
||||
// }
|
||||
//
|
||||
// switch(ULT_getDataStatus)
|
||||
// {
|
||||
// case 0x00:
|
||||
// if(timer_expired(&waitingTimer))
|
||||
// {
|
||||
// ULT_getDataStatus = 0x01;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case 0x01:
|
||||
// distance_1 = IR_GetDistanceData(1);
|
||||
// // if(dataOutState1 == 1) //第一路测距数据采集成功
|
||||
// // {
|
||||
// // dataOutState1 = 0;
|
||||
// ULT_getDataStatus = 0x02;
|
||||
// // // printf("\r\n第1路采集OK\r\n");
|
||||
// // }
|
||||
// break;
|
||||
//
|
||||
// case 0x02:
|
||||
// distance_2 = IR_GetDistanceData(2);
|
||||
// // if(dataOutState2 == 1) //第一路测距数据采集成功
|
||||
// // {
|
||||
// // dataOutState2 = 0;
|
||||
// ULT_getDataStatus = 0x03;
|
||||
// // // printf("\r\n第2路采集OK\r\n");
|
||||
// // }
|
||||
// break;
|
||||
//
|
||||
// case 0x03:
|
||||
// getDistance1 = distance_1;
|
||||
// getDistance2 = distance_2;
|
||||
//
|
||||
// // printf("\r\n测距:No1 = %3.1f cm, ", (float)distance_1);
|
||||
// // printf("No2 = %3.1f cm\r\n", (float)distance_2);
|
||||
// // printf("No3 = %3.1f cm, ", (float)distance3);
|
||||
// // printf("No4 = %3.1f cm\r\n", (float)distance4);
|
||||
// ULT_getDataStatus = 0x00;
|
||||
// timer_restart(&waitingTimer);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/*************************** (C) COPYRIGHT 2017 CXHY ****************************
|
||||
* 文件名 :IR_Distancer.h
|
||||
* 描 述 :红外测距驱动代码
|
||||
* 版 本 :V1.0
|
||||
* 作 者 :XuZhongPing
|
||||
* 日 期 :2017/08/04
|
||||
*********************************************************************************/
|
||||
#ifndef __IR_Distancer_H
|
||||
#define __IR_Distancer_H
|
||||
#include "stm32f10x.h"
|
||||
|
||||
extern uint8_t ir_Distance1;
|
||||
extern uint8_t ir_dataOutState1;
|
||||
extern uint8_t ir_Distance2;
|
||||
extern uint8_t ir_dataOutState2;
|
||||
|
||||
void IR_GetAdc(void);
|
||||
|
||||
uint8_t IR_GetDistanceData(uint8_t num);
|
||||
void IR_GetDistanceTask_01(void);
|
||||
void IR_GetDistanceTask_02(void);
|
||||
|
||||
#endif
|
||||
|
||||
/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/
|
||||
Reference in New Issue
Block a user