单片机比赛准备05-蓝桥杯-第三届初赛模拟题
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();
}
}