添加部分常用API。 添加 newlife rpc 通讯。
JiuHuan 编写于 2024-08-16 10:56:23
microCLib
#include "TM7711.h"
#include "Array.h"
#include "SysTime.h"
#include "Debug.h"

#define DisableIrq() __disable_irq()
#define EnableIrq() __enable_irq()

static void DelayUs(int us)
{
	for (int i = 0; i < us; i++)
	{
		for (volatile int j = 0; j < 15; j++);
	}
}

/// <summary>初始化</summary>
/// <param name="thiss"></param>
/// <returns></returns>
bool TM7711Init(TM7711_t* thiss)
{
	if (thiss == NULL)return false;
	if (thiss->SCK == P0)return false;
	if (thiss->DOUT == P0)return false;

	memset(thiss->SrcData, 0x00, sizeof(thiss->SrcData));
	thiss->PushIdx = 0;

	GpioInit(thiss->SCK, PIN_OUTPUT, PIN_OUTPUT_PP, PIN_NO_PULL, 0, 0);
	GpioInit(thiss->DOUT, PIN_INPUT, PIN_OUTPUT_PP, PIN_PULL_UP, 0, 0);

	thiss->LastStamp = GetCurrentTimeMs();
	thiss->ErrCnt = 0;

	return true;
}

/// <summary>获取数据</summary>
/// <param name="thiss">对象自己</param>
/// <returns></returns>
uint TM7711GetDstData(TM7711_t* thiss)
{
	// 去掉最大值,去掉最小值。 取一半做平均数。
	uint temp[ArrayLength(thiss->SrcData)];

	memcpy(temp, thiss->SrcData, sizeof(temp));
	// 排序
	ArraySortUint(temp, ArrayLength(temp));

	int sun = 0;
	int len = ArrayLength(temp) - 4;
	for (int i = 2; i < len+2; i++)
	{
		sun += temp[i];
	}

	int avevalue = sun / len;

	if (abs(thiss->LastValue - avevalue) < 16)
	{
		return thiss->LastValue & (~16);
	}
	
	thiss->LastValue = avevalue;
	return avevalue & (~16);

	// return temp[ArrayLength(temp) / 2];
}

/// <summary>丢数据到滤波器内</summary>
/// <param name="thiss"></param>
/// <param name="data"></param>
void TM7711PushData(TM7711_t* thiss, uint data)
{
	// 24bit数据。判断一下越界。
	if ((data & 0xfe000000) != 0)return;
	if (data < 0x10000)return;

	if (thiss->PushIdx >= ArrayLength(thiss->SrcData)) thiss->PushIdx = 0;

	thiss->SrcData[thiss->PushIdx] = data;
	thiss->PushIdx++;
}

static uint _TM7711GetData25(TM7711_t* thiss)
{
	// 上升沿 -- 设备输出电平
	// 输出一直延伸到,下一个上升沿
	uint data = 0;
	for (int i = 0; i < 24; i++)
	{
		GpioWrite(thiss->SCK, true);
		DelayUs(1);
		GpioWrite(thiss->SCK, false);

		DelayUs(1);
		data <<= 1;
		if (GpioRead(thiss->DOUT))
		{
			data |= 0x01;
		}
	}

	GpioWrite(thiss->SCK, true);
	DelayUs(1);
	GpioWrite(thiss->SCK, false);

	// 负数
	if ((data & 0x00800000) != 0)
	{
		data &= 0x7fffff;
		// data |= 0x80000000;
	}
	else
	{
		data |= 0x800000;
	}

	return data;
}

static void Reset(TM7711_t* thiss)
{
	Time_t now = GetCurrentTimeMs();

	GpioWrite(thiss->SCK, true);
	DebugPrintf("TM Reset\r\n");
	DelayMs(5);
	GpioWrite(thiss->SCK, false);

	DisableIrq();
	_TM7711GetData25(thiss);
	EnableIrq();

	thiss->LastStamp = now;
	thiss->ErrCnt = 0;
}

/// <summary>25bit 读数据。设置10HZ差分。无噪声位17bit</summary>
/// <param name="thiss"></param>
/// <returns></returns>
uint TM7711GetData25(TM7711_t* thiss)
{
	Time_t now = GetCurrentTimeMs();
	if (now - thiss->LastStamp > 1000)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	if (now - thiss->LastStamp < 90)return 0xffffffff;
	// GpioWrite(thiss->SCK, false);

	// DOUT 高电平,表示数据还未准备好。
	if (GpioRead(thiss->DOUT))return 0xffffffff;
	// 读取时间。
	thiss->LastStamp = now;

	DisableIrq();
	uint data = _TM7711GetData25(thiss);
	EnableIrq();

	bool err = (((data & 0x7ffff0) == 0) || ((data & 0x7ffff0) == 0x7ffff0));
	if (err)thiss->ErrCnt++;
	else thiss->ErrCnt = 0;

	// 进入休眠
	if (thiss->ErrCnt > 8)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	return data;
}

