蓝桥杯单片机第十三届国赛

目录

main.c

iic.c

iic.h


第十三届国赛有难度,重难点就是定时器冲突,而且非常矛盾,用多了变量在定时器中断里面也会出错,频率测量,超声波,pwm波,当然数码管也可以动态扫描,而常用的定时器只有0、1、2,所以要合理的分配定时器。

首先看一下题目中的N-MOTOR电机驱动(输出pwm波)在哪:

如上图,J3排针第六个,其引脚为573的out6,也就是0x20;

接下来主程序:

main.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
sbit TX=P1^0;
sbit RX=P1^1;
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,0x8e,0x89,0x88,0x8c};
code uchar dis_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar dis_buf[]={11,11,11,11,11,11,11,11};
uint freq;
uchar para_freq=90;//后面×100再比较
uchar jiemian;
uchar para;
uchar shidu;
uchar para_shidu=40;
uint distance;
uint i;
uchar para_distance=6;//后面×10再比较
uchar count;
uchar dis_count=0;
bit f_flag=0;
bit d_flag=0;
bit cm=0;
bit hz=0;
bit led_flag;
bit count_flag=0;
bit k1_flag;
uint Newzheng,Newfan,fan,zheng,time,intr;
bit pwm_flag;
void Allinit(void);
void display(void);
void Delayms(uint ms);
void display_jiemian(void);
void keyscan(void);
void Timer0Init(void);
void Timer1Init(void);
void sonic(void);
void send_wave(void);
void led_kz(void);
void pwm(void);
void DA_output(void);
void jdq_kz(void);
void Timer2Init(void);
void main(void)
{
	Allinit();
	Timer0Init();
	Timer1Init();
	Timer2Init();
	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)
	{
		shidu=AD_Read(0x03)*0.39;
		keyscan();
		DA_output();
		led_kz();
		jdq_kz();
		pwm();
		display_jiemian();
		display();
	}
}

void display_jiemian(void)
{
	if(jiemian==0)//频率界面显示
	{
		if(freq>99&&hz==0)
		{
			dis_buf[0]=22;dis_buf[1]=21;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>99&&hz==1)
		{
			dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
			dis_buf[5]=21;dis_buf[6]=freq/1000+10;dis_buf[7]=freq%1000/100;
		}
		if(freq>999&&hz==0)
		{
			dis_buf[0]=22;dis_buf[1]=21;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>999&&hz==1)
		{
			dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;
			dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=freq/1000+10;dis_buf[7]=freq%1000/100;
		}
		if(freq>9999&&hz==0)
		{
			dis_buf[0]=22;dis_buf[1]=21;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>9999&&hz==1)
		{
			dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;
			dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=freq/10000;dis_buf[6]=freq%10000/1000+10;dis_buf[7]=freq%1000/100;
		}
	}
	else if(jiemian==1)
	{
		dis_buf[0]=23;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
		dis_buf[6]=shidu/10;dis_buf[7]=shidu%10;
	}
	else if(jiemian==2)
	{
		sonic();
		if(cm==0)//cm
		{
			dis_buf[0]=24;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=count;dis_buf[4]=21;dis_buf[5]=21;
			dis_buf[6]=distance/10;dis_buf[7]=distance%10;
		}
		if(cm==1)//m
		{
			dis_buf[0]=24;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
			dis_buf[5]=distance/100+10;dis_buf[6]=distance%100/10;dis_buf[7]=distance%10;
		}
		
	}
	else if(jiemian==3)
	{
		if(para==0)
		{
			if(para_freq>99)
			{
				dis_buf[0]=25;dis_buf[1]=1;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
				dis_buf[5]=para_freq/100;dis_buf[6]=para_freq%100/10+10;dis_buf[7]=para_freq%10;
			}
			if(para_freq>9)
			{
				dis_buf[0]=25;dis_buf[1]=1;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
				dis_buf[6]=para_freq/10+10;dis_buf[7]=para_freq%10;
			}
			
		}
		else if(para==1)
		{
			dis_buf[0]=25;dis_buf[1]=2;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
			dis_buf[6]=para_shidu/10;dis_buf[7]=para_shidu%10;
		}
		else if(para==2)
		{
			dis_buf[0]=25;dis_buf[1]=3;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
			dis_buf[6]=para_distance/10+10;dis_buf[7]=para_distance%10;
		}
	}
}

void DA_output(void)
{
	if(shidu<=para_shidu)
	{
		DA_Write(51);
	}
	else if(shidu>para_shidu&&shidu<80)
	{
		DA_Write((5+((4/(80-para_shidu))*(shidu-80))*51));
	}
	else if(shidu>=80)
	{
		DA_Write(255);
	}
}

