百分表(千分表)与STM32通信方式和源码
1、系统概述
市面上采集百分表/千分表测量仪的数据很多是通过转接线、集中器或蓝牙无线模块等,但在某些项目中使用并不方便,根据项目需求很多时候是单片机直接与百分表等仪表通信,如下图所示。
2、仪表接口及数据格式
2.1. 仪表接口
市面上采集百分表/千分表测量仪均采用Mini USB接口,其接口定义基本一致,如下图所示。
2.2数据格式
测量仪表采用主动输出方式,低位在前高位在后,其输出的数据是28位串行数据,即每个CLK时钟信号代表1bit,每bit的数值是0还是1则由DA决定,其输出时序图如下图所示。
测量仪表发送的数据按4位二进制数的BCD码表示一个10进制位。如测量仪表最低10进制位是9,则BCD码为0x9,其4位二进制就是1001,如测量仪表的10进制数是6,则BCD码为0x6,其4位二进制数位0110. 如果收到的数据是0x12345,则显示数据为12.345. 所有的28位时钟传递28位二进制数据,每四位二进制代表一个十进制的数据,24位代表6位十进制数据,第25位表示单位,如0表示公制,1则表示英制,第26位表示符号,如0表示正数,1则表示负数。
3、STM32通信
由于测量仪表是主动输出,故STM32的接口定义为输入接口。测量仪表每120ms向外发送一次数据,1秒最多发送8次数据,为了能够更准确地接收数据,采用外部中断方式进入接收。
3.1接口定义
#define METER_CLK_Pin GPIO_Pin_5
#define METER_CLK_Port GPIOB
#define METER_DATA_Pin GPIO_Pin_4
#define METER_DATA_Port GPIOB
#define METER_CLK_PinSource GPIO_PinSource5
#define METER_CLK_PortSource GPIO_PortSourceGPIOB
#define METER_CLK_EXTI_Line EXTI_Line5
#define METER_CLD_VALUE() GPIO_ReadInputDataBit(METER_CLK_Port,METER_CLK_Pin)
#define METER_DATA_VALUE() GPIO_ReadInputDataBit(METER_DATA_Port,METER_DATA_Pin)
void Meter_Gpio_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能GPIOA和GPIOB时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); //PB3和PB4
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitStructure.GPIO_Pin = METER_CLK_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_Out_PP;
GPIO_Init(METER_CLK_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = METER_DATA_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IPU;
GPIO_Init(METER_DATA_Port, &GPIO_InitStructure);
/* EXTI line(PB5) mode config */
GPIO_EXTILineConfig(METER_CLK_PortSource,METER_CLK_PinSource);
EXTI_InitStructure.EXTI_Line = METER_CLK_EXTI_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升和下降沿中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
3.2中断函数
//放中断函数中调用
void Meter_Rev_Data(void)
{
if(Meter_Struct.RevTimer>100)
{
Meter_Struct.RevTimer = 0;
//Meter_Struct.RevFlag = false;
Meter_Struct.RevCount=0;
Meter_Struct.RevValue = 0;
}
else
{
if(Meter_Struct.RevCount>=28)
{
Meter_Struct.NewValue = 0xFFFFFFFF; //无效数据
Meter_Struct.NewFlag = 2;
return;
}
}
if(METER_DATA_VALUE())
{
Meter_Struct.RevValue |= (0x01<<Meter_Struct.RevCount);
}
Meter_Struct.RevCount++;
if(Meter_Struct.RevCount>=28)
{
Meter_Struct.NewValue = Meter_Struct.RevValue;
Meter_Struct.NewFlag = 1;
}
}
由于接收的是BCD码,并不方便使用,可将其转换为HEX方式,其转换代码如下。
/**********************************************************************
** 函数名称:uint8 BCDToHEX(uint8 BCD)
** 功能说明:将BCD码转换为10进制数据,如BCD码0x59(0101 1001)转换为10制进数59
** 入口参数:BCD待转换的数据
** 出口参数:转换后的数据
**********************************************************************/
uint8_t BCDToHEX(uint8_t BCD)
{
return((BCD & 0x0f) +((BCD & 0xf0)>>4)*10);
}
在主函数中,可直接调用采集的数据,如下所示。
void Meter_Rev_NewPro(void)
{
uint8_t i,temp[3];
uint32_t Value;
if(Meter_Struct.RevTimer>300) //若超过300ms依然未收到脉冲信号,证明数据线未接或未开机
{
Meter_Struct.RevTimer = 0;
Meter_Struct.NewValue = 0xFFFFFFFF; //无效数据
Meter_Struct.NewFlag = 3;
}
if(Meter_Struct.NewFlag==1)
{
Meter_Pro_Struct.NowBCDValue = Meter_Struct.NewValue;
Meter_Struct.NewFlag = 0;
Value = Meter_Pro_Struct.NowBCDValue&0x00FFFFFF;
for(i=0;i<3;i++)
{
temp[i]=BCDToHEX(Value>>(i*8));
}
Meter_Pro_Struct.NowHexValue = temp[0]+temp[1]*100+temp[2]*10000;
if((Meter_Pro_Struct.NowBCDValue>>24)&0x00000001) //单位,1表示英制,0表示公制
{
Meter_Pro_Struct.NowHexValue =(float)Meter_Pro_Struct.NowHexValue*0.254;
}
if((Meter_Pro_Struct.NowBCDValue>>25)&0x00000001) //符号,1表示负数,0表示正数
{
Meter_Pro_Struct.NowHexValue = 0-Meter_Pro_Struct.NowHexValue; //负数
}
Meter_Pro_Struct.ErrFlag = false;
//实际结果放大了1000倍,如公制1670=1.67mm
}
else if(Meter_Struct.NewFlag==2||Meter_Struct.NewFlag==3) //数值无效
{
Meter_Pro_Struct.ErrFlag = true;
Meter_Pro_Struct.NowHexValue = 0xFFFFFFFF;
}
}
其完整的代码链接如下:
https://download.csdn.net/download/shujian123/87880737