首页 > 其他分享 >作息时间提示控制项目

作息时间提示控制项目

时间:2023-11-19 19:35:02浏览次数:24  
标签:RESET 控制 作息时间 WriteBit 提示 GPIOC TIME GPIO Bit

目录

前言

这个项目主要针对于选择的人们作息不规律而设计的一个项目,这个项目是使用stm32f103系列的芯片来制作的(R6和C8)都可以使用。

一、使用的元器件

  • DS1302时钟芯片
  • STM32F103R6
  • 按键
  • LCD1602显示屏
  • 蜂鸣器
  • 蓝牙模块HC-05

二、仿真图

这个可以添加一个蓝牙手机连接功能,但是我这个仿真有问题所以等实物的时候我会添加一个蓝牙模块上去实现远程停止定时和设置时间等内容。

三、项目分析

首先先实现LCD显示时间内容,这里需要写一个DS1302的驱动来进行读取内容,然后将读取的内容显示到屏幕上面即可。然后需要写一个判断来判断获取到的时间与设计的时间进行一个比较,然后如果时间到了那就可以启动蜂鸣器报警模块来提醒用户该休息了。

然后需要对按键进行判断,当按下KEY1按键那就将提醒关闭,KEY2按键是设置内容的。

四、代码编写

这里就开始写代码了,首先要编写一个驱动模块,先实现DS1302的读取和设置,这里已经写好了,直接使用即可:

#include "ds1302.h"

// 设置命令
u8 gREAD_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
u8 gWRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

// 用来设置时钟的数组,秒 分 时 日 月 年,都是BCD码
u8 gDS1302_TIME[7] = {0x57, 0x59, 0x21, 0x20, 0x04, 0x05, 0x21};

void MX_Init_DS1302(){
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStruct.GPIO_Pin = RST | CLK | IO;         
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void ds1302_write_byte(u8 addr,u8 dat)
{
	u8 i=0;
	
	GPIO_WriteBit(GPIOC, RST, Bit_RESET);
		
	GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
	
	GPIO_WriteBit(GPIOC, RST, Bit_SET);
	

	for(i=0;i<8;i++){
		GPIO_WriteBit(GPIOC, IO, addr&0x01);
		addr>>=1;
		GPIO_WriteBit(GPIOC, CLK, Bit_SET);
		
		GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
	}
	for(i=0;i<8;i++){
		GPIO_WriteBit(GPIOC, IO, dat&0x01);
		dat>>=1;
		GPIO_WriteBit(GPIOC, CLK, Bit_SET);
		
		GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
				
	}
	GPIO_WriteBit(GPIOC, RST, Bit_RESET);
		
}

u8 ds1302_read_byte(u8 addr)
{
	u8 i=0;
	u8 temp=0;
	u8 value=0;

	GPIO_WriteBit(GPIOC, RST, Bit_RESET);
		
	GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
	
	GPIO_WriteBit(GPIOC, RST, Bit_SET);
	
	
	for(i=0;i<8;i++){
		GPIO_WriteBit(GPIOC, IO, addr&0x01);
		addr>>=1;	
		GPIO_WriteBit(GPIOC, CLK, Bit_SET);
		
		GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
				
	}
	for(i=0;i<8;i++){
		temp=GPIO_ReadInputDataBit(GPIOC, IO);
		value=(temp<<7)|(value>>1);
		GPIO_WriteBit(GPIOC, CLK, Bit_SET);
		
		GPIO_WriteBit(GPIOC, CLK, Bit_RESET);
				
	}
	GPIO_WriteBit(GPIOC, RST, Bit_RESET);
		
	GPIO_WriteBit(GPIOC, CLK, Bit_SET);
	
	GPIO_WriteBit(GPIOC, IO, Bit_RESET);
	
	GPIO_WriteBit(GPIOC, IO, Bit_SET);
		
	return value;		
}

void ds1302_init(void)
{
	u8 i=0;
	ds1302_write_byte(0x8E,0X00);
	for(i=0;i<7;i++)
	{
		ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);	
	}
	ds1302_write_byte(0x8E,0X80);	
}

void ds1302_read_time(void)
{
	u8 i=0;
	for(i=0;i<7;i++)
	{
		gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);	
	}	
}
#ifndef __DS1302_H
#define __DS1302_H

#include "stm32f10x.h"