void jdq_kz(void)
{
	P0=0xff;
	if(distance>para_distance*10)
	{
		P2=(P2&0x1f)|0xa0;
		P0=0x10;P2=0;
		if(count_flag==0)
		{
			count_flag=1;
			count++;
			EEPROM_Write(0x00,count);
			Delayms(5);
		}
	}
	else
	{
		P2=(P2&0x1f)|0xa0;
		P0=0x00;P2=0;
		count_flag=0;
	}
}

void pwm(void)
{
	if(freq>para_freq*100)
	{
		pwm_flag=1;
	}
	else
	{
		pwm_flag=0;
	}
}

void led_kz(void)
{
	P0=0xff;
	if(led_flag==0)
	{
		if(jiemian==0)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfe;P2=0;
		}
		else if(jiemian==1)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfd;P2=0;
		}
		else if(jiemian==2)
		{
			P2=(P2&0x1f)|0x80;
			P0=P0&0xfb;P2=0;
		}
	}
	else if(led_flag==1)
	{
		if(jiemian==0)
		{
			P2=(P2&0x1f)|0x80;
			P0=(P0|~0xfe);P2=0;
		}
		else if(jiemian==1)
		{
			P2=(P2&0x1f)|0x80;
			P0=(P0|~0xfd);P2=0;
		}
		else if(jiemian==2)
		{
			P2=(P2&0x1f)|0x80;
			P0=(P0|~0xfb);P2=0;
		}
	}
	if(jiemian==3)
	{
		P2=(P2&0x1f)|0x80;
		P0=0xff;
	}
	if(freq>para_freq*100)
	{
		P2=(P2&0x1f)|0x80;
		P0=P0&0xf7;P2=0;
	}
	else
	{
		P2=(P2&0x1f)|0x80;
		P0=(P0|~0xf7);P2=0;
	}
	if(shidu>para_shidu)
	{
		P2=(P2&0x1f)|0x80;
		P0=P0&0xef;P2=0;
	}
	else
	{
		P2=(P2&0x1f)|0x80;
		P0=(P0|~0xef);P2=0;
	}
	if(distance>para_distance*10)
	{
		P2=(P2&0x1f)|0x80;
		P0=P0&0xbf;P2=0;
	}
	else
	{
		P2=(P2&0x1f)|0x80;
		P0=(P0|~0xbf);P2=0;
	}
}

