蓝桥杯单片机第十一届省赛(第一场)

主函数代码

#include<iic.h>
#include<intrins.h>

sfr P4=0xc0;
sbit R3=P3^2;
sbit R4=P3^3;
sbit C4=P3^4;
sbit C3=P3^5;

unsigned char code led_nodot[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code led_dot[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char code upn[]={0xc1,0x8c,0xc8};
unsigned int 	count_er=0;//统计错误按键数
unsigned int	Vp=0;      //参考电压
unsigned int    Vn=0;	   //PCF8591测出来的电压
unsigned int    state=0;   //窗口切换变量
unsigned int    t=0;	   //时间变量
unsigned int    t_v=0;	   //统计Vn>Vp的时间
unsigned int    count=0;   //统计下降时Vn>Vp的次数
unsigned char   led=0xff;  //保存流水灯的状态,防止数码管程序干扰
unsigned char   Vn_value;	//保存PCF8591测出来的值
bit state_v=0;				//用来界定Vn>Vp时是上升还是下降
void serve_timer_INT0(){
	TMOD=0x01;
	TH0=(65535-50000)/256;//50ms
	TL0=(65535-50000)%256;
	TR0=1;
	EA=1;
	ET0=1;
}
void timer_INT0() interrupt 1 using 1{
	TH0=(65535-50000)/256;//50ms
	TL0=(65535-50000)%256;

	t++;
	if(Vp>Vn){
		t_v++;
	}
	else
		t_v=0;
} 
void choose(unsigned int n){
	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;
	}
}
void delay(unsigned int k)	//@11.0592MHz
{
	unsigned char data i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	while(k--){
	do
	{
		while (--j);
	} while (--i);}
}
void smg_display(unsigned int n,unsigned char dat){
	choose(6);
	P0=0x01<<n;
	choose(7);
	P0=dat;
	delay(1);
	choose(0);			//防止最后一位数码管显示过亮
}
void smg_show(){
smg_display(0,upn[state]);
switch(state){
	case 0:
		smg_display(5,led_dot[Vn/100%10]);
		smg_display(6,led_nodot[Vn/10%10]);
		smg_display(7,led_nodot[Vn%10]);
		break;
	case 1:
		smg_display(5,led_dot[Vp/100%10]);
		smg_display(6,led_nodot[Vp/10%10]);
		smg_display(7,led_nodot[Vp%10]);
		break;
	case 2:
		if(count>99)
			smg_display(5,led_nodot[count/100%10]);
		if(count>9)
			smg_display(6,led_nodot[count/10%10]);
			smg_display(7,led_nodot[count%10]);
		break;
}
}
//unsigned char EEPROM_read(unsigned char addr);
//void EEPROM_write(unsigned char dat);
//unsigned char PCF8591_read(unsigned char addr);
void check_keyboard(){
R4=0;
R3=1;
C3=C4=1;
if(C3==0){
	delay(1);
		if(C3==0){
			count_er=0;	
		if(state==1)
			EEPROM_write(Vp/10);	//退出1状态时保存Vp	//除以10是因为前面乘了100

		state++;
		if(state>=3)
			state=0;

		while(!C3){
			smg_show();
		}
	}
}

R3=0;
R4=1;
C3=C4=1;
if(C3==0){
	delay(1);
	if(C3==0){
		if(state==2){
			count_er=0;	
			count=0;
		}
		else
			count_er++;
			while(!C3){
				smg_show();
		}
	}
}
R4=0;
R3=1;
C3=C4=1;
if(C4==0){
	delay(1);
	if(C4==0){
		if(state==1){
			Vp+=50;
			count_er=0;
			if(Vp>500)
				Vp=0;
		}
		else
			count_er++;
		while(!C4){
			smg_show();
		}
	}
}
R3=0;
R4=1;
C3=C4=1;
	if(C4==0){
		delay(1);
		if(C4==0){
			if(state==1){
				if(Vp==0)
					Vp=500;
				else
					Vp-=50;
				count_er=0;
				}
				else
					count_er++;
			while(!C4){
			smg_show();
			}
		}
	}
}
void check_led(){
	if(t_v>=100){
		led=led & 0xfe;
		choose(4);
		P0=led;
		choose(0);
	}
	else{
		led=led | 0x01;
		choose(4);
		P0=led;
		choose(0);
	}
	if(count%2!=0){
		led=led & 0xfd;
		choose(4);
		P0=led;
		choose(0);
	}
	else{
		led=led | 0x02;
		choose(4);
		P0=led;
		choose(0);
	}
	if(count_er>=3){
		led=led & 0xfb;
		choose(4);
		P0=led;
		choose(0);
	}
	else{
		led=led | 0x04;
		choose(4);
		P0=led;
		choose(0);
	}
}
void get_Vn(){
Vn_value=PCF8591_read(0x03);
Vn=Vn_value*(5.0/255)*100;
	if(Vn<Vp && state_v==0){
		count++;
		state_v=1;
	}
	else if(Vn>Vp && state_v==1){
		state_v=0;
	}
}
void main(){
choose(4);
P0=led;
choose(5);
P0=0x00;
serve_timer_INT0();
Vp=EEPROM_read(0x00)*10;
while(1){
	smg_show();
	check_keyboard();
	check_led();
if(t%10==0){		//每隔0.5秒刷新一次电压Vn
	get_Vn();
}
}
}

iic.c文件


#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;
    }
}


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;
    }
}


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;
}


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

unsigned char EEPROM_read(unsigned char addr){
unsigned char ret;
IIC_Start(); 
IIC_SendByte(0xa0); 
IIC_WaitAck();
IIC_SendByte(addr); 
IIC_WaitAck();
IIC_Stop(); 
	
IIC_Start();
IIC_SendByte(0xa1); 
IIC_WaitAck();
ret=IIC_RecByte(); 
IIC_Ack(1); 
IIC_Stop();  
return ret;
}
void EEPROM_write(unsigned char dat){
IIC_Start(); 
IIC_SendByte(0xa0); 
IIC_WaitAck();
IIC_SendByte(0x00); 
IIC_WaitAck();
IIC_SendByte(dat); 
IIC_Ack(1); 
IIC_Stop(); 
}
unsigned char PCF8591_read(unsigned char addr){
unsigned char ret;
IIC_Start(); 
IIC_SendByte(0x90); 
IIC_WaitAck();
IIC_SendByte(addr); 
IIC_WaitAck();

IIC_Start();
IIC_SendByte(0x91); 
IIC_WaitAck();
ret=IIC_RecByte(); 
IIC_Ack(1); 
IIC_Stop();  
return ret;
}
//void PCF8591_out(unsigned char dat){
//IIC_Start(); 
//IIC_SendByte(0x90); 
//IIC_WaitAck();
//IIC_SendByte(0x40); 
//IIC_WaitAck();
//IIC_SendByte(dat); 

//IIC_Ack(1); 
//IIC_Stop(); 
//}

iic.h文件

#ifndef _IIC_H
#define _IIC_H

#include "regx52.h"
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1


sbit SDA = P2^1;  /* ˽ߝП */
sbit SCL = P2^0;  /* ʱדП */

void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
unsigned char EEPROM_read(unsigned char addr);
void EEPROM_write(unsigned char dat);
unsigned char PCF8591_read(unsigned char addr);
//void PCF8591_out(unsigned char dat);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值