[Lanqiao Cup Microcontroller] Application Summary of 6 Advanced Modules (IO Mode)

(1) [DS18B20 temperature sensor]

The last three digits of the digital tube display the current ambient temperature.

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

Just expand the parameters in all delay functions called in the official source code (2022 version) by 10 times

/*
  程序说明: 单总线驱动程序
  软件环境: 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();  //数码管显示
	}
}

(2) [DS1302 clock]

Digital tube display clock

ds1302.h

Directly add the official underlying driver code without modification.

#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

Pay attention to check whether the pins match

/*
  程序说明: 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--);
}

DS1302clock.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();
	}
}

(3) [NE555 timer and frequency measurement]

Digital tube display frequency output

The content related to the digital tube is the same as the previous reference.ch file

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

(4) [IIC-PCF8951-A/D]

[Click this link to learn the PCF8591 tutorial from Mr. XiaoBee immediately]

The digital tube displays ADC voltage data

上电时光敏电阻0x03The voltage display is controlled by
independent buttons. The voltage display S4is controlled by电位器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

Added on the basis of the official underlying files

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

iic.c

Added on the basis of the official underlying files

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


(5) [IIC-AT24C02]

[Click this link to learn Teacher XiaoBee’s AT24C02 tutorial immediately]

Stored data will not be lost during power outage

Once the power is turned on, the data changes once
This time the latches and header files also use modular programming.
There will be 2 warnings that the PCD8951 function is not called.
Since the 24C02 function is very similar to the 8951 function, it can be written according to its mode. Therefore, I did not delete the 8951 function and directly retained it from the previous section of the project. If it is written but not used, a warning will appear.

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

(6) [Ultrasonic ranging]

(I’m just lazy, let’s play with the national competition module first…

Guess you like

Origin blog.csdn.net/Taylor_Kurt/article/details/128916502