使用蓝桥杯单片机实现ADC采集和实时时钟界面转换与报警功能

该系统基于STM32微控制器,利用ADC模块检测光敏电阻和转口输出的电压,当电压超过预设阈值时触发不同报警模式,如流水灯和蜂鸣器。同时,结合DS1302实时时钟模块,整点时刻会触发继电器吸合及特定LED显示。用户可通过按键切换显示内容,并能停止报警。初始化设置包括关闭继电器和蜂鸣器,显示电压和设定初始时间为8:58:00。
摘要由CSDN通过智能技术生成

目录

1.使用的模块

2.基本功能

3.报警的功能

4.按键功能

5.初始化

4)数码管显示图片

                                                      电压显示

                                                     实时时钟显示

6.代码如下

main

iic.c

iic.h

ds1302.c

ds1302.h


1.使用的模块

1)蜂鸣器和继电器。

2)LED灯。

3)数码管。

4)AD、DA模块。

5)独立按键模块。

6)DS302模块。

2.基本功能

1)光敏电阻输出的电压超过3V就产生报警。

2)转口输出的电压超过3.5V就产生报警。

3)数码管可以显示电压和实时时钟。

4)时间为整点时发生警报。

3.报警的功能

1)光敏电阻输出的电压报警产生的功能为100ms流水灯和蜂鸣器响继电器吸合。

2)转口电阻输出的电压报警产生的功能为LED灯隔个点亮。

3)光敏电阻输出的电压报警和转口报警同时符合条件时值产生光敏报警模式。

4)当实时时钟的时间为整点时继电器吸合,LED3点亮其他熄灭。

4.按键功能

1)S4按下转换数码管显示界面。

2)在什么界面都是S5按下报警停止。

5.初始化

1)继电器与蜂鸣器都关闭。

2)数码管显示ADC界面。

3)实时时钟初始时间为8:58:00。

4)数码管显示图片

                                                      电压显示

                                                     实时时钟显示

 

6.代码如下

main

#include <STC15F2K60S2.H>
#include "iic.h"
#include "ds1302.h"

void Delay()		//@12.000MHz
{
	unsigned char i, j;

	i = 6;
	j = 211;
	do
	{
		while (--j);
	} while (--i);
}


void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0x18;		//设置定时初始值
	T2H = 0xFC;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	EA=1;               //开启总中断
	IE2  |= 0x04;       //开启定时器2中断
}
void Device(unsigned char p2,unsigned char p0)//配置138锁存器
{
	P0=p0;
	P2=P2&0x1f|p2;	
	P2 &=0x1f;	
}

void system()//初始化
{
	Device(0xa0,0);//关闭蜂鸣器与继电器
	Device(0x80,0xff);//关闭LED灯
}

unsigned int smgs[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x80,0x39,0x40};
//0~9  10U 11 .  13-
void smg(unsigned n,unsigned m)//数码管显示函数
{
	int a;
	a=0x01<<n;
	Device(0xc0,0);
	Device(0xe0,~smgs[m]);//显示内容
	Device(0xc0,a);//位置n+1
}
unsigned char u1,ms,u2;//收集电压的1变量相关变量
unsigned int  u1_5,u2_5;//变量的转变

void ADC_read()//ADC采集,10模式采集一次 ,  因为每次都是上一次的值,所以要使用两次该函数
{	
if(ms>=10)
{	
	ms=0;
	ADC(0x41);
	u1=ADC(0x41);
	ADC(0x43);
	u2=ADC(0x43);
    //255->500
    u1_5=u1*100/51;
    u2_5=u2*100/51;
}	

}
//Delay()作用是让数码管显示更加明亮
void show_adc()//显示电压的函数
{
	smg(0,u1_5/100);Delay();
    smg(0,11);Delay();
	smg(1,u1_5/10%10);Delay();
    
	smg(2,u1_5%10);Delay();
	smg(4,u2_5/100);Delay();
    smg(4,11);Delay();
	smg(5,u2_5/10%10);Delay();
	smg(6,u2_5%10);Delay();
	smg(7,10);Delay();
}

int s,min,h;//收据时间变量
void ds1302()//实时时钟采集
{
s= BCDToDec(Read_Ds1302_Byte( 0x81 ));
min=BCDToDec(Read_Ds1302_Byte( 0x83 ));
h=BCDToDec(Read_Ds1302_Byte( 0x85 ));
}

void show_sj()//实时时钟显示函数
{
	smg(0,h/10);Delay();
	smg(1,h%10);Delay();
    smg(2,13);Delay();
	smg(3,min/10);Delay();
	smg(4,min%10);Delay();
    smg(5,13);Delay();
	smg(6,s/10);Delay();
	smg(7,s%10);Delay();
}


