蓝桥杯单片机第十届省赛

这届省赛不难,但是是我第一次使用定时器扫描数码管和按键写程序,效果比Delay好太多,是真的好用!但出现的问题也会变多,其中主要是外设冲突问题。

目录

数码管显示

显示定时器

独立按键

main.c

iic.c

iic.h


先来看看定时器扫描数码管

数码管显示
void display(void)
{
	static uchar i=0;
	
	P0=0xff;//消除鬼影
	P2=(P2&0x1f)|0xe0;
	P2=0;

	P0=0x00;
	P2=(P2&0x1f)|0xc0;
	P0=dis_bit[i];
	P2=0;

	P0=0xff;
	P2=(P2&0x1f)|0xe0;
	P0=tab[dis_buf[i]];
	P2=0;
				
	if(++i==8)i=0;

}

显示定时器

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

void Tim0(void) interrupt 1
{
	display();
	if(++Key_flag==10)
	{
		Key_flag=0;
	}
	if(++smg_slow_down==70)//目的是减速,防止更新频率太快,导致外设显示冲突
	{
		smg_slow_down=0;
	}
	if(++led_slow_down==100)
	{
		led_slow_down=0;
	}
}
独立按键
uchar Key_Read(void)
{
	uchar Key_num,Key_value;
	
	P3|=0x0f;//准双向口,先拉高
	Key_num=P3&0x0f;
	
	switch(Key_num)
	{
		case 0x0e: Key_value = 7; break;
		case 0x0d: Key_value = 6; break;
		case 0x0b: Key_value = 5; break;
		case 0x07: Key_value = 4; break;
		default: Key_value=0;break;
	}
	
	return Key_value;
}

void Key_isolated(void)
{
	uchar Key_Temp,Key_Down,Key_Up;
	static uchar Key_Old=0;
	
	if(Key_flag)return;
	Key_flag=1;
	/****************消抖(网上有详细的教学)************/
	Key_Temp=Key_Read();
	Key_Down=Key_Temp&(Key_Temp^Key_Old);
	Key_Up=~Key_Temp&(Key_Temp^Key_Old);
	Key_Old=Key_Temp;
	
	if(Key_Down)
	{
		switch(Key_Down)
		{
			case 7:
			smg_flag=~smg_flag;
			break;
			case 6: 
			Led_mode=~Led_mode;
			break;
			case 5:
			DA_flag=~DA_flag;
			break;
			case 4: 
			jiemian=~jiemian;	
			break;
			default:break;
		}
	}
}
main.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>

	
code uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
							0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xff,0xc1,0x8e};
code uchar dis_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位选
uchar dis_buf[]={11,11,11,11,11,11,11,11};//段选
void display(void);//显示函数
void Delayms(uint ms);	//延时函数
void Allinit(void);//外设初始化函数
void Timer0Init(void);//定时器初始化
void Timer1Init(void);
uchar Key_Read(void);
void Key_isolated(void);
void smg_display(void);
void Led_Control(void);
uchar Key_flag=0;//独立按键减速
uchar smg_slow_down;//数码管减速
uchar led_slow_down;
bit jiemian=0;//界面切换
bit f_flag;//频率正反切换
bit DA_flag=0;
bit Led_mode;
bit smg_flag;
uint freq;//频率
uint Voltage;//电压
uint tt;//频率测量标志
uint time;//时间
uint zheng,fan,Newzheng,Newfan;//频率测量series
uchar AD;
void main(void)
{
	Allinit();
	Timer0Init();
	Timer1Init();
	dis_buf[0]=21;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=21;
	while(1)
	{
		smg_display();
		Key_isolated();
		Led_Control();
	}
}

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

void Tim0(void) interrupt 1
{
	display();
	if(++Key_flag==10)
	{
		Key_flag=0;
	}
	if(++smg_slow_down==70)
	{
		smg_slow_down=0;
	}
	if(++led_slow_down==100)
	{
		led_slow_down=0;
	}
	tt++;
	if(tt==969)
	{
		TR1=1;
	}
	else if(tt==999)
	{
		tt=0;
		TR1=0;
		time=(Newzheng+Newfan)*5;
		freq=1000000/time;
	}
}

void Timer1Init(void)		//5微秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC9;		//设置定时初值
	TH1 = 0xFF;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	EA=1;		//定时器1开始计时
	ET1=1;
}

void Tim1(void) interrupt 3
{
	if(P34==0)
	{
		fan++;
		if(f_flag==1)
		{
			f_flag=0;
			Newzheng=zheng;
			zheng=0;
		}
	}
	else if(P34==1)
	{
		zheng++;
		if(f_flag==0)
		{
			f_flag=1;
			Newfan=fan;
			fan=0;
		}
	}
}


uchar Key_Read(void)
{
	uchar Key_num,Key_value;
	
	P3|=0x0f;//准双向口,先拉高
	Key_num=P3&0x0f;
	
	switch(Key_num)
	{
		case 0x0e: Key_value = 7; break;
		case 0x0d: Key_value = 6; break;
		case 0x0b: Key_value = 5; break;
		case 0x07: Key_value = 4; break;
		default: Key_value=0;break;
	}
	
	return Key_value;
}

