蓝桥杯单片机第8届国赛程序题参考答案

        答案仅供参考,有错误欢迎指正,非常感谢!!!

        文件较多,代码较长,感谢查看!!!

目录

题目分析

第一部分题目分析

 第二部分题目分析

main.h

main.c

Init.h

Init.c

SMG.h

SMG.c

DSQ.h

DSQ.c

YanShi.h

YanShi.c

DLKey.h

DLKey.c

iic.h

iic.c

CSB.h

CSB.c

题目分析

总结一句:题目看着很简单,实际做起来脑壳很炸裂

第一部分题目分析

 

 单纯从上图的显示功能来看,它里面包含的逻辑就已经很多了。

  1. 判断当前属于哪种操作
  2. 对历史测量到的距离进行记录
  3. 显示上一次的测量数据
  4. 上一次的测量数据是什么时候测的
  5. 上一次测量到数据,断电后再上电,上一次测量数据的显示
  6. 上一次测量到数据,断电后再上电,再次测量数据,数码管的显示
  7. 测量数据的次数不够10次时,在加操作的情况下,怎么显示;在无操作的情况下,怎么显示。如果次数大于10次时呢?在这两种操作情况下,又该怎样分别显示
  8. 测量数据的次数只有0、1次时,两种操作情况下,又要怎样分别显示,显示的内容应该是怎样的

这些问题我们都应该去考虑,不能老整一堆bug出来。

 第二部分题目分析

 这部分题目的要求还算好一点。

  1. 数据编号只给了两位显示,说明数据编号的范围最大可以去到99,可以说还有点人性化
  2. 数据编号就是对应第几次测量数据
  3. 数据只能显示近10次的测量数据

main.h

#ifndef __MAIN_H_
#define __MAIN_H_

#define uchar unsigned char
#define uint unsigned int
	
#include <STC15F2K60S2.H>

#include "Init.h"
#include "SMG.h"
#include "DSQ.h"
#include "YanShi.h"
#include "DLKey.h"
#include "iic.h"
#include "CSB.h"

void JiLu_Init();
void SMG_XianShi();
void LED_Show();

#endif

main.c

#include "main.h"

uchar flag0=0;//定时器0标志位
uchar ju_li=0;//距离
uchar jie_mian=0;//界面
uchar cao_zuo=0;//操作
uchar ye_shu=0;//页数
uchar can_shu;//参数
uchar can_shu1;//参数,确定值
uchar JuLi_Old[10];//进10次的测量距离记录
uchar JiLu_GeShu=0;//记录的个数
uchar JiLu_ZhuangTai=0;//记录状态。0或其他数据:没有记录数据;1:存储有数据记录
uchar S4_AnXia_flag=0;//S4按键标志位,判断上电后,S4按键是否被按下过
uint L1_time=0;//L1LED的闪烁时间
uchar L1_flag=0;//L1闪烁标志位

