#include "board_common.h"
|
|
#include "app.h"
|
|
|
|
typedef enum
|
{
|
T_I = 1,
|
T_V,
|
}DATA_TYPE;
|
|
typedef enum
|
{
|
I_0 = 0,
|
I_1,
|
I_2,
|
I_3,
|
}I_CHANNEL;
|
|
typedef enum
|
{
|
V_0= 0,
|
V_1,
|
V_2,
|
V_3
|
}V_CHANNEL;
|
|
#define ADC_CHANNEL_MAX_NUM 10
|
#define ADC_SAMPLE_BUFFER_SIZE 20
|
|
|
#pragma pack (1)
|
|
typedef struct
|
{
|
uint8_t header[2]; /* 报文头0xAA 0x55 */
|
uint8_t type; /* 1:电流, 2:电压 */
|
uint8_t channel; /* 通道 */
|
uint16_t crc; /* CRC */
|
}RxPacket;
|
|
#define RX_PACKET_SIZE sizeof(RxPacket)
|
typedef union
|
{
|
RxPacket packet;
|
uint8_t buffer[RX_PACKET_SIZE];
|
}RxPacket_u;
|
|
|
typedef struct
|
{
|
uint8_t header[2]; /* 报文头0xAA 0x55 */
|
uint8_t type; /* 1:电流, 2:电压 */
|
uint8_t channel; /* 通道 */
|
uint16_t value; /* 数值 */
|
uint16_t crc; /* CRC */
|
}RxPacketRes;
|
|
#define RX_PACKET_RES_SIZE sizeof(RxPacketRes)
|
typedef union
|
{
|
RxPacketRes packet;
|
uint8_t buffer[RX_PACKET_RES_SIZE];
|
}RxPacketRes_u;
|
|
#pragma pack ()
|
|
static uint16_t adcSampleBuffer[ADC_CHANNEL_MAX_NUM][ADC_SAMPLE_BUFFER_SIZE] = {0};
|
static bool adcDataReadable = false;
|
|
void PrintHex(const unsigned char *buffer, unsigned int len)
|
{
|
unsigned int i;
|
PRINTF("\r\n");
|
for(i=0; i<len; i++)
|
{
|
PRINTF("%02x ", buffer[i]);
|
if (i!=0 && ((i+1)%16) == 0)
|
PRINTF("\r\n");
|
}
|
PRINTF("\r\n");
|
}
|
|
static uint16_t CRC16(const uint8_t *Buf , uint32_t usLen)
|
{
|
uint16_t i, j;
|
uint16_t usCrc = 0xFFFF;
|
for ( i = 0 ; i < usLen ; i++ )
|
{
|
usCrc ^= Buf[i];
|
for ( j = 0 ; j < 8 ; j++ )
|
{
|
if ( usCrc & 1 )
|
{
|
usCrc >>=1;
|
usCrc ^=0xA001;
|
}
|
else
|
{
|
usCrc >>= 1;
|
}
|
}
|
}
|
return usCrc;
|
}
|
|
void ADC_Sample(void)
|
{
|
/* 采样adc数据 */
|
ADC_SampleData sampleData;
|
memset(&sampleData, 0x0, sizeof(ADC_SampleData));
|
if (ADC1_ADC_GetSampleData(&sampleData, sizeof(ADC_SampleData)) < 0)
|
return ;
|
/*
|
* 将采样数据存储到指定buffer
|
*/
|
static uint8_t bufferIndex = 0;
|
uint8_t channel = 0;
|
for (; channel < ADC_CHANNEL_MAX_NUM; channel++)
|
{
|
adcSampleBuffer[channel][bufferIndex] = sampleData.sampleBuffer[channel];
|
}
|
|
if (bufferIndex < ADC_SAMPLE_BUFFER_SIZE)
|
{
|
bufferIndex++;
|
}
|
else
|
{
|
bufferIndex = 0;
|
adcDataReadable = true; /* buffer已经满,数据可读 */
|
}
|
|
}
|
|
double RootMeanSquareCalc(uint16_t *data, uint8_t num)
|
{
|
double sum = 0;
|
uint8_t i = 0;
|
|
for(; i<num; i++)
|
{
|
sum += data[i] * data[i]; /* 平方和 */
|
|
//PRINTF("%d\r\n", data[i]);
|
}
|
|
return sqrt(sum/num);
|
}
|
|
|
static void ReportChannelData(DATA_TYPE type, uint8_t ch)
|
{
|
double rootMeanSquareVref = RootMeanSquareCalc((uint16_t *)&adcSampleBuffer[0], ADC_SAMPLE_BUFFER_SIZE);
|
PRINTF("ref:%f\r\n", rootMeanSquareVref);
|
double rootMeanSquare = 0.0;
|
|
uint32_t v33 = 2500*4095/(uint16_t)rootMeanSquare;
|
rootMeanSquare = RootMeanSquareCalc((uint16_t *)&adcSampleBuffer[1], ADC_SAMPLE_BUFFER_SIZE);
|
uint32_t v12 = 12*v33*rootMeanSquare/4095;
|
uint32_t vo = 0;
|
uint32_t vi = 0;
|
uint32_t v5 = 0;
|
uint32_t value = 0;
|
switch (type)
|
{
|
case T_I:
|
rootMeanSquare = RootMeanSquareCalc((uint16_t *)&adcSampleBuffer[6+ch], ADC_SAMPLE_BUFFER_SIZE);
|
PRINTF("ADC:%f\r\n", rootMeanSquare);
|
vo = 100*2500*rootMeanSquare/rootMeanSquareVref;
|
value = vo/100;
|
PRINTF("vi:%d\t\ti:%d(0.01mA)\r\n", vo,value);
|
break;
|
case T_V:
|
rootMeanSquare = RootMeanSquareCalc((uint16_t *)&adcSampleBuffer[2+ch], ADC_SAMPLE_BUFFER_SIZE);
|
PRINTF("ADC:%f\r\n", rootMeanSquare);
|
vo = 2500*rootMeanSquare/rootMeanSquareVref;
|
vi = 1000*vo/452; /* vo=0.452 x vi */
|
value = vi;
|
PRINTF("vo:%d\t\tvi:%d(1mV)\r\n", vo, vi);
|
break;
|
}
|
|
RxPacketRes_u resPacket;
|
memset(&resPacket, 0x0, sizeof(RxPacketRes_u));
|
resPacket.packet.header[0] = 0xAA;
|
resPacket.packet.header[1] = 0x55;
|
resPacket.packet.type = type;
|
resPacket.packet.channel = ch;
|
resPacket.packet.value = value;
|
resPacket.packet.crc = CRC16(resPacket.buffer, sizeof(RxPacketRes_u)-2);
|
|
PRINTF("Send:");
|
PrintHex((const unsigned char *)resPacket.buffer, sizeof(RxPacketRes_u));
|
Board_USART2Send(resPacket.buffer, sizeof(RxPacketRes_u));
|
}
|
|
static int ParserRecvPacket(uint8_t *buffer, uint8_t len, RxPacket_u *data)
|
{
|
PRINTF("Receive:");
|
PrintHex((const unsigned char *)buffer, len);
|
|
if (len != sizeof(RxPacket_u))
|
return -1;
|
|
RxPacket_u *packet = (RxPacket_u *)buffer;
|
if (packet->packet.header[0] != 0xAA && packet->packet.header[1] != 0x55)
|
return -1;
|
|
uint16_t crc = packet->packet.crc;
|
uint16_t calCrc = CRC16((const uint8_t *)buffer, RX_PACKET_SIZE-2);
|
if (crc != calCrc)
|
return -1;
|
if (adcDataReadable)
|
ReportChannelData(packet->packet.type, packet->packet.channel);
|
|
return 0;
|
}
|
|
|
int8_t Board_USART_Process(void)
|
{
|
uint8_t u8Rx = 0;
|
uint32_t u32TestTimeOut = jiffies + 5000;
|
uint32_t u32RecvTimeOut = jiffies + 200;
|
const uint8_t u8SendBuffer[32] = "Recv OK\r\n";
|
uint8_t u8RecvBuffer[32] = {0};
|
uint8_t u8Index = 0;
|
|
RxPacket_u data;
|
memset(&data, 0x0, sizeof(RxPacket_u));
|
while(1)
|
{
|
while( !Timeout_Happened(u32RecvTimeOut))
|
{
|
if (!Board_USART2Recv(&u8Rx, 200))
|
{
|
u8RecvBuffer[u8Index] = u8Rx;
|
if (u8Index <= (sizeof(u8RecvBuffer)-1))
|
u8Index++;
|
else
|
break;
|
}
|
}
|
|
if(u8Index > 0)
|
{
|
ParserRecvPacket(u8RecvBuffer, u8Index, &data);
|
}
|
u8Index = 0;
|
memset(u8RecvBuffer, 0, sizeof(u8RecvBuffer));
|
u32RecvTimeOut = jiffies + 200;
|
}
|
return -1;
|
}
|
|