蓝桥杯之单片机学习(二十九)——第十三届蓝桥杯单片机第二场(超声波未实现)

一、题目展示

在这里插入图片描述

二、代码展示

2.1 main.c

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

#define uchar unsigned char
#define uint unsigned int
	
uchar SMG_duanma[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
uchar yi,er,san,si,wu,liu,qi,ba;
float real_high_limit_dianya = 4.5;
float real_low_limit_dianya = 0.5;
float low_limit_dianya = 0.5;
float high_limit_dianya = 4.5;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L8 = P0^7;
uchar tt = 0;
uchar t = 0;
uchar miao = 0;

//界面参数
uchar Mode = 0;
//上限下限切换
uchar Mode_limit_high_low = 0;
//连续测距
uchar continue_check_juli = 0;
//超声波距离参数(固定)
uchar juli = 45;

//138译码器
void SelectHC138(uchar channel);
//初始化
void Initsys();
void SMG_Bit(uchar pos, uchar value);
void Delay_one_ms();
//SMG展示
void SMG_Display();
void Delay_five_ms();
void Alone_Key();
//电压界面
void Display_Mode_dianya();
//参数界面
void Display_Mode_canshu();
//测距界面
void Display_Mode_ceju();
//LED显示
void LED_Display();
void Timer0Init(void);		//5毫秒@12.000MHz
void L8_light();

void main()
{
	Initsys();
	Timer0Init();
	while(1)
	{
		if(Mode == 0)
		{
			Display_Mode_dianya();
		}
		else if(Mode == 1)
		{
			Display_Mode_canshu();
		}
		else if(Mode == 2)
		{
			Display_Mode_ceju();
		}
		SMG_Display();
		Alone_Key();
		LED_Display();
		L8_light();
	}
}

void L8_light()
{
	float Rb2_dianya;
	Rb2_dianya = Read_ADC_Rb2() * 0.01963;
	if(Rb2_dianya >= real_low_limit_dianya && real_high_limit_dianya >= Rb2_dianya)
	{
		continue_check_juli = 1;
		Write_DAC(136);
	}
	else
	{
		continue_check_juli = 0;
		Write_DAC(0);
	}
}

//LED显示
void LED_Display()
{
	P0 = 0XFF;
	if(Mode == 0)
	{
		SelectHC138(4);
		L1 = 0;
		L2 = 1;
		L3 = 1;
	}
	else if(Mode == 1)
	{
		SelectHC138(4);
		L1 = 1;
		L2 = 0;
		L3 = 1;
	}
	else if(Mode == 2)
	{
		SelectHC138(4);
		L1 = 1;
		L2 = 1;
		L3 = 0;
	}
}

//电压界面
void Display_Mode_dianya()
{
	unsigned long Rb2_dianya;
	Rb2_dianya = Read_ADC_Rb2() * 0.01963 * 100;
	yi = 0XC1;
	er = san = si = wu = 0XFF;
	liu = SMG_duanma[Rb2_dianya / 100] - 0X80;
	qi = SMG_duanma[Rb2_dianya % 100 / 10];
	ba = SMG_duanma[Rb2_dianya % 10];
}
//参数界面
void Display_Mode_canshu()
{
	if(Mode_limit_high_low == 0)
	{
		yi = 0X8C;
		er = san = liu = 0XFF;
		if(miao == 0)
		{
			si = SMG_duanma[(uint)high_limit_dianya] - 0X80;
			wu = SMG_duanma[(uint)(high_limit_dianya * 10) % 10];
		}
		else if(miao != 0)
		{
			si = 0XFF;
			wu = 0XFF;
		}
		
		qi = SMG_duanma[(uint)low_limit_dianya] - 0X80;
		ba = SMG_duanma[(uint)(low_limit_dianya * 10) % 10];
	}
	else if(Mode_limit_high_low == 1)
	{
		yi = 0X8C;
		er = san = liu = 0XFF;
		si = SMG_duanma[(uint)high_limit_dianya] - 0X80;
		wu = SMG_duanma[(uint)(high_limit_dianya * 10) % 10];
		if(miao == 0)
		{
		qi = SMG_duanma[(uint)low_limit_dianya] - 0X80;
		ba = SMG_duanma[(uint)(low_limit_dianya * 10) % 10];
		}
		else if(miao != 0)
		{
			qi = ba = 0XFF;
		}
	}
}

//测距界面
void Display_Mode_ceju()
{
	float Rb2_dianya;
	Rb2_dianya = Read_ADC_Rb2() * 0.01963;
	if(Rb2_dianya >= real_low_limit_dianya && real_high_limit_dianya >= Rb2_dianya)
	{
		yi = 0XC3;
		er = san = si = wu = liu = 0XFF;
		qi = SMG_duanma[juli / 10];
		ba = SMG_duanma[juli % 10];
		continue_check_juli = 1;
		Write_DAC(136);
	}
	else
	{
		yi = 0XC3;
		er = san = si = wu = 0XFF;
		liu = qi = ba = 0X88;
		continue_check_juli = 0;
		Write_DAC(0);
	}
}

//138译码器
void SelectHC138(uchar channel)
{
	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;
	}
}

