蓝桥杯单片机_13届源代码

本文详细描述了一个嵌入式系统的开发过程,涉及DS1302实时时钟的读写、DS18B20温度传感器的数据获取与显示,以及按键对功能模式和显示SMG的控制。通过定时器实现时间更新和状态指示灯操作。
摘要由CSDN通过智能技术生成
#include "reg52.h"
#include "ds1302.h"
#include "onewire.h"
sfr P4 = 0xc0;
sbit R1 = P3 ^ 3;
sbit R2 = P3 ^ 2;
sbit C1 = P4 ^ 2;
sbit C2 = P3 ^ 5;

#define TSMG 500

code unsigned char SMG_NoDot[18] = {
    0xc0, 0xf9,
    0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80,
    0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};

code unsigned char SMG_Dot[10] = {
    0x40, 0x79,
    0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
    0x10}; //-0x80就好了其实

code unsigned char READ_RTC_ADDR[7] = {
    0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};

code unsigned char WRITE_RTC_ADDR[7] = {
    0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

unsigned char Time[7] = {
    0x30, 0x59, 0x23, 0x19, 0x02, 0x01, 0x24};

void Set_HC573(unsigned char channel, unsigned char dat)
{
    P0 = dat;
    switch (channel)
    {
    case 4:
        P2 = (P2 & 0x1f) | 0x80;
        break;
    case 5:
        P2 = (P2 & 0x1f) | 0xa0;
        break;
    case 6:
        P2 = (P2 & 0x1f) | 0xc0;
        break;
    case 7:
        P2 = (P2 & 0x1f) | 0xe0;
        break;
    case 0:
        P2 = (P2 & 0x1f) | 0x00;
        break;
    }
    P2 = (P2 & 0x1f) | 0x00;
}

void DelaySMG(unsigned int t)
{
    while (t--)
        ;
}

void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
    Set_HC573(6, 0x01 << pos);
    Set_HC573(7, value);
    DelaySMG(TSMG);
    Set_HC573(6, 0x01 << pos);
    Set_HC573(7, 0xff);
}

void DisplaySMG_All(unsigned char value)
{
    Set_HC573(6, 0xff);
    Set_HC573(7, value);
}

//================定义变量区=================
unsigned int temp = 0;
unsigned char param = 23;
unsigned char hour = 0x23;
unsigned char min = 0x59;
unsigned char second = 0x30;
unsigned char stat_led = 0xff;
unsigned char stat_jdq = 0x00;
unsigned char F_time = 0;
unsigned char F_smg = 1;
unsigned char F_mode = 1;
unsigned int count_100ms = 0;
unsigned int count_5s = 0;

void DisplaySMG_U1()
{
    DisplaySMG_Bit(0, 0xc1);
    DisplaySMG_Bit(1, SMG_NoDot[1]);
    DisplaySMG_Bit(5, SMG_NoDot[temp / 100]);
    DisplaySMG_Bit(6, SMG_Dot[temp / 10 % 10]);
    DisplaySMG_Bit(7, SMG_NoDot[temp % 10]);
    DisplaySMG_All(0xff);
}

void DisplaySMG_U2_Mode1()
{
    DisplaySMG_Bit(0, 0xc1);
    DisplaySMG_Bit(1, SMG_NoDot[2]);
    DisplaySMG_Bit(3, SMG_NoDot[hour >> 4]);
    DisplaySMG_Bit(4, SMG_NoDot[hour & 0x0f]);
    DisplaySMG_Bit(5, 0xbf);
    DisplaySMG_Bit(6, SMG_NoDot[min >> 4]);
    DisplaySMG_Bit(7, SMG_NoDot[min & 0x0f]);
    DisplaySMG_All(0xff);
}

void DisplaySMG_U2_Mode2()
{
    DisplaySMG_All(0xff);
    DisplaySMG_Bit(0, 0xc1);
    DisplaySMG_Bit(1, SMG_NoDot[2]);
    DisplaySMG_Bit(3, SMG_NoDot[min >> 4]);
    DisplaySMG_Bit(4, SMG_NoDot[min & 0x0f]);
    DisplaySMG_Bit(5, 0xbf);
    DisplaySMG_Bit(6, SMG_NoDot[second >> 4]);
    DisplaySMG_Bit(7, SMG_NoDot[second & 0x0f]);
    DisplaySMG_All(0xff);
}

void DisplaySMG_U3()
{
    DisplaySMG_Bit(0, 0xc1);
    DisplaySMG_Bit(1, SMG_NoDot[3]);
    DisplaySMG_Bit(6, SMG_NoDot[param / 10]);
    DisplaySMG_Bit(7, SMG_NoDot[param % 10]);
    DisplaySMG_All(0xff);
}

void Display_Info()
{
    switch (F_smg)
    {
    case 1:
        DisplaySMG_U1();
        break;
    case 2:
        DisplaySMG_U2_Mode1();
        break;
    case 3:
        DisplaySMG_U3();
        break;
    case 4:
        DisplaySMG_U2_Mode2();
        break;
    }
}

void Init_ds1302()
{
    unsigned char i;
    Write_Ds1302_Byte(0x8e, 0x00);
    for (i = 0; i < 7; i++)
    {
        Write_Ds1302_Byte(WRITE_RTC_ADDR[i], Time[i]);
    }
    Write_Ds1302_Byte(0x8e, 0x80); // 写能保护
}