#define RST GPIO_Pin_1
#define CLK GPIO_Pin_2
#define IO GPIO_Pin_3

extern u8 gDS1302_TIME[7];  // 读取时间的数组

void MX_Init_DS1302();
void ds1302_init(void);
void ds1302_read_time(void);


#endif

也可以直接到我的gitee中进行下载:DS1302

然后就可以进行读取其中的内容了,这里使用的就是一个全局数组进行接收数据,接收的顺序是秒,分,时,读取的代码如下:

ds1302_read_time();
time = gDS1302_TIME[2]/16 * 10 + (gDS1302_TIME[2]&0x0f);
minute = gDS1302_TIME[1]/16 * 10 + (gDS1302_TIME[1]&0x0f);
second = gDS1302_TIME[0]/16 * 10 + (gDS1302_TIME[0]&0x0f);

这里需要转换一下,因为读取的是BCD码,然后就可以进行显示了:

sprintf((char*)time_buf, "%2d:%2d:%2d", time, minute, second);
show_string(0, 0, time_buf);

这里使用的是LCD1602的驱动程序中的显示字符串的函数,下载链接:led1602模块

然后就可以进行时间的判断了:

if ((time == TIME) && ((minute < MINUTE + response) && (minute >= MINUTE)) && (flag == 1)){
    // 时间到了开始警报
    alarm();
}
else {
    // 如果还在定时的范围中就不复位flag
    if ((time == TIME) && ((minute < MINUTE + response) && (minute >= MINUTE))){
        flag = 0;
    }
    else{
        // 如果不在这个范围中就复位flag
        flag = 1;
    }
}

这里添加了一个flag变量,这个变量是当按下了KEY1后就会停止响应,如果按下了,但是还是在定时的范围中,那么不会复位,因为你停止了就没必要继续响了。

然后就是按键的功能实现:

if (GPIO_ReadInputDataBit(GPIOA, KEY1) == Bit_RESET){
    // 按下了停止按键
    flag = 0;
    stopSound();
}
if (GPIO_ReadInputDataBit(GPIOA, KEY2) == Bit_RESET){
    // 设置和确认
    delay_ms(20);
    while(GPIO_ReadInputDataBit(GPIOA, KEY2) == Bit_RESET);
    // 清屏
    show_string(0, 0, (unsigned char*)"                ");
    show_string(0, 1, (unsigned char*)"                ");
    while(1){
        sprintf((char*)buf, "TIME:%2d", TIME);
        show_string(3, 0, buf);
        sprintf((char*)buf, "MINUTE:%2d", MINUTE);
        show_string(3, 1, buf);
        if (select == 0){
            show_string(0, 0, (unsigned char*)"->");
            show_string(0, 1, (unsigned char*)"  ");
        }
        else{
            show_string(0, 1, (unsigned char*)"->");
            show_string(0, 0, (unsigned char*)"  ");
        }
        if (GPIO_ReadInputDataBit(GPIOA, KEY1) == Bit_RESET){
            // 选择
            delay_ms(20);
            while(GPIO_ReadInputDataBit(GPIOA, KEY1) == Bit_RESET);
            select = ~select & 0x01;
        }
        else if (GPIO_ReadInputDataBit(GPIOA, KEY3) == Bit_RESET){
            // 增加
            delay_ms(20);
            while(GPIO_ReadInputDataBit(GPIOA, KEY3) == Bit_RESET);
            if (select == 0){
                if (++TIME >= 24){
                    TIME = 0;
                }
            }
            else{
                if (++MINUTE >= 60){
                    MINUTE = 0;
                }
            }
        }
        else if (GPIO_ReadInputDataBit(GPIOA, KEY4) == Bit_RESET){
            // 减少
            delay_ms(20);
            while(GPIO_ReadInputDataBit(GPIOA, KEY4) == Bit_RESET);
            if (select == 0){
                if (--TIME == 255){
                    TIME = 23;
                }
            }
            else{
                if (--MINUTE == 255){
                    MINUTE = 59;
                }
            }
        }
        if (GPIO_ReadInputDataBit(GPIOA, KEY2) == Bit_RESET){
            delay_ms(20);   // 消抖
            // 清屏
            show_string(0, 0, (unsigned char*)"                ");
            show_string(0, 1, (unsigned char*)"                ");
            break;
        }
    }
}

