feat: add STM32 four-channel weighing firmware

This commit is contained in:
FinleyHsu
2026-07-28 11:01:55 +08:00
commit 1282b9b77e
205 changed files with 80376 additions and 0 deletions
@@ -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*******************/