蓝桥杯单片机第十届省赛题详细讲解

看之前强烈建议先自己做一遍!!!

演示视频

题目讲解

在这里插入图片描述
首先将程序框图的PCF8591(模拟输入和输出),按键,数码管,NE555都先调试好。
在这里插入图片描述
基本要求,将P34和NE555的输出用超声波的跳线帽连接起来。
在这里插入图片描述
按照数码管对应的显示出来就行了,注意频率测量需要只显示使用的。

uchar tab[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf,0x81,0xc1};//f u
uchar SMG[8]={
    
    20,20,20,20,20,20,20,20};//初始显示20,全息数码管
uint high=0,low=0,highdata=0,lowdata=0;//ne555高低时间
uint time;//ne555时间
uchar SMG_mode=0;//控制数码管模式
void main(void)
{
    
    
	init();
	Timer0Init();
	EA=1;ET0=1;
	while(1)
	{
    
    
		if(SMG_mode==0)
		{
    
    
			led &=0xfd;led |=0x01;//L2点亮,L1熄灭
			time=(1000000/((highdata+lowdata)*20));\
			SMG[0]=22;SMG[1]=20;
			if(time<10){
    
    SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[6]=20;
				SMG[7]=time/10;}
			
			else if(time<100){
    
    SMG[2]=SMG[3]=SMG[4]=SMG[5]=20;
				SMG[6]=time%100/10;SMG[7]=time%10;}
			
			else if(time<1000){
    
    SMG[2]=SMG[3]=SMG[4]=20;
				SMG[5]=time%1000/100;
				SMG[6]=time%100/10;SMG[7]=time%10;}
			
			else if(time<10000){
    
    SMG[2]=SMG[3]=20;
			SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
			SMG[6]=time%100/10;SMG[7]=time%10;}
			
			else if(time<100000){
    
    SMG[2]=20;SMG[3]=time/10000;
				SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
				SMG[6]=time%100/10;SMG[7]=time%10;}
		}
		else if(SMG_mode==1)
		{
    
    
			led &=0xfe;led |=0x02;//L1点亮,L2熄灭
			SMG[0]=23;SMG[1]=SMG[2]=SMG[3]=SMG[4]=20;
			move=1.9607*move;//move *(5 /255 *100) 将0-255转换到0-500,便于显示
			if(move<150)led |=0x04;//L3熄灭
			else if(move<250) led &=0xfb;//L3点亮
			else if(move<350)led |=0x04;//L3熄灭
			else led &=0xfb;//L3点亮
			SMG[5]=move/100+10;SMG[6]=move%100/10;SMG[7]=move%10;
			move=IIC_read(PCF8591_address,Move_address);//读取滑动变阻器
//			IIC_write(PCF8591_address,Output_address,move);//输出			
		}
}

然后看按键控制。
在这里插入图片描述
S4:控制电压和频率界面
S5:控制电压输出
S6:LED使能
S7:数码管显示
首先分别建立对应的变量进行控制,然后按照对应的按键补充功能。

void Dkey_scan(void)
{
    
    
	static uchar keybyte=0;
	static uchar key;
	if(((P3&0X0F)!=0X0F)&&(keybyte==0))
	{
    
    
		Delay5ms();
		if((P3&0X0F)!=0X0F)
		{
    
    
			keybyte=1;key=P3&0x0f;
		}
	}
	if((keybyte==1)&&((P3&0X0F)==0X0F))
	{
    
    
		if((P3&0X0F)==0X0F)
		{
    
    
			switch(key)
			{
    
    
				case 0x0e: //S7
					if(SMG_out==0)SMG_out=1;
				else SMG_out=0;
					break;
				case 0x0d: //S6
					if(led_mode==0)led_mode=1;
				else led_mode=0;					
					break;
				case 0x0b: //S5
					if(Output_mode==0)Output_mode=1;
				else Output_mode=0;
					break;
				case 0x07: //S4
					if(SMG_mode==0)SMG_mode=1;
				else SMG_mode=0;
					break;
			}
			keybyte=0;
		}
	}
}
if(Output_mode==0){
    
    IIC_write(PCF8591_address,Output_address,102);
led |=0x10;}//输出2v  模式0
else {
    
    IIC_write(PCF8591_address,Output_address,move);
led &=0xef;}//输出move v  模式1

在这里插入图片描述

在这里插入图片描述
然后就是LED的模式。

if(SMG_mode==0)
{
    
    led &=0xfd;led |=0x01;//L2点亮,L1熄灭}
else if(SMG_mode==1)
{
    
    led &=0xfe;led |=0x02;//L1点亮,L2熄灭}

if(move<150)led |=0x04;//L3熄灭
else if(move<250) led &=0xfb;//L3点亮
else if(move<350)led |=0x04;//L3熄灭
else led &=0xfb;//L3点亮

if(Output_mode==0){
    
    IIC_write(PCF8591_address,Output_address,102);
led |=0x10;}//输出2v  模式0 L1熄灭
else {
    
    IIC_write(PCF8591_address,Output_address,move);
led &=0xef;}//输出move v  模式1 L1亮

if(time<1000)led |=0x08;  //L4熄灭
else if(time<5000)led &=0xf7; //L4点亮
else if(time<10000)led |=0x08; //L4熄灭
else led &=0xf7; //L4点亮

if(led_mode==1){
    
    P2=0X80;P0=led;}
else {
    
    P2=0X80;P0=0xff;}

初始化要求。
在这里插入图片描述

完整程序

main.c

#include<stc15f2k60s2.h>
#include"intrins.h"
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int

#define PCF8591_address 0x90
#define Light_address 0x01
#define Move_address 0x03
#define Output_address 0x40

void SMG_output(void);
void init(void);
void Delay1ms(void);
void Timer0Init(void);
void Dkey_scan(void);
void Delay5ms(void);
uchar tab[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf,0x8e,0xc1};//f u
uchar SMG[8]={
    
    20,20,20,20,20,20,20,20};//初始显示20,全息数码管
uint high=0,low=0,highdata=0,lowdata=0;//ne555高低时间
uint time;//ne555时间
uchar SMG_mode=0;//控制数码管模式
bit Output_mode=0;//控制输出电压
bit led_mode=0;//控制led
bit SMG_out=0;//数码管显示
uint move=0;//pcf8591的滑动变阻器读取值
uchar led=0xff;
void main(void)
{
    
    
	init();
	Timer0Init();
	EA=1;ET0=1;
	while(1)
	{
    
    
		if(SMG_out==1)
		{
    
    
			if(SMG_mode==0)
			{
    
    
				led &=0xfd;led |=0x01;//L2点亮,L1熄灭
				time=(1000000/((highdata+lowdata)*20));\
				SMG[0]=22;SMG[1]=20;
				if(time<10){
    
    SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[6]=20;
					SMG[7]=time/10;}
				
				else if(time<100){
    
    SMG[2]=SMG[3]=SMG[4]=SMG[5]=20;
					SMG[6]=time%100/10;SMG[7]=time%10;}
				
				else if(time<1000){
    
    SMG[2]=SMG[3]=SMG[4]=20;
					SMG[5]=time%1000/100;
					SMG[6]=time%100/10;SMG[7]=time%10;}
				
				else if(time<10000){
    
    SMG[2]=SMG[3]=20;
				SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
				SMG[6]=time%100/10;SMG[7]=time%10;}
				
				else if(time<100000){
    
    SMG[2]=20;SMG[3]=time/10000;
					SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
					SMG[6]=time%100/10;SMG[7]=time%10;}
			}
			else if(SMG_mode==1)
			{
    
    
				led &=0xfe;led |=0x02;//L1点亮,L2熄灭
				SMG[0]=23;SMG[1]=SMG[2]=SMG[3]=SMG[4]=20;
				move=1.9607*move;//move *(5 /255 *100) 将0-255转换到0-500,便于显示
				if(move<150)led |=0x04;//L3熄灭
				else if(move<250) led &=0xfb;//L3点亮
				else if(move<350)led |=0x04;//L3熄灭
				else led &=0xfb;//L3点亮
				SMG[5]=move/100+10;SMG[6]=move%100/10;SMG[7]=move%10;
				move=IIC_read(PCF8591_address,Move_address);//读取滑动变阻器
	//			IIC_write(PCF8591_address,Output_address,move);//输出			
			}
		}
		else if(SMG_out==0)//关闭显示
		{
    
    
			SMG[0]=SMG[1]=SMG[6]=SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[7]=20;//全息
		}
		
		if(Output_mode==0){
    
    IIC_write(PCF8591_address,Output_address,102);
		led |=0x10;}//输出2v  模式0 L1熄灭
		else {
    
    IIC_write(PCF8591_address,Output_address,move);
		led &=0xef;}//输出move v  模式1 L1亮
		
		if(time<1000)led |=0x08;  //L4熄灭
		else if(time<5000)led &=0xf7; //L4点亮
		else if(time<10000)led |=0x08; //L4熄灭
		else led &=0xf7; //L4点亮
		if(led_mode==1){
    
    P2=0X80;P0=led;}
		else {
    
    P2=0X80;P0=0xff;}
		SMG_output();
		Dkey_scan();
	}
}

void Dkey_scan(void)
{
    
    
	static uchar keybyte=0;
	static uchar key;
	if(((P3&0X0F)!=0X0F)&&(keybyte==0))
	{
    
    
		Delay5ms();
		if((P3&0X0F)!=0X0F)
		{
    
    
			keybyte=1;key=P3&0x0f;
		}
	}
	if((keybyte==1)&&((P3&0X0F)==0X0F))
	{
    
    
		if((P3&0X0F)==0X0F)
		{
    
    
			switch(key)
			{
    
    
				case 0x0e: //S7
					if(SMG_out==0)SMG_out=1;
				else SMG_out=0;
					break;
				case 0x0d: //S6
					if(led_mode==0)led_mode=1;
				else led_mode=0;					
					break;
				case 0x0b: //S5
					if(Output_mode==0)Output_mode=1;
				else Output_mode=0;
					break;
				case 0x07: //S4
					if(SMG_mode==0)SMG_mode=1;
				else SMG_mode=0;
					break;
			}
			keybyte=0;
		}
	}
}


void time0() interrupt 1
{
    
    
	if(P34==1)
	{
    
    
		high++;
		if(low !=0)
		{
    
    
			lowdata=low;
			low=0;
		}
	}
	else if(P34==0)
	{
    
    
		low++;
		if(high !=0)
		{
    
    
			highdata=high;
			high=0;
		}
	}	
}

void SMG_output(void)
{
    
    
	uchar i;
	for(i=0;i<8;i++)
	{
    
    
	P2=(P2&0X1F)|0Xc0;
	P0=(1<<i);
	P2=(P2&0X1F)|0Xe0;
	P0=tab[SMG[i]];
	Delay1ms();
	}
	P2=(P2&0X1F)|0Xc0;
	P0=0Xff;
	P2=(P2&0X1F)|0Xe0;
	P0=0Xff;	
}

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



void init(void)
{
    
    
	P2=(P2&0X1F)|0XA0;
	P0=0X00;
	P2=(P2&0X1F)|0X80;
	P0=0Xff;
	P2=(P2&0X1F)|0Xc0;
	P0=0Xff;
	P2=(P2&0X1F)|0Xe0;
	P0=0Xff;	
}

void Delay5ms()		//@11.0592MHz
{
    
    
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
    
    
		while (--j);
	} while (--i);
}


void Delay1ms(void)		//@11.0592MHz
{
    
    
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
    
    
		while (--j);
	} while (--i);
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "stc15f2k60s2.h"
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int

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

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
void IIC_write(uchar hw_address,uchar reg_address,uchar num);
uchar IIC_read(uchar hw_address,uchar reg_address);


#endif

iic.c

#include "iic.h"

#define DELAY_TIME 40

void IIC_write(uchar hw_address,uchar reg_address,uchar num)
{
    
    
	IIC_Start();
	IIC_SendByte(hw_address&0xfe);
	IIC_WaitAck();
	IIC_SendByte(reg_address);
	IIC_WaitAck();
	IIC_SendByte(num);
	IIC_WaitAck();	
	IIC_Stop();	
}	

uchar IIC_read(uchar hw_address,uchar reg_address)
{
    
    
	uchar num;
	IIC_Start();
	IIC_SendByte(hw_address&0xfe);
	IIC_WaitAck();
	IIC_SendByte(reg_address);	
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(hw_address|0x01);
	IIC_WaitAck();
	num=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();	
	
	return num;
}

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

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

工程文件

工程文件

猜你喜欢

转载自blog.csdn.net/darlingqx/article/details/127622699