zl程序教程

您现在的位置是:首页 >  其他

当前栏目

单片机比赛准备05-蓝桥杯-第三届初赛模拟题(模拟传送装置)

模拟单片机 蓝桥 准备 05 比赛 第三届 传送
2023-09-14 09:13:04 时间

iic.h:

#ifndef _IIC_H
#define _IIC_H
#define uchar unsigned char
#define uint unsigned int 
//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
uchar ad_read(uchar add);
void eeprom_write(uchar add,uchar dat);
uchar eeprom_read(uchar add);
#endif

iic.c:

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

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


#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}    


#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */


//总线启动条件
void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(bit ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}
uchar ad_read(uchar add)
{
	uchar temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	
	return temp;
}
void eeprom_write(uchar add,uchar dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
uchar eeprom_read(uchar add)
{
	uchar temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	
	return temp;
}

主函数:

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


uchar seg[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0X82,0XF8,
0X80,0X90,0XFF};//数码管显示值
uchar n;//led的移位状态
uint tim;//定时器计时的值
uint zhong;//重量的值
uchar flag_s=0;//继电器开关标志
uchar fangxiang=0;//灯的方向
uchar yi,er,san,si;//数码管显示位

void allinit();
void Delayms(uint ms);
void display(uchar yi,er,san,si);
void key();
void led_zheng();
void led_fan();
void control();
void Timer0Init(void);
void Timer1Init(void);
void main()
{
	allinit();
	Timer0Init();
	Timer1Init();
	eeprom_write(0x00,0);
	while(1)
	{
		display(yi,er,san,si);
	}
}

void allinit()
{
	P2=0xa0;P0=0x00;//关闭蜂鸣器 继电器
	
	P2=0x80;P0=0xff;//关闭led
	
	P2=0xe0;P0=0xff;//段选
	P2=0xc0;P0=0xff;//位选
}
void display(uchar yi,er,san,si)
{	
	P2=0xe0;P0=0xff;
	P2=0xe0;P0=seg[yi];//段选
	P2=0xc0;P0=0x01;//位选
	Delayms(1);
	
	P2=0xe0;P0=0xff;
	P2=0xe0;P0=seg[er];//段选
	P2=0xc0;P0=0x02;//位选
	Delayms(1);
		
	P2=0xe0;P0=0xff;
	P2=0xe0;P0=seg[san];//段选
	P2=0xc0;P0=0x04;//位选
	Delayms(1);
	
	P2=0xe0;P0=0xff;
	P2=0xe0;P0=seg[si];//段选
	P2=0xc0;P0=0x08;//位选
	Delayms(1);
/*	
	P2=0xe0;P0=seg[wu];//段选
	P2=0xc0;P0=0x10;//位选
	Delayms(2);
	
	P2=0xe0;P0=seg[liu];//段选
	P2=0xc0;P0=0x20;//位选
	Delayms(2);
	
	P2=0xe0;P0=seg[qi];//段选
	P2=0xc0;P0=0x40;//位选
	Delayms(2);
	
	P2=0xe0;P0=seg[ba];//段选
	P2=0xc0;P0=0x80;//位选
	Delayms(2);
*/

}

void key()
{
	if(P30==0)
	{
		Delayms(5);
		if(P30==0)
		{
			flag_s=0;
		}
		while(!P30)
		{
			display(yi,er,san,si);
		};
	}
	
	if(P31==0)
	{
		Delayms(5);
		if(P31==0)
		{
			fangxiang=2;
		}
		while(!P31)
		{
			display(yi,er,san,si);
		};
	}
	
	if(P32==0)
	{
		Delayms(5);
		if(P32==0)
		{
			fangxiang=1;
		}
		while(!P32)
		{
			display(yi,er,san,si);
		};
	}
	
	if(P33==0)
	{
		Delayms(5);
		if(P33==0)
		{
			flag_s=1;
		}
		while(!P33)
		{
			display(yi,er,san,si);
		};
	}
}

void led_zheng()
{
	P2=0x80;
	P0=~(1<<n);
	n++;
	if(n==8)n=0;
}

void led_fan()
{
	P2=0x80;
	P0=~(0x80>>(8-n));
	n--;
	if(n==0)n=8;
}
void control()
{
	P2=0xa0;P0=0x00;//关闭蜂鸣器 继电器
	P2=0x80;P0=0xff;//关闭led
	P2=0xe0;P0=0xff;//段选
	P2=0xc0;P0=0xff;//位选
	if(zhong>750)
	{
		P2=0xa0;P0=0x40;//关闭蜂鸣器 继电器
		P2=0x80;P0=0xff;//关闭led
	}
	else if(flag_s==1)
	{
		P2=0xa0;P0=0x10;
		if(fangxiang==1)
			led_zheng();
		else if(fangxiang==2)
			led_fan();
		else
		{
			P2=0xa0;P0=0x10;
			P2=0x80;P0=0xff;
		}
	}
	else 
	{
		fangxiang=0;
		n=0;
		P2=0xa0;P0=0x00;//关闭蜂鸣器 继电器
		P2=0x80;P0=0xff;//关闭led
	}
	
}
void Delayms(uint ms)		//@11.0592MHz
{
	unsigned char i, j,k;
	for(k=ms;k>0;k--)
	{
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
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 Timer1Init(void)		//1微秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;
	ET1=1;
}
void timer1(void) interrupt 3
{
	uchar add=0x00;
	uchar temp;
	if(zhong>750)
	{
		temp=eeprom_read(add);
		if(zhong!=temp)
		{
			eeprom_write(add,zhong);
			add++;
		}
	}
}
void timer0(void) interrupt 1
{
	tim++;
	key();
	zhong=(uint)(ad_read(0x03)/255.0*1000);
	yi=zhong/1000;
	er=zhong/100%10;
	san=zhong/10%10;
	si=zhong%10;
	if(tim==200)
	{
		tim=0;
		control();
	}
}