打印
[STM32F1]

我使用STM32f107+fm31256,读取出来得时间都是FF

[复制链接]
781|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dengdc|  楼主 | 2023-3-8 19:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用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++;
}


}

使用特权

评论回复
沙发
Undshing| | 2023-3-8 19:54 | 只看该作者
io口模拟的iic的时序?

使用特权

评论回复
板凳
童雨竹| | 2024-4-8 08:10 | 只看该作者

只要内存占用量不超过 256.0 就可以用 small 模式编译

使用特权

评论回复
地板
Wordsworth| | 2024-4-8 09:13 | 只看该作者

专门的滤波器来阻止交流噪声进入周围的电路

使用特权

评论回复
5
Clyde011| | 2024-4-8 10:16 | 只看该作者

电流型变换器电流检测电阻的公共接点和输出端电阻分压器的下端

使用特权

评论回复
6
公羊子丹| | 2024-4-8 11:09 | 只看该作者

超过变量128后必须使用compact模式编译

使用特权

评论回复
7
万图| | 2024-4-8 12:12 | 只看该作者

引线长度就决定了其响应信号的波长

使用特权

评论回复
8
Uriah| | 2024-4-8 13:15 | 只看该作者

数字电压表(DVM)或仪器来测量效率

使用特权

评论回复
9
帛灿灿| | 2024-4-8 15:11 | 只看该作者

任何一条PCB引线都可能成为天线

使用特权

评论回复
10
Bblythe| | 2024-4-8 16:14 | 只看该作者

滤波电容、功率开关管或整流器、电感或变压器

使用特权

评论回复
11
周半梅| | 2024-4-8 18:10 | 只看该作者

128以上的某些地址为特殊寄存器使用,不能给程序用

使用特权

评论回复
12
Pulitzer| | 2024-4-8 19:13 | 只看该作者

交流能量就会从输入或输出滤波电容上流进流出

使用特权

评论回复
13
probedog| | 2024-8-13 17:25 | 只看该作者
硬件连接不对?

使用特权

评论回复
14
laocuo1142| | 2024-8-13 17:26 | 只看该作者
可能是FM31256初始化问题

使用特权

评论回复
15
powerantone| | 2024-8-13 17:27 | 只看该作者
检查RTC寄存器访问

使用特权

评论回复
16
stormwind123| | 2024-8-13 17:27 | 只看该作者
确保FM31256的电源稳定,并且没有因为电压过低或过高而导致工作不正常。
检查是否有复位信号被意外触发,导致RTC被重置。

使用特权

评论回复
17
狄克爱老虎油| | 2024-8-17 23:54 | 只看该作者
都是F就是全高电平吧

使用特权

评论回复
18
狄克爱老虎油| | 2024-8-17 23:55 | 只看该作者
狄克爱老虎油 发表于 2024-8-17 23:54
都是F就是全高电平吧

应该是配置的不对

使用特权

评论回复
19
grfqq325| | 2024-8-28 12:01 | 只看该作者
数据线和时钟线与 STM32F107 的 I2C 引脚连接检查一下。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

892

主题

13885

帖子

7

粉丝