一、环境介绍
MCU: STM32F103C8T6
姿态传感器: MPU6050
温度传感器: DS18B20
编译软件: keil5
二、功能介绍
完整项目源码下载地址: https://download.csdn.net/download/xiaolong1126626497/18657534
时钟可以根据MPU6050测量的姿态自动调整显示画面方向,也就是倒着拿、横着拿、反着拿都可以让时间显示是正对着自己的,时间支持自己调整,支持串口校准。可以按键切换页面查看环境温度显示。
支持串口时间校准:
三、核心代码
3.1 main.c
#include "stm32f10x.h"
#include "beep.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include #include #include "exti.h" #include "timer.h" #include "rtc.h" #include "wdg.h" #include "ds18b20.h" #include "oled.h" #include "fontdata.h" #include "adc.h" #include "FunctionConfig.h" #include "mpu6050.h" #include "inv_mpu.h" #include "inv_mpu_dmp_motion_driver.h" /* 函数功能: 绘制时钟表盘框架 */ void DrawTimeFrame(void) { u8 i; OLED_Circle(32,32,31);//画外圆 OLED_Circle(32,32,1); //画中心圆 //画刻度 for(i=0;i<60;i++) { if(i%5==0)OLED_DrawAngleLine(32,32,6*i,31,3,1); } OLED_RefreshGRAM(); //刷新数据到OLED屏幕 } /* 函数功能: 更新时间框架显示,在RTC中断里调用 */ char TimeBuff[20]; void Update_FrameShow(void) { /*1. 绘制秒针、分针、时针*/ OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-6-90,27,0);//清除之前的秒针 OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-90,27,1); //画秒针 OLED_DrawAngleLine2(32,32,rtc_clock.min*6-6-90,24,0); OLED_DrawAngleLine2(32,32,rtc_clock.min*6-90,24,1); OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-6-90,21,0); OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-90,21,1); //绘制电子钟时间 sprintf(TimeBuff,"%d",rtc_clock.year); OLED_ShowString(65,16*0,16,TimeBuff); //年份字符串 OLED_ShowChineseFont(66+32,16*0,16,4); //显示年 sprintf(TimeBuff,"%d/%d",rtc_clock.mon,rtc_clock.day); OLED_ShowString(75,16*1,16,TimeBuff); //月 if(rtc_clock.sec==0)OLED_ShowString(65,16*2,16," "); //清除多余的数据 sprintf(TimeBuff,"%d:%d:%d",rtc_clock.hour,rtc_clock.min,rtc_clock.sec); OLED_ShowString(65,16*2,16,TimeBuff); //秒 //显示星期 OLED_ShowChineseFont(70,16*3,16,5); //星 OLED_ShowChineseFont(70+16,16*3,16,6); //期 OLED_ShowChineseFont(70+32,16*3,16,rtc_clock.week+7); //具体的值 } u8 DS18B20_TEMP_Info[10]; //DS18B20温度信息 /* 函数功能: DS18B20温度显示页面 */ void DS18B20_ShowPageTable(short DS18B20_temp) { char DS18B20_buff[10]; //存放温度信息 unsigned short DS18B20_intT=0,DS18B20_decT=0; //温度值的整数和小数部分 DS18B20_intT = DS18B20_temp >> 4; //分离出温度值整数部分 DS18B20_decT = DS18B20_temp & 0xF; //分离出温度值小数部分 sprintf((char*)DS18B20_TEMP_Info,"%d.%d",DS18B20_intT,DS18B20_decT); //保存DS18B20温度信息,发送给上位机 OLED_ShowString(34,0,16,"DS18B20"); if(DS18B20_temp==0xFF) { OLED_ShowString(0,30,16," "); //清除一行的显示 //显示温度错误信息 OLED_ShowString(0,30,16,"DS18B20 Error!"); } else { sprintf(DS18B20_buff,"%sC ",DS18B20_TEMP_Info); //显示温度 OLED_ShowString(40,30,16,DS18B20_buff); } } int main(void) { u8 stat; u8 key_val; u32 TimeCnt=0; u16 temp_data; //温度数据 short aacx,aacy,aacz; //加速度传感器原始数据 short gyrox,gyroy,gyroz; //陀螺仪原始数据 short temp; float pitch,roll,yaw; //欧拉角 u8 page_cnt=0; //显示的页面 u8 display_state1=0; u8 display_state2=0; BEEP_Init(); //初始化蜂鸣器 LED_Init(); //初始化LED KEY_Init(); //按键初始化 DS18B20_Init(); //DS18B20 USARTx_Init(USART1,72,115200);//串口1的初始化 TIMERx_Init(TIM1,72,20000); //辅助串口1接收。20ms为一帧数据。 RTC_Init(); //RTC初始化 OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示 //OLED_Init(0xc0,0xa0); //OLED显示屏初始化--翻转显示 while(MPU6050_Init()) //初始化MPU6050 { printf("MPU6050陀螺仪初始化失败!rn"); DelayMs(500); } // //注意:陀螺仪初始化的时候,必须正常摆放才可以初始化成 // while(mpu_dmp_init()) // { // printf("MPU6050陀螺仪设置DMP失败!rn"); // DelayMs(1000); // } OLED_Clear(0x00); //清屏 DrawTimeFrame(); //画时钟框架 while(1) { key_val=KEY_GetValue(); if(key_val) { page_cnt=!page_cnt; //时钟页面 if(page_cnt==0) { //清屏 OLED_Clear(0); DrawTimeFrame(); //画时钟框架 RTC->CRH|=1<<0; //开启秒中断 } else if(page_cnt==1) { //清屏 OLED_Clear(0); RTC->CRH&=~(1<<0); //关闭秒中断 } } if(USART1_RX_STATE) { //*20200530154322 //通过串口1校准RTC时间 if(USART1_RX_BUFF[0]=='*') { rtc_clock.year=(USART1_RX_BUFF[1]-48)*1000+(USART1_RX_BUFF[2]-48)*100+(USART1_RX_BUFF[3]-48)*10+(USART1_RX_BUFF[4]-48)*1; rtc_clock.mon=(USART1_RX_BUFF[5]-48)*10+(USART1_RX_BUFF[6]-48)*1; rtc_clock.day=(USART1_RX_BUFF[7]-48)*10+(USART1_RX_BUFF[8]-48)*1; rtc_clock.hour=(USART1_RX_BUFF[9]-48)*10+(USART1_RX_BUFF[10]-48)*1; rtc_clock.min=(USART1_RX_BUFF[11]-48)*10+(USART1_RX_BUFF[12]-48)*1; rtc_clock.sec=(USART1_RX_BUFF[13]-48)*10+(USART1_RX_BUFF[14]-48)*1; RTC_SetTime(rtc_clock.year,rtc_clock.mon,rtc_clock.day,rtc_clock.hour,rtc_clock.min,rtc_clock.sec); OLED_Clear(0); //OLED清屏 DrawTimeFrame();//画时钟框架 } USART1_RX_STATE=0; USART1_RX_CNT=0; } //时间记录 DelayMs(10); TimeCnt++; if(TimeCnt>=100) //1000毫秒一次 { TimeCnt=0; LED1=!LED1; temp_data=DS18B20_ReadTemp(); // printf("temp_data=%d.%dn",temp_data>>4,temp_data&0xF); // stat=mpu_dmp_get_data(&pitch,&roll,&yaw); // temp=MPU6050_Get_Temperature(); //得到温度值 //MPU6050_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪原始数据 MPU6050_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据 //printf("温度数据:%drn",temp); // printf("陀螺仪原始数据 :x=%d y=%d z=%drn",gyrox,gyroy,gyroz); printf("加速度传感器数据:x=%d y=%d z=%drn",aacx,aacy,aacz); // printf("欧垃角:横滚角=%d 俯仰角=%d 航向角=%drn",(int)(roll*100),(int)(pitch*100),(int)(yaw*10)); // //正着显示 if(aacz>=15000) { printf("正着显示n"); if(display_state1!=1) { display_state2=0; display_state1=1; OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示 } } //翻转显示
上一篇:STM32+ESP8266+MQTT协议连接腾讯物联网开发平台
下一篇:STM32+HC05串口蓝牙设计简易的蓝牙音箱
设计资源 培训 开发板 精华推荐
- 具有 SAMD2x 参考设计的 DALI 从堆栈
- LTC6259HDC 1.3MHz、20uA 高功率高效轨至轨 I/O 运算放大器的典型应用
- 智商超频卡
- 2022Y-T3P-STM32F103开发板
- 具有三重 LDO 控制器的 Vrm 8.5 兼容 5 位可编程同步降压控制器 IC 的典型应用
- 1W,一个用于 LED 照明的 LED 闪光灯 LED 驱动器
- 用于 LED 照明的 NCL30030 组合功率因数校正和准谐振反激控制器的典型应用
- MIC2099-1YMT EV,基于 MIC2099 限流、高端电源开关的评估板
- 具有STCH03 CC模式初级感应开关控制器的15W 5V输出USB适配器评估板
- 负载开关IC TCK321G、TCK322G、TCK323G应用&电路