话不多说,我们一起来看看第十届(2019)的题目吧。

题目

 这次的题目还是三大模块(数码管、LED、按键),还用到了ADC、DAC、NE555,除了NE555之前没有见过,其他也都是一些常见的外设,只要平常都练习过,也就不难,最重要的还是编程逻辑。 

1 数码管显示

数码管有电压测量界面和频率测量界面。

2 LED

界面为电压测量界面L1亮,频率测量界面L2亮,电压在[1.5,2.5)或者>=3.5V时L3亮,频率在[1k,5k)或者>=10k时L4亮,当输出固定电压时L5灭,否则L5亮。

3 按键模块

使用的是独立按键,s4是电压测量界面和频率测量界面的切换,s5是DAC固定输出电压或者DAC输出随电压器输出电压变化而变化,s6是LED的开关,s7是数码管显示的开关。

4 NE555

NE555就是使用两个定时器,一个用来计数,一个用来定时。其中定时1ms看计数记录了多少,转动RB3,频率会改变。

5 ADC

就是改写底层驱动代码部分(IIC)。

6 DAC

就是改写底层驱动代码部分(IIC)。

IIC.c

#include"IIC.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    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;
}

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

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

unsigned char Read_AD()
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(0x03);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	
	return temp;
}

void DA_out(unsigned char date)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

IIC.h

#ifndef _IIC_H_
#define _IIC_H_

#include<stc15f2k60s2.h>
#include<intrins.h>

void IIC_Delay(unsigned char i);
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
unsigned char Read_AD();
void DA_out(unsigned char date);

#endif

init.c

#include"init.h"

#define u8 unsigned char
#define u16 unsigned int
#define state_0 0
#define state_1 1
#define state_2 2

static u8 key_state,key_num,key_press,segadder;
u8 value=0;
extern bit mode,tube;
extern u8 a;

u8 code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc1,0xce};
u8 seg[]={11,11,11,11,11,11,11,11};

void all_init()  //关闭无关外设
{
	P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;
	
	P2=(P2&0x1f)|0xa0;P04=0;P06=0;P2&=0x1f;
	
	P2=(P2&0x1f)|0xc0;P0=0x00;P2&=0x1f;
	
	P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f;
}

void display()   //数码管显示函数
{
	P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f;
	
	P2=(P2&0x1f)|0xc0;P0=1<<segadder;P2&=0x1f;
	
	P2=(P2&0x1f)|0xe0;
	if((a==1||mode==0)&&segadder==5&&tube==1)
		P0=tab[seg[segadder]]&0x7f;
	else
		P0=tab[seg[segadder]];
	P2&=0x1f;
	
	if(++segadder==8)segadder=0;
}

u8 Read_key()   //独立键盘
{
	key_press=P3&0x0f;
	switch(key_state)
	{
		case state_0:
			if(key_press!=0x0f)
				key_state=state_1;
		break;
		case state_1:
			if(key_press!=0x0f)
			{
				if((key_press & 0x08)==0) key_num=4;
				if((key_press & 0x04)==0) key_num=5;
				if((key_press & 0x02)==0) key_num=6;
				if((key_press & 0x01)==0) key_num=7;
				key_state=state_2;
			}
			else
				key_state=state_0;
		break;
		case state_2:
			if(key_press==0x0f)
				key_state=state_0;
		break;
	}
	value=key_num;
	key_num=0;
	return value;
}

void Timer1Init(void)		//定时器1定时1ms
{
	AUXR |= 0x40;		
	TMOD &= 0x0F;	
	TL1 = 0xCD;	
	TH1 = 0xD4;	
	TF1 = 0;		
	TR1 = 1;
  EA = 1;
  ET1 = 1;	
}

void Timer0Init(void)  //定时器0 调到计数模式
{
		TMOD = 0x04;    
		TL0 = 0;
		TH0 = 0;
		TF0 = 0;
		TR0 = 1;
		ET0 = 1;
}

init.h

#ifndef _INIT_H_
#define _INIT_H_

#include<stc15f2k60s2.h>

void all_init();
void display();
unsigned char Read_key();
void Timer1Init(void);
void Timer0Init(void);


#endif

jm.c

#include"jm.h"

#define u8 unsigned char
#define u16 unsigned int
	
extern bit mode,v,led,tube;    // extern表示此变量是在别处定义的,要在此处引用
extern u8 seg[];
extern u16 F,RB2;