void keyscan(void)
{
	if(P30==0)//s7
	{
		Delayms(10);
		if(P30==0)
		{
			if(jiemian==3)
			{
				if(para==0)//khz
				{
					para_freq-=5;
					if(para_freq==5)
					{
						para_freq=120;
					}
				}
				else if(para==1)
				{
					para_shidu-=10;
					if(para_shidu==0)
					{
						para_shidu=60;
					}
				}
				else if(para==2)//m
				{
					para_distance-=1;
					if(para_distance==0)
					{
						para_distance=12;
					}
				}
			}
			else if(jiemian==1)
			{
				if(k1_flag==0)
				{
					intr=0;
					k1_flag=1;
				}
				
			}
			else if(jiemian==0)
			{
				hz=~hz;
			}
		}
		while(P30==0){led_kz();display();}
	}
	if(P30==1)
	{
		k1_flag=0;
	}
	if(P31==0)//s6
	{
		Delayms(10);
		if(P31==0)
		{
			if(jiemian==3)
			{
				if(para==0)//khz
				{
					para_freq+=5;
					if(para_freq==125)
					{
						para_freq=10;
					}
				}
				else if(para==1)
				{
					para_shidu+=10;
					if(para_shidu==70)
					{
						para_shidu=10;
					}
				}
				else if(para==2)//m
				{
					para_distance+=1;
					if(para_distance==13)
					{
						para_distance=1;
					}
				}
			}
			else if(jiemian==2)
			{
				cm=~cm;
			}
		}
		while(P31==0);
	}
	if(P32==0)
	{
		Delayms(10);
		if(P32==0)
		{
			if(para==0)
			{
				para=1;
			}
			else if(para==1)
			{
				para=2;
			}
			else if(para==2)
			{
				para=0;
			}
		}
		while(P32==0);
	}
	if(P33==0)
	{
		Delayms(10);
		if(P33==0)
		{
			if(jiemian==0)
			{
				jiemian=1;intr=0;
			}
			else if(jiemian==1)
			{
				jiemian=2;intr=0;
			}
			else if(jiemian==2)
			{
				jiemian=3;para=0;intr=0;
			}
			else if(jiemian==3)
			{
				jiemian=0;intr=0;
			}
		}
		while(P33==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
{
	if(jiemian==0)
	{
		intr++;
		if(intr==100)
		{
			led_flag=~led_flag;
		}
		else if(intr==200)
		{
			led_flag=~led_flag;
		}
		else if(intr==300)
		{
			led_flag=~led_flag;
		}
		else if(intr==400)
		{
			led_flag=~led_flag;
		}
		else if(intr==500)
		{
			led_flag=~led_flag;
		}
		else if(intr==600)
		{
			led_flag=~led_flag;
		}
		else if(intr==700)
		{
			led_flag=~led_flag;
		}
		else if(intr==800)
		{
			led_flag=~led_flag;
		}
		else if(intr==900)
		{
			led_flag=~led_flag;
		}
		else if(intr==969)
		{
			AUXR |= 0x10;
		}
		else if(intr==999)
		{
			AUXR &= ~0x10;
			intr=0;
			led_flag=~led_flag;
			time=(Newzheng+Newfan)*5;
			freq=1000000/time;
		}
	}
	else if(jiemian==2)//超声
	{
		intr++;
		if(intr==100)
		{
			led_flag=~led_flag;
		}
		else if(intr==200)
		{
			led_flag=~led_flag;
		}
		else if(intr==300)
		{
			led_flag=~led_flag;
		}
		else if(intr==400)
		{
			led_flag=~led_flag;
		}
		else if(intr==500)
		{
			led_flag=~led_flag;
		}
		else if(intr==600)
		{
			intr=0;
			d_flag=1;
			led_flag=~led_flag;
		}
	}
	else if(jiemian==1)
	{
		intr++;
		if(intr==100)
		{
			led_flag=~led_flag;
		}
		else if(intr==200)
		{
			led_flag=~led_flag;
		}
		else if(intr==300)
		{
			led_flag=~led_flag;
		}
		else if(intr==400)
		{
			led_flag=~led_flag;
		}
		else if(intr==500)
		{
			led_flag=~led_flag;
		}
		else if(intr==600)
		{
			led_flag=~led_flag;
		}
		else if(intr==700)
		{
			led_flag=~led_flag;
		}
		else if(intr==800)
		{
			led_flag=~led_flag;
		}
		else if(intr==900)
		{
			led_flag=~led_flag;
		}
		else if(intr==1000)
		{
			led_flag=~led_flag;
			intr=0;
			if(k1_flag==1)count=0;
		}
	}
	if(pwm_flag==1)
	{
		intr++;
		if(intr<200)
		{
			P2=(P2&0x1f)|0xa0;
			P0=P0&0x20;P2=0;
		}
		else if(intr>=200&&intr<1000)
		{
			intr=0;
			P2=(P2&0x1f)|0xa0;
			P0=(P0|~0x20);P2=0;
		}
	}
}

void Timer1Init(void)		//5微秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
}

void tim2(void) interrupt 12
{
	if(jiemian==0)
	{
		if(P34==0)
		{
			fan++;
			if(f_flag==1)
			{
				f_flag=0;
				Newfan=fan;
				fan=0;
			}
		}
		else if(P34==1)
		{
			zheng++;
			if(f_flag==0)
			{
				f_flag=1;
				Newzheng=zheng;
				zheng=0;
			}
		}
	}
}
void Timer2Init(void)		//5u秒@11.0592MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xFB;		//设置定时初值
	T2H = 0xFF;
	IE2 |= 0x04;
	EA=1;
}

void sonic(void)
{
	uint t;
	if(d_flag==1)
	{
		dis_count++;
		d_flag=0;
		send_wave();
		TR1=0;
		while(TF1==0&&RX==0);
		TR1=1;
		while(TF1==0&&RX==1);
		TR1=0;
		if(TF1==1)
		{
			TF1=0;
		}
		else if(TF1==0)
		{
			t=TH1;
			t<<=8;
			t|=TL1;
			distance=(uint)t*0.017;
			distance/=12;
			if(dis_count==1)
			{
				distance=0;
			}
		}
		TH1=0;
		TL1=0;
	}

	
}

void send_wave(void)
{
	uchar n=8;
	do
	{
		TX=1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		TX=0;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	}
	while(n--);
}

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

void display(void)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		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;
		
		Delayms(1);
		
		P2=(P2&0x1f)|0xe0;
		P0=0xff;P2=0;
	}
}

void Delayms(uint ms)
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=845;j>0;j--);
}
iic.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
sbit sda=P2^1;
sbit scl=P2^0;
#define DELAY_TIME	10

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

uchar AD_Read(uchar add)
{
	uchar temp;
	
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	
	return temp;
}

void DA_Write(uchar dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

void EEPROM_Write(uchar add,uchar dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(add);
	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 I2CWaitAck(void);
unsigned char I2CReceiveByte(void);
uchar AD_Read(uchar add);
void DA_Write(uchar dat);
void EEPROM_Write(uchar add,uchar dat);

#endif
	

 以上就是全部内容,其中超声波有一点问题,就是第一次读取的时候值会跳很大,我这里是固定了92,所以我写了一个do{}while,更好的方法还没有找到。欢迎大佬指点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值