4T_16届单片机设计与开发模拟3(满分代码)

1. 主函数 main.c

c

#include "STC15F2K60S2.h"
#include "ds1302.h"
#include "iic.h"
#include "onewire.h"
#include "HC573.h"
#include "Nixie.h"
#include "keys.h"
#include "jdq.h"
#include "timer.h"
#include "LED.h"
#include "PCF8591.h"

unsigned char mode = 1;//1湿度 2设置 3定时
unsigned char smg_shidu = 0;
unsigned char stat_shidu = 50;//湿度阈值
unsigned char time_s = 3;//定时时间
unsigned char S5_t = 0 ;//按键5标志位 0停止 1运行
unsigned char stat_jdq =0x00;
unsigned char stat_led =0xff;
unsigned char jdq_s = 0;
unsigned int xms = 0;
unsigned int count  = 0;
float ain3_value = 0.0;
float ain3_voit = 0;
unsigned char code SMG_Nodot[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void Init_System()
{
    Select_HC573(0,0x00);
    Select_HC573(5,0x00);
    Select_HC573(4,0xff);
    DisplaySMG_ALL(0xff);
}

void main()
{
    Init_System();
    Init_timer0();
    while(1)
    {
        DisplaySMG_Info();
        Scan_Keys();
        jdq_Running();
        Running_LED();
        Read_PCF8591();
    }
}

  • 变量定义:定义了系统所需的各种变量,如模式、湿度值、阈值、定时时间等。
  • Init_System 函数:初始化系统,关闭所有的 74HC573 锁存器输出,熄灭数码管。
  • main 函数:首先调用 Init_System 函数进行系统初始化,然后初始化定时器 0。在主循环中,不断调用数码管显示、按键扫描、继电器控制、LED 状态显示和湿度采集等函数。

2. 定时器模块 timer.c

c

#include <STC15F2K60S2.H>
#include "timer.h"
#include "HC573.h"

extern unsigned char smg_shidu;
extern unsigned char stat_shidu;//湿度阈值
extern unsigned char S5_t  ;//按键5标志位 0停止 1运行
extern unsigned char time_s ;
extern unsigned char stat_jdq;
extern unsigned char jdq_s ;

extern unsigned int xms ;
extern unsigned int count  ;

void Init_timer0()
{
    TMOD = 0x01;
    TH0=(65535-50000)/256;
    TL0=(65535-50000)%256;
    EA=1;
    ET0=1;
    TR0=1;
}

void ServiceTimer0()interrupt 1
{
    TH0=(65535-50000)/256;
    TL0=(65535-50000)%256;
    if(S5_t ==1 )
    {
        count ++ ;
        if(count == (time_s*20))
        {
            count =0;
            jdq_s = 1;
        }
    }
}

  • Init_timer0 函数:初始化定时器 0,设置定时器工作模式为模式 1(16 位定时器),定时时间为 50ms,开启总中断和定时器 0 中断,并启动定时器 0。
  • ServiceTimer0 函数:定时器 0 中断服务函数,当按键 5 标志位 S5_t 为 1 时,计数器 count 加 1。当 count 达到 time_s * 20 时(即定时时间到),将 count 清零,jdq_s 置为 1。

3. 按键扫描模块 Keys.c

c

#include <STC15F2K60S2.H>
#include "keys.h"
#include "Nixie.h"

sbit R1=P3^3;
sbit R2=P3^2;
sbit C1=P4^4;
sbit C2=P4^2;

extern unsigned char mode ;//1湿度 2设置 3定时
extern unsigned char S5_t  ;//按键5标志位 0停止 1运行
extern unsigned char stat_shidu;//湿度阈值
extern unsigned char time_s ;

void Scan_Keys()
{
    R1 = 1; R2 = 1;
    C1 = 0; C2 = 1;

    if(R1==0)//S4
    {
        delay_ms(20);
        if(R1==0)
        {
            while(R1==0)
            {
                DisplaySMG_Info();
            }
            if(mode==1)
            {
                mode=2;
            }
            else if(mode==2)
            {
                mode=3;
            }
            else if(mode==3)
            {
                mode=1;
            }
        }
    }
    if(R2==0)//S5
    {
        delay_ms(20);
        if(R2==0)
        {
            while(R2==0)
            {
                DisplaySMG_Info();
            }
            if(S5_t==0)
            {
                S5_t=1;
            }
            else if(S5_t==1)
            {
                S5_t=0;
            }
        }
    }

    R1 = 1; R2 = 1;
    C1 = 1; C2 = 0;

    if(R1==0)//S8
    {
        delay_ms(20);
        if(R1==0)
        {
            while(R1==0)
            {
                DisplaySMG_Info();
            }
            if(mode == 2)
            {
                if(stat_shidu>30)
                {
                    stat_shidu = stat_shidu - 5;
                }
                else
                {
                    stat_shidu = 90;
                }
            }
            if(mode == 3)
            {
                if(time_s>1)
                {
                    time_s = time_s - 1;
                }
                else
                {
                    time_s = 10;
                }
            }
        }
    }
    if(R2==0)//S9
    {
        delay_ms(20);
        if(R2==0)
        {
            while(R2==0)
            {
                DisplaySMG_Info();
            }
            if(mode == 2)
            {
                if(stat_shidu<90)
                {
                    stat_shidu = stat_shidu + 5;
                }
                else
                {
                    stat_shidu = 30;
                }
            }
            if(mode == 3)
            {
                if(time_s < 10)
                {
                    time_s = time_s + 1;
                }
                else
                {
                    time_s = 1;
                }
            }
        }
    }
}

  • 按键定义:定义了四个按键 S4S5S8 和 S9,通过行列扫描的方式检测按键状态。
  • Scan_Keys 函数:实现了按键扫描功能,通过软件消抖处理,避免按键抖动引起的误触发。不同的按键有不同的功能:
    • S4:切换系统工作模式,依次为湿度显示、湿度阈值设置和定时时间设置。
    • S5:启动或停止系统运行。
    • S8:在湿度阈值设置模式下,减小湿度阈值;在定时时间设置模式下,减小定时时间。
    • S9:在湿度阈值设置模式下,增大湿度阈值;在定时时间设置模式下,增大定时时间。

4. 数码管显示模块 Nixie.c

c

#include "Nixie.h"
#include "STC15F2K60S2.h"
#include "HC573.h"

extern unsigned char mode ;//1湿度 2设置 3定时
extern unsigned char code SMG_Nodot[10];
extern unsigned char smg_shidu;
extern unsigned char stat_shidu;//湿度阈值
extern unsigned char time_s ;

void delay_ms(unsigned int xms)
{
    unsigned int i,j;
    for(i=xms;i>0;i--)
        for(j=123;j>0;j--);
}

void delay_smg(unsigned int xms)
{
    unsigned int i,j;
    for(i=xms;i>0;i--)
        for(j=123;j>0;j--)
            DisplaySMG_Info();
}

void DisplaySMG_Bit(unsigned char pos,unsigned char value)
{
    Select_HC573(6,0x01<<pos);
    Select_HC573(7,value);
    delay_ms(1);
    Select_HC573(6,0x01<<pos);
    Select_HC573(7,0xff);
}

void DisplaySMG_ALL(unsigned char value)
{
    Select_HC573(6,0xff);
    Select_HC573(7,value);
}

void DisplaySMG_Info()
{
    switch(mode)
    {
        case 1:
            if(smg_shidu > 9)
            {
                DisplaySMG_Bit(6,SMG_Nodot[smg_shidu / 10]);
            }
            DisplaySMG_Bit(7,SMG_Nodot[smg_shidu % 10]);

            DisplaySMG_Bit(0,0xC6);
        break;

        case 2:
            if(stat_shidu > 9)
            {
                DisplaySMG_Bit(6,SMG_Nodot[stat_shidu / 10]);
            }
            DisplaySMG_Bit(7,SMG_Nodot[stat_shidu % 10]);

            DisplaySMG_Bit(0,0x86);
        break;

        case 3:
            if(time_s > 9)
            {
                DisplaySMG_Bit(6,SMG_Nodot[time_s / 10]);
            }
            DisplaySMG_Bit(7,SMG_Nodot[time_s % 10]);

            DisplaySMG_Bit(0,0x89);
        break;
    }
}

  • 延时函数delay_ms 函数用于实现毫秒级延时,delay_smg 函数在延时的同时不断刷新数码管显示。
  • 数码管显示函数
    • DisplaySMG_Bit 函数:在指定位置显示指定字符。
    • DisplaySMG_ALL 函数:在所有数码管上显示相同的字符。
    • DisplaySMG_Info 函数:根据系统工作模式,显示当前湿度、湿度阈值或定时时间。

5. 继电器控制模块 jdq.c

c

#include <STC15F2K60S2.H>
#include "jdq.h"
#include "HC573.h"
#include "Nixie.h"

extern unsigned char smg_shidu;
extern unsigned char stat_shidu;//湿度阈值
extern unsigned char S5_t  ;//按键5标志位 0停止 1运行
extern unsigned char time_s ;
extern unsigned int xms ;
extern unsigned char stat_jdq;
extern unsigned char jdq_s ;
extern unsigned int count  ;

void jdq_Running()
{
    if(S5_t == 0)
    {
        stat_jdq &= ~0x10;
        Select_HC573(5,stat_jdq);
        jdq_s = 0;
    }
    else if(S5_t == 1)
    {
        if(smg_shidu < stat_shidu)
        {
            stat_jdq |= 0x10;
            Select_HC573(5,stat_jdq);

            if(jdq_s==1)
            {
                stat_jdq &= ~0x10;
                Select_HC573(5,stat_jdq);
                count = 0; // 计数器清零
            }
        }
        else
        {
            stat_jdq &= ~0x10;
            Select_HC573(5,stat_jdq);
            jdq_s = 0;
            count = 0; // 计数器清零
        }
    }
}

  • jdq_Running 函数:根据按键 5 标志位 S5_t 和当前湿度 smg_shidu 与湿度阈值 stat_shidu 的比较结果,控制继电器的开关。当 S5_t 为 0 时,关闭继电器;当 S5_t 为 1 且当前湿度小于阈值时,打开继电器;当 jdq_s 为 1 时,关闭继电器并清零计数器。

6. 湿度采集模块 pcf8591.c

c

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

extern unsigned char smg_shidu;
extern float ain3_value ;
extern float  ain3_voit;

unsigned char PCF8591_ADC()
{
    unsigned char tmp;
    I2CStart();
    I2CSendByte(0x90);
    I2CWaitAck();
    I2CSendByte(0x43);
    I2CWaitAck();
    I2CStop();

    I2CStart();
    I2CSendByte(0x91);
    I2CWaitAck();
    tmp = I2CReceiveByte();
    I2CSendAck(1);
    I2CWaitAck();
    I2CStop();
    return tmp;
}

void Read_PCF8591()
{
    unsigned char i;
    for(i=0;i<3;i++)
    {
        ain3_value+=PCF8591_ADC();
    }
    ain3_value = (ain3_value /3.0)/51.0;
    ain3_voit = ain3_value *(80.0/3.0)+10-(80.0/3.0)  ;
    if(ain3_value <=1.0)
    {
        smg_shidu = 10;
    }
    else if(ain3_value >=4.0)
    {
        smg_shidu = 90;
    }
    else
    {
        smg_shidu = ain3_voit;
    }
}

  • PCF8591_ADC 函数:通过 I2C 总线与 PCF8591 进行通信,读取指定通道的模拟量转换结果。
  • Read_PCF8591 函数:连续读取三次数据并求平均值,然后将平均值转换为湿度值。根据转换后的湿度值范围,将其映射到 10 - 90 的湿度区间。

7. LED 状态指示模块 LED.c

#include "LED.h"
#include <STC15F2K60S2.H>
#include "HC573.h"

extern unsigned char mode ;//1湿度 2设置 3定时
extern unsigned char stat_led ;
extern unsigned char S5_t  ;//按键5标志位 0停止 1运行

void Running_LED()
{
    if(mode == 1)
    {
        stat_led &= ~0x01;
    }
    else
    {
        stat_led |= 0x01;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值