【蓝桥杯单片机】第十二届省赛(原创解答代码)

3本人参加15届蓝桥杯单片机组,目前仍然在学习,关于第12届省赛这是我写的解答代码,欢迎大家评论区指正。

学习于小蜜蜂老师

 1.主函数(main.c)

#include "reg52.h"
#include "onewire.h"
#include "smgh.h"
#include "iic.h"


sfr P4=0xC0;

sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;

sbit C1=P4^4;
sbit C2=P4^2;
sbit C3=P3^5;
sbit C4=P3^4;

float get_DS18B20=0;
unsigned int smg_DS18B20=0;
unsigned char mode=1;
unsigned char x_mode=1;
unsigned char hot=25;
unsigned int smg_v=0;
void DA_Write(unsigned char dat)
{
    IIC_Start();          
  IIC_SendByte(0x90);    //PCF8591的写设备地址 
  IIC_WaitAck();  
  IIC_SendByte(0x41);   //输出DAC,转换AIN3  
  IIC_WaitAck();                 
  IIC_SendByte(dat);     //设置DAC电压输出参数
  IIC_WaitAck();          //产生非应答信号                 
  IIC_Stop();
}
void Display()
{
    switch(mode)
    {
        case 1:
            smg_DS18B20=get_DS18B20*100;
            DisplaySMG_Bit(0,0xc6);
            DisplaySMG_Bit(4,SMGNoDot_CA[smg_DS18B20/1000]);
            DisplaySMG_Bit(5,SMGDot_CA[smg_DS18B20/100%10]);
            DisplaySMG_Bit(6,SMGNoDot_CA[smg_DS18B20/10%10]);
            DisplaySMG_Bit(7,SMGNoDot_CA[smg_DS18B20%10]);
        select573(4,0xfd);
        break;
        case 2:
            smg_DS18B20=get_DS18B20*10;
            DisplaySMG_Bit(0,0x8c);
            DisplaySMG_Bit(6,SMGNoDot_CA[hot/10]);
            DisplaySMG_Bit(7,SMGNoDot_CA[hot%10]);
        select573(4,0xfb);
        break;
        case 3:
            smg_DS18B20=get_DS18B20*100;
            switch(x_mode)
            {
                case 1:
                    if(smg_DS18B20<hot*100)
                    {
                        DA_Write(0);
                        DisplaySMG_Bit(0,0x88);
                        DisplaySMG_Bit(5,SMGDot_CA[0]);
                        DisplaySMG_Bit(6,SMGNoDot_CA[0]);
                        DisplaySMG_Bit(7,SMGNoDot_CA[0]);
                    }
                    else if(smg_DS18B20>hot*100)
                    {
                        DA_Write(255);
                        DisplaySMG_Bit(0,0x88);
                        DisplaySMG_Bit(5,SMGDot_CA[5]);
                        DisplaySMG_Bit(6,SMGNoDot_CA[0]);
                        DisplaySMG_Bit(7,SMGNoDot_CA[0]);
                    }
                    select573(4,0xfe);
                break;
                case 2:
                    if(smg_DS18B20<2000)
                    {
                        DA_Write(51);
                        DisplaySMG_Bit(0,0x88);
                        DisplaySMG_Bit(5,SMGDot_CA[1]);
                        DisplaySMG_Bit(6,SMGNoDot_CA[0]);
                        DisplaySMG_Bit(7,SMGNoDot_CA[0]);
                        
                    }
                    else if(smg_DS18B20>2000||smg_DS18B20<4000)
                    {
                        smg_v=(smg_DS18B20*0.15)-200;
                        DA_Write((smg_v*51)/100);
                        DisplaySMG_Bit(0,0x88);
                        DisplaySMG_Bit(5,SMGDot_CA[smg_v/100]);
                        DisplaySMG_Bit(6,SMGNoDot_CA[smg_v/10%10]);
                        DisplaySMG_Bit(7,SMGNoDot_CA[smg_v%10]);
                    }
                    else if(smg_DS18B20>4000)
                    {
                        DA_Write(210);
                        DisplaySMG_Bit(0,0x88);
                        DisplaySMG_Bit(5,SMGDot_CA[4]);
                        DisplaySMG_Bit(6,SMGNoDot_CA[0]);
                        DisplaySMG_Bit(7,SMGNoDot_CA[0]);
                    }
                    select573(4,0xf7);
                break;
                
            }
        break;
  }
}
void GetDS18B20()
{
    unsigned char low,high;
    unsigned int temp=0;
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);
    Display();
    init_ds18b20();
    Display();
    Write_DS18B20(0xcc);
    Write_DS18B20(0xbe);
    Display();
    low=Read_DS18B20();
    high=Read_DS18B20();
    temp=(high<<8)|low;
  Display();
    if((temp&0xf800)==0x0000)
    {
        get_DS18B20=temp*0.0625;
    }
    Display();
}
void Scankennys()
{
    R4=0;
    R1=R2=R3=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        delay(100);
        if(C1==0)
        {
            switch(mode)
            {
                case 1:
                    mode=2;
                break;
                case 2:
                    mode=3;
                break;
                case 3:
                    mode=1;
                break;
            }
            while(C1==0)
            {
                if(mode==1)
                {
                    GetDS18B20();
                }
                Display();
            }
            
        }
    }
    if(mode==2)
    {
    R3=0;
    R1=R2=R4=1;
    C1=C2=C3=C4=1;
        if(C2==0)
        {
            delay(100);
            if(C2==0)
            {
                hot++;
            }
            while(C2==0)
            {
                Display();
            }
        }
    R4=0;
    R1=R2=R3=1;
    C1=C2=C3=C4=1;
        if(C2==0)
        {
            delay(100);
            if(C2==0)
            {
                hot--;
            }
            while(C2==0)
            {
                Display();
            }
        }
    }
    R3=0;
    R1=R2=R4=1;
    C1=C2=C3=C4=1;
    if(C1==0)
    {
        delay(100);
        if(C1==0)
        {
            switch(x_mode)
            {
              case 1:
                    x_mode=2;
                break;
        case 2:
                    x_mode=1;
                break;
      }                
            while(C1==0)
            {
                Display();
            }
            
        }
    }
}
void main()
{
    initsystem();
    while(1)
    {
        Scankennys();
        GetDS18B20();
    }
    
}

  1. 2.onewire.c(单总线底层驱动代码)

