天天看点

HX711压力检测模块在cc2530Z-Stack协议栈上的移植

   前些日子项目中用到得把压力传感器HX711模块移植到Z-Stack协议栈上,期间遇到一些挫折,但几经波折总算是弄出来了。遂将其记录下来方便日后学习。

    首先上传感器的图片,淘宝20块收来的,配备了5kg的压力传感器,真的很值。

HX711压力检测模块在cc2530Z-Stack协议栈上的移植

                     硬件连接

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转换的输入通道和增益。参见下表。

HX711压力检测模块在cc2530Z-Stack协议栈上的移植

下面只给出核心代码,省略了头文件和很多变量定义以及一些其他函数。

/*********************************************************************
* 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

HX711压力检测模块在cc2530Z-Stack协议栈上的移植