前些日子项目中用到得把压力传感器HX711模块移植到Z-Stack协议栈上,期间遇到一些挫折,但几经波折总算是弄出来了。遂将其记录下来方便日后学习。
首先上传感器的图片,淘宝20块收来的,配备了5kg的压力传感器,真的很值。
硬件连接
HX711 CC2530
VCC 3.3V
GND GND
SCK P0_6
DOUT P0_7
HX711内部特性和结构在这里忽略,我只讲一下如何通过串口通信对其进行驱动。
其中串口通信由SCK、和DOUT脚组成,可以用来选择输入通道和增益,输出数据。
当数据输出管脚DOUT为高电平的时候,表明A/D转换器还未准备好输出数据,此时SCK应保持低电平。当DOUT电平从高到低,SCK应输入25 ~ 27不等的时钟脉冲。其中第一个时钟脉冲的上升沿将读出24位数据的最高位(MSB),直至第24个时钟脉冲完成,24位数据从最高位至最低位逐位输出完成。第25至27个时钟用来选择下一次A/D转换的输入通道和增益。参见下表。
下面只给出核心代码,省略了头文件和很多变量定义以及一些其他函数。
/*********************************************************************
* INCLUDES
*/
/*记录移植驱动HX711传感器的经历
*1,Get_Maopi()这个函数只能在初始化的时候调用一次.不能多次调用
*2,延时1微妙要调用三次asm("nop")
*/
long HX711_Buffer = 0;
long Weight_Maopi = 0,Weight_Shiwu = 0;
float Weight = 0;
#define GapValue 430
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt );
#if defined(ZDO_COORDINATOR)
#else
static void delayMicroseconds();
static void Get_Maopi();
static long Get_Weight();
static unsigned long HX711_Read(void); //增益128
#endif
void SerialApp_Init( uint8 task_id )
{
P0DIR |= 0x10; //P0_4定义为输出
P0DIR &= 0xdf;//P0_5定义为输入
Get_Maopi();//初识话的时候一定不要忘了先获取毛皮的重量。不然计算出来的结果为0
}
UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )
{
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
afIncomingMSGPacket_t *MSGpkt;
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SerialApp_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case AF_INCOMING_MSG_CMD:
SerialApp_ProcessMSGCmd( MSGpkt );
break;
case ZDO_STATE_CHANGE:
SerialApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( SerialApp_NwkState == DEV_END_DEVICE)
//联网成功启动周期性上报事件
osal_start_timerEx( SerialApp_TaskID,SERIALAPP_SEND_PERIODIC_EVT,SERIALAPP_SEND_PERIODIC_TIMEOUT );
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt );
}
return ( events ^ SYS_EVENT_MSG );
}
//在此事件中可以定时向协调器发送节点传感器参数信息
if ( events & SERIALAPP_SEND_PERIODIC_EVT )
{
SerialApp_SendPeriodicMessage();
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_SEND_PERIODIC_EVT,
(SERIALAPP_SEND_PERIODIC_TIMEOUT + (osal_rand() & 0x00FF)) );
return (events ^ SERIALAPP_SEND_PERIODIC_EVT);
}
return ( 0 );
}
void SerialApp_SendPeriodicMessage( void )
{
#if defined(ZDO_COORDINATOR)
#else
uint8 m[30];
Weight = Get_Weight(); //计算放在传感器上的重物重量
HalLcdWriteStringValue( "g: ",Weight,10,HAL_LCD_LINE_3);
sprintf(m,"%f g\r\n",Weight);
HalUARTWrite(0,m,strlen(m)+1);
#endif
// SerialApp_SendData_Lamp(ZIGBEE_FUN_CODE_CHECK_LAMP);
}
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
Weight_Maopi = HX711_Read();
}
//****************************************************
//称重
//****************************************************
long Get_Weight()
{
HX711_Buffer = HX711_Read();
Weight_Shiwu = HX711_Buffer;
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);
return Weight_Shiwu;
}
//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
bool Flag = 0;
P0_5=1;
delayMicroseconds();
P0_4=0;
delayMicroseconds();
count=0;
while(P0_5);
for(i=0;i<24;i++)
{
P0_4=1;
delayMicroseconds();
count=count<<1;
P0_4=0;
delayMicroseconds();
if(P0_5)
count++;
}
P0_4=1;
count ^= 0x800000;
delayMicroseconds();
P0_4=0;
delayMicroseconds();
delayMicroseconds();
return(count);
}
void delayMicroseconds()
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
运行效果,可以看到我放了一个水杯,测出来的重量在455g。嗯,还是比较准确的。好啦,这是我的第一篇博客,文笔什么的还欠佳,我会慢慢越做越好哒~ 也算是记录自己学到的一点东西了,说不定以后忘了还能回过头来看看hhh