蓝桥杯校赛

2018年“蓝桥杯” 第九届全国软件和信息技术专业人才大赛个人赛
单片机设计与开发项目
河南大学民生学院预选赛试题
“简易摄氏、华氏双显温度计”设计
设计功能要求:
1 上电自检,数码管LED全亮,3秒钟后黑屏,然后蜂鸣器响200mS;(25分)
2 按键S4,显示学号后四位;(15分)
3 按下S5,测温,即显示当前温度;【该代码段要求逐行注释】
再次按下S5,将温度显示为华氏温度。(25分)
4 按下S6,存储当前温度;(15分)
5 按下S7,显示存储温度;再次按下S7,将温度显示为华氏温度。(20分)
注:1温度显示保留小数点1位,显示格式位xx.xC 或xx.xF
2 华氏与摄氏的换算公式位:οF = ℃ × 1.8 + 32
3 自检阶段,按键无效
4 完成程序设计任务,并将工程文件保存在学号+姓名命名的文件夹中上交
拓展要求:断电重启后,存储温度值不丢失
成绩分两部分:现场测试成绩(占70%)+代码成绩(占30%)

程序:

主程序

#include "stc15f2k60s2.h"
#include "onewire.h"
#include "iic.h"

                         // 0    1    2    3    4    5    6    7    8    9
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
                   // 灭    c    f    0.   1.   2.  3.    4.   5.   6.   7.   8.   9.
                     0xff,0xc6,0x8e,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char dspbuf[8]={10,10,10,10,10,10,10,10};
unsigned char dspcom;
unsigned char key_v,flag0,flag1,flag2;
int i;
int temper0,temper1,temper2,temper3;

unsigned char keyscan(void);
void display(void);
void delay10ms();    
void cls_buzz()
{
    P2=0xa0;
    P0=0x00;
    P2=0x1f;
}
void on_led() //led and shumaguan 
{
    P2=0x80;
    P0=0x00;
    
    P2=0xe0;
    P0=0x00;
    P2=0xc0;
    P0=0xff;
}
void delay10ms()        //@11.0592MHz
{
    unsigned char i, j;

    i = 108;
    j = 145;
    do
    {
        while (--j);
    } while (--i);
}

void main()
{
    cls_buzz();
    on_led();
    
    AUXR |= 0x80;        //定时器时钟1T模式
    TMOD &= 0xF0;        //设置定时器模式
    TL0 = 0xCD;        //设置定时初值
    TH0 = 0xD4;        //设置定时初值
    TF0 = 0;        //清除TF0标志
//    TR0 = 1;        //定时器0开始计时
    ET0 = 1;
    
    AUXR |= 0x40;        //定时器时钟1T模式
    TMOD &= 0x0F;        //设置定时器模式
    TL1 = 0xCD;        //设置定时初值
    TH1 = 0xD4;        //设置定时初值
    TF1 = 0;        //清除TF1标志
    TR1 = 1;        //定时器1开始计时
    ET1 = 1;
    EA  = 1;
    while(1)
    {
        while(flag2)
        {
        key_v=keyscan();
        if (key_v==4)
        {
            dspbuf[0]=3;
            dspbuf[1]=0;
            dspbuf[2]=6;
            dspbuf[3]=1;
        }
        if (key_v==5)
        {
            flag0++;
            if(flag0==3)
            {
                flag0=1;
            }
        }
        if (flag0==1)
        {
            temper0=temper_read()*10;
            dspbuf[4]=temper0/100;
            dspbuf[5]=temper0%100/10+13;
            dspbuf[6]=temper0%100%10;
            dspbuf[7]=11;
        }
        if (flag0==2)
        {
            temper1=(temper_read()*1.8+32)*10;
            dspbuf[4]=temper1/100;
            dspbuf[5]=temper1%100/10+13;
            dspbuf[6]=temper1%100%10;
            dspbuf[7]=12;
        }
        if (key_v==6)
        {
            write_eeprom(0x00,dspbuf[4]);
            write_eeprom(0x01,dspbuf[5]);
            write_eeprom(0x02,dspbuf[6]);
            write_eeprom(0x03,temper_read());
        }
        if (key_v==7)
        {
            flag1++;
            if (flag1==3)
            {
                flag1=1;
            }
            if (flag1==1)
            {
                dspbuf[0]=3;
            dspbuf[1]=0;
            dspbuf[2]=6;
            dspbuf[3]=1;
//                temper2=read_eeprom(0x00)*10;
                dspbuf[0]=read_eeprom(0x00);
              dspbuf[1]=read_eeprom(0x01);
              dspbuf[2]=read_eeprom(0x02);
              dspbuf[3]=11;
            }
            if (flag1==2)
            {
                dspbuf[0]=3;
            dspbuf[1]=0;
            dspbuf[2]=6;
            dspbuf[3]=1;
                temper3=(read_eeprom(0x03)*1.8+32)*10;
                dspbuf[0]=temper3/100;
              dspbuf[1]=temper3%100/10+13;
              dspbuf[2]=temper3%100%10;
              dspbuf[3]=12;
            }
        }
    }
}
}