//初始化
void Initsys()
{
	SelectHC138(4);
	P0 = 0XFF;
	SelectHC138(5);
	P0 = 0X00;
	
	SelectHC138(6);
	P0 = 0XFF;
	SelectHC138(7);
	P0 = 0XFF;
}

void SMG_Bit(uchar pos, uchar value)
{
	SelectHC138(6);
	P0 = 0X01 << pos;
	SelectHC138(7);
	P0 = value;
}

void Delay_one_ms()
{
	uint i;
	for(i = 845; i > 0; i--);
}
//SMG展示
void SMG_Display()
{
	SMG_Bit(0,yi);
	Delay_one_ms();
	SMG_Bit(1,er);
	Delay_one_ms();
	SMG_Bit(2,san);
	Delay_one_ms();
	SMG_Bit(3,si);
	Delay_one_ms();
	
	SMG_Bit(4,wu);
	Delay_one_ms();
	SMG_Bit(5,liu);
	Delay_one_ms();
	SMG_Bit(6,qi);
	Delay_one_ms();
	SMG_Bit(7,ba);
	Delay_one_ms();
}

void Delay_five_ms()
{
	uint i,j;
	for(j = 0; j < 5; j++)
	for(i = 845; i > 0; i--);
}

void Alone_Key()
{
	//S7
	if(P30 == 0)
	{
		Delay_five_ms();
		if(P30 == 0)
		{
			if(Mode == 1 && Mode_limit_high_low == 0 && high_limit_dianya != 0.5)
			{
				high_limit_dianya = high_limit_dianya - 0.5;
			}
			else if(Mode == 1 && Mode_limit_high_low == 1 && low_limit_dianya != 0.5)
			{
				low_limit_dianya = low_limit_dianya - 0.5;
			}
		}
		while(!P30);
	}
	//S6
	if(P31 == 0)
	{
		Delay_five_ms();
		if(P31 == 0)
		{
			if(Mode == 1 && Mode_limit_high_low == 0 && (uint)high_limit_dianya != 5)
			{
				high_limit_dianya = high_limit_dianya + 0.5;
			}
			else if(Mode == 1 && Mode_limit_high_low == 1 && (uint)low_limit_dianya != 5)
			{
				low_limit_dianya = low_limit_dianya + 0.5;
			}

		}
		while(!P31);
	}
	//S5
	if(P32 == 0)
	{
		Delay_five_ms();
		if(P32 == 0)
		{
			if(Mode == 1)
			{
				if(Mode_limit_high_low == 0)Mode_limit_high_low = 1;
				else if(Mode_limit_high_low == 1)Mode_limit_high_low = 0;
			}
		}
		while(!P32);
	}
	//S4
	if(P33 == 0)
	{
		Delay_five_ms();
		if(P33 == 0)
		{
			if(Mode == 0){Mode = 1;Mode_limit_high_low = 0;high_limit_dianya = real_high_limit_dianya;low_limit_dianya = real_low_limit_dianya;}
			else if(Mode == 1){Mode = 2;real_high_limit_dianya = high_limit_dianya;real_low_limit_dianya = low_limit_dianya;}
			else if(Mode == 2){Mode = 0;continue_check_juli = 0;}
		}
		while(!P33);
	}
}

void Timer0Init(void)		//5毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xA0;		//设置定时初值
	TH0 = 0x15;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;
	EA = 1;
}

void Timer0Server() interrupt 1
{
	tt++;
	t++;
	if(tt == 20)
	{
		if(continue_check_juli == 1)
		{
			P0 = 0XFF;
			SelectHC138(4);
			L8 = ~L8;
		}
		tt = 0;
	}
	if(t == 90)
	{
		if(Mode == 1)
		{
			miao = ~miao;
		}
		t = 0;
	}
}

2.2 iic.c

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
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;  					
    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;    
}

float Read_ADC_Rb2()
{
	float dat;
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(0X03); //进入Rb2
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0X91);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return dat;
}

void Write_DAC(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(0X40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

2.3 iic.h

#ifndef __IIC_H__
#define __IIC_H__

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

sbit SDA = P2^1;
sbit SCL = P2^0;

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); 
float Read_ADC_Rb2();
void Write_DAC(unsigned char dat);
	
#endif
posted @ 2022-05-14 21:24  周末不下雨  阅读(89)  评论(0编辑  收藏  举报