当前位置:网站首页>技能梳理[email protected]+adxl345+电机震动+串口输出
技能梳理[email protected]+adxl345+电机震动+串口输出
2022-06-30 09:37:00 【Sky_Lannister】
基于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;
LED0=!LED0;
}
if(count_num % 10 == 0)
{
printf("%c",0XFF);
printf("%c",0XFF);
printf("%c",(uint16_t)(Acc_X_hex/255));
printf("%c",(uint16_t)Acc_X_hex);
value_buf[fil_count++] = Acc_X_hex;
if(fil_count == LINE_FIL_N)
{
fil_count = 0;
}
for (u8 count=0; count<LINE_FIL_N; count++)
{
fil_sum += value_buf[count];
}
fil_sum = fil_sum / LINE_FIL_N;
printf("%c",(uint16_t)(fil_sum/255));
printf("%c",(uint16_t)fil_sum);
fil_sum = 0;
}
if(alarm_is_free == 10)//alarm_is_free=10,初始值为10
{
if(temperature/10 < 25 && Fre_sum_fil < 40)alarmFlag=0;//蜂鸣器报警
else alarmFlag =1;
}
if(alarm_is_free<10)
{
alarm_is_free++;
}
t=KEY_Scan(0); //得到按键值
if(t == KEY0_PRES)LED0=!LED0;
else if(t == KEY1_PRES){
alarmFlag=!alarmFlag;
delay_ms(20000);
alarm_is_free=0;
}
delay_ms(10);
_mqtt.Init(rxbuf,0,txbuf,0);//MQTT初始化
string=MyCreatJson( );
_mqtt.PublishData("/sys/gl8dRlBcJhj/ESP8266/thing/event/property/post", //具有发布权限的TOPIC
string, //符合json数据格式的消息串
0); //消息等级
free(string);//!!!!发布完要释放空间 ?
}
}
5、部分参考资料
6、注意事项
#这款模块检测的精度不是特别准,几乎可以认为是一个震动传感器,为了出来一个电机其它不突然数据变大的情况,用的一个累加值
完整可运行项目地址
边栏推荐
- Quick completion guide for mechanical arm (V): end effector
- ModuleNotFoundError: No module named ‘_swigfaiss‘
- Jump table introduction
- Who should the newly admitted miners bow to in front of the chip machine and the graphics card machine
- MIT-6874-Deep Learning in the Life Sciences Week5
- Js获取指定字符串指定字符位置&指定字符位置区间的子串【简单详细】
- 浏览器复制的网址粘贴到文档是超链接
- GNN hands on practice (II): reproduction graph attention network gat
- About Jul
- Enter the world of helium (hNT) hotspot servers to bring you different benefits
猜你喜欢

MySQL advanced SQL statement of database (1)

Yixian e - commerce publie un rapport trimestriel: adhérer à la R & D et à l’investissement de la marque, réaliser un développement durable et de haute qualité

Quick completion guide for manipulator (4): reducer of key components of manipulator

WGet -- 404 not found due to spaces in URL

MIT-6874-Deep Learning in the Life Sciences Week6

逸仙電商發布一季報:堅持研發及品牌投入,實現可持續高質量發展

Force buckle 428 Serialize and deserialize n-tree DFS

How to seize the opportunity of NFT's "chaos"?

NLopt--非线性优化--原理介绍及使用方法

跳跃表介绍
随机推荐
unable to convert expression into double array
Great Wall digital art digital collection platform releases the creation Badge
李沐《动手学习深度学习》d2lbook环境搭建
[JVM] brief introduction to CMS
MySQL log management, backup and recovery of databases (2)
MySQL index, transaction and storage engine of database (2)
1033 To Fill or Not to Fill
Right click to open CMD (command line)
基于强化学习的股票量化交易Automated-Stock-Trading-Ensemble-Strategy
L'activité "Kunming City coffee map" a rouvert
Who should the newly admitted miners bow to in front of the chip machine and the graphics card machine
MIT-6874-Deep Learning in the Life Sciences Week4
Applying applet container technology to IOT ecological construction
ModuleNotFoundError: No module named ‘_ swigfaiss‘
跳跃表介绍
How does the diode work?
A brief introduction to database mysql
GD32 RT-Thread PWM驱动函数
戴森设计大奖,以可持续化设计改变世界
乡村振兴公益基金启动暨古茶树非遗保护公益行发布