第11届蓝桥杯单片机省赛首场竞赛代码解析

目录

一,题目

二,题目难点及分析

        1,固定的模块:

        2,改变的地方:

        3,我觉得的难点:

三,代码参考:

main.c

IIC.c

IIC.H

四,有不完美的地方,请见谅。 


一,题目

二,题目难点及分析

        1,固定的模块:

PCF8591和24C02模块,不懂的同学可以去看看小蜜蜂的强化题目写一下:

【备赛宝典】小蜜蜂老师关于蓝桥杯单片机大赛的独家教程及资源大汇总-小蜜蜂笔记

        2,改变的地方:

   与前面几届的题目不同的主要是按键变成了矩阵键盘,矩阵键盘我写的十分简单,例如S12,当行R4=0,其余’行列‘为1,只要C2=0时,S12就按键按下

    R4 = 0;
    R1 = R2= R3 = 1;
    C1 = C2 = C3 = C4 = 1;
    if (C2 == 0)                                                        // "S12"
    {
        Delay(100);
        if (C2 == 0)

    其他的基本上没有什么改变,不会的可以看看我的代码,或者找老师请教。

        3,我觉得的难点:

         应该是判断Vpp < param(参数),计数器加1:

        我的想法是设置两个变量stat_volt开始电压和old_volt大于param的先前电压,只要满足(old_volt > param && param > SMG_volt),便可以加1。

三,代码参考:

main.c

#include "STC15.H"
#include "IIC.h"

#define uchar unsigned char 
#define uint unsigned int
	
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

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


uchar code SMG_NoDot[18]={0xc0,0xf9,
    0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
    0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};

uchar code SMG_Dot[10]={0x40,0x79,
    0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

		
uint DAC_value = 0;
float DAC_volt = 0;
uint SMG_volt = 0;
		
uint param = 0;	
uchar stat_led = 0xff;
uchar count_v = 0; 
uchar mode = 3;
uchar count = 0;

uint stat_volt = 0;
uint old_volt = 0;
uchar dat_error = 0;
uchar F_time = 0;
uchar dat_24c02 = 0;


void Delay(uint t)
{
	while(t--);
}

void Select_HC573(uchar n,uchar dat)
{
	P2 = (P2 & 0x1f) | 0x00;
	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 Choose_SMG(uchar dat,uchar pos)
{
	Select_HC573(6,0x01 << pos);
	Select_HC573(7,dat);
	
	Delay(500);
	
	Select_HC573(6,0x01 << pos);
	Select_HC573(7,0xff);
}

void Display_SMG()
{
	 switch(mode)
	 { 
		 case 1:
			Choose_SMG(0xc1,0);        								//1100 0001  "U" 
			Delay(100);
		 
			Choose_SMG(SMG_Dot[SMG_volt / 100],5);
			Delay(100);
			Choose_SMG(SMG_NoDot[(SMG_volt / 10) % 10],6);
			Delay(100);
			Choose_SMG(SMG_NoDot[SMG_volt % 10],7);
			Delay(100);
		 break;
		 
		 case 2:
			Choose_SMG(0x8C,0);        								//1000 1100  "P" 
			Delay(100);
		 
			Choose_SMG(SMG_Dot[param / 100],5);
			Delay(100);
			Choose_SMG(SMG_NoDot[(param / 10) % 10],6);
			Delay(100);
			Choose_SMG(SMG_NoDot[param % 10],7);
			Delay(100);
		 break;
		 
		 case 3:
			Choose_SMG(0xc8,0);        								//1100 1000  "n" 
			Delay(100);
		 
			if(count_v > 9)
			{
				Choose_SMG(SMG_NoDot[(count_v / 10) % 10],6);
			}
				Delay(100);
			
				Choose_SMG(SMG_NoDot[count_v % 10],7);
				Delay(100);
		 break;
	 }
}

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

void Service_Timer0() interrupt 1
{
	TH0 = (65536 - 50000) / 256;
	TL0 = (65536 - 50000) % 256;
	
	if(stat_volt == 0)
	{
		stat_volt = 1;
		old_volt = SMG_volt;
	}
	else
	{
    if (old_volt > param && param > SMG_volt)
    {
        count_v++;
        if (count_v >= 100) 
        {
            count_v = 0;
        }

       if(count_v % 2 == 0)
			 {
					stat_led |= 0x02;
				 Select_HC573(4,stat_led);
			 }
			 else
			 {
					stat_led &= ~0x02;
				 Select_HC573(4,stat_led);
			 }
			}
		old_volt = SMG_volt;
	}
	if(F_time == 1)
	{
		count++;
		if(count >= 100)
		{
			if(SMG_volt < param)
			{
				stat_led &= ~0x01;
				Select_HC573(4,stat_led);
				F_time = 0;
			}
			
		}
	}
}

void write_24c02(uchar addree,uchar dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(addree);
	I2CWaitAck();
	
	I2CSendByte(dat);
	I2CWaitAck();
	
	I2CStop();
}

uchar read_24c02(uchar addree)
{
	uchar tmp;
	
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(addree);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	tmp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return tmp;
}

uchar Read_PCF8591_AIN()
{
	uchar tmp;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	
	I2CSendByte(0x03);
	I2CWaitAck();
	
	Display_SMG();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	
	tmp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return tmp;
}

void Vpp_work()
{
	uchar i;
	for(i = 0;i < 3;i++)
	{
		DAC_value += Read_PCF8591_AIN();
	}
	DAC_value = DAC_value / 3;
	
	DAC_volt = DAC_value * (5.0 / 255);
	SMG_volt = DAC_volt * 100;
	
	if(SMG_volt < param)
	{
		if(F_time == 0)
		{
			F_time = 1;
		}
	}	
	else
	{
		F_time = 0;
		count = 0;
		stat_led |= 0x01;
		Select_HC573(4,stat_led);
	}
	Display_SMG();
	Select_HC573(4,stat_led);
}

void Scan_keys()
{
	R4 = 0;
	R1 = R2= R3 = 1;
	C1 = C2 = C3 = C4 = 1;
	
	if(C2 == 0)														// "S12"
	{
		Delay(100);
		if(C2 == 0)
		{
			dat_error = 0;
			if(mode == 3)
			{
				mode = 1;
			}
			else if(mode == 1)
			{
				mode = 2;
			}
			else if(mode == 2)
			{
				mode = 3;
				dat_24c02 = param / 10;
				write_24c02(0x00,dat_24c02);
			}
			while(C2 == 0)
			{
				Vpp_work();
			}
		}
	}
	
	if(C1 == 0)														// "S16"
	{
		Delay(100);
		if(C1 == 0)
		{
			if(mode == 2)
			{
				dat_error = 0;
				if(param < 500)
				{
					param = param + 50;
				}
				else
				{
					param = 0;
				}
				
			}	
			else
			{
				dat_error++;
			}
			
			while(C1 == 0)
			{
				Vpp_work();
			}
		}
	}

	R3 = 0;
	R1 = R2 = R4 = 1;
	C1 = C2 = C3 = C4 = 1;
	
	if(C1 == 0)														// "S17"
	{
		Delay(100);
		if(C1 == 0)
		{
			if(mode == 2)
			{
				dat_error = 0;
				if(param <= 500)
				{
					param = param - 50;
				}
				else
				{
					param = 500;
				}
			}	
			else
			{
				dat_error++;
			}
			
			while(C1 == 0)
			{
				Vpp_work();
			}
		}
	}

	if(C2 == 0)													//"S13"
	{
		Delay(100);
		if(C2 == 0)
		{
			if(mode == 3)
			{
				dat_error = 0;
				count_v = 0;
			}
			else
			{
				dat_error++;
			}
			
			while(C2 == 0)
			{
				Vpp_work();
			}
		}
	}
		
}

void key_err()
{
	if(dat_error >= 3)
			{
				stat_led &= ~0x04;
				Select_HC573(4,stat_led);
			}
			else
			{
				stat_led |= 0x04;
				Select_HC573(4,stat_led);
			}
}

void Init_System()
{
	Select_HC573(0,0x00);
	Select_HC573(5,0x00);
	Select_HC573(4,0xff);
	
	Select_HC573(6,0xff);
	Select_HC573(7,0xff);
	
	dat_24c02 = read_24c02(0x00);
	if(dat_24c02 > 500 || dat_24c02 % 5 != 0)
	{
		dat_24c02 = 0;
	}
	param = dat_24c02 * 10;
}


void main()
{
	Init_System();
	Init_Timer();
	while(1)
	{
		Scan_keys();
		Vpp_work();
		key_err();
	}
}

IIC.c

#include "STC15.H"
#include "intrins.h"

sbit sda = P2^1;
sbit scl = P2^0;

#define DELAY_TIME	5

//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

IIC.H

#ifndef IIC_H
#define IIC_H

void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);


#endif

四,有不完美的地方,请见谅。 

作者:humanfireworks

物联沃分享整理
物联沃-IOTWORD物联网 » 第11届蓝桥杯单片机省赛首场竞赛代码解析

发表回复