资讯详情

技能梳理25@stm32+adxl345+电机震动+串口输出

基于f103zet6单片机,使用adxl345检测电机振动频率,串口打印,程序模板为正点原子

1、项目简介

在这里插入图片描述

2、实现逻辑

#对adxl345初始化 #检测电机振动(加速度),串口打印

3、应用场景

#检测电机或其他物品的振动

4.梳理核心代码

#define SlaveAddress 0xA6 //定义器件在IIC根据总线的地址ALT ADDRESS不同修改地址引脚 //ALT ADDRESS引脚接地时地址为0xA6.接电源时地址为0x3A  unsigned char BUF[8];                        //接收数据缓存区  unsigned char ge,shi,bai,qian,wan;           //显示变量 unsigned char err; float temp_X,temp_Y,temp_Z; float Acc_X,Acc_Y,Acc_Z,q; short Frequency; void SCL_Set_Output(void) { 
          GPIO_InitTypeDef  GPIO_InitStructure;  GPIO_InitStructure.GPIO_Pin = SCL_GPIO_PIN;       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(SCL_GPIO, &GPIO_InitStructure);            }   void SDA_Set_Output(void) { 
          GPIO_InitTypeDef  GPIO_InitStructure;  GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN;       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(SDA_GPIO, &GPIO_InitStructure);            }   void SDA_Set_Input(void)
{ 
        
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(SDA_GPIO, &GPIO_InitStructure);					 
}

/************************************** 起始信号 **************************************/
void ADXL345_Start(void)
{ 
        
    SCL_OUT();
    SDA_OUT();
    SET_SDA();//SDA = 1; //拉高数据线
    SET_SCL();//SCL = 1; //拉高时钟线
    delay_us(2);//Delay5us(); //延时
    CLE_SDA();//SDA = 0; //拉低数据线
    delay_us(2);//Delay5us(); //延时
    CLE_SCL();//SCL = 0; //拉低时钟线
}

/************************************** 停止信号 **************************************/
void ADXL345_Stop(void)
{ 
        
    SCL_OUT();
    SDA_OUT();
    CLE_SDA();//SDA = 0; //拉低数据线
    SET_SCL();//SCL = 1; //拉高时钟线
    delay_us(2);//Delay5us(); //延时
    SET_SDA();//SDA = 1; //产生上升沿
    delay_us(2);//Delay5us(); //延时
    CLE_SCL();
}

/************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/
void ADXL345_SendACK(uchar ack)
{ 
           
    SCL_OUT();
    SDA_OUT();
    if(ack==0)//SDA = ack; //写应答信号
    { 
        
      CLE_SDA();
    }
    else
    { 
        
      SET_SDA();
    }
    SET_SCL();//SCL = 1; //拉高时钟线
    delay_us(2);//Delay5us(); //延时
    CLE_SCL();//SCL = 0; //拉低时钟线
    delay_us(5);//Delay5us(); //延时
}

/************************************** 接收应答信号 **************************************/
uchar ADXL345_RecvACK(void)
{ 
        
    SDA_INT();
    SCL_OUT();
    SET_SCL();//SCL = 1; //拉高时钟线
    delay_us(2);// Delay5us(); //延时
    SET_SCL();
    if(SDA_VAL()== Bit_SET)   //CY = SDA; //读应答信号
    { 
        
      err = 1;
    }
    else
    { 
        
      err = 0;
    }
 
    CLE_SCL() ;//SCL = 0; //拉低时钟线
    delay_us(5);// Delay5us(); //延时
    SDA_OUT();
    return err;
}

/************************************** 向IIC总线发送一个字节数据 **************************************/
void ADXL345_SendByte(unsigned char dat)
{ 
        
    unsigned char i;
    SCL_OUT();
    SDA_OUT();
    for (i=0; i<8; i++)         //8位计数器
    { 
        
        delay_us(5);             //延时
        if(dat&0x80)  //SDA = CY; //送数据口 
        { 
        SET_SDA();}
        else
        { 
        CLE_SDA();}       
        delay_us(5);             //延时
        SET_SCL();//SCL = 1; //拉高时钟线
        delay_us(5);             //延时
        CLE_SCL();//SCL = 0; //拉低时钟线
        dat <<= 1;              //移出数据的最高位
    }
    ADXL345_RecvACK();
}