void timer0(void) interrupt 1
{
    display();
}
void timer1(void) interrupt 3
{
    i++;
    if (i==3000)
    {
        P2=0x80;
      P0=0xff;
        P2=0x1f;
        
        P2=0xa0;
      P0=0x40;
        P2=0x1f;
        
        TR0=1;
    }
    if (i==3200)
    {
        cls_buzz();
        TR1=0;
        flag2=1;
    }
}
void display(void)
{
    P2=0xe0;
    P0=0xff;
    P2=0x1f;
    
    P0=1<<dspcom;    
    P2=0xc0;
    P2=0x1f;
    
    P2=0xe0;
    P0=tab[dspbuf[dspcom]];
    P2=0x1f;
    if (++dspcom==8)
    {
        dspcom=0;
    }
}
unsigned char keyscan(void)
{
    unsigned char key=0;
    unsigned char GPIO;
    GPIO=P3;
    GPIO&=0x0f;
    if (GPIO!=0x0f)
    {
        delay10ms();
        GPIO=P3;
        GPIO&=0x0f;
        if (GPIO!=0x0f)
        {
            switch(GPIO)
            {
                case 0x0e:key=7;break;
                case 0x0d:key=6;break;
                case 0x0b:key=5;break;
                case 0x07:key=4;break;
                default:break;
            }
            while(GPIO!=0x0f)
            {
                GPIO=P3;
            GPIO&=0x0f;
            }
        }
    }
    return key;
}

IIC模块

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(12MHz)
  日    期: 2011-8-9
*/

#include "iic.h"

//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    somenop;
    SDA = 0;
    somenop;
    SCL = 0;    
}

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

//应答位控制
void IIC_Ack(unsigned char ackbit)
{
    if(ackbit) 
    {    
        SDA = 0;
    }
    else 
    {
        SDA = 1;
    }
    somenop;
    SCL = 1;
    somenop;
    SCL = 0;
    SDA = 1; 
    somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
    SDA = 1;
    somenop;
    SCL = 1;
    somenop;
    if(SDA)    
    {   
        SCL = 0;
        IIC_Stop();
        return 0;
    }
    else  
    { 
        SCL = 0;
        return 1;
    }
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {   
        if(byt&0x80) 
        {    
            SDA = 1;
        }
        else 
        {
            SDA = 0;
        }
        somenop;
        SCL = 1;
        byt <<= 1;
        somenop;
        SCL = 0;
    }
}

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


//向EEPROM里写数据(地址)/
void write_eeprom(unsigned char add,unsigned char date)
{
    
    IIC_Start();
    IIC_SendByte(0xa0);//发送方式字 1010 0000 激活该器件写操作
    IIC_WaitAck();
    IIC_SendByte(add);
    IIC_WaitAck();
    IIC_SendByte(date);
    IIC_WaitAck();
    IIC_Stop();
    delay10ms();
}
//从EEPROM里读数据(地址)/
unsigned char read_eeprom(unsigned char add)
{
    unsigned char date;
    IIC_Start();
    IIC_SendByte(0xa0);//发送方式字 1010 0000 激活该器件写操作
    IIC_WaitAck();
    IIC_SendByte(add);
    IIC_WaitAck();
    IIC_Start();
    IIC_SendByte(0xa1);//发送方式字 1010 0001 激活该器件读操作
    IIC_WaitAck();
    date=IIC_RecByte();
    IIC_Ack(0);
    IIC_Stop();
    return date;
}
原文地址:https://www.cnblogs.com/liushuizs/p/10334285.html