void Read_DS1302_Time()
{

    hour = 23;
    min = 59;
    second = Read_Ds1302_Byte(0x81);
    min = Read_Ds1302_Byte(0x83);
    hour = Read_Ds1302_Byte(0x85);
    if (min == 0 && second == 0)
    {
        stat_led = stat_led & (~0x01);
        Set_HC573(4, stat_led);
        F_time = 1;
    }
}

void Init_Timer0()
{
    TL0 = (65535 - 50000) % 256;
    TH0 = (65535 - 50000) / 256;
    TMOD = 0x01; // 设置定时器模式
    ET0 = 1;
    EA = 1;
    TR0 = 1; // 定时器0开始计时
}

void Service_Timer0() interrupt 1
{
    TL0 = (65535 - 50000) % 256;
    TH0 = (65535 - 50000) / 256;

    Read_DS1302_Time(); // 正常更新
    if (stat_jdq == 0x10)
    {
        count_100ms++;
        if (count_100ms == 2)
        {
            count_100ms = 0;
            if ((stat_led & 0x04) == 0x04)
            {
                stat_led &= ~0x04;
            }
            else
            {
                stat_led |= 0x04;
            }
            Set_HC573(4, stat_led);
        }
    }
    if (F_time == 1)
    {
        count_5s++;
        if (F_mode == 1)
        {
            stat_jdq = 0x10;
        }
        if (count_5s == 100)
        {
            count_5s = 0;
            F_time = 0;
            stat_jdq = 0x00;
            stat_led |= 0x05;
            Set_HC573(4, stat_led);
        }
        Set_HC573(5, stat_jdq);
    }
}

void Init_ds18b20_adc()
{
    unsigned char LSB, MSB;

    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);
    do
    {
        init_ds18b20();
        Write_DS18B20(0xcc);
        Write_DS18B20(0xbe);
        LSB = Read_DS18B20();
        MSB = Read_DS18B20();
        MSB = (MSB << 4) | (LSB >> 4);
    } while (MSB == 85);
}

void Read_ds18b20_adc()
{
    unsigned char LSB, MSB;

    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);

    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0xbe);

    LSB = Read_DS18B20();
    MSB = Read_DS18B20();

    temp = 0x0000;
    temp = MSB;
    temp = (temp <<= 8) | LSB;
    if ((temp & 0xf800) == 0x0000)
    {
        temp = temp * 0.625; // 实际温度 * 10,smg显示
    }
    Display_Info();

    if (F_mode == 0)
    {
        if (temp > param * 10)
        {
            stat_jdq = 0x10;
        }
        else
        {
            stat_jdq = 0x00;
            stat_led |= 0x04;
        }
        Set_HC573(4, stat_led);
        Set_HC573(5, stat_jdq);
    }
}

void Scan_Keys()
{
    C1 = C2 = 1;
    R1 = 0;
    R2 = 1;
    if (C1 == 0)
    {
        DelaySMG(500);
        if (C1 == 0)
        {
            switch (F_smg)
            {
            case 1:
                F_smg = 2;
                break;
            case 2:
                F_smg = 3;
                break;
            case 3:
                F_smg = 1;
                break;
            }
            while (C1 == 0)
            {
                if (F_smg == 1)
                {
                    Read_ds18b20_adc();
                }
                Display_Info();
            }
        }
    }

    if (C2 == 0) // S16
    {
        DelaySMG(500);
        if (C2 == 0)
        {
            if (F_smg == 3)
            {
                if (param == 99)
                {
                    param = 99;
                }
                else
                {
                    param = param + 1;
                }
                // 为什么我不动也会加呢
                while (C2 == 0)
                {
                    Display_Info();
                }
            }
        }
    }

    // S13
    R1 = 1;
    R2 = 0;
    C1 = C2 = 1;
    if (C1 == 0)
    {
        DelaySMG(500);
        if (C1 == 0)
        {
            if (F_mode == 0)
            {
                F_mode = 1;
                if (F_time == 0)
                {
                    stat_jdq = 0x00;
                }
                stat_led |= 0x02;
            }
            else if (F_mode == 1)
            {
                F_mode = 0;
                if (F_time == 1)
                {
                    if (temp <= param * 10)
                    {
                        stat_jdq = 0x00;
                    }
                }
                stat_led &= ~0x02;
            }
            if (stat_jdq == 0x00)
            {
                stat_led |= 0x04;
            }
            Set_HC573(4, stat_led);
            Set_HC573(5, stat_jdq);
            while (C1 == 0)
            {
                Read_ds18b20_adc();
                Display_Info();
            }
        }
    }

    // S17
    if (C2 == 0)
    {
        DelaySMG(500);
        if (C2 == 0)
        {
            if (F_smg == 3)
            {
                if (param == 10)
                {
                    param = 10;
                }
                else
                {
                    param = param - 1;
                }
                while (C2 == 0)
                {
                    Display_Info();
                }
            }
            else if (F_smg == 2)
            {
                F_smg = 4;
                while (C2 == 0)
                {
                    Display_Info();
                }
                F_smg = 2;
            }
        }
    }
}

void Init_sys()
{
    Set_HC573(0, 0x00);
    Set_HC573(5, 0x00);
    DisplaySMG_All(0xff);
    Init_ds18b20_adc();
    F_mode = 0;
    stat_led &= ~0x02;
    Set_HC573(4, stat_led);
    Init_ds1302();
    Init_Timer0();
}

void main()
{
    Init_sys();
    while (1)
    {
        Read_ds18b20_adc();
        Scan_Keys();
    }
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Caihua_X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值