void main(){
	uchar key_num;
	char i;
	BanZi_Init();
	SMG_Init();
	DSQ_0_Init();
	DLKey_Init();
	JiLu_Init();//记录初始化
	JiLu_ZhuangTai=IIC_EEPROM_GetDate(0x00);
	if(JiLu_ZhuangTai==0){//多次上电,但未存储数据
		IIC_EEPROM_XieDate(0x05,0);
		Delay10ms();
	}
	else if(JiLu_ZhuangTai==1){//存储有数据记录
		JiLu_GeShu=IIC_EEPROM_GetDate(0x05);
		Delay10ms();
		if(JiLu_GeShu<10){//存储的数据小于10个
			for(i=0;i<JiLu_GeShu;i++){
				EA=0;
				JuLi_Old[i]=IIC_EEPROM_GetDate(i+0x10);
				EA=1;
				Delay10ms();
			}
		}
		else{//存储的数据大于等于10个
			for(i=0;i<10;i++){
				EA=0;
				JuLi_Old[i]=IIC_EEPROM_GetDate(i+0x10);
				EA=1;
				Delay10ms();
			}
		}
		
	}
	else{//第一次上电
		IIC_EEPROM_XieDate(0x00,0);//EEPROM标志位地址
		Delay10ms();
		IIC_EEPROM_XieDate(0x05,0);//记录个数存储地址
		Delay10ms();
		IIC_EEPROM_XieDate(0x06,0);//参数存储地址
		Delay10ms();
		for(i=0x10;i<=0x19;i++){//0x10-0x19,近10个数据存储地址
			IIC_EEPROM_XieDate(i,0);
			Delay10ms();
		}
	}

	JiLu_GeShu=IIC_EEPROM_GetDate(0x05);
	Delay10ms();
	can_shu1=IIC_EEPROM_GetDate(0x06);
	Delay10ms();
	can_shu=can_shu1;
	while(1){
		//获取键值
		key_num=DLKey_GetKeynum();
		if(key_num==4){//启动测量
			S4_AnXia_flag=1;//S4按键被按下,更改标志位
			ju_li=CSB_GetJuLi();
			JiLu_GeShu++;
			L1_flag=1;
			
			//数据存储
			IIC_EEPROM_XieDate(0x00,1);//EEPROM标志位地址,置1,有数据存入
			Delay10ms();
			IIC_EEPROM_XieDate(0x05,JiLu_GeShu);//记录个数存储地址
			Delay10ms();
			if(JiLu_GeShu>10){//记录的个数大于10个
				for(i=1;i<10;i++){
					JuLi_Old[i-1]=JuLi_Old[i];
				}
				JuLi_Old[9]=ju_li;
				for(i=0;i<10;i++){//0x10-0x19,近10个数据存储地址
					EA=0;
					IIC_EEPROM_XieDate(0x10+i,JuLi_Old[i]);
					EA=1;
					Delay10ms();
				}
			}
			else{
				JuLi_Old[JiLu_GeShu-1]=ju_li;
				for(i=0;i<JiLu_GeShu;i++){//0x10-0x19,近10个数据存储地址
					EA=0;
					IIC_EEPROM_XieDate(0x10+i,JuLi_Old[i]);
					EA=1;
					Delay10ms();
				}
			}
		}
		else if(key_num==5){//数据回显
			jie_mian++;
			jie_mian=jie_mian%2;
			if(jie_mian!=2){//退出参数设置界面,保存当前设置
				can_shu1=can_shu;
				IIC_EEPROM_XieDate(0x06,can_shu1);
				Delay10ms();
			}
		}
		else if(key_num==6){//参数设置
			jie_mian++;
			jie_mian=jie_mian%3;
			if(jie_mian==1){
				jie_mian++;
				jie_mian=jie_mian%3;
			}
			if(jie_mian!=2){//退出参数设置界面,保存当前设置
				can_shu1=can_shu;
				IIC_EEPROM_XieDate(0x06,can_shu1);
				Delay10ms();
			}
		}
		else if(key_num==7){
			switch(jie_mian){
				case 0:{//测距界面
					cao_zuo++;
					cao_zuo=cao_zuo%2;
					break;
				}
				case 1:{//回显界面
					ye_shu++;
					if(JiLu_GeShu>=10){//记录数据达到10个以上
						ye_shu=ye_shu%10;
					}
					else if(JiLu_GeShu>=1){//记录数据有1-9个
						ye_shu=ye_shu%JiLu_GeShu;
					}
					else{//没有记录数据
						ye_shu=0;
					}
					break;
				}
				case 2:{//参数设置界面
					can_shu=can_shu+10;
					can_shu=can_shu%100;
					break;
				}
			}
		}
		
		//模拟信号输出
		if(ju_li<=can_shu1){//距离小于参数
			IIC_DAC_XieDate(0);
		}
		else{//距离大于参数
			if(((ju_li-can_shu)*0.02)>5){//计算的距离异常
				IIC_DAC_XieDate(255);
			}
			else{
				IIC_DAC_XieDate(51*(ju_li-can_shu1)*0.02);
			}
		}
	}
}

void DSQ_0_ZD() interrupt 1{
	flag0++;
	
	if(L1_flag){
		L1_time++;
		if(L1_time>2000){
			L1_time=0;
			L1_flag=0;
		}
	}
	else{
		L1_time=0;
	}
	
	if(flag0>=1){
		flag0=0;
		SMG_XianShi();
		LED_Show();
	}
}

