【蓝桥杯单片机】6个进阶模块应用总结(IO模式)

(一)【DS18B20温度传感器】

数码管后三位显示当前环境温度

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

//unsigned char rd_temperature(void);  为避免出现警告,可删除此句
//将onewire.c中除延时函数外的函数声明引入在此头文件中

void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);

#endif

onewire.c

只需将官方所给的源码(2022版本)中调用的所有延时函数中的参数扩大10倍

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
    
    
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    
    
	unsigned char i;
	for(i=0;i<8;i++)
	{
    
    
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(50);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(50);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
    
    
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
    
    
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
    
    
			dat |= 0x80;
		}	    
		Delay_OneWire(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
    
    
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}







DS18B20.c

#include "reg52.h"
#include "onewire.h"  //引入提供的底层驱动文件(头文件中需要进行修改)
//#include "absacc.h" MM模式(存储扩展)
unsigned char SMG_NODOT[10]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //无小数点段码
unsigned char SMG_DOT[10]={
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};  //有小数点段码

void Select_HC573(unsigned char channel)  //锁存器选择 
{
    
    
	switch(channel)
	{
    
    
		case 4: P2 = P2 & 0x1f | 0x80; break;  //LED控制
		case 5: P2 = P2 & 0x1f | 0xa0; break;  //蜂鸣器、继电器
		case 6: P2 = P2 & 0x1f | 0xc0; break;  //数码管com共阳端
		case 7: P2 = P2 & 0x1f | 0xe0; break;  //数码管段码端
	}
}

void SMG_bit(unsigned char pos, unsigned char dat)  //控制单个数码管显示
{
    
    
	Select_HC573(7);  //消影
	P0 = 0xff;
	
	Select_HC573(6);  //显示位置
	P0 = 0x01 << pos;
	Select_HC573(7);  //显示内容
	P0 = dat;
}

void SMG_DisplayAll(unsigned char dat)  //控制全部数码管显示
{
    
    
	Select_HC573(6);   //全部数码管的共阳端有效
	P0 = 0xff;
	Select_HC573(7);  //控制全部数码管的段码端
	P0 = dat;
}
void SMG_Delay(unsigned char t)  //动态数码管刷新延时函数
{
    
    
	while(t--);
}

unsigned int temp = 0x0000;  //温度变量,16位无符号int整型
void SMG_Display()  //数码管显示函数
{
    
    
	SMG_bit(7,SMG_NODOT[temp % 10]);  //三位数的最后一位
	SMG_Delay(100);
	SMG_bit(6,SMG_DOT[(temp % 100) / 10]);  //三位数的中间位,带小数点
	SMG_Delay(100);
	SMG_bit(5,SMG_NODOT[temp / 100]);  //三位数的第一位
	SMG_Delay(100);
	
	SMG_bit(4,0xff);  //由于温度只需三位,故其余数码管位都不需显示内容
	SMG_Delay(100);
	SMG_bit(3,0xff);
	SMG_Delay(100);
	SMG_bit(2,0xff);
	SMG_Delay(100);
	SMG_bit(1,0xff);
	SMG_Delay(100);
	SMG_bit(0,0xff);
	SMG_Delay(100);
	
	SMG_DisplayAll(0xff);  //消影
}

unsigned char LSB,MSB;  //定义低8位、高8位变量
void Read_temp()  //读写温度
{
    
    
	init_ds18b20();  //复位
	Write_DS18B20(0xcc);  //跳过ROM
	Write_DS18B20(0x44);  //转换温度
	
	init_ds18b20();  //复位
	Write_DS18B20(0xcc);  //跳过ROM
	Write_DS18B20(0xbe);  //读暂存器
	
	//读取时,低位在前,高为在后
	LSB = Read_DS18B20();  //读取低8位字节
	MSB = Read_DS18B20();  //读取高8位字节
	
	init_ds18b20();  //复位,停止暂存器数据读取
	
	temp = MSB;  //先赋值高8位到低位上
	temp = (temp << 8 ) + LSB;  //将LSB和MSB整合成为一个16位的整数(+就是|或)
	
	if((temp & 0xf800) == 0x0000)  //高5位判断采用结果是正温度(全是0)还是负温度
	{
    
    
		//正温度处理办法
		//详细内容参考<https://www.xmf393.com/2019/08/18/20190801801/>
		temp = temp >> 4;  //取出温度结果的整数部分
		temp = temp * 10;  //放大10倍,然后加上小数部分
		temp = temp + (LSB & 0x0f) * 0.625;
	}
}