这里的按键功能比较复杂,因为涉及到一个按键判断功能的一个内容,所以在KEY2中又添加了一个死循环,在死循环中进行设置,当然这个功能不会影响DS1302时钟的。

总结

其实这个项目还是很简单的,等后面有时间我会改写一下这个项目,让单片机中插入一个系统,然后再用系统进行控制。大家有什么想法可以在下面留言,我这都会看到的。

标签:RESET,控制,作息时间,WriteBit,提示,GPIOC,TIME,GPIO,Bit
From: https://www.cnblogs.com/Lavender-edgar/p/17842438.html

相关文章

  • shell 循环控制shift、continue、break、exit
    shift命令#位置参数可以用shift命令左移。比如shift3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。不带参数的shift命令相当于shift1。#测试shift命令(x_shift3.sh)[root@linux-serverscript]#catx_shift3.sh #!/bin/bashshiftecho"......
  • oracle19cPDB数据库连不上,提示ORA-01109: database not open
    今天尝试创建了一个RAC环境的PDB数据库,在本地执行alterpluggabledatabasepdb01open成功了,但是使用上去了plus连接还是连接不上,提示错误如下:C:\Users\Administrator>sqlplussystem/[email protected]:1521/pdb01SQL*Plus:Release19.0.0.0.0-Productionon星期日1......
  • echarts坐标轴线、坐标轴刻度线、网格线控制
    xAxis:{name:'',axisTick:{show:true//坐标轴刻度线},axisLine:{//轴线show:false},splitLine:{//网格线show:true},axisLabel:{//坐标轴样式textStyle:{color:'#636363'}}}参考文章echarts坐......
  • Prompt Engineering & Prompt Injection 提示词工程
    \(\quad\)提示词工程是通过使用提示词,挖掘大模型的潜力。只不过有人使用该方法做出一些违背开发者本意的事情。\(\quad\)简单理解是,说明我是谁,我遇到了什么,我需要提供什么帮助。通过这些提示词,让大模型精确度理解我么得需求。但有时会遇到一些安全性问题(奶奶工具)。......
  • C语言【控制语句】
    C语言【控制语句】一、分支控制语句1、if语句略。2、switch...case如下switch(表达式){ case常量1://...break;case常量2://...break;defaule://...break;}注意:switch括号里的表达式只能存在......
  • Java开发者的Python快速进修指南:控制之if-else和循环技巧
    简单介绍在我们今天的学习中,让我们简要了解一下Python的控制流程。考虑到我们作为有着丰富Java开发经验的程序员,我们将跳过一些基础概念,如变量和数据类型。如果遇到不熟悉的内容,可以随时查阅文档。但在编写程序或逻辑时,if-else判断和循环操作无疑是我们经常使用的基本结构。毕竟,......
  • IDEA控制台输出中文乱码
    1.问题如下图,我使用的文件编码格式为UFT-8,这里会出现中文乱码的问题。且我并不方便直接修改全局文件编码格式,有可能会造成未知错误。2.解决参考链接:IDEA控制台中文乱码4种解决方案2.1选中要运行的项目,并点击编辑配置2.2在VM选项中加入-Dfile.encoding=GBK选项即可......
  • 【9.0】Python基础之流程控制语句
    【一】流程控制语句介绍程序是由语句构成,而流程控制语句是用来控制程序中每条语句执行顺序的语句。可以通过控制语句实现更丰富的逻辑以及更强大的功能。几乎所有编程语言都有流程控制语句,功能也都基本相似。其流程控制方式有顺序结构分支结构循环结构这里最简单......
  • 【第7章】访问控制技术原理与应用(信息安全工程师)
    7.1访问控制概述 7.1.1访问控制概念 访问控制是指对资源对象的访问者授权、控制的方法及运行机制。访问者又称为主体,可以是用户、进程、应用程序等;而资源对象又称为客体,即被访问的对象,可以是文件、应用服务、数据等;授权是访问者可以对资源对象进行访问的方式,如文件的读、......
  • 微信小程序使用canvas导出图片时提示报错为canvasToTempFilePath:fail fail canvas is
    uni使用小程序时,组件里面有个canvas,页面上面也有一个canvs。组件里面的canvas想导出图片,报canvasToTempFilePath:failfailcanvasisempty。在canvasToTempFilePath里面要加上第二个参数,传入this;uni.canvasToTempFilePath({canvasId:"canvas"......