int led;//时间变量
int w;//位移变量
void Led_running()//流水灯函数
{
	if(led>500)
{
	led=0;
	Device(0x80,~(0x01 << w));
	w++;
	w=w%8;
	Device(0xa0,0x50);
}	

}
unsigned char adc=0;//adc报警变量
int b=0;//按键功能变量
void adc_jb()//报警函数
{
 //光敏电阻  
if((u1_5>300)&&(adc==1)&&(b==0))
{
	Led_running();
    Device(0xa0,0x50);
}
//转口器
if((u2_5>350)&&(adc==2)&&(b==0))
{
	Device(0x80,0xaa);
	Device(0xa0,0);
}
//变量优先级条件
if((u1_5>300)&&(u2_5>300))
{adc=1;}

if((u2_5>350)&&(u1_5<300))
{adc=2;}

if((u2_5<350)&&(u1_5>300))
{adc=1;}

if((u2_5<350)&&(u1_5<300))
{adc=3;b=0;}

if((adc!=1)&&(adc!=2))
{Device(0x80,0xff);Device(0xa0,0);}

}

void ds1302_bj()//实时时钟报警器
{
//报警条件
if((min==0)&&(s==0)&&(b==0))
{
    Device(0x80,~0x03);
    Device(0xa0,0x10);
}


if(min==0&&(s==5))
{
    b=0;
    Device(0xa0,0);
    Device(0x80,0xff);
}

}

int i;//界面转换变量
void key()//按键
{
if(P33==0)//s4
{Delay();if(P33==0){i++;i=i%2;while(P33==0){}}}
if(P32==0)//s5
{Delay();if(P32==0){b=1;}}

}


void main()
{
	system();
	Timer2Init();
	vClock_Set(8,58,00);//实时时钟初始化时间
while(1)
{
	    
}
}

void t2() interrupt 12//中断入口
{
    key();
    ADC_read();
	ms++;
	led++;
    ds1302();
   //根据变量显示界面
     if(i==0)
    {
    show_adc();
    adc_jb();
    }
	if(i==1)
    {
   show_sj();
   ds1302_bj();
    }
    
    if(b==1)
{
    Device(0xa0,0);
    Device(0x80,0xff);
}
    

}

ds1302.c

#include <intrins.h>
#include "ds1302.h"
#include <STC15F2K60S2.H>

sbit SCK=P1^7;		
sbit IO=P2^3;		
sbit CE = P1^3;   		// DS1302复位											

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		IO=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
 	CE=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	CE=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
 	CE=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(IO)
 		temp|=0x80;	
 		SCK=1;
	} 
 	CE=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	IO=0;	_nop_();
	IO=1;	_nop_();
	return (temp);			
}


//实时时钟转变
void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second)
{
	Write_Ds1302_Byte(0x8e,0x00);			//关闭写保护
	Write_Ds1302_Byte(0x80,DecToBCD(second));       //写入小时数据到对应的地址
	Write_Ds1302_Byte(0x82,DecToBCD(minute));       //写入分钟数据到对应的地址
	Write_Ds1302_Byte(0x84,DecToBCD(hour));         //写入秒钟数据到对应的地址
	Write_Ds1302_Byte(0x8e,0x80);			//打开写保护
}

 ds1302.h

#ifndef __DS1302_H
#define __DS1302_H


#define DecToBCD(dec) (dec/10*16)+(dec%10)//10进制转变为BCD码
#define BCDToDec(bcd) (bcd/16*10)+(bcd%16)//BCD码转变为10进制

unsigned char Read_Ds1302_Byte( unsigned char address );
void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second);

#endif

iic .c

#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

void Delay_Ms(unsigned int ms)		//@12.000MHz
{
	unsigned char i, j;
while(ms--)
{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}
}


//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}
 


//ADC输出函数	
char ADC(unsigned  char c)
{
char q;
 IIC_Start();
 IIC_SendByte(0x90);
 IIC_WaitAck();
 IIC_SendByte(c);
 IIC_WaitAck();


 IIC_Start();
 IIC_SendByte(0x91);
 IIC_WaitAck();
q=IIC_RecByte();
 IIC_SendAck(1);
 IIC_Stop();

return q;
}

iic  .h

#ifndef _IIC_H
#define _IIC_H

void Write_EEPROM(unsigned char add, unsigned char dat);
unsigned char  ucRead_EEPROM(unsigned char add);
char ADC(unsigned  char c);

#endif

期待大家一起谈论不足之处。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值