/************************************** 从IIC总线接收一个字节数据 **************************************/
unsigned char ADXL345_RecvByte(void)
{ 
        
    unsigned char i;
    unsigned char Mid;
    unsigned char dat = 0;
    SDA_INT();
    SCL_OUT();

    for (i=0; i<8; i++)         //8位计数器
    { 
        
        dat <<= 1;
        delay_us(5);            //延时
        SET_SCL();

			if(SDA_VAL()== Bit_SET)   //CY = SDA; //读应答信号
			{ 
        
				Mid = 1;
			}
			else
			{ 
        
				Mid = 0;
			}
        if(Mid) dat++;
        delay_us(5);     
        CLE_SCL();//SCL = 0; //拉低时钟线
    }
    return dat;
}

//******单字节写入*******************************************

void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
{ 
        
    ADXL345_Start();                  //起始信号
    ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
    ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页 
    ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页 
    ADXL345_Stop();                   //发送停止信号
}

//********单字节读取*****************************************
uchar Single_Read_ADXL345(uchar REG_Address)
{ 
          uchar REG_data;
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
    ADXL345_SendByte(REG_Address);            //发送存储单元地址,从0开始 
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
    REG_data=ADXL345_RecvByte();              //读出寄存器数据
	  ADXL345_SendACK(1);   
	  ADXL345_Stop();                           //停止信号
    return REG_data; 
}
//*********************************************************
//
//连续读出ADXL345内部加速度数据,地址范围0x32~0x37
//
//*********************************************************
void Multiple_Read_ADXL345(void)
{ 
           uchar i;
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
    ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始 
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
	 for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
    { 
        
        BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
        if (i == 5)
        { 
        
           ADXL345_SendACK(1);                //最后一个数据需要回NOACK
        }
        else
        { 
        
          ADXL345_SendACK(0);                //回应ACK
       }
   }
    ADXL345_Stop();                          //停止信号
    delay_us(5);
}


//*****************************************************************

//初始化ADXL345,根据需要请参考pdf进行修改************************
void Init_ADXL345(void)
{ 
                               //
   Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
   
	 Single_Write_ADXL345(0x2C,0x08);   //速率设定为25 参考pdf13页
   Single_Write_ADXL345(0x2D,0x08);   //选择电源模式 参考pdf24页 //参考14页表7进行修改
   Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
   Single_Write_ADXL345(0x38,0x00);
	 Single_Write_ADXL345(0x2F,0x00);
	 Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
   Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
   Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
}
//***********************************************************************
//显示x轴
void ReadData_x(void)
{ 
           
  int  Acc_dis_data,dis_data,Acc_speed,Dis;                       //变量
  Multiple_Read_ADXL345();       	//连续读出数据,存储在BUF中
  /*获取syz轴加速度*/
	Acc_dis_data=(BUF[1]<<8)+BUF[0];  //合成数据 
  Acc_X=(float)Acc_dis_data*3.9/1000*9.8;  //计算数据和显示,查考ADXL345快速入门第4页
  Acc_dis_data=(BUF[3]<<8)+BUF[2];  //合成数据 
  Acc_Y=(float)Acc_dis_data*3.9/1000*9.8;  //计算数据和显示,查考ADXL345快速入门第4页
  Acc_dis_data=(BUF[5]<<8)+BUF[4];    //合成数据 
  Acc_Z=(float)Acc_dis_data*3.9/1000*9.8;  //计算数据和显示,查考ADXL345快速入门第4页
	/*获取syz轴坐标*/
	dis_data=(BUF[1]<<8)+BUF[0];  //合成数据 
  temp_X=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  dis_data=(BUF[3]<<8)+BUF[2];  //合成数据 
  temp_Y=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  dis_data=(BUF[5]<<8)+BUF[4];    //合成数据 
  temp_Z=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
	
}