void Key_isolated(void)
{
	uchar Key_Temp,Key_Down,Key_Up;
	static uchar Key_Old=0;
	
	if(Key_flag)return;
	Key_flag=1;
	
	Key_Temp=Key_Read();
	Key_Down=Key_Temp&(Key_Temp^Key_Old);
	Key_Up=~Key_Temp&(Key_Temp^Key_Old);
	Key_Old=Key_Temp;
	
	if(Key_Down)
	{
		switch(Key_Down)
		{
			case 7:
			smg_flag=~smg_flag;
			break;
			case 6: 
			Led_mode=~Led_mode;
			break;
			case 5:
			DA_flag=~DA_flag;
			break;
			case 4: 
			jiemian=~jiemian;	
			break;
			default:break;
		}
	}
}

void smg_display(void)
{
	if(smg_slow_down)return;
		smg_slow_down=1;
			
	AD=IIC_Read(0x03);

	Voltage=AD*1.96078431372549;
	
	if(smg_flag==0)
	{
		if(jiemian==0)
		{
			if(DA_flag==0)
			{
				dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
				dis_buf[5]=200/100+10;dis_buf[6]=200%100/10;dis_buf[7]=200%10;
				
				DA_Write(2*51);
			}
			else if(DA_flag==1)
			{
				dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
				dis_buf[5]=Voltage/100+10;dis_buf[6]=Voltage%100/10;dis_buf[7]=Voltage%10;
				DA_Write(AD);
			}
		}
		else if(jiemian==1)
		{
			dis_buf[0]=23;dis_buf[1]=21;
			if(freq<10)
			{
				dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=freq;
			}
			else if(freq>=10&&freq<100)
			{
				dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=freq/10;dis_buf[7]=freq%10;
			}
			else if(freq>=100&&freq<999)
			{
				dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=freq/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
			}
			else if(freq>=1000&&freq<10000)
			{
				dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=freq/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
			}
			else if(freq>=10000&&freq<100000)
			{
				dis_buf[2]=21;dis_buf[3]=freq/10000;dis_buf[4]=freq%10000/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
			}
			else if(freq>=100000)
			{
				dis_buf[2]=freq/100000;dis_buf[3]=freq%100000/10000;dis_buf[4]=freq%10000/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
			}
		}
	}
	else if(smg_flag==1)
	{
		dis_buf[0]=21;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=21;
	}
}

void Led_Control(void)
{
	if(led_slow_down)return;
	led_slow_down=1;
	
	P0=0xff;
	
	if(Led_mode==0)
	{
		if(jiemian==0)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfe;P2=0;
		}
		else
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfd;P2=0;
		}
		if(DA_flag==1)
		{
			if(Voltage<150||(Voltage>=250&&Voltage<350))
			{
				P2=(P2&0x1f)|0x80;
				P0=P0|(~0xfb);P2=0;
			}
			else if((Voltage>=150&&Voltage<250)||(Voltage>=350))
			{
				P2=(P2&0x1f)|0x80;
				P0=P0&0xfb;P2=0;
			}

		}
		else if(DA_flag==0)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfb;P2=0;
		}
		if(freq<1000||(freq>=5000&&freq<10000))
		{
			P2=(P2&0x1f)|0x80;
			P0=P0|(~0xf7);P2=0;
		}
		else if(freq>=1000&&freq<5000||(freq>=10000))
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xf7;P2=0;
		}
		if(DA_flag==0)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0|(~0xef);P2=0;
		}
		else
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xef;P2=0;
		}
		P2=0;
	}
	else if(Led_mode==1)
	{
		P2=(P2&0x1f)|0x80;
		P0=0xff;P2=0;
	}
	
}

void Allinit(void)
{
	P2=(P2&0x1f)|0xa0;
	P0=0x00;
	P2=0;
	P2=(P2&0x1f)|0x80;
	P0=0xff;
	P2=0;
	P2=(P2&0x1f)|0xc0;
	P0=0x00;
	P2=0;
	P2=(P2&0x1f)|0xf0;
	P0=0xff;
	P2=0;
}

void display(void)
{
	static uchar i=0;
	
	P0=0xff;//消除鬼影
	P2=(P2&0x1f)|0xe0;
	P2=0;

	P0=0x00;
	P2=(P2&0x1f)|0xc0;
	P0=dis_bit[i];
	P2=0;

	P0=0xff;
	P2=(P2&0x1f)|0xe0;
	P0=tab[dis_buf[i]];
	P2=0;
				
	if(++i==8)i=0;

}

iic.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
#define DELAY_TIME	5
sbit sda=P2^1;
sbit scl=P2^0;
//
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 DA_Write(uchar dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}
iic.h
#ifndef _IIC_H
#define _IIC_H


#define uchar unsigned char
#define uint unsigned int

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 DA_Write(uchar dat);
#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值