我使用STM32f107+fm31256,读取出来得时间都是FF这是我的程序
#include "fm31256.h"
#include "delay.h"
#define IIC_WRITE 0xa0 //芯片引脚可选硬件地址均为0
#define IIC_READ 0xa1 //芯片引脚可选硬件地址均为0
#define REG_READ 0Xd1 //register read //芯片引脚可选硬件地址均为0
#define REG_WRITE 0Xd0 //register write//芯片引脚可选硬件地址均为0
#define Sht30_I2C_Sda_GPIO GPIOB
#define Sht30_I2C_Sda_ClockCmd RCC_AHBPeriph_GPIOB
#define Sht30_I2C_Sda_PIN GPIO_Pin_7
#define Sht30_I2C_Scl_GPIO GPIOB
#define Sht30_I2C_Scl_ClockCmd RCC_AHBPeriph_GPIOB
#define Sht30_I2C_Scl_PIN GPIO_Pin_6
#define Sht30_I2C_Scl_SET GPIO_SetBits(Sht30_I2C_Scl_GPIO,Sht30_I2C_Scl_PIN)
#define Sht30_I2C_Scl_CLR GPIO_ResetBits(Sht30_I2C_Scl_GPIO,Sht30_I2C_Scl_PIN)
#define Sht30_I2C_Scl_READ GPIO_ReadInputDataBit(Sht30_I2C_Scl_GPIO,Sht30_I2C_Scl_PIN)
#define Sht30_I2C_Sda_SET GPIO_SetBits(Sht30_I2C_Sda_GPIO,Sht30_I2C_Sda_PIN)
#define Sht30_I2C_Sda_CLR GPIO_ResetBits(Sht30_I2C_Sda_GPIO,Sht30_I2C_Sda_PIN)
#define Sht30_I2C_Sda_READ GPIO_ReadInputDataBit(Sht30_I2C_Sda_GPIO,Sht30_I2C_Sda_PIN)
// SDA on port B, bit 14
#define SDA_LOW() Sht30_I2C_Sda_CLR // set SDA to low
#define SDA_OPEN() Sht30_I2C_Sda_SET // set SDA to open-drain
#define SDA_READ Sht30_I2C_Sda_READ // read SDA
// SCL on port B, bit 13 /* -- adapt the defines for your uC -- */
#define SCL_LOW() Sht30_I2C_Scl_CLR // set SCL to low
#define SCL_OPEN() Sht30_I2C_Scl_SET // set SCL to open-drain
#define SCL_READ Sht30_I2C_Scl_READ // read SCL
//初始化IIC
void IIC_Init(void) /* -- adapt the init for your uC -- */
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
// GPIO_InitStructure.GPIO_Mode = GPIO_OType_OD;//开漏输出
// GPIO_InitStructure.GPIO_Mode = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
// GPIO_InitStructure.GPIO_Mode = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_7);
}
//SDA设置为输入
void SDA_IN (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//先使能外设IO portc时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空输入
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
//SDA设置为输出
void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//先使能外设IO portc时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_PuPd = GPIO_OType_OD;
// GPIO_InitStructure.GPIO_PuPd = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
//产生IIC起始信号
void Start(void)
{
SDA_OUT(); //sda线设置为输出
// SDA_OPEN();
SDA_OPEN();
SCL_OPEN();
delay_us(16);
SDA_LOW(); //START:when CLK is high,DATA change form high to low
delay_us(16);
SCL_LOW(); //钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void Stop(void)
{
SDA_OUT();//sda线输出
SCL_LOW();
SDA_LOW();//STOP:when CLK is high DATA change form low to high
delay_us(16);
SCL_OPEN();
SDA_OPEN();//发送I2C总线结束信号
delay_us(16);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA设置为输入
SDA_OPEN();delay_us(4);
SCL_OPEN();delay_us(4);
while(SDA_READ)
{
ucErrTime++;
if(ucErrTime>250)
{
Stop();
return 1;
}
}
SCL_LOW();//时钟输出0
return 0;
}
//产生ACK应答
void Ack(void)
{
SCL_LOW();
SDA_OUT();
SDA_LOW();
delay_us(8);
SCL_OPEN();
delay_us(8);
SCL_LOW();
}
//不产生ACK应答
void IIC_NAck(void)
{
SCL_LOW();
SDA_OUT();
SDA_OPEN();
delay_us(8);
SCL_OPEN();
delay_us(8);
SCL_LOW();
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void WriteByte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
SCL_LOW();//拉低时钟开始数据传输
for(t=0;t<8;t++) //开始准备信号线
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
SDA_OPEN();
else
SDA_LOW();
txd<<=1;
delay_us(8); //对TEA5767这三个延时都是必须的
SCL_OPEN();
delay_us(8);
SCL_LOW();
delay_us(8);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t ReadByte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL_LOW();
delay_us(8);
SCL_OPEN();
receive<<=1;
if(SCL_READ)receive++;
delay_us(4);
}
if (!ack)
IIC_NAck();//发送nACK
else
Ack(); //发送ACK
return receive;
}
void WriteReg(u8 RegAdd,u8 Wdata)
{
Start();
WriteByte(REG_WRITE);
// while(IIC_Wait_Ack());
Ack();
// RegAdd = RegAdd & 0x1f;
WriteByte(RegAdd);
Ack();
// IIC_Wait_Ack();
WriteByte(Wdata);
Ack();
// IIC_Wait_Ack();
Stop();
}
u8 ReadReg(u8 RegAdd)
{
u8 RetValue;
Start();
WriteByte(REG_WRITE); //执行写入操作
// while(IIC_Wait_Ack());
Ack();
WriteByte(RegAdd); //读取地址
// IIC_Wait_Ack();
Ack();
Start();
WriteByte(REG_READ); //执行读取操作
// IIC_Wait_Ack();
Ack();
RetValue = ReadByte(0);
// SCL = 1; SDA = 1;SCL = 0;
SCL_OPEN();
SDA_OPEN();
SCL_LOW();
Stop();
return RetValue;
}
u8 ReadFRAM(u16 Address)
{
u8 RetValue;
Start();
WriteByte(IIC_WRITE);
Ack();
WriteByte((u8)(Address>>8));
Ack();
WriteByte((u8)(Address));
Ack();
Start();
WriteByte(IIC_READ);
Ack();
RetValue = ReadByte(0);
// SCL = 1;SDA = 1;SCL = 0;
SCL_OPEN();
SDA_OPEN();
SCL_LOW();
Stop();
return RetValue;
}
void WriteFRAM(u16 Address,u8 Wdata)
{
Start();
WriteByte(IIC_WRITE);
Ack();
WriteByte((u8)(Address>>8));
Ack();
WriteByte((u8)(Address));
Ack();
WriteByte(Wdata);
Ack();
Stop();
}
void Set_Realtime(u8 *realtime)//时间格式:低字节--高字节 秒,分,时,星期,日,月,年。
{
u8 i;
WriteReg(0x00,0x00); //停止写操作
WriteReg(0x00,0x02); //允许写操作
for(i=0;i<7;i++)WriteReg(0x02+i,realtime);
WriteReg(0x00,0x00); //停止写操作
}
void Get_Realtime(u8 *realtime)//时间格式:低字节--高字节 秒,分,时,星期,日,月,年。
{
u8 i;
WriteReg(0x00,0x00); //停止写操作
WriteReg(0x00,0x01); //允许读操作
for(i=0;i<7;i++)realtime=ReadReg(0x02+i);
WriteReg(0x00,0x00); //芯片时间更新至用户寄存器
}
void WatchDog_Enable(u8 timer)
{
timer=timer | 0x80; //看门狗使能
WriteReg(0x0A,timer); //重置看门狗计数器的数值
}
void WatchDog_Clear(void)
{
WriteReg(0x09,0x0A); //喂狗
}
void WatchDog_Disable(void)
{
WriteReg(0x0A,0x00);
}
void Fm31256_init(void)
{
IIC_Init();
// WriteReg(0x0B,0x00);//无写保护,VTP=2.6V
// WriteReg(0x0A,0x1f); //看门狗关闭,禁止看门狗计数器
// WriteReg(0x09,0x0a); //清除复位标志,看门狗计数器复位
// WriteReg(0x01,0x00); //启动时钟
// WriteReg(0x0B,0x04);
}
int main(void)
{
delay_init();
Fm31256_init();
WriteReg(CONTROL,0x80);
// delay_ms(5);
WriteReg(CONTROL,0x00); //启动时钟
//WriteReg(FLAGS,0x00); //清除标志位
WriteReg(FLAGS,0x02); //允许写操作
WriteReg(YEAR,0x08); //写时间
WriteReg(MOUNTH,0x01);
WriteReg(DAY,0x30);
WriteReg(DATE,0x03);
WriteReg(HOUR,0x15);
WriteReg(MINUTE,0x15);
WriteReg(SECOND,0x00);
WriteReg(FLAGS,0x00); //停止写操作
while(1)
{
Get_Realtime(retime);
}
}
这个是官方51的例程
#include
#define uint unsigned int
#define uchar unsigned char
#define IIC_WRITE 0xa0
#define IIC_READ 0xa1
#define REG_READ 0Xd1 //register read
#define REG_WRITE 0Xd0 //register write
#define WRITEPROTECT 0x0b //写保护
#define YEAR 0x08
#define MOUNTH 0x07
#define DAY 0x06
#define DATE 0x05
#define HOUR 0x04
#define MINUTE 0x03
#define SECOND 0x02
#define CONTROL 0x01 //控制
#define FLAGS 0x00 //标志
#define WDTFLAG 0x09 //看门狗标志
#define WDTTIME 0x0a //看门狗时间
uchar Time[7];
uchar counter = 0;
sbit SDA = P0^0;
sbit SCL = P0^1;
//sbit SDA = P1^2; //the SDA bit is prot 1 bit 3
//sbit SCL = P1^3; //the SCL bit is prot 1 bit 4
sbit CNT1 = P1^4; //event counter1 output
sbit CNT2 = P1^5; //enent counter2 output
sbit CAL = P1^6; //cal output
sbit RST = P1^7; //watchdog output
uchar bdata bbyte;
sbit d0 = bbyte^0;
sbit d1 = bbyte^1;
sbit d2 = bbyte^2;
sbit d3 = bbyte^3;
sbit d4 = bbyte^4;
sbit d5 = bbyte^5;
sbit d6 = bbyte^6;
sbit d7 = bbyte^7;
//================================
void Start() //开始
{
SDA = 1;
SCL = 1;
SDA = 0;
}
//=================================
void Stop() //停止
{
SDA = 0;
SCL = 1;
SDA = 1;
}
//=================================
void WriteByte(uchar Wdata) //写字节
{
bbyte = Wdata;
SCL = 0;
SDA = d7;SCL = 1; SCL = 0;
SDA = d6;SCL = 1; SCL = 0;
SDA = d5;SCL = 1; SCL = 0;
SDA = d4;SCL = 1; SCL = 0;
SDA = d3;SCL = 1; SCL = 0;
SDA = d2;SCL = 1; SCL = 0;
SDA = d1;SCL = 1; SCL = 0;
SDA = d0;SCL = 1; SCL = 0;
}
//==================================
uchar ReadByte() //读字节
{
uchar RetValue;
SCL =0;
SCL = 1;d7 = SDA;SCL = 0;
SCL = 1;d6 = SDA;SCL = 0;
SCL = 1;d5 = SDA;SCL = 0;
SCL = 1;d4 = SDA;SCL = 0;
SCL = 1;d3 = SDA;SCL = 0;
SCL = 1;d2 = SDA;SCL = 0;
SCL = 1;d1 = SDA;SCL = 0;
SCL = 1;d0 = SDA;SCL = 0;
RetValue = bbyte;
return RetValue;
}
//====================================
void Ack() //应答
{
uchar i;
SCL = 1;
i= 100;
while((i--)&&SDA);
SCL = 0;
}
//====================================
uchar ReadFRAM(uint Address) //
{
uchar RetValue;
Start();
WriteByte(IIC_WRITE);
Ack();
WriteByte((uchar)(Address>>8));
Ack();
WriteByte((uchar)(Address));
Ack();
Start();
WriteByte(IIC_READ);
Ack();
RetValue = ReadByte();
SCL = 1;SDA = 1;SCL = 0;
Stop();
return RetValue;
}
//=====================================
void WriteReg(uchar RegAdd,uchar Wdata) //写
{
Start();
WriteByte(REG_WRITE);
Ack();
RegAdd = RegAdd & 0x1f;
WriteByte(RegAdd);
Ack();
WriteByte(Wdata);
Ack();
Stop();
}
//=====================================
uchar ReadReg(uchar RegAdd) //读
{
uchar RetValue;
Start();
WriteByte(REG_WRITE);
Ack();
WriteByte(RegAdd);
Ack();
Start();
WriteByte(REG_READ);
Ack();
RetValue = ReadByte();
SCL = 1; SDA = 1;SCL = 0;
Stop();
return RetValue;
}
//=====================================
void WriteFRAM(uint Address,uchar Wdata)
{
Start();
WriteByte(IIC_WRITE);
Ack();
WriteByte((uchar)(Address>>8));
Ack();
WriteByte((uchar)(Address));
Ack();
WriteByte(Wdata);
Ack();
Stop();
}
//======================================
void Initiation(void) //initial for 9600 baud rate,use T1
{
TMOD |= 0x21;
TL1 = 0xfd;
TH1 = 0xfd;
SCON = 0x50;
PCON = 0X00;
EA = 1;
ET0 = 1; /* 允许定时器0中断 */
TL0 = 0xdc;
TH0 = 0x00; /* 定时器赋予初值 */
}
//=======================================
void SendData(uchar Sdata)
{
SBUF = Sdata;
while(!TI);
TI = 0;
}
//=======================================
void main(void)
{
uint Add;
uchar ReadData;
WriteReg(CONTROL,0x80); //停止时钟
Initiation(); //定时器中断
TR1 = 1;
SendData(0x11);
/*for(Add = 0;Add < 0xff;Add++)
{
WriteFRAM(Add,0xaa);
}
for(Add = 0x100;Add < 0x1ff;Add++)
{
WriteFRAM(Add,0x11);
}
for(Add = 0;Add < 0x1ff;Add++)
{
ReadData = ReadFRAM(Add);
SendData(ReadData);
}*/
//软件写保护功能不能实现????????????
//WriteReg(WRITEPROTECT,0x08); //软件写保护1/4
//WriteReg(WRITEPROTECT,0x10); //软件写保护1/2
//WriteReg(WRITEPROTECT,0x18); //软件写保护全部
/*for(Add = 0;Add < 0x1ff;Add++)
{
WriteFRAM(Add,0x55);
}
for(Add = 0;Add < 0x1ff;Add++)
{
ReadData = ReadFRAM(Add);
SendData(ReadData);
} */
WriteReg(CONTROL,0x00); //启动时钟
//WriteReg(FLAGS,0x00); //清除标志位
WriteReg(FLAGS,0x02); //允许写操作
WriteReg(YEAR,0x08); //写时间
WriteReg(MOUNTH,0x01);
WriteReg(DAY,0x30);
WriteReg(DATE,0x03);
WriteReg(HOUR,0x15);
WriteReg(MINUTE,0x15);
WriteReg(SECOND,0x00);
WriteReg(FLAGS,0x00); //停止写操作
//WriteReg(FLAGS,0x01); //允许读操作
TR0 = 1; //启动定时器0
while(1){;}
}
//=========================================
//定时中断,读取时钟
//=========================================
void Timer0() interrupt 1
{
TH0 = 0xdc;
TL0 = 0x00;
if(counter == 100)
{
counter = 0;
WriteReg(FLAGS,0x01); //允许读操作
Time[0] = ReadReg(YEAR);
SendData(Time[0]);
Time[1] = ReadReg(MOUNTH);
SendData(Time[1]);
Time[2] = ReadReg(DAY);
SendData(Time[2]);
Time[3] = ReadReg(DATE);
SendData(Time[3]);
Time[4] = ReadReg(HOUR);
SendData(Time[4]);
Time[5] = ReadReg(MINUTE);
SendData(Time[5]);
Time[6] = ReadReg(SECOND);
SendData(Time[6]);
WriteReg(FLAGS,0x00);
}
else
{
counter++;
}
}
scl和sda分别连到了单片机得PB6和PB7
|
|