链接:https://pan.baidu.com/s/1fscNgkshupeaJGGRapj8UQ
提取码:2022
(里面包含选择题)
可以直接从百度网盘下载或者将下列代码复制粘贴,其中有蓝桥杯提供的底层代码,有修改的已经标注在开头。
题目
iic.h蓝桥杯底层代码,没有改变
#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);
#endif
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;
}
11.c//程序运行代码
#include <reg52.h>
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int
sfr P4=0xc0;//矩阵键盘里面P3^6->P4^2;P3^7->P4^4;P4要进行定义
sbit P3_0=P3^0;
sbit P3_1=P3^1;
sbit P3_2=P3^2;
sbit P3_3=P3^3;
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit P3_4=P3^4;
sbit P3_5=P3^5;
sbit P4_2=P4^2;
sbit P4_4=P4^4;
uchar V_data=0;//电压值
uint P_data=0;//电压参数值扩大100倍
uint N_data=0;//电压相等的次数(注意看触发条件,不是单纯相等就加,要由大变小)
uchar N_flag1=0;//防止一直加
uint L3_flag=0;//控制L3,大于等于3时亮
uchar L1_flag=0;//控制L1
uint key12=0;//按键S12
uint T0_count=0;//定时器
uchar code smg_duan[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc1,0x8c,0xc8};
void select_138(uchar x);//138选择
void close_all();//初始化关闭外设
void read_V();//读取Rb2电压
void smg_bit(uchar pos,uchar num);//数码管显示一位,不带小数点
void smg_bit2(uchar pos,uchar num);//数码管显示一位,带小数点
void all_smg(uchar Char);//控制所有数码管,用来消影
void display_V();//显示电压值
void display_P();//显示电压参数值
void display_N();//显示次数
void read_P(uchar addr);//读取电压参数值
void write_P(uchar addr,uchar x);//将电压参数值写入iic地址
void delay(uchar x);//延迟函数
void key_scan();//按键扫描
void display();//总显示
void LED_running();//Led灯
void Timer_init();//定时器初始化
void main()
{
close_all();
Timer_init();
read_P(0);//上电后读取电压参数值
while(1)
{
float V_num=0;
read_V();
V_num=V_data*1.961;//将读取电压值变为十进制并且扩大100倍
if (V_num > P_data)//P_data也是电压参数值扩大100倍
{
N_flag1 = 1;
}
else if (V_num <= P_data)
{
if (N_flag1 == 1)//防止一直加
{
N_data++;
N_flag1 = 0;
}
}
if(V_num<P_data)//读出电压值小于电压参数,定时器打开
{
TR0=1;
}
if(V_num>=P_data)//读出电压值大于电压参数,定时器关闭,全部重置
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=0;
T0_count=0;L1_flag=0;
}
key_scan();
display();
LED_running();
}
}
//==========138选择========
void select_138(uchar x)
{
switch(x)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;break;
case 0:
P2 = (P2 & 0x1f) | 0x00;break;
}
}
/*
巧记
0x1f=000 1 1111
0x80=100 0 0000 //4
0xa0=101 0 0000 //5
0xc0=110 0 0000 //6
0xe0=111 0 0000 //7
0x00=000 0 0000 //0
看前3位
*/
//============关闭外设===========
void close_all()
{
select_138(4);
P0=0xff;
select_138(5);
P0=0x00;
select_138(0);
}
//==========读取Rb2============
void read_V()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
V_data=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
}
//===========数码管=============
void smg_bit(uchar pos,uchar num)
{
select_138(7);
P0=0xff;
select_138(6);
P0=(0x01<<pos);
select_138(7);
P0=smg_duan[num];
select_138(0);
}
void smg_bit2(uchar pos,uchar num)
{
select_138(7);
P0=0xff;
select_138(6);
P0=(0x01<<pos);
select_138(7);
P0=(smg_duan[num]&0x7f);
select_138(0);
}
void all_smg(uchar Char)
{
select_138(6);
P0=0xff;
select_138(7);
P0=Char;
}
void display_V()
{
smg_bit(0,10);
delay(500);
smg_bit2(5,V_data/51);
delay(500);
smg_bit(6,(V_data%51)*10/51);
delay(500);
smg_bit(7,(((V_data%51)*10)%51)*10/51);
delay(500);
all_smg(0xff);
}
void display_P()
{
smg_bit(0,11);
delay(500);
smg_bit2(5,P_data/100);
delay(500);
smg_bit(6,P_data%100/10);
delay(500);
smg_bit(7,0);
delay(500);
all_smg(0xff);
}
void display_N()
{
smg_bit(0,12);
delay(500);
if(N_data>99)
{
N_data=0;
}
if(N_data>9)
{
smg_bit(6,N_data/10);
delay(500);
}
smg_bit(7,N_data%10);
delay(500);
all_smg(0xff);
}
//===========读写P_data========
void read_P(uchar addr)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
P_data=IIC_RecByte()*10;
}
void write_P(uchar addr,uchar x)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(x);
IIC_WaitAck();
IIC_Stop();
}
//===========延迟========
void delay(uchar x)
{
while(x--){};
}
//===========按键========
void key_scan()
{
P3=0xff;
P4=0xff;
P4_4=0;
if(P3_0==0)//7
{
delay(100);
if(P3_0==0)
{
L3_flag++;
while(!P3_0){display();LED_running();};
}
}
if(P3_1==0)//6
{
delay(100);
if(P3_1==0)
{
L3_flag++;
while(!P3_1){display();LED_running();};
}
}
if(P3_2==0)//5
{
delay(100);
if(P3_2==0)
{
L3_flag++;
while(!P3_2){display();LED_running();};
}
}
if(P3_3==0)//4
{
delay(100);
if(P3_3==0)
{
L3_flag++;
while(!P3_3){display();LED_running();};
}
}
P3=0xff;//要重置,不然可能与第一列重复
P4=0xff;
P4_2=0;
if(P3_0==0)//11
{
delay(100);
if(P3_0==0)
{
L3_flag++;
while(!P3_0){display();LED_running();};
}
}
if(P3_1==0)//10
{
delay(100);
if(P3_1==0)
{
L3_flag++;
while(!P3_1){display();LED_running();};
}
}
if(P3_2==0)//9
{
delay(100);
if(P3_2==0)
{
L3_flag++;
while(!P3_2){display();LED_running();};
}
}
if(P3_3==0)//8
{
delay(100);
if(P3_3==0)
{
L3_flag++;
while(!P3_3){display();LED_running();};
}
}
P3=0xff;
P4=0xff;
P3_5=0;
if(P3_0==0)//15
{
delay(100);
if(P3_0==0)
{
L3_flag++;
while(!P3_0){display();LED_running();};
}
}
if(P3_1==0)//14
{
delay(100);
if(P3_1==0)
{
L3_flag++;
while(!P3_1){display();LED_running();};
}
}
if(P3_2==0)//13
{
delay(100);
if(P3_2==0)
{
L3_flag=0;
if(key12==2)
{
N_data=0;
}
while(!P3_2){display();LED_running();};
}
}
if(P3_3==0)//12
{
delay(100);
if(P3_3==0)
{
L3_flag=0;
key12=(key12+1)%3;
while(!P3_3){display();LED_running();};
}
}
P3=0xff;
P4=0xff;
P3_4=0;
if(P3_0==0)//19
{
delay(100);
if(P3_0==0)
{
L3_flag++;
while(!P3_0){display();LED_running();};
}
}
if(P3_1==0)//18
{
delay(100);
if(P3_1==0)
{
L3_flag++;
while(!P3_1){display();LED_running();};
}
}
if(P3_2==0)//17
{
delay(100);
if(P3_2==0)
{
L3_flag=0;
if(key12==1)
{
P_data=P_data-50;//按一下减0.5V,扩大100倍就减50
if(P_data==-50)
{
P_data=500;
}
write_P(0,P_data/10);//题目要求是电压参数值的10倍,P_data为100倍
}
while(!P3_2){display();LED_running();};
}
}
if(P3_3==0)//16
{
delay(100);
if(P3_3==0)
{
L3_flag=0;
if(key12==1)
{
P_data+=50;//按一下加0.5V,扩大100倍就加50
if(P_data==550)
{
P_data=0;
}
write_P(0,P_data/10);//题目要求是电压参数值的10倍,P_data为100倍
}
while(!P3_3){display();LED_running();};
}
}
P3=0xff;
P4=0xff;
}
//=======总显示=======
void display()
{
if(key12==0)
{
display_V();
}
if(key12==1)
{
display_P();
}
if(key12==2)
{
display_N();
}
}
//==========LED===========
void LED_running()
{
select_138(4);
if((N_data%2==0)&&(N_data!=0))
{
L2=0;
}
if(L3_flag>=3)
{
L3=0;
}
if(L3_flag<3)
{
L3=1;
}
if(L1_flag==1)
{
L1=0;
}
if(L1_flag==0)
{
L1=1;
}
select_138(0);
}
//========定时器==========
void Timer_init()
{
TMOD=0x01;
EA=1;ET0=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=0;//刚开始关闭,读出电压值小于电压参数时开始
}
void t0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
T0_count++;
if(T0_count==100)//5秒
{
L1_flag=1;
T0_count=0;
TR0=0;
}
}