void SMG_XianShi(){//数码管显示
	switch(jie_mian){
		case 0:{//测距显示界面
			if(cao_zuo){//加操作
				if(S4_AnXia_flag){//上电后,S4按键被按下过
					if(JiLu_GeShu>10){//记录的数据达到10个以上
						if((JuLi_Old[8]+JuLi_Old[9])>=100){
							SMG_Show(cao_zuo,16,(JuLi_Old[8]+JuLi_Old[9])/100,((JuLi_Old[8]+JuLi_Old[9])/10)%10,(JuLi_Old[8]+JuLi_Old[9])%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if((JuLi_Old[8]+JuLi_Old[9])>=10){
							SMG_Show(cao_zuo,16,16,(JuLi_Old[8]+JuLi_Old[9])/10,(JuLi_Old[8]+JuLi_Old[9])%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if((JuLi_Old[8]+JuLi_Old[9])>=0){
							SMG_Show(cao_zuo,16,16,16,(JuLi_Old[8]+JuLi_Old[9]),ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
					else{//记录的数据1-10个
						if(JiLu_GeShu>1){//记录的个数达到2个以上
							if((JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])>=100){
								SMG_Show(cao_zuo,16,(JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])/100,((JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])/10)%10,(JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if((JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])>=10){
								SMG_Show(cao_zuo,16,16,(JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])/10,(JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if((JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2])>=0){
								SMG_Show(cao_zuo,16,16,16,(JuLi_Old[JiLu_GeShu-1]+JuLi_Old[JiLu_GeShu-2]),ju_li/100,(ju_li/10)%10,ju_li%10);
							}
						}
						else if(JiLu_GeShu==1){//记录的个数有1个
							if(JuLi_Old[JiLu_GeShu-1]>=100){
								SMG_Show(cao_zuo,16,JuLi_Old[JiLu_GeShu-1]/100,(JuLi_Old[JiLu_GeShu-1]/10)%10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=10){
								SMG_Show(cao_zuo,16,16,JuLi_Old[JiLu_GeShu-1]/10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=0){
								SMG_Show(cao_zuo,16,16,16,JuLi_Old[JiLu_GeShu-1],ju_li/100,(ju_li/10)%10,ju_li%10);
							}
						}
					}
				}
				else{//上电后,S4按键没有被按下过
					if(JiLu_GeShu>10){//记录的数据达到10个以上
						if(JuLi_Old[9]>=100){
							SMG_Show(cao_zuo,16,JuLi_Old[9]/100,(JuLi_Old[9]/10)%10,JuLi_Old[9]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[9]>=10){
							SMG_Show(cao_zuo,16,16,JuLi_Old[9]/10,JuLi_Old[9]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[9]>=0){
							SMG_Show(cao_zuo,16,16,16,JuLi_Old[9],ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
					else{//记录的数据0-10个
						if(JiLu_GeShu>=1){//记录的个数达到1个以上
							if(JuLi_Old[JiLu_GeShu-1]>=100){
								SMG_Show(cao_zuo,16,JuLi_Old[JiLu_GeShu-1]/100,(JuLi_Old[JiLu_GeShu-1]/10)%10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=10){
								SMG_Show(cao_zuo,16,16,JuLi_Old[JiLu_GeShu-1]/10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=0){
								SMG_Show(cao_zuo,16,16,16,JuLi_Old[JiLu_GeShu-1],ju_li/100,(ju_li/10)%10,ju_li%10);
							}
						}
						else{//没有记录的个数
							SMG_Show(cao_zuo,16,16,16,0,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
				}
			}
			else{//无操作
				if(S4_AnXia_flag){//上电后,S4按键被按下过
					if(JiLu_GeShu>10){//记录的数据达到10个以上
						if(JuLi_Old[8]>=100){
							SMG_Show(cao_zuo,16,JuLi_Old[8]/100,(JuLi_Old[8]/10)%10,JuLi_Old[8]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[8]>=10){
							SMG_Show(cao_zuo,16,16,JuLi_Old[8]/10,JuLi_Old[8]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[8]>=0){
							SMG_Show(cao_zuo,16,16,16,JuLi_Old[8],ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
					else{//记录的数据有1-10个
						if(JiLu_GeShu>=2){//2-9个数据记录
							if(JuLi_Old[JiLu_GeShu-2]>=100){
								SMG_Show(cao_zuo,16,JuLi_Old[JiLu_GeShu-2]/100,(JuLi_Old[JiLu_GeShu-2]/10)%10,JuLi_Old[JiLu_GeShu-2]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-2]>=10){
								SMG_Show(cao_zuo,16,16,JuLi_Old[JiLu_GeShu-2]/10,JuLi_Old[JiLu_GeShu-2]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-2]>=0){
								SMG_Show(cao_zuo,16,16,16,JuLi_Old[JiLu_GeShu-2],ju_li/100,(ju_li/10)%10,ju_li%10);
							}
						}
						else{//0或1个数据
							SMG_Show(cao_zuo,16,16,16,0,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
				}
				else{//上电后,S4按键没有被按下过
					if(JiLu_GeShu>10){//记录的数据达到10个以上
						if(JuLi_Old[9]>=100){
							SMG_Show(cao_zuo,16,JuLi_Old[9]/100,(JuLi_Old[9]/10)%10,JuLi_Old[9]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[9]>=10){
							SMG_Show(cao_zuo,16,16,JuLi_Old[9]/10,JuLi_Old[9]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
						else if(JuLi_Old[9]>=0){
							SMG_Show(cao_zuo,16,16,16,JuLi_Old[9],ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
					else{//记录的数据0-10个
						if(JiLu_GeShu>=1){//记录的个数达到1个以上
							if(JuLi_Old[JiLu_GeShu-1]>=100){
								SMG_Show(cao_zuo,16,JuLi_Old[JiLu_GeShu-1]/100,(JuLi_Old[JiLu_GeShu-1]/10)%10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=10){
								SMG_Show(cao_zuo,16,16,JuLi_Old[JiLu_GeShu-1]/10,JuLi_Old[JiLu_GeShu-1]%10,ju_li/100,(ju_li/10)%10,ju_li%10);
							}
							else if(JuLi_Old[JiLu_GeShu-1]>=0){
								SMG_Show(cao_zuo,16,16,16,JuLi_Old[JiLu_GeShu-1],ju_li/100,(ju_li/10)%10,ju_li%10);
							}
						}
						else{//没有记录的个数
							SMG_Show(cao_zuo,16,16,16,0,ju_li/100,(ju_li/10)%10,ju_li%10);
						}
					}
				}
			}
			break;
		}
		case 1:{//数据回显界面
			if(JiLu_GeShu>10){//记录的数据达到10个以上
				SMG_Show((JiLu_GeShu-9+ye_shu)/10,(JiLu_GeShu-9+ye_shu)%10,16,16,16,JuLi_Old[ye_shu]/100,(JuLi_Old[ye_shu]/10)%10,JuLi_Old[ye_shu]%10);
			}
			else if(JiLu_GeShu>0){//记录的数据1-10个
				SMG_Show((ye_shu+1)/10,(ye_shu+1)%10,16,16,16,JuLi_Old[ye_shu]/100,(JuLi_Old[ye_shu]/10)%10,JuLi_Old[ye_shu]%10);
			}
			else{
				SMG_Show(0,0,16,16,16,JuLi_Old[ye_shu]/100,(JuLi_Old[ye_shu]/10)%10,JuLi_Old[ye_shu]%10);
			}
			break;
		}
		case 2:{//参数设置界面
			SMG_Show(15,16,16,16,16,16,can_shu/10,0);
			break;
		}
	}
}

void JiLu_Init(){//记录初始化
	uchar i;
	for(i=0;i<10;i++){
		JuLi_Old[i]=0;
	}
}

void LED_Show(){//LED显示
	uchar L1=0xff;
	uchar L7_8=0xff;
	if(L1_flag){
		if((L1_time/100)%2){
			L1=0xfe;
		}
		else{
			L1=0xff;
		}
	}
	else{
		L1=0xff;
	}
	if(jie_mian==1){//数据回显界面
		L7_8=0x7f;
	}
	else if(jie_mian==2){//参数设置界面
		L7_8=0xbf;
	}
	else{
		L7_8=0xff;
	}
	P0=L1&L7_8;
	P2=(P2&0x1f)|0x80;
	P2=(P2&0x1f)|0x00;
}

Init.h

#ifndef __INIT_H_
#define __INIT_H_

#include <STC15F2K60S2.H>

void BanZi_Init();

#endif

Init.c

#include "Init.h"

void BanZi_Init(){
	P2=(P2&0x1f)|0xa0;
	P0=0x00;
	P2=(P2&0x1f)|0x80;
	P0=0xff;
}

SMG.h

#ifndef __SMG_H_
#define __SMG_H_

#include <STC15F2K60S2.H>

void SMG_Init();
void SMG_Show(unsigned char n1,n2,n3,n4,n5,n6,n7,n8);

#endif

SMG.c

#include "SMG.h"

unsigned char code SMG_ZK[]={                       //????
//   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

void SMG_Init(){
	P2=(P2&0x1f)|0xc0;
	P0=0xff;
	P2=(P2&0x1f)|0xe0;
	P0=0xff;
}

void SMG_Show(unsigned char n1,n2,n3,n4,n5,n6,n7,n8){
	static unsigned char i=0;
	i++;
	i=i%8;
	P2=(P2&0x1f)|0xc0;
	switch(i){
		case 1:{
			P0=0x01;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n1];
			break;
		}
		case 2:{
			P0=0x02;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n2];
			break;
		}
		case 3:{
			P0=0x04;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n3];
			break;
		}
		case 4:{
			P0=0x08;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n4];
			break;
		}
		case 5:{
			P0=0x10;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n5];
			break;
		}
		case 6:{
			P0=0x20;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n6];
			break;
		}
		case 7:{
			P0=0x40;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n7];
			break;
		}
		case 0:{
			P0=0x80;
			P2=(P2&0x1f)|0xe0;
			P0=~SMG_ZK[n8];
			break;
		}
	}
	P2=(P2&0x1f)|0x00;
}

DSQ.h

#ifndef __DSQ_H_
#define __DSQ_H_

#include <STC15F2K60S2.H>

void DSQ_0_Init();

#endif

DSQ.c

#include "DSQ.h"

void DSQ_0_Init(){
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;
	ET0=1;
}

YanShi.h

#ifndef __YANSHI_H_
#define __YANSHI_H_

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

void Delay10ms();

#endif

YanShi.c

#include "YanShi.h"

void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}

DLKey.h

#ifndef __DLKEY_H_
#define __DLKEY_H_

#include "YanShi.h"

void DLKey_Init();
unsigned char DLKey_GetKeynum();

#endif

DLKey.c

#include "DLKey.h"

void DLKey_Init(){
	P30=1;
	P31=1;
	P32=1;
	P33=1;
}

unsigned char DLKey_GetKeynum(){
	unsigned char key_num=0;
	if(P30==0){
		Delay10ms();
		if(P30==0){
			key_num=7;
		}
		while(P30==0);
	}
	else if(P31==0){
		Delay10ms();
		if(P31==0){
			key_num=6;
		}
		while(P31==0);
	}
	else if(P32==0){
		Delay10ms();
		if(P32==0){
			key_num=5;
		}
		while(P32==0);
	}
	else if(P33==0){
		Delay10ms();
		if(P33==0){
			key_num=4;
		}
		while(P33==0);
	}
	DLKey_Init();
	return key_num;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

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

sbit SDA = P2^1;
sbit SCL = P2^0;

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); 

unsigned char IIC_ADC_GetDate(unsigned char di_zhi);
void IIC_DAC_XieDate(unsigned char date);
void IIC_EEPROM_XieDate(unsigned char di_zhi,unsigned char date);
unsigned char IIC_EEPROM_GetDate(unsigned char di_zhi);

#endif

iic.c

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
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;  					
    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;    
}

unsigned char IIC_ADC_GetDate(unsigned char di_zhi){
	unsigned char date;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(di_zhi);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	date=IIC_RecByte();
	IIC_SendAck(1);
	IIC_WaitAck();
	IIC_Stop();
	return date;
}

void IIC_DAC_XieDate(unsigned char date){
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

void IIC_EEPROM_XieDate(unsigned char di_zhi,unsigned char date){
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(di_zhi);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char IIC_EEPROM_GetDate(unsigned char di_zhi){
	unsigned char date;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(di_zhi);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	date=IIC_RecByte();
	IIC_SendAck(1);
	IIC_WaitAck();
	IIC_Stop();
	return date;
}

CSB.h

#ifndef __CSB_H_
#define __CSB_H_

#define FS P10
#define JS P11

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

void Delay13us();
void CSB_FS_MC();
float CSB_GetJuLi();

#endif

CSB.c

#include "CSB.h"

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

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

void CSB_FS_MC(){
	unsigned char i=8;
	while(i>0){
		i--;
		FS=1;
		Delay13us();
		FS=0;
		Delay13us();
	}
}

float CSB_GetJuLi(){
	float ju_li;
	unsigned int time=0;
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0;		//设置定时初值
	TH1 = 0;		//设置定时初值
	ET1=0;
	CSB_FS_MC();
	TR1 = 1;		//定时器1开始计时
	while(JS==1&&TF1==0);
	TR1=0;
	if(JS==0&&TF1==0){
		time=((unsigned int)TH1<<8)|(unsigned int)TL1;
		ju_li=(time*1.0*0.017)/12.0;
	}
	else{
		ju_li=255;
		TF1 = 0;		//清除TF1标志
	}
	TH1=0;
	TL1=0;
	return ju_li;
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

因心,三人水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值