int main(void)
{ 
        								  
#define ACC_X_FIL 500
#define TEMP_X_FIL 50 
#define LINE_FIL_N 10
	
	u8 time=0,j;
	
	u8 fil_count;
	uint16_t value_buf[LINE_FIL_N];
	
	u8 i;
	u8 t=0;
	uint16_t Acc_X_hex, TEMP_X_hex, Acc_X_hex_last, TEMP_X_hex_last;
	uint32_t count_num = 0, fre = 0, fre_sum_fil = 0, fre_sum[10] = { 
        0}, fre_sum_num = 0, fil_sum = 0;

	uart_init(115200); 	//串口初始化为115200
	delay_init();	   	 	//延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	LED_Init();		  		//初始化与LED连接的硬件接口 
	usart3_init(115200);		//初始化串口3 
	KEY_Init();
	BEEP_Init();
	OLED_Clear();
  TIM2_Int_Init(4999,7199);
	TIM6_Int_Init(2499,7199);
	OLED_Init();			//初始化OLED 
	Init_ADXL345();		//adxl345初始化
	DS18B20_Init();   //DS18B20初始化
	
	printf("start !!!\r\n");
	
	OLED_ShowString(0,0,"Electric machinery",12); 
	OLED_ShowString(0,52,"ASCII:",12);  
 	OLED_ShowString(64,52,"CODE:",12);
	OLED_Refresh_Gram();		//更新显示到OLED
	
	u8 ret;
	ret=atk_8266_wifista_test();
  delay_ms(1500);
	if(ret==2) 
	{ 
        
	  printf("wifi init ok !!!\r\n");
		_mqtt.Init(rxbuf,0,txbuf,0);//MQTT初始化
		
		//MQTT连接 
	  ret=_mqtt.Connect("gl8dRlBcJhj.ESP8266|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|",
	                  "ESP8266&gl8dRlBcJhj",
										"223d122ec212698603b5c2af5b73c9d0936e1c1e6327c566ea938089e56452ff");
		delay_ms(1500);
		delay_ms(1500);//这两段延时可以适当减少,但删掉好像会出问题

	}
	  _mqtt.Init(rxbuf,0,txbuf,0);//MQTT初始化
	  ret=_mqtt.SubscribeTopic("/sys/a1e8HLT2lBT/test/thing/service/property/set",0,1);
	  delay_ms(3000);//可以删掉试试

	char * string=NULL;
	
	if(Single_Read_ADXL345(0X00)==0xe5)	
  { 
        
    delay_ms(5);
  }
  else
  { 
        
    delay_ms(3);
  }
	j=' ';
	while(1)
	{ 
        
		count_num++;
		
		OLED_ShowChar(48,48,j,16,1);//显示ASCII字符 
		OLED_Refresh_Gram();
		j++;
		if(j>'~')j=' ';
		OLED_ShowNum(103,48,j,3,16);//显示ASCII字符的码值
		
		if(time%100==0){ 
        
			temperature=DS18B20_Get_Temp();
			ReadData_x();  						//三轴检测函数
		}
		//printf("\r\nTemp:%d.%d .C\n",temperature/10,temperature%10);
// printf(" X=%4.3f m/s2 Y=%4.3f m/s2 Z=%4.3f m/s2\r\n",Acc_X,Acc_Y,Acc_Z);
// printf("x轴的值:%.1f y轴的值:%.1f Z轴的值:%.1f\r\n",temp_X,temp_Y,temp_Z);
// printf("%4.3f\r\n",Acc_X);
		
		Acc_X_hex = Acc_X * 1000;
		TEMP_X_hex = temp_X;
		

		if((abs(Acc_X_hex - Acc_X_hex_last) > ACC_X_FIL))//滤波
		{ 
        
			fre++;
		}
		if((abs(TEMP_X_hex - TEMP_X_hex_last) > TEMP_X_FIL))
		{ 
        
			fre++;
		}
		Acc_X_hex_last = Acc_X_hex;
		TEMP_X_hex_last = TEMP_X_hex;
		
		if(count_num % 100 == 0)//经校准此时为1s
		{ 
        
			fre_sum[(fre_sum_num++) % 10] = fre;
			
			for(i=0; i<10; i++)
			{ 
        
				fre_sum_fil += fre_sum[i];
			}
			fre_sum_fil = fre_sum_fil/10;
			printf("\r\nTemp:%d.%d .C\n",temperature/10,temperature%10);
			printf("fre is: %d HZ\r\n",fre_sum_fil);
			
			Fre_sum_fil = fre_sum_fil;
			
			fre_sum_fil = 0;
			fre = 0 

标签: 传感器adxl001z9530速度式振动变送器参数加速度传感器adxl345报警振动变送器1b振动变送器参数hlt2000传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台