void jm4()
{
	if(mode==0)
		jm5();    //电压测量界面
	else          //频率测量界面
	{
		seg[0]=13;
		seg[1]=11;
		seg[2]=11;
		if(F/10000!=0)
		{
			seg[3]=F/10000;
			seg[4]=F/1000%10;
			seg[5]=F/100%10;
			seg[6]=F/10%10;
			seg[7]=F%10;
		}
		else if(F/1000!=0)     
		{
			seg[3]=11;       //未使用到的数码管熄灭
			seg[4]=F/1000;
			seg[5]=F/100%10;
			seg[6]=F/10%10;
			seg[7]=F%10;
		}
		else if(F/100!=0)
		{
			seg[3]=11;
			seg[4]=11;
			seg[5]=F/100;
			seg[6]=F/10%10;
			seg[7]=F%10;
		}
		else
		{
			seg[3]=11;
			seg[4]=11;
			seg[5]=11;
			seg[6]=F/10;
			seg[7]=F%10;
		}
	}
}

void jm5()
{
	if(v==0)
	{
		seg[0]=12;
		seg[1]=11;
		seg[2]=11;
		seg[3]=11;
		seg[4]=11;
		seg[5]=2;
		seg[6]=0;
		seg[7]=0;
	}
	else if(v==1)
	{
		seg[0]=12;
		seg[1]=11;
		seg[2]=11;
		seg[3]=11;
		seg[4]=11;
		seg[5]=RB2/100;
		seg[6]=RB2/10%10;
		seg[7]=RB2%10;
	}
}

void jm6()   //LED函数
{
	u8 i=0xff;
	if(led==1)
	{
		if(mode==0)
		{
			P2=(P2&0x1f)|0x80;P0=0xfe;P2&=0x1f;
		}
		else
		{
			P2=(P2&0x1f)|0x80;P0=0xfd;P2&=0x1f;
		}
		if((RB2>=150&&RB2<250)||(RB2>350))
		{
			P2=(P2&0x1f)|0x80;P02=0;P2&=0x1f;
		}
		else
		{
			P2=(P2&0x1f)|0x80;P02=1;P2&=0x1f;
		}
		if((F>=1000&&F<5000)||(F>=10000))
		{
			P2=(P2&0x1f)|0x80;P03=0;P2&=0x1f;
		}
		else
		{
			P2=(P2&0x1f)|0x80;P03=1;P2&=0x1f;
		}
		if(v==1)
		{
			P2=(P2&0x1f)|0x80;P04=0;P2&=0x1f;
		}
		else
		{
			P2=(P2&0x1f)|0x80;P04=1;P2&=0x1f;
		}
	}
	else
	{
		P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;
	}
}

void jm7()    //数码管开关函数
{
	if(tube==0)
	{
		seg[0]=11;
		seg[1]=11;
		seg[2]=11;
		seg[3]=11;
		seg[4]=11;
		seg[5]=11;
		seg[6]=11;
		seg[7]=11;
	}
	else
		jm4();
}

jm.h

#ifndef _JM_H_
#define _JM_H_

#include<stc15f2k60s2.h>

void jm4();
void jm5();
void jm6();
void jm7();

#endif

main.c

#include"init.h"
#include"IIC.h"
#include"jm.h"

#define u8 unsigned char
#define u16 unsigned int
	
u8 num=0,a=0,b=0;
u16 RB2_count=0,F_count=0,F=0,RB2=0;
bit mode=0,v=0,led=1,tube=1,F_flag=0,RB2_flag=0;

void main()
{
	all_init();
	Timer1Init();
	Timer0Init();
	while(1)
	{
		num=Read_key();
		switch(num)
		{
			case 4:
				mode^=1;
			  a=0;
			break;
			case 5:
				v^=1;
				a=1;
			break;
			case 6:
				led^=1;
			  b=0;
			break;
			case 7:
				tube^=1;
			jm7();
			break;
		}
		if(a==0&&tube==1)jm4();
		if(a==1&&tube==1)jm5();
		if(b==0)jm6();
		if(F_flag==1)    //计算频率
		{
			F_flag=0;	
			TR0=0;
			F=TH0*256+TL0;
			TL0=0;
			TH0=0;
			TR0=1;
		}
		if(RB2_flag==1)
		{
			RB2_flag=0;
			RB2=Read_AD();
			if(v==0)DA_out(102.4);   //DAC输出
			else DA_out(RB2);		
			RB2=(RB2*100)/51.0+0.5;
		}
	}
}

void Timer1() interrupt 3
{
	display();
	if(++RB2_count==500)
	{
		RB2_count=0;
		RB2_flag=1;
	}
	if(++F_count==1000)
	{
		F_count=0;
		F_flag=1;
	}
}

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