/// <summary>26bit 读数据。设置40HZ温度</summary>
/// <param name="thiss"></param>
/// <returns></returns>
uint TM7711GetData26(TM7711_t* thiss)
{
	Time_t now = GetCurrentTimeMs();	
	if (now - thiss->LastStamp > 1000)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	if (now - thiss->LastStamp < 15)return 0xffffffff;
	// GpioWrite(thiss->SCK, false);
	// DOUT 高电平,表示数据还未准备好。
	if (GpioRead(thiss->DOUT))return 0xffffffff;
	// 读取时间。
	thiss->LastStamp = now;

	DisableIrq();
	uint data = _TM7711GetData25(thiss);

	DelayUs(1);
	GpioWrite(thiss->SCK, true);
	DelayUs(1);
	GpioWrite(thiss->SCK, false);

	EnableIrq();

	bool err = (((data & 0x7ffff0) == 0) || ((data & 0x7ffff0) == 0x7ffff0));
	if (err)thiss->ErrCnt++;
	else thiss->ErrCnt = 0;

	// 进入休眠
	if (thiss->ErrCnt > 8)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	return data;
}

/// <summary>27bit 读数据。设置40HZ差分</summary>
/// <param name="thiss"></param>
/// <returns></returns>
uint TM7711GetData27(TM7711_t* thiss)
{
	Time_t now = GetCurrentTimeMs();	
	if (now - thiss->LastStamp > 1000)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	if (now - thiss->LastStamp < 15)return 0xffffffff;
	// GpioWrite(thiss->SCK, false);
	// DOUT 高电平,表示数据还未准备好。
	if (GpioRead(thiss->DOUT))return 0xffffffff;
	// 读取时间。
	thiss->LastStamp = now;

	DisableIrq();
	uint data = _TM7711GetData25(thiss);

	DelayUs(1);
	GpioWrite(thiss->SCK, true);
	DelayUs(1);
	GpioWrite(thiss->SCK, false);

	DelayUs(1);
	GpioWrite(thiss->SCK, true);
	DelayUs(1);
	GpioWrite(thiss->SCK, false);

	EnableIrq();

	bool err = (((data & 0x7ffff0) == 0) || ((data & 0x7ffff0) == 0x7ffff0));
	if (err)thiss->ErrCnt++;
	else thiss->ErrCnt = 0;

	// 进入休眠
	if (thiss->ErrCnt > 8)
	{
		Reset(thiss);
		return 0xffffffff;
	}

	return data;
}

/*

#include "Debug.h"
#include "SysTime.h"

static TM7711_t TmInfo[4] =
{
	{ .SCK = PB10, .DOUT = PB11,},
	{ .SCK = PB1,  .DOUT = PB2, },
	{ .SCK = PD3 , .DOUT = PB7, },
	{ .SCK = PB9,  .DOUT = PB8, },
};

void TM7711TestInit(void)
{
	TM7711Init(&TmInfo[0]);
	TM7711Init(&TmInfo[1]);
	TM7711Init(&TmInfo[2]);
	TM7711Init(&TmInfo[3]);
}

void TM7711Test(void)
{
	Time_t now = GetCurrentTimeMs();
	static Time_t TmLast = 0;
	if (now - TmLast >= 105)
	{
		TM7711PushData(&TmInfo[0], TM7711GetData25(&TmInfo[0]));
		TM7711PushData(&TmInfo[1], TM7711GetData25(&TmInfo[1]));
		TM7711PushData(&TmInfo[2], TM7711GetData25(&TmInfo[2]));
		TM7711PushData(&TmInfo[3], TM7711GetData25(&TmInfo[3]));

		static byte cnt = 0;
		cnt++;
		if (cnt >= 4)
		{
			int dst1 = TM7711GetDstData(&TmInfo[0]);
			int dst2 = TM7711GetDstData(&TmInfo[1]);
			int dst3 = TM7711GetDstData(&TmInfo[2]);
			int dst4 = TM7711GetDstData(&TmInfo[3]);
			DebugPrintf("%08X\t%08X\t%08X\t%08X\r\n", dst1, dst2, dst3, dst4);
			// DebugPrintf("%10d\t%10d\t%10d\t%10d\r\n", dst1, dst2, dst3, dst4);
			cnt = 0;
		}

		TmLast = now;
	}
}

*/