蓝桥杯第十届省赛真题答案
频率和电压的采集
目录
main.c
#include "stc15f2k60s2.h"
#include "iic.h"
#include "intrins.h"
typedef unsigned int u16;
typedef unsigned char u8;
/******IO口管脚定义******/
sbit key4=P3^3;
sbit key5=P3^2;
sbit key6=P3^1;
sbit key7=P3^0;
/******全局变量定义******/
int pinlv,jishu,time;
int dianya;
bit jianmian=0;
bit moshi=0;
bit LEDgongneng=0;
bit shumaguangongneng=0;
/********************************************************
函数名:Delaynus(u16 i) //@12.000MHz
功能:延时n个微秒
输入:无
输出:无
作者:张鹤
*********************************************************/
void Delaynus(u16 i) //@12.000MHz
{
while(i--)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/********************************************************
函数名:key()
功能:独立按键扫描函数
输入:无
输出:无
作者:张鹤
*********************************************************/
void key()
{
if(key4==0)
{
jianmian=~jianmian;
}
if(key5==0)
{
moshi=~moshi;
}
if(key6==0)
{
LEDgongneng=~LEDgongneng;
}
if(key7==0)
{
shumaguangongneng=~shumaguangongneng;
}
while(!(key4==1&&key5==1&&key6==1&&key7==1));//按键释放检查
}
/********************************************************
模块:数码管显示操作(包含了开关LDE和数码管功能函数)
功能:数码管显示相应的数据
输入:无
输出:无
作者:张鹤
*********************************************************/
u8 code sumaduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
u8 display[8];
void digital()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i)
{
case 0:
P0=0X01;P2=(P2&0X1F)|0XC0;break;
case 1:
P0=0X02;P2=(P2&0X1F)|0XC0;break;
case 2:
P0=0X04;P2=(P2&0X1F)|0XC0;break;
case 3:
P0=0X08;P2=(P2&0X1F)|0XC0;break;
case 4:
P0=0X10;P2=(P2&0X1F)|0XC0;break;
case 5:
P0=0X20;P2=(P2&0X1F)|0XC0;break;
case 6:
P0=0X40;P2=(P2&0X1F)|0XC0;break;
case 7:
P0=0X80;P2=(P2&0X1F)|0XC0;break;
}
P2&=0X1F;
P0=display[i];
P2=(P2&0X1F)|0XE0;
Delaynus(80);
P0=0XFF;
P2&=0X1F;
}
}
void pinlvdisplay()
{
display[0]=0x8e;
display[1]=0xff;
display[2]=0xff;
if(pinlv>=10000)
{
display[3]=sumaduan[pinlv/10000];
display[4]=sumaduan[pinlv%10000/1000];
display[5]=sumaduan[pinlv%1000/100];
display[6]=sumaduan[pinlv%100/10];
display[7]=sumaduan[pinlv%10];
digital();
}
if(pinlv>=1000&&pinlv<10000)
{
display[3]=0xff;
display[4]=sumaduan[pinlv%10000/1000];
display[5]=sumaduan[pinlv%1000/100];
display[6]=sumaduan[pinlv%100/10];
display[7]=sumaduan[pinlv%10];
digital();
}
if(pinlv>=100&&pinlv<1000)
{
display[3]=0xff;
display[4]=0xff;
display[5]=sumaduan[pinlv%1000/100];
display[6]=sumaduan[pinlv%100/10];
display[7]=sumaduan[pinlv%10];
digital();
}
if(pinlv>=10&&pinlv<100)
{
display[3]=0xff;
display[4]=0xff;
display[5]=0xff;
display[6]=sumaduan[pinlv%100/10];
display[7]=sumaduan[pinlv%10];
digital();
}
}
//void ceshipinlv()
//{
// display[0]=sumaduan[pinlv/10000];
// display[1]=sumaduan[pinlv%10000/1000];
// display[2]=sumaduan[pinlv%100/10];
// display[3]=sumaduan[pinlv%10];
// display[4]=0xff;
// display[5]=0xff;
// display[6]=0xff;
// display[7]=0xff;
// digital();
//}
void dianyadisplay()
{
display[0]=0xc1;
display[1]=0xff;
display[2]=0xff;
display[3]=0xff;
display[4]=0xff;
display[5]=sumaduan[dianya/100]+0x80;
display[6]=sumaduan[dianya%100/10];
display[7]=sumaduan[dianya%10];
digital();
}
void pinlvLED()
{
if(pinlv<1000)
{
P0=0XFD;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else if(pinlv<5000)
{
P0=0XF5;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else if(pinlv<10000)
{
P0=0XFD;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else
{
P0=0XF5;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
}
void dianyaLED()
{
if(dianya<150)
{
P0=0XFe;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else if(dianya<250)
{
P0=0XF6;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else if(dianya<350)
{
P0=0XFe;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
else
{
P0=0XF6;
P2=(P2&0X1F)|0X80;
P2=0X1F;
}
}
/********************************************************
函数名:Timer0Init(void) //@12.000MHz
Timer1Init(void) //5毫秒@12.000MHz
功能:NE555频率采集
输入:无
输出:无
作者:引用STC—ISP的功能,有所改动
*********************************************************/
void Timer0Init(void) //@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD = 0x04; //设置定时器模式,计数模式
TL0 = 0xff; //设置定时初始值
TH0 = 0xff; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void Timer1Init(void) //5毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xA0; //设置定时初始值
TH1 = 0x15; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
/********************************************************
函数名:initlize()
功能:蓝桥杯单片机初始化(关闭蜂鸣器,LED,数码管)
输入:无
输出:无
作者:张鹤
*********************************************************/
void initlize()
{
P0=0XFF;
P2=(P2&0X1F)|0XE0;
Delaynus(80);
P2=(P2&0X1F)|0XC0;
P2=(P2&0X1F)|0X80;
P2&=0X1F;
P0=0x00;
P2=(P2&0X1F)|0Xa0;
P2&=0X1F;
}
void main()
{
initlize();
Timer0Init();
Timer1Init();
while(1)
{
key();
if(jianmian==0)
{
if(moshi==0)
{
dianya=200;
}
else
{
ADC_init();
dianya=ADC_Read();
}
if(LEDgongneng==0)
{
dianyaLED();
}
else
{
P0=0Xff;
P2=(P2&0X1F)|0X80;
P2&=0X1F;
}
if(shumaguangongneng==0)
{
dianyadisplay();
}
else
{
P0=0XFF;
P2=(P2&0X1F)|0XE0;
Delaynus(80);
P2=(P2&0X1F)|0XC0;
P2&=0X1F;
}
}
else
{
if(LEDgongneng==0)
{
pinlvLED();
}
else
{
P0=0Xff;
P2=(P2&0X1F)|0X80;
P2&=0X1F;
}
if(shumaguangongneng==0)
{
pinlvdisplay();
}
else
{
P0=0XFF;
P2=(P2&0X1F)|0XE0;
Delaynus(80);
P2=(P2&0X1F)|0XC0;
P2&=0X1F;
}
}
}
}
void timer0() interrupt 1
{
jishu++;
}
void timer1() interrupt 3
{
TL1 = 0xA0; //设置定时初始值
TH1 = 0x15; //设置定时初始值
time++;
if(time>=200)
{
time=0;
pinlv=jishu;
jishu=0;
}
}
IIC.C
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
/*引用了蓝桥杯提供的2019年数据包,如有侵权,练习作者删除*/
#include "stc15f2k60s2.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 ADC_init()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Delay(10);
}
int ADC_Read()
{
int voltage,adc;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
adc=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
IIC_Delay(10);
voltage=adc*100/51;
return voltage;
}
IIC.H
/*引用了蓝桥杯提供的2019年数据包,如有侵权,练习作者删除*/
#ifndef _IIC_H
#define _IIC_H
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 ADC_init();
int ADC_Read();
#endif