STM32+MPU6050设计便携式Mini桌面时钟(自动调整时间显示方向)

发布者:HappyHearted最新更新时间:2022-10-14 来源: csdn关键字:STM32  MPU6050 手机看文章 扫描二维码
随时随地手机看文章

一、环境介绍

MCU:  STM32F103C8T6


姿态传感器:  MPU6050


OLED显示屏:  0.96寸SPI接口OLED


温度传感器: 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显示屏初始化--正常显示 

                }

            }

            //翻转显示

[1] [2] [3]
关键字:STM32  MPU6050 引用地址:STM32+MPU6050设计便携式Mini桌面时钟(自动调整时间显示方向)

上一篇:STM32+ESP8266+MQTT协议连接腾讯物联网开发平台
下一篇:STM32+HC05串口蓝牙设计简易的蓝牙音箱

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved