第六届蓝桥杯国赛——智能物料传送系统

功能基本完全

main.c:

​
#include <STC15F2K60S2.H>
#include "iic.h"
#include "distance.h"
#define uchar unsigned char
#define uint unsigned int
uchar code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

uchar code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
uchar num[8]={16,16,16,16,16,16,16,16};
uint u,distance,time1=2,time2=4,time,distance;
uchar trg,cont;
uchar load_flag,stuff_type,set_flag=0;
bit read_flag,flag_500ms,send_flag,sending_flag,key_flag,stop_flag;
sbit relay=P0^4;
sbit buzzer=P0^6;
void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}
void init()
{
	P2=0xa0;P0=0x00;
	P2=0xc0;P0=0xff;
	P2=0xe0;P0=0xff;
	P2=0x80;P0=0xff;
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}
void time0() interrupt 1
{
	static uint i,display_count,read_count,count_500ms,count_1s,key_count;
	if(++display_count==2)
	{
		display_count=0;
		P2=0xc0;P0=0x00;
		P2=0xe0;P0=~t_display[num[i]];
		P2=0xc0;P0=T_COM[i];
		if(++i==8)	i=0;
	}
	if(++read_count==10)
	{
		read_count=0;
		read_flag=1;
	}
	if(++key_count==10)
	{
		key_count=0;
		key_flag=1;
	}

	if(++count_500ms==500)
	{
		count_500ms=0;
		flag_500ms=~flag_500ms;
	}

	if(send_flag==1&&stop_flag==0)
	{
		if(++count_1s==1000)
		{
			count_1s=0;
			time--;
			if(time==0)
			{
				 send_flag=0;
				 P2=0xa0;P0=0x00;P2=0x00;//关继电器
			}
		}
	}
}

void data_read()
{
	if(send_flag==0&&stop_flag==0)
	{
		u=ad_get()*1.00/255*500;
		if(u>0&&u<100)
			load_flag=0;
		else if(u>=100&&u<400)
			load_flag=1;
		else if(u>=400)
			load_flag=2;
	
		distance=rec_ware();
		if(distance<=30)
		{
			stuff_type=1;
			time=time1;
		}	
		else if(distance>30)
		{
			stuff_type=2;
			time=time2;
		}
			
	}
	

		
}

void display()
{
	if(send_flag==0&&stop_flag==0&&set_flag==0)
	{
	   	if(load_flag!=0)
		{
	//		num[0]=u/100;
	//		num[1]=u%100/10;
	//		num[2]=u%10;
			num[0]=1;
			num[1]=16;
			num[2]=16;
			num[3]=distance%100/10;
			num[4]=distance%10;
			num[5]=16;
			num[6]=16;
			num[7]=stuff_type;
		}
		if(load_flag==0)
		{
			num[0]=16;
			num[1]=16;
			num[2]=16;
			num[3]=16;
			num[4]=16;
			num[5]=16;
			num[6]=16;
			num[7]=16;	
		}
	}
	if((send_flag==1||stop_flag==1)&&set_flag==0)
	{
		num[0]=2;
		num[1]=16;
		num[2]=16;
		num[3]=16;
		num[4]=16;
		num[5]=16;
		num[6]=time/10;
		num[7]=time%10;
	}
	if(set_flag==1)
	{
		num[0]=3;
		num[1]=16;
		num[2]=16;
		if(flag_500ms)
		{
			num[3]=time1/10;
			num[4]=time1%10;	
		}
		else
		{
			num[3]=16;
			num[4]=16;
		}
		num[5]=16;
		num[6]=time2/10;
		num[7]=time2%10;
	}
	else if(set_flag==2)
	{
		num[0]=3;
		num[1]=16;
		num[2]=16;
		num[3]=time1/10;
		num[4]=time1%10;
		num[5]=16;
		if(flag_500ms)
		{
			num[6]=time2/10;
			num[7]=time2%10;	
		}
		else
		{
			num[6]=16;
			num[7]=16;
		}	
	}

}
void LED_relay_buzzer()
{
	if(u>0&&u<100)
	{
		P2=0x80;P0=0xfe;P2=0x00;
	}
		
	else if(u>=100&&u<400)
	{
		P2=0x80;P0=0xfd;P2=0x00;
	}	
	else if(u>=400)
	{
		if(flag_500ms)
		{
			P2=0x80;P0=0xfb;P2=0x00;
		}
		else
		{
			P2=0x80;P0=0xff;P2=0x00;	
		}
	}

	if(stop_flag==1)
	{
		if(flag_500ms)
		{
			P2=0x80;P0=P0&0xf7;P2=0x00;
		}
		if(!flag_500ms)
		{
			P2=0x80;P0=P0&0xff;P2=0x00;
		}
	}

	if(send_flag!=1)
	{
		if(u>=400)
		{
			P2=0xa0;buzzer=1;relay=0;P2=0x00;     //过载 开蜂鸣器
		}
		else
			P2=0xa0;P0=0x00;P2=0x00;	
	}


}