void Init_System()  //初始化关闭外设
{
    
    
	Select_HC573(5);
	P0 = 0x00;
	Select_HC573(4);
	P0 = 0xff;
}

void main()
{
    
    
	Init_System();  //初始化关闭外设
	while(1)
	{
    
    
		Read_temp();  //读写温度
		SMG_Display();  //数码管显示
	}
}

(二)【DS1302时钟】

数码管显示时钟

ds1302.h

直接添加官方提供的底层驱动代码不需要修改

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif

ds1302.c

注意检查管脚是否匹配

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

#include <reg52.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
    
    
	unsigned char i;
	for (i=0;i<8;i++)     	
	{
    
     
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
    
    
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
    
    
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{
    
    		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

smg.h

#ifndef _SMG_H
#define _SMG_H

code unsigned char SMG_NODOT[10]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code unsigned char SMG_DOT[10]={
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

void Select_HC573(unsigned char channel);
void SMG_bit(unsigned char pos,unsigned char dat);
void SMG_all(unsigned char dat);
void SMG_Delay(unsigned int t);
	
#endif

smg.c

#include "reg52.h"

void Select_HC573(unsigned char channel)
{
    
    
	switch(channel)
	{
    
    
		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; 
	}
}

void SMG_bit(unsigned char pos,unsigned char dat)
{
    
    
	Select_HC573(7);
	P0 = 0xff;
	Select_HC573(6);
	P0 = 0x01 << pos;
	Select_HC573(7);
	P0 = dat;
}

void SMG_all(unsigned char dat)
{
    
    
	Select_HC573(6);
	P0 = 0xff;
	Select_HC573(7);
	P0 = dat;
}

void SMG_Delay(unsigned int t)
{
    
    
	while(t--);
}

DS1302时钟.c

#include "reg52.h"
#include "ds1302.h"
#include "smg.h"

/*================读写地址=================*/
unsigned char write_ds1302_address[7]={
    
    0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char read_ds1302_address[7]={
    
    0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char Time[7]={
    
    0x13,0x59,0x10,0x28,0x01,0x06,0x23};  //BCD码 23年1月28日 星期六 10:59:13


/*============日历时钟参数设置函数========*/
void DS1302_Config() 
{
    
    
	char i;
	Write_Ds1302_Byte(0x8e,0x00);  //允许向内存写入数据
	for(i = 0; i < 7; i++)   //写入7个字节的时间参数
	{
    
    
		Write_Ds1302_Byte(write_ds1302_address[i],Time[i]); 
	}
	Write_Ds1302_Byte(0x8e,0x80);  //禁止向内存写入数据
}

/*============日历时钟数据读取函数============*/
void Read_Time()
{
    
    
	char i;
	for(i = 0; i < 7; i++)
	{
    
    
		Time[i] = Read_Ds1302_Byte(read_ds1302_address[i]); 
	}
}

/*==============数码管显示函数================*/
void SMG_Display()
{
    
    
	SMG_bit(0,SMG_NODOT[Time[2] / 16]);
	SMG_Delay(100);
	SMG_bit(1,SMG_NODOT[Time[2] % 16]);
	SMG_Delay(100);
	
	SMG_bit(2,0xbf); 
	SMG_Delay(100);
	
	SMG_bit(3,SMG_NODOT[Time[1] / 16]);
	SMG_Delay(100);
	SMG_bit(4,SMG_NODOT[Time[1] % 16]);
	SMG_Delay(100);
	
	SMG_bit(5,0xbf);
	SMG_Delay(100);
	
	SMG_bit(6,SMG_NODOT[Time[0] / 16]);
	SMG_Delay(100);
	SMG_bit(7,SMG_NODOT[Time[0] % 16]);
	SMG_Delay(100);
	
	SMG_all(0xff);
}
 
/*==============程序初始化关闭外设=============*/
void Init_System()
{
    
    
	Select_HC573(5);
	P0 = 0x00;
	Select_HC573(4);
	P0 = 0xff;
}

/*==================主函数=====================*/
void main()
{
    
    
	Init_System();
	DS1302_Config();
	while(1)
	{
    
    
		Read_Time();
		SMG_Display();
	}
}

(三)【NE555定时器与频率测量】

数码管显示频率输出

数码管相关内容与上一个引用相同.c.h文件

#include "reg52.h"
#include "smg.h"

void Init_System()
{
    
    
	Select_HC573(5);
	P0 = 0x00;
	Select_HC573(4);
	P0 = 0xff;
}

void Init_Time()
{
    
    
	TH0 = 0xff;  //T0做计数器,用来计数
	TL0 = 0xff;  //记一次数刚好溢出一次
	
	TH1 = (65535 - 50000 + 1) / 256;  //T1做定时器
	TL1 = (65535 - 50000 + 1) % 256;  //定时时长50ms
	
	TMOD = 0x06;  //T0 8位自动重装 模式2;T1 16位自动重装 模式0
	//0000 0110

	ET0 = 1;
	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
}	
	
unsigned int count_f = 0;
unsigned int dat_f = 0;
unsigned char count_t = 0;
void Service_Time0() interrupt 1
{
    
    
	count_f++;
}
	
void Service_Time1() interrupt 3
{
    
    
	count_t++;
	if(count_t == 20)  //50ms * 20 = 1s
	{
    
    
		dat_f = count_f;
		count_f = 0;
		count_t = 0;
	}
}

void SMG_Display()
{
    
    
	SMG_bit(0,0x8e);  //显示F,表示频率测量
	SMG_Delay(100);
	
	SMG_bit(1,0xff);  //空两个数码管
	SMG_Delay(100);
	SMG_bit(2,0xff);
	SMG_Delay(100);
	
	if(dat_f > 9999)  //5位数
	{
    
    
		SMG_bit(3,SMG_NoDot[dat_f / 10000]);
		SMG_Delay(100);
	}
	if(dat_f > 999)
	{
    
    
		SMG_bit(4,SMG_NoDot[(dat_f / 1000) % 10]);
		SMG_Delay(100);
	}
	if(dat_f > 99)
	{
    
    
		SMG_bit(5,SMG_NoDot[(dat_f / 100) % 10]);
		SMG_Delay(100);
	}
	if(dat_f > 9)
	{
    
    
		SMG_bit(6,SMG_NoDot[(dat_f / 10) % 10]);
		SMG_Delay(100);
	}

	SMG_bit(7,SMG_NoDot[dat_f % 10]);
	SMG_Delay(100);

	SMG_all(0xff);  //消影
}
	
void main()
{
    
    	
	Init_System();
	Init_Time();
	while(1)
	{
    
    
		SMG_Display();
	}
}
	

(四)【IIC-PCF8951-A/D】

【点击此链接,立即学习小蜜蜂老师的PCF8591教程】

数码管显示ADC电压数据

上电时光敏电阻0x03 控制电压显示
独立按键S4控制 电位器0x01 电压显示

smg.h

#ifndef _SMG_H
#define _SMG_H

unsigned char SMG_NoDot[10]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char SMG_Dot[10]={
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

void Select_HC573(unsigned char channel);
void SMG_Delay(unsigned char t);
void SMG_Bit(unsigned char pos,unsigned char value);
void SMG_All(unsigned char dat);
	
#endif

smg.c

#include "reg52.h"

void Select_HC573(unsigned char channel)
{
    
    
	switch(channel)
	{
    
    
		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;
	}
}

void SMG_Delay(unsigned char t)
{
    
    
	while(t--);
}

void SMG_Bit(unsigned char pos,unsigned char value)
{
    
    
	Select_HC573(7);
	P0 = 0xff;
	Select_HC573(6);
	P0 = 0x01 << pos;
	Select_HC573(7);
	P0 = value;
}

void SMG_All(unsigned char dat)
{
    
    
	Select_HC573(6);
	P0 = 0xff;
	Select_HC573(7);
	P0 = dat;
}
	

iic.h

在官方给的底层文件基础上添加

unsigned char PCF8591_adc(unsigned char addr);  //新增adc函数
void PCF8591_dac(unsigned char dat);			//新增dac函数

iic.c

在官方给的底层文件基础上添加

unsigned char PCF8591_adc(unsigned char addr) 
{
    
    
	unsigned char tmp;
	
	IIC_Start();				//IIC总线起始信号	
	
	IIC_SendByte(0x90);			//PCF8591的写设备地址
	IIC_WaitAck();				//等待从机应答
	
	IIC_SendByte(addr);			//写入PCF8591的控制字节
	IIC_WaitAck();				//等待从机应答
	
	IIC_Stop(); 				//IIC总线停止信号
	
	IIC_Start();				//IIC总线起始信号
	
	IIC_SendByte(0x91);			//PCF8591的读设备地址
	IIC_WaitAck();				//等待从机应答
	
	tmp = IIC_RecByte();		//读取PCF8591的数据 
	IIC_SendAck(1);				//产生非应答信号
	
	IIC_Stop();					//IIC总线停止信号
	return tmp;
}

void PCF8591_dac(unsigned char dat)
{
    
    
	IIC_Start();				//IIC总线起始信号	
	
	IIC_SendByte(0x90);			//PCF8591的写设备地址
	IIC_WaitAck();				//等待从机应答
	
	IIC_SendByte(0x43);			//写入PCF8591的控制字节
	IIC_WaitAck();				//等待从机应答

	IIC_SendByte(dat);			//dat-输出dac数据
	IIC_WaitAck();				//等待从机应答
	
	IIC_Stop();					//IIC总线停止信号
}

main.c

#include "reg52.h"
#include "iic.h"
#include "smg.h"

unsigned char dat = 0;
unsigned char channel = 0;
unsigned char stat = 0;
sbit S4 = P3^3;

void SMG_Display()
{
    
    
	SMG_Bit(0,0xbf);
	SMG_Delay(500);
	SMG_Bit(1,SMG_NoDot[channel]);
	SMG_Delay(500);
	SMG_Bit(2,0xbf);
	SMG_Delay(500);
	SMG_Bit(3,0xff);
	SMG_Delay(500);
	SMG_Bit(4,0xff);
	SMG_Delay(500);
	
	SMG_Bit(5,SMG_NoDot[dat / 100]);
	SMG_Delay(500);
	SMG_Bit(6,SMG_NoDot[dat % 100 / 10]);
	SMG_Delay(500);
	SMG_Bit(7,SMG_NoDot[dat % 10]);
	SMG_Delay(500);
	
	SMG_All(0xff);
}

void Init_System()
{
    
    
	Select_HC573(5);
	P0 = 0x00;
	Select_HC573(4);
	P0 = 0xff;
}

void Key_Scan()
{
    
    
	if(S4 == 0)
	{
    
    
		SMG_Delay(100);
		if(S4 == 0)
		{
    
    
			if(stat == 0)
			{
    
    
				stat = 1;
				while(S4 == 0)
				{
    
    
					channel = 1;  
					dat = PCF8591_adc(0x03);
					SMG_Display();
				}
			}
			else if(stat == 1)
			{
    
    
				stat = 0;
				while(S4 == 0)
				{
    
    
					channel = 3;  
					dat = PCF8591_adc(0x01);
					SMG_Display();
				}
			}
		}
	}
}

void main()
{
    
    
	Init_System();
	while(1)
	{
    
    
		Key_Scan();
		if(stat == 0)  				//上电时stat=0,光敏电阻控制显示电压
		{
    
    
			channel = 1;  
			dat = PCF8591_adc(0x01);
			SMG_Display();
			
		}
		else if(stat == 1)			//使用按键,电位器控制显示电压
		{
    
    
			channel = 3;  
			dat = PCF8591_adc(0x03);
			SMG_Display();
		}
	}
}


(五)【IIC-AT24C02】

【点击此链接,立即学习小蜜蜂老师的AT24C02教程】

存储数据掉电不丢失

上电一次,数据改变一次
此次锁存器与头文件也采用了模块化编程
会出现2个PCD8951函数未调用的警告
由于24C02与8951函数十分相似,可以照它的模式编写,所以8951函数我没有删除,直接从上一节工程中保留下来,写了却没有使用就会出现警告

headfile.h

#ifndef _HEADFILE_H
#define _HEADFILE_H

#include "reg52.h"		//引脚
#include "config.h"		//锁存器、系统初始化
#include "smg.h"		//数码管显示
#include "iic.h"		//PCF8951、AT24C02

#endif

config.c

#include "reg52.h"

void Select_HC573(unsigned char channel)
{
    
    
	switch(channel)
	{
    
    
		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;
	}
}

void Init_System()
{
    
    
	Select_HC573(5);
	P0 = 0x00;
	Select_HC573(4);
	P0 = 0xff;	
}

config.h

#ifndef _CONFIG_H
#define _CONFIG_H

void Select_HC573(unsigned char channel);
void Init_System();

#endif

smg.c

#include "reg52.h"
#include "config.h"

void SMG_Delay(unsigned char t)
{
    
    
	while(t--);
}

void SMG_Bit(unsigned char pos,unsigned char value)
{
    
    
	Select_HC573(7);
	P0 = 0xff;
	Select_HC573(6);
	P0 = 0x01 << pos;
	Select_HC573(7);
	P0 = value;
}

void SMG_All(unsigned char dat)
{
    
    
	Select_HC573(6);
	P0 = 0xff;
	Select_HC573(7);
	P0 = dat;
}

smg.h

#ifndef _SMG_H
#define _SMG_H

code unsigned char SMG_NoDot[10]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code unsigned char SMG_Dot[10]={
    
    0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

void SMG_Delay(unsigned char t);
void SMG_Bit(unsigned char pos,unsigned char value);
void SMG_All(unsigned char dat);

#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;    
}


unsigned char PCF8951_adc(unsigned char addr)
{
    
    
	unsigned char tmp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	tmp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	return tmp;
}
void PCF8951_dac(unsigned char dat)
{
    
    
	IIC_Start();	
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
unsigned char AT24C02_read(unsigned char addr)
{
    
    
	unsigned char tmp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	tmp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	return tmp;
}	
void AT24C02_write(unsigned char addr,unsigned char date)
{
    
    
	IIC_Start();	
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

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

unsigned char PCF8951_adc(unsigned char addr);
void PCF8951_dac(unsigned char dat);
	
unsigned char AT24C02_read(unsigned char addr);
void AT24C02_write(unsigned char addr,unsigned char date);

#endif

main.c

#include "headfile.h"
unsigned char dat1 = 0,dat2 = 0,dat3 = 0;

void Delay(unsigned int t)
{
    
    
	while(t--);
}

void read_write()
{
    
    
	dat1 = AT24C02_read(0x01);
	dat2 = AT24C02_read(0x03);
	dat3 = AT24C02_read(0x05);
	
	dat1 = dat1 + 1;
	dat2 = dat2 + 2;
	dat3 = dat3 + 3;
	
	if(dat1 > 10)dat1 = 0;
	if(dat2 > 20)dat2 = 0;
	if(dat3 > 30)dat3 = 0;
	
	AT24C02_write(0x01, dat1);
	Delay(3000);
	AT24C02_write(0x03, dat2);
	Delay(3000);
	AT24C02_write(0x05, dat3);
	Delay(3000);
}

void SMG_Display()
{
    
    
	SMG_Bit(0,SMG_NoDot[dat1 / 10]);
	SMG_Delay(500);
	SMG_Bit(1,SMG_NoDot[dat1 % 10]);
	SMG_Delay(500);
	
	SMG_Bit(2,0xbf);
	SMG_Delay(500);
	
	SMG_Bit(3,SMG_NoDot[dat2 / 10]);
	SMG_Delay(500);
	SMG_Bit(4,SMG_NoDot[dat2 % 10]);
	SMG_Delay(500);
	
	SMG_Bit(5,0xbf);
	SMG_Delay(500);
	
	SMG_Bit(6,SMG_NoDot[dat3 / 10]);
	SMG_Delay(500);
	SMG_Bit(7,SMG_NoDot[dat3 % 10]);
	SMG_Delay(500);
	
	SMG_All(0xff);
}


void main()
{
    
    
	Init_System();
	read_write();
	while(1)
	{
    
    
		SMG_Display();
		
	}
}

(六)【超声波测距】

(偷个小懒,国赛模块先放一放吧…

猜你喜欢

转载自blog.csdn.net/Taylor_Kurt/article/details/128916502