#include "onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{
  while(t--);
}

//DS18B20芯片初始化
bit init_dS18b20(void)
{
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(144);
	DQ = 0;
	Delay_OneWire(960); 
	DQ = 1;
	Delay_OneWire(120); 
	initflag = DQ;    
	Delay_OneWire(60);
  
	return initflag;
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(60);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(60);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(60);
	}
	return dat;
}

 3.iic.c

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

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
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);
}

//发送应答


//等待应答
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总线上接收数据

4.iic.h

#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

#endif

5.onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include "reg52.h"

sbit DQ = P1^4;  
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
#endif

6.smgc.c(这是我的模版,控制数码管以及573锁存器的选择,应用起来比较方便)

#include "reg52.h"

sbit S7=P3^6;
sbit S6=P3^5;
sbit S5=P3^4;
sbit S4=P3^3;
void select573(unsigned char n,dat)
{
	P0=dat;
	switch(n)
	{
		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 delay(unsigned int t)
{
	while(t--);

}
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
  select573(6, 0x01 << pos);    //数码管的段位
  select573(7, value);          //数码管显示内容
  delay(500);                //数码管点亮时长
  select573(6, 0x01 << pos);        
  select573(7, 0xff);            //消隐
}
void Displayall(unsigned char dat)
{
	select573(6,0xff);
	
	select573(7,dat);
	
}
void initsystem()
{
	select573(4,0xff);
	
	select573(5,0x00);
	Displayall(0xff);
	
}



 7.smgh.h(模板头文件)

#ifndef _SMGH_H
#define _SMGH_H



code unsigned char SMGNoDot_CA[10] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code unsigned char SMGDot_CA[10] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void select573(unsigned char n,dat);
void DisplaySMG_Bit(unsigned char pos , value);
void delay(unsigned int t);
void Displayall(unsigned char dat);
void initsystem();
#endif

应该是把所有功能都实现了,我觉得这个写法可能没有全部模块儿化那么简洁结构条理。

但是非常适合新手小白理解。如有不懂可以私信提问,看到了就回。同时恳请大佬指正改进!

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值