
#include <reg52.h> // 包含51单片机寄存器定义的头文件
#include <intrins.h> //包含_nop_()函数定义的头文件
#define OP_READ 0xa1 // 器件地址以及读取 *** 作,0xa1即为1010 0001B
#define OP_WRITE 0xa0 // 器件地址以及写入 *** 作,0xa1即为1010 0000B
sbit SCL=P3^4//将串行时钟总线SCL位定义在为P3.4引脚
sbit SDA=P3^5 //将串行数据总线SDA位定义在为P3.5引脚
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}//定义共阳数码管显示字型码
unsigned char sec=0//定义计数值,每过1秒,sec加1
unsigned int count//定时中断次数
bit write=0//写24C08的标志
sbit shiwei=P2^6//十位选通定义
sbit gewei=P2^7//个位选通定义
sbit K5=P3^2 //清0按键
/*****************************************************
函数功能:延时1ms
***************************************************/
void delay1ms()
{
unsigned char i,j
for(i=0i<10i++)
for(j=0j<33j++)
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i
for(i=0i<ni++)
delay1ms()
}
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
// 开始位
{
SDA = 1 //SDA初始化为高电平“1”
SCL = 1 //开始数据传送时,要求SCL为高电平“1”
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SDA = 0 //SDA的下降沿被认为是开始信号
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SCL = 0 //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()// 停止位
{
SDA = 0//SDA初始化为低电平“0” _n
SCL = 1//结束数据传送时,要求SCL为高电平“1”
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SDA = 1 //SDA的上升沿被认为是结束信号
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SDA=0
SCL=0
}
/***************************************************
函数功能:检测应答位
***************************************************/
bit Ask() //检测应答
{
bit ack_bit //储存应答位
SDA = 1 // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
//以让SDA线转由接收设备(AT24Cxx)控制
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
SCL = 1 //根据上述规定,SCL应为高电平
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
ack_bit = SDA//接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
//若送高电平,表示没有接收到,传送异常 结束发送
SCL = 0 //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
return ack_bit // 返回AT24Cxx应答位
}
/***************************************************
函数功能:从AT24Cxx读取数据
出口参数:x
***************************************************/
unsigned char ReadData()
// 从AT24Cxx移入数据到MCU
{
unsigned char i
unsigned char x //储存从AT24Cxx中读出的数据
for(i = 0i <8i++)
{
SCL = 1 //SCL置为高电平
x<<=1 //将x中的各二进位向左移一位
x|=(unsigned char)SDA //将SDA上的数据通过按位“或“运算存入x中
SCL = 0 //在SCL的下降沿读出数据
}
return(x) //将读取的数据返回
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
void WriteCurrent(unsigned char y)
{
unsigned char i
for(i = 0i <8i++) // 循环移入8个位
{
SDA = (bit)(y&0x80) //通过按位“与”运算将最高位数据送到S
//因为传送时高位在前,低位在后
_nop_() //等待一个机器周期
SCL = 1 //在SCL的上升沿将数据写入AT24Cxx
_nop_() //等待一个机器周期
_nop_()//等待一个机器周期
SCL = 0 //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1 //将y中的各二进位向左移一位
}
}
/***************************************************
函数功能:向AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
start() //开始数据传递
WriteCurrent(OP_WRITE) //选择要 *** 作的AT24Cxx芯片,并告知要对其写入数据
Ask()
WriteCurrent(add) //写入指定地址
Ask()
WriteCurrent(dat) //向当前地址(上面指定的地址)写入数据
Ask()
stop() //停止数据传递
delaynms(4) //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:从AT24Cxx中的当前地址读取数据
出口参数:x (储存读出的数据)
***************************************************/
unsigned char ReadCurrent()
{
unsigned char x
start() //开始数据传递
WriteCurrent(OP_READ) //选择要 *** 作的AT24Cxx芯片,并告知要读其数据
Ask()
x=ReadData()//将读取的数据存入x
stop() //停止数据传递
return x //返回读取的数据
}
/***************************************************
函数功能:从AT24Cxx中的指定地址读取数据
入口参数:set_addr
出口参数:x
***************************************************/
unsigned char ReadSet(unsigned char set_addr)
// 在指定地址读取
{
start() //开始数据传递
WriteCurrent(OP_WRITE) //选择要 *** 作的AT24Cxx芯片,并告知要对其写入数据
Ask()
WriteCurrent(set_addr) //写入指定地址
Ask()
return(ReadCurrent()) //从指定地址读出数据并返回
}
/***********************************************************/
void LEDshow() //LED显示函数
{
P0=table[sec/10]
shiwei=0
delaynms(2)
shiwei=1
P0=table[sec%10]
gewei=0
delaynms(2)
gewei=1
}
/***********************************************************/
/***************************************************
函数功能:主函数
***************************************************/
void main(void)
{
TMOD=0x01//定时器0工作在方式1
ET0=1
EA=1
TH0=(65536-50000)/256//对TH0 TL0赋值
TL0=(65536-50000)%256//使定时器0.05秒中断一次
SDA = 1 // SDA=1,SCL=1,使主从设备处于空闲状态
SCL = 1
sec=ReadSet(2)//读出保存的数据赋于sec
TR0=1//开始计时
while(1)
{
LEDshow()
if(write==1) //判断计时器是否计时一秒
{
write=0//清零
WriteSet(2,sec)//在24c08的地址2中写入数据sec
}
if(K5==0){
delaynms(10)
if(K5==0){
sec=0
}
}
}
}
/**************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
TH0=(65536-50000)/256//对TH0 TL0赋值
TL0=(65536-50000)%256//重装计数初值
count++//每过50ms tcnt加一
if(count==20) //计满20次(1秒)时
{
count=0//重新再计
sec++
write=1//1秒写一次24C08
if(sec==100) //定时100秒,在从零开始计时
{sec=0}
}
}
//实例85:将数据"0x0f"写入AT24C02再读出送P1口显示#include <reg51.h> // 包含51单片机寄存器定义的头文件
#include <intrins.h> //包含_nop_()函数定义的头文件
#define OP_READ 0xa1 // 器件地址以及读取 *** 作,0xa1即为1010 0001B
#define OP_WRITE 0xa0 // 器件地址以及写入 *** 作,0xa1即为1010 0000B
sbit SDA=P3^4 //将串行数据总线SDA位定义在为P3.4引脚
sbit SCL=P3^3//将串行时钟总线SDA位定义在为P3.3引脚
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j
for(i=0i<10i++)
for(j=0j<33j++)
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i
for(i=0i<ni++)
delay1ms()
}
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
// 开始位
{
SDA = 1 //SDA初始化为高电平“1”
SCL = 1 //开始数据传送时,要求SCL为高电平“1”
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
SDA = 0 //SDA的下降沿被认为是开始信号
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
SCL = 0 //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()
// 停止位
{
SDA = 0//SDA初始化为低电平“0” _n
SCL = 1//结束数据传送时,要求SCL为高电平“1”
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SDA = 1 //SDA的上升沿被认为是结束信号
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
_nop_()//等待一个机器周期
SDA=0
SCL=0
}
/***************************************************
函数功能:从AT24Cxx读取数据
出口参数:x
***************************************************/
unsigned char ReadData()
// 从AT24Cxx移入数据到MCU
{
unsigned char i
unsigned char x //储存从AT24Cxx中读出的数据
for(i = 0i <8i++)
{
SCL = 1 //SCL置为高电平
x<<=1 //将x中的各二进位向左移一位
x|=(unsigned char)SDA //将SDA上的数据通过按位“或“运算存入x中
SCL = 0 //在SCL的下降沿读出数据
}
return(x) //将读取的数据返回
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
bit WriteCurrent(unsigned char y)
{
unsigned char i
bit ack_bit //储存应答位
for(i = 0i <8i++) // 循环移入8个位
{
SDA = (bit)(y&0x80) //通过按位“与”运算将最高位数据送到S
//因为传送时高位在前,低位在后
_nop_() //等待一个机器周期
SCL = 1 //在SCL的上升沿将数据写入AT24Cxx
_nop_() //等待一个机器周期
_nop_()//等待一个机器周期
SCL = 0 //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1 //将y中的各二进位向左移一位
}
SDA = 1// 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
//以让SDA线转由接收设备(AT24Cxx)控制
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
SCL = 1 //根据上述规定,SCL应为高电平
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
_nop_() //等待一个机器周期
ack_bit = SDA//接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
//若送高电平,表示没有接收到,传送异常
SCL = 0 //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
return ack_bit // 返回AT24Cxx应答位
}
/***************************************************
函数功能:向AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
start() //开始数据传递
WriteCurrent(OP_WRITE) //选择要 *** 作的AT24Cxx芯片,并告知要对其写入数据
WriteCurrent(add) //写入指定地址
WriteCurrent(dat) //向当前地址(上面指定的地址)写入数据
stop() //停止数据传递
delaynms(4) //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:从AT24Cxx中的当前地址读取数据
出口参数:x (储存读出的数据)
***************************************************/
unsigned char ReadCurrent()
{
unsigned char x
start() //开始数据传递
WriteCurrent(OP_READ) //选择要 *** 作的AT24Cxx芯片,并告知要读其数据
x=ReadData()//将读取的数据存入x
stop() //停止数据传递
return x //返回读取的数据
}
/***************************************************
函数功能:从AT24Cxx中的指定地址读取数据
入口参数:set_addr
出口参数:x
***************************************************/
unsigned char ReadSet(unsigned char set_addr)
// 在指定地址读取
{
start() //开始数据传递
WriteCurrent(OP_WRITE) //选择要 *** 作的AT24Cxx芯片,并告知要对其写入数据
WriteCurrent(set_addr) //写入指定地址
return(ReadCurrent()) //从指定地址读出数据并返回
}
/***************************************************
函数功能:主函数
***************************************************/
main(void)
{
SDA = 1 // SDA=1,SCL=1,使主从设备处于空闲状态
SCL = 1
WriteSet(0x36,0x0f) //在指定地址“0x36”中写入数据“0x0f”
P1=ReadSet(0x36) //从指定地址“0x36中读取数据并送P1口显示
}
//AT24C系列读写程序//本程序调试通过
#include "csh.h"
#include<reg51.h>
#include <intrins.h>
sbit SDA=P3^3//AT24C02数据线
sbit SCL=P3^2//AT24C02时钟线
//sbit SDA=P3^4//AT24C02数据线
//sbit SCL=P3^3//AT24C02时钟线
void start()
// 开始位
{
SDA = 1
SCL = 1
_nop_()
_nop_()
SDA = 0
_nop_()
_nop_()
_nop_()
_nop_()
SCL = 0
}
void stop()
// 停止位
{
SDA = 0
_nop_()
_nop_()
SCL = 1
_nop_()
_nop_()
_nop_()
_nop_()
SDA = 1
}
unsigned char shin()
// 从AT24Cxx移入数据到MCU
{
unsigned char i,read_data
for(i = 0i <8i++)
{
SCL = 1
read_data <<= 1
read_data |= (unsigned char)SDA
SCL = 0
}
return(read_data)
}
bit shout(unsigned char write_data)
// 从MCU移出数据到AT24Cxx
{
unsigned char i
bit ack_bit
for(i = 0i <8i++) // 循环移入8个位
{
SDA = (bit)(write_data &0x80)
_nop_()
SCL = 1
_nop_()
_nop_()
SCL = 0
write_data <<= 1
}
SDA = 1 // 读取应答
_nop_()
_nop_()
SCL = 1
_nop_()
_nop_()
_nop_()
_nop_()
ack_bit = SDA
SCL = 0
return ack_bit // 返回AT24Cxx应答位
}
void write_byte(unsigned char addr, unsigned char write_data)
// 在指定地址addr处写入数据write_data
{
start()
shout(OP_WRITE)
shout(addr)
shout(write_data)
stop()
delay(10) // 写入周期
}
unsigned char read_current()
// 在当前地址读取
{
unsigned char read_data
start()
shout(OP_READ)
read_data = shin()
stop()
return read_data
}
unsigned char read_random(unsigned char random_addr)
// 在指定地址读取
{
start()
shout(OP_WRITE)
shout(random_addr)
return(read_current())
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)