void key_scan()
{
	uchar readdata=P3^0xff;
	trg=readdata&(readdata^cont);
	cont=readdata;
}
void key_func()
{
	switch(trg)
	{
		case 0x08:          //启动传送
			if(load_flag==1&&send_flag!=1)
			{
				send_flag=1;
				P2=0xa0;relay=1;buzzer=0;P2=0x00;   //开继电器
			}
			break;
		case 0x04:           //紧急停止
			if(send_flag==1&&stop_flag==0)
			{
				send_flag=0;
				stop_flag=1;
				P2=0xa0;P0=0x00;P2=0x00;   //关继电器
			}
			else if(send_flag==0&&stop_flag==1)
			{
				stop_flag=0;
				send_flag=1;
				P2=0xa0;relay=1;buzzer=0;P2=0x00;   //开继电器
			}
			break;
		case 0x02:	          //设置
			if(load_flag==0)
			{
				if(++set_flag==3)
				{
					set_flag=0;
				}	
			}
			break;
		case 0x01:                  //time+1
			if(load_flag==0)
			{
				if(set_flag==1)
					if(++time1==11)
						time1=1;
				if(set_flag==2)
					if(++time2==11)
						time2=1;
				write_24C02(1,time1);
				Delay10ms();
				write_24C02(2,time2);
				Delay10ms();
			}break;
		default:
			break;
	}
}
void init_24c02()
{
	if(read_24C02(0)==10)     //不是第一次上电
	{
		time1=read_24C02(1);
		time2=read_24C02(2);
	}
	else
	{
		write_24C02(0,10);
		Delay10ms();
		write_24C02(1,time1);
		Delay10ms();
		write_24C02(2,time2);
		Delay10ms();
	}
}
void main()
{
	init();
	init_24c02();
	init_pcf8591(0x03);
	Timer0Init();
	while(1)
	{
		if(key_flag)
		{
			key_flag=0;
			key_scan();
			key_func();
		}
		if(read_flag==1)
		{
			read_flag=0;
			data_read();
			display();
			LED_relay_buzzer();
		}
	}
}

​

iic.c:

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include "reg52.h"
#include "intrins.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);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    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;
}

//通过I2C总线发送数据
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;  
}

//从I2C总线上接收数据
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;    
}
void init_pcf8591(unsigned char add)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();	
}
unsigned char ad_get()
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return temp;
}
void write_24C02(unsigned char add, unsigned char dat)
{
    IIC_Start();
    IIC_SendByte(SlaveAddrW);
    IIC_WaitAck();
    IIC_SendByte(add); 
    IIC_WaitAck();
    IIC_SendByte(dat); 
    IIC_WaitAck();
    IIC_Stop();
}


unsigned char read_24C02(unsigned char add)
{
    unsigned char temp;
    IIC_Start();
    IIC_SendByte(SlaveAddrW); 
    IIC_WaitAck();
    IIC_SendByte(add); 
    IIC_WaitAck();

    IIC_Start();
    IIC_SendByte(SlaveAddrR); 
    IIC_WaitAck();
    temp = IIC_RecByte(); 
    IIC_Stop();
    return temp; 
}

distance.c:

#include <STC15F2K60S2.H>
#include <intrins.h>

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}

void send_ware(void)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		P10=1;
		Delay12us();
		P10=0;
		Delay12us();
	}
}

unsigned int rec_ware()
{
	unsigned int time,distance;
	send_ware();
	TR1=1;
	while((TF1==0)&&(P11==1));
	TR1=0;
	
	if(TF1==1)
	{
		TF1=0;
		distance=999;
	}
	else
	{
		time=(TH1<<8)|TL1;
		distance=(unsigned int)(time*0.017);
	}
	TH1=0x00;
	TL1=0x00;
	
	return distance;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值