【蓝桥杯单片机】第十一届省赛代码实现

本文介绍了第十一届省赛中基于STC15F2K60S2单片机的代码实现,涉及I2C通信、数字显示、定时器控制、按键处理和电压检测功能。代码展示了如何使用HC573模块、PCF8591和AT24C02进行数据交互,以及处理中断和服务功能。
摘要由CSDN通过智能技术生成

 第十一届省赛代码实现,经简单测试正常,有问题欢迎指出。

main.c

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

code unsigned char SegNoDot_Table[] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 
0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e };
code unsigned char SegDot_Table[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

sbit R1 = P3^2;
sbit R2 = P3^3;
sbit C1 = P3^5;
sbit C2 = P3^4;

unsigned char L1_f = 0;
unsigned char time_f = 0;
unsigned char Invalid_count = 0;
unsigned char stat_led = 0xff;
unsigned char DescendingEdge = 0;
unsigned char flag = 0;
unsigned char mode = 1;
unsigned int Volt_smg = 0;
unsigned char Volt_init = 0;
float Volt_temp = 0.0;
int Volt_param = 0;
unsigned char count = 0;

void HC573_C(unsigned char channel, unsigned char value)
{
	P2 = (P2 & 0x1f) | 0x00;
	P0 = value;
	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;
	}
	P2 = (P2 & 0x1f) | 0x00;	
}

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

void DisplaySMG_bit(unsigned char pos, unsigned char value)
{
	HC573_C(6,0x01 << pos);
	HC573_C(7,value);
	DelaySMG(500);
	HC573_C(6,0x01 << pos);
	HC573_C(7,0xff);
}

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

void Display_Function()
{
	switch(mode)
	{
		case 1:
			DisplaySMG_bit(0,0xc1);
			DisplaySMG_bit(5,SegDot_Table[Volt_smg / 100]);
			DisplaySMG_bit(6,SegNoDot_Table[Volt_smg / 10 % 10]);
			DisplaySMG_bit(7,SegNoDot_Table[Volt_smg % 10]);
			break;
		case 2:
			DisplaySMG_bit(0,0x8c);
			DisplaySMG_bit(5,SegDot_Table[Volt_param / 100]);
			DisplaySMG_bit(6,SegNoDot_Table[Volt_param / 10 % 10]);
			DisplaySMG_bit(7,SegNoDot_Table[Volt_param % 10]);
			break;
		case 3:
			DisplaySMG_bit(0,0xc8);
			DisplaySMG_bit(6,SegNoDot_Table[count / 10]);
			DisplaySMG_bit(7,SegNoDot_Table[count % 10]);
			break;
	}
}

void Init_Timer0()
{
	TH0 = (65535 - 50000) / 256;
	TL0 = (65535 - 50000) % 256;
	TMOD = 0x00;
	ET0 = 1;
	EA = 1;
	TR0 = 0;
}

void Service_Timer0() interrupt 1
{
	time_f++;
	if(time_f == 100)
	{
		time_f = 0;
		stat_led = (stat_led & 0xfe) | 0x00;
		HC573_C(4,stat_led);
	}
}

unsigned char PCF8591_Read()
{
	unsigned char temp = 0;
	
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return temp;
}

void AT24C02_Write(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(0x00);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
	DelaySMG(1000);
}

unsigned char AT24C02_Read()
{
	unsigned char temp = 0;
	
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(0x00);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	temp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return temp;
}

void ScanKeys()
{
	R1 = 1;R2 = 0;
	C1 = 1;C2 = 1;
	//S12
	if(C1 == 0)
	{
		DelaySMG(500);
		if(C1 == 0)
		{
			switch(mode)
			{
				case 1:
					mode = 2;
					break;
				case 2:
					mode = 3;
					AT24C02_Write(Volt_param / 10);
					break;
				case 3:
					mode = 1;
					break;
			}
			Invalid_count = 0;
			while(C1 == 0)
			{
				Display_Function();
			}
		}
	}
	//S16
	if(C2 == 0)
	{
		DelaySMG(500);
		if(C2 == 0)
		{
			if(mode == 2)
			{
				Volt_param = Volt_param + 50;
				if(Volt_param > 500)
				{
					Volt_param = 0;
				}
				Invalid_count = 0;
			}
			else
			{
				Invalid_count++;
			}
			while(C2 == 0)
			{
				Display_Function();
			}
		}
	}
	//S13
	R1 = 0;R2 = 1;
	if(C1 == 0)
	{
		DelaySMG(500);
		if(C1 == 0)
		{
			if(mode == 3)
			{
				count = 0;
				Invalid_count = 0;
			}
			else
			{
				Invalid_count++;
			}
			while(C1 == 0)
			{
				Display_Function();
			}
		}
	}
	//S17
	if(C2 == 0)
	{
		DelaySMG(500);
		if(C2 == 0)
		{
			if(mode == 2)
			{
				Volt_param = Volt_param - 50;
				if(Volt_param < 0)
				{
					Volt_param = 500;
				}
				Invalid_count = 0;
			}
			else
			{
				Invalid_count++;
			}
			while(C2 == 0)
			{
				Display_Function();
			}
		}
	}
}

void CountDetection()
{
	if(Volt_smg > Volt_param)
	{
		flag = 1;
	}
	if((flag == 1) && (Volt_smg <= Volt_param))
	{
		count++;
		if(count % 2 == 1)
		{
			stat_led = (stat_led & 0xfd) | 0x00;
			HC573_C(4,stat_led);
		}
		else
		{
			stat_led = (stat_led & 0xfd) | 0x02;
			HC573_C(4,stat_led);
		}
		flag = 0;
	}
}

void System_Funtion()
{
	Volt_init = PCF8591_Read();
	Volt_temp = Volt_init * 5 / 255;
	Volt_smg = Volt_temp * 100;
	CountDetection();
	Display_Function();
	ScanKeys();
	if(Invalid_count >=3)
	{
		stat_led = (stat_led & 0xfb) | 0x00;
		HC573_C(4,stat_led);
	}
	else
	{
		stat_led = (stat_led & 0xfb) | 0x04;
		HC573_C(4,stat_led);
	}
	
	if(Volt_smg < Volt_param)
	{
		TR0 = 1;
	}
	else
	{
		TR0 = 0;
		time_f = 0;
		stat_led = (stat_led & 0xfe) | 0x01;
		HC573_C(4,stat_led);
	}
}

void Init_sys()
{
	HC573_C(4,0xff);
	HC573_C(5,0x00);
	DisplaySMG_All(0xff);
	Volt_param = AT24C02_Read() * 10;
	Init_Timer0();
}

void main()
{
	Init_sys();
	while(1)
	{
		System_Funtion();
	}
}

 iic.c

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "stc15f2k60s2.h"
#include "intrins.h"
#define DELAY_TIME	5
sbit scl = P2^0;
sbit sda = P2^1;
//
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

static void I2C_Delay(unsigned char n);
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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值