完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
暑假里搞了一下数学建模,然后其余时间学了一些STM32,大概上是把一些基础的东西都弄明白了,更高级的操作只能等以后有时间再做深究了。这个摔倒报警装置是本人第一次用32做的一个小项目了,部分模块的代码是直接移植正点原子的,大家有什么问题的话可以多看一下正点原子的代码,写的还是很不错的。初学32,感觉能做出这样一个作品还是比较有成就感的,希望大家有什么问题都能和我一起探讨一下,共同进步!
简述STM32F103 ARM公司的高性能"Cortex-M3"内核 1.25DMips/MHz,而ARM7TDMI只有0.95DMips/MHz 一流的外设 1μs的双12位ADC,4兆位/秒的UART,18兆位/秒的SPI,18MHz的I/O翻转速度 低功耗 在72MHz时消耗36mA(所有外设处于工作状态),待机时下降到2μA 最大的集成度 复位电路、低电压检测、调压器、精确的RC振荡器等 简单的结构和易用的工具 下面介绍作品: 功能简介
模块介绍 软件设计 Part 1: 在单片机1中通过MPU6050的DMP处理器自主处理原始数据,得到pitch、roll、yaw这三个角度数据和加速度,减少的单片机的运算量,降低负荷,再通过NRF24L01在循环中传输经过处理之后的数据,兼顾到MP6050的噪声较大和单片机数据刷新需要较快,循环分为一组三次,每三次的传输,第一次发送数据到地址一,第二次发送数据到地址二,第三次将数据舍弃,并重复该过程。同时在发送过程中,在数据的末尾加上校验位,检验数据发送是否正确,是否有误发误收的情况。 Part 2: 在单片机2中,利用中断接收单片机1所发送的数据,以减少主程序的工作量,接收到数据之后在OLED上实时显示3种航向角数据,在中断接受数据的同时,对数据进行处理,检测老人是否摔倒,如果检测出摔倒,中断中立刻赋值标志位,在主程序执行的时候判断标志位是否为一,然后通过SIM800C模块对已经设定好的电话号码进行拨打。从而达到呼救和提醒家人的目的。 Part 3: 单片机3中可以接受前两块单片机所有传输的数据,按下按键KEY_0,是查看单片机1所发送的加速度数据,按下按键KEY_1是查看单片机1发送的航向角数据,按下按键KEY_UP是查看单片机2发送的数据。 部分代码(发送数据方) #include "delay.h" #include "sys.h" #include "usart.h" #include "timer.h" #include "led.h" #include "mpu6050.h" #include "inv_mpu.h" #include "inv_mpu_dmp_motion_driver.h" #include "24l01.h" extern u8 TX_ADDRESS[TX_ADR_WIDTH]; extern u8 RX_ADDRESS[RX_ADR_WIDTH]; //串口1发送1个字符 //c:要发送的字符 void usart1_send_char(u8 c) { while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(USART1,c); } //传送数据给匿名四轴上位机软件(V2.6版本) //fun:功能字. 0XA0~0XAF //data:数据缓存区,最多28字节!! //len:data区有效数据个数 void usart1_niming_report(u8 fun,u8*data,u8 len) { u8 send_buf[32]; u8 i; if(len>28)return; //最多28字节数据 send_buf[len+3]=0; //校验数置零 send_buf[0]=0X88; //帧头 send_buf[1]=fun; //功能字 send_buf[2]=len; //数据长度 for(i=0;i for(i=0;i for(i=0;i } //发送加速度传感器数据和陀螺仪数据 //aacx,aacy,aacz:x,y,z三个方向上面的加速度值 //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值 void mpu6050_send_data(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz) { u8 tbuf[12]; tbuf[0]=(aacx>>8)&0XFF; tbuf[1]=aacx&0XFF; tbuf[2]=(aacy>>8)&0XFF; tbuf[3]=aacy&0XFF; tbuf[4]=(aacz>>8)&0XFF; tbuf[5]=aacz&0XFF; tbuf[6]=(gyrox>>8)&0XFF; tbuf[7]=gyrox&0XFF; tbuf[8]=(gyroy>>8)&0XFF; tbuf[9]=gyroy&0XFF; tbuf[10]=(gyroz>>8)&0XFF; tbuf[11]=gyroz&0XFF; usart1_niming_report(0XA1,tbuf,12);//自定义帧,0XA1 } //通过串口1上报结算后的姿态数据给电脑 //aacx,aacy,aacz:x,y,z三个方向上面的加速度值 //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值 //roll:横滚角.单位0.01度。 -18000 -> 18000 对应 -180.00 -> 180.00度 //pitch:俯仰角.单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度 //yaw:航向角.单位为0.1度 0 -> 3600 对应 0 -> 360.0度 void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw) { u8 tbuf[28]; u8 i; for(i=0;i<28;i++)tbuf=0;//清0 tbuf[0]=(aacx>>8)&0XFF; tbuf[1]=aacx&0XFF; tbuf[2]=(aacy>>8)&0XFF; tbuf[3]=aacy&0XFF; tbuf[4]=(aacz>>8)&0XFF; tbuf[5]=aacz&0XFF; tbuf[6]=(gyrox>>8)&0XFF; tbuf[7]=gyrox&0XFF; tbuf[8]=(gyroy>>8)&0XFF; tbuf[9]=gyroy&0XFF; tbuf[10]=(gyroz>>8)&0XFF; tbuf[11]=gyroz&0XFF; tbuf[18]=(roll>>8)&0XFF; tbuf[19]=roll&0XFF; tbuf[20]=(pitch>>8)&0XFF; tbuf[21]=pitch&0XFF; tbuf[22]=(yaw>>8)&0XFF; tbuf[23]=yaw&0XFF; usart1_niming_report(0XAF,tbuf,28);//飞控显示帧,0XAF } int main(void) { u8 report=1; //默认开启上报 u16 t=0; u32 step_cnt; u32 res; u16 i; u8 address1[5]={0x34,0x43,0x10,0x10,0x02}; u8 address2[5]={0x34,0x43,0x10,0x10,0x03}; u8 tmp_buf[33]; float pitch,roll,yaw; //欧拉角 short aacx,aacy,aacz; //加速度传感器原始数据 short gyrox,gyroy,gyroz; //陀螺仪原始数据 short temp; //温度 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(500000); //串口初始化为500000 delay_init(); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 MPU_Init(); //初始化MPU6050 NRF24L01_Init(); /*u16 led0pwmval=0; u16 a=17000; u8 dir=1; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 TIM3_PWM_Init(19999,71); // 72分频,最高频率20000 while(1) { delay_ms(500); if(dir)led0pwmval+=500; else led0pwmval-=500; if(led0pwmval>18000)dir=0; if(led0pwmval==0)dir=1; a+=500; if(a>19500) a=17500; TIM_SetCompare2(TIM3,a); //以45°为基本转动单位 LED0=!LED0; delay_ms(200); } */ while(mpu_dmp_init()&&NRF24L01_Check()) { delay_ms(200); } while(1) { NRF24L01_TX_Mode(); if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0) { temp=MPU_Get_Temperature(); //得到温度值 MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据 MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪数据 res=dmp_get_pedometer_step_count(&step_cnt); if(res)step_cnt=0; if(report)mpu6050_send_data(aacx,aacy,aacz,gyrox,gyroy,gyroz);//用自定义帧发送加速度和陀螺仪原始数据 if(report)usart1_report_imu(aacx,aacy,aacz,gyrox,gyroy,gyroz,(int)(roll*100),(int)(pitch*100),(int)(yaw*10)); //LED0=!LED0; //delay_ms(200); if(t%3==0) { for(i=0;i<5;i++) { TX_ADDRESS=address1; RX_ADDRESS=address1; } tmp_buf[0]=temp/1000+'0'; tmp_buf[1]=temp/100%10+'0'; tmp_buf[2]=temp/10%10+'0'; tmp_buf[3]=temp%10+'0'; temp=pitch*10; if(temp<0) { temp=-temp; tmp_buf[4]='-'; } else tmp_buf[4]='+'; tmp_buf[5]=temp/1000+'0'; tmp_buf[6]=temp/100%10+'0'; tmp_buf[7]=temp/10%10+'0'; tmp_buf[8]=temp%10+'0'; temp=roll*10; if(temp<0) { temp=-temp; tmp_buf[9]='-'; } else tmp_buf[9]='+'; tmp_buf[10]=temp/1000+'0'; tmp_buf[11]=temp/100%10+'0'; tmp_buf[12]=temp/10%10+'0'; tmp_buf[13]=temp%10+'0'; temp=yaw*10; if(temp<0) { temp=-temp; tmp_buf[14]='-'; } else tmp_buf[14]='+'; tmp_buf[15]=temp/1000+'0'; tmp_buf[16]=temp/100%10+'0'; tmp_buf[17]=temp/10%10+'0'; tmp_buf[18]=temp%10+'0'; temp=step_cnt; if(temp<0) { temp=-temp; tmp_buf[19]='-'; } else tmp_buf[19]='+'; tmp_buf[20]=temp/1000+'0'; tmp_buf[21]=temp/100%10+'0'; tmp_buf[22]=temp/10%10+'0'; tmp_buf[23]=temp%10+'0'; tmp_buf[27]=0+'0';//校验位 NRF24L01_TxPacket(tmp_buf);//向NRF1传输数据(航向角数据) //delay_ms(10); LED0=!LED0; delay_ms(100); } if(t%3==1) { for(i=0;i<5;i++) { TX_ADDRESS=address2; RX_ADDRESS=address2; } tmp_buf[0]=temp/1000+'0'; tmp_buf[1]=temp/100%10+'0'; tmp_buf[2]=temp/10%10+'0'; tmp_buf[3]=temp%10+'0'; temp=aacx*10; if(temp<0) { temp=-temp; tmp_buf[4]='-'; } else tmp_buf[4]='+'; tmp_buf[5]=temp/10000+'0'; tmp_buf[6]=temp/1000%10+'0'; tmp_buf[7]=temp/100%10+'0'; tmp_buf[8]=temp/10%10+'0'; tmp_buf[9]=temp%10+'0'; temp=aacy*10; if(temp<0) { temp=-temp; tmp_buf[10]='-'; } else tmp_buf[10]='+'; tmp_buf[11]=temp/10000+'0'; tmp_buf[12]=temp/1000%10+'0'; tmp_buf[13]=temp/100%10+'0'; tmp_buf[14]=temp/10%10+'0'; tmp_buf[15]=temp%10+'0'; temp=aacz*10; if(temp<0) { temp=-temp; tmp_buf[16]='-'; } else tmp_buf[16]='+'; tmp_buf[17]=temp/10000+'0'; tmp_buf[18]=temp/1000%10+'0'; tmp_buf[19]=temp/100%10+'0'; tmp_buf[20]=temp/10%10+'0'; tmp_buf[21]=temp%10+'0'; temp=step_cnt; if(temp<0) { temp=-temp; tmp_buf[22]='-'; } else tmp_buf[22]='+'; tmp_buf[23]=temp/1000+'0'; tmp_buf[24]=temp/100%10+'0'; tmp_buf[25]=temp/10%10+'0'; tmp_buf[26]=temp%10+'0'; tmp_buf[27]=1+'0';//校验位 NRF24L01_TxPacket(tmp_buf);//向NRF2传输数据(加速度数据) LED0=!LED0; delay_ms(100); } t++; if(t==100)t=0; //LED0=!LED0; //delay_ms(200); } //LED0=!LED0; //delay_ms(200); } } 遇到的问题 1.NRF一发多收,一收多发数据相互干扰 2.在外部中断接受NRF数据,但是中断进不去 3.MPU6050传输数据不稳定,噪声较大 学习STM32F103的感悟 学习两个月的STM32F103ZET6,从看正点原子的视频开始,慢慢理解库函数如何开发,串口通信,无线通信,以及TFT屏,OLED屏,各类传感器模块,再到从ZET6的程序移植到C8T6上的程序,对定时器,外部中断的配置理解更深,学会看开发指南,查芯片手册数据手册,对着原理图接线,出现问题及时用仿真器硬件调试。对于大多数问题都有了自己的认识。在今后的学习过程中,可能会深入到更高级的应用中去,类似于SD卡,文件操作,UCOS,EMWIN,也可能学习性能更高的F4、H7系列。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1786 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1622 浏览 1 评论
1089 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
730 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1942浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
739浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
576浏览 3评论
599浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
561浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 19:05 , Processed in 0.907583 second(s), Total 48, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号