hhhhhhhaa 发表于 2018-8-10 10:50:59

feixiang20 发表于 2018-8-10 00:04
指针和中断有问题吗,加一个看看呢
IIC_Stop(); //产生一个停止条件
delay_ms(10);...

delay_ms(10);这个是单独写的还是keil里自带的啊

hhhhhhhaa 发表于 2018-8-10 10:51:33

huangyanga 发表于 2018-8-9 18:22
data_buff=I2C_ReceiveData(I2C1);
---------确定这样写可以?整数赋给一个指针了

可以,确定,能读取到数据,这个不是指针,是一个数组

hhhhhhhaa 发表于 2018-8-10 10:52:11

wudianjun2001 发表于 2018-8-9 17:04
读时间的话定时读就可以了,不行的话先网上找个IO口模拟IIC的程序先试试,我一般都喜欢用模拟的,不喜欢MCU ...

怎么才能定时读取啊?我是初学的

wudianjun2001 发表于 2018-8-10 11:49:06

hhhhhhhaa 发表于 2018-8-10 10:52
怎么才能定时读取啊?我是初学的

定时中断啊

hhhhhhhaa 发表于 2018-8-10 13:38:46

wudianjun2001 发表于 2018-8-10 11:49
定时中断啊

不会用定时中断

发表于 2018-8-10 13:43:07

定时中断读取也不对啊。应该是像上面说的用delay的方式,可以用系统默认的systick做。

hhhhhhhaa 发表于 2018-8-10 14:51:24

安 发表于 2018-8-10 13:43
定时中断读取也不对啊。应该是像上面说的用delay的方式,可以用系统默认的systick做。 ...

有sys的示例吗

发表于 2018-8-10 16:31:03

官方例程库里面全有。

hhhhhhhaa 发表于 2018-8-10 16:38:40

安 发表于 2018-8-10 16:31
官方例程库里面全有。

太复杂了,看不懂,自己写了个延时程序 ,调用一下就好了
void Delay_MS(u16 dly)      
{
        u16 i,j;
        for(i=0;i<dly;i++)
                for(j=10000;j>0;j--);
}

hhhhhhhaa 发表于 2018-12-17 11:15:23

IIC.h文件
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
#include "delay.h"


//IIC所有操作函数
void IIC_Init(void) ;         //初始化IIC的IO口               


u8 IIC_Start(void);                          //发送IIC开始信号
void IIC_Stop(void);                                  //发送IIC停止信号
u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号
void IIC_Ack(void);                                          //IIC发送ACK信号
void IIC_NAck(void);                                  //IIC不发送ACK信号

void IIC_Send_Byte(u8 txd);               //IIC发送一个字节
u8 IIC_Read_Byte(void);       //IIC读取一个字节


#endif

经过几个月的学习,最近又想好好去研究一下PCF8563与IIC通讯,重新编写了IIC.c 和IIC.h的文件,最基本的文件编写完成后,开始编写PCF8563.c 和pcf8563.h文件 最后在主函数里直接调用 具体代码如下
#include "myiic.h"


#define SCL_PIN       GPIO_Pin_6
#define SDA_PIN       GPIO_Pin_7

#define SCL_H         GPIOB->BSRR = SCL_PIN
#define SCL_L         GPIOB->BRR= SCL_PIN
   
#define SDA_H         GPIOB->BSRR = SDA_PIN
#define SDA_L         GPIOB->BRR= SDA_PIN

#define SCL_read      GPIOB->IDR& SCL_PIN
#define SDA_read      GPIOB->IDR& SDA_PIN


#defineFALSE(0)
#defineTRUE   (1)

#define I2C_delay()   delay_ms(4)





//第一步初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ;   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
}



//产生IIC起始信号
u8 IIC_Start(void)
{
                                SDA_H;
              delay_ms(10);
                                SCL_H;
                                delay_ms(10);
//                                if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
                                SDA_L;
                                delay_ms(10);
//                                if(SDA_read)return FALSE; //SDA线为高电平则总线出错,退出
                                SCL_L;
                                delay_ms(10);
                                return TRUE;
}          
//产生IIC停止信号
void IIC_Stop(void)
{
          SCL_L;
                I2C_delay();
                SDA_L;
                I2C_delay();
                SCL_H;
                I2C_delay();
                SDA_H;
                I2C_delay();
          SCL_L;
          I2C_delay();
                                                                  
}
//等待应答信号到来
//返回值:1,接收应答失败
//      0,接收应答成功
u8 IIC_Wait_Ack(void)
{
          SCL_L;
                I2C_delay();
                SDA_H;
                I2C_delay();
                SCL_H;
                I2C_delay();
                if(SDA_read)
                {
                        SCL_L;
                        return FALSE;
                }
                SCL_L;
                return TRUE;
       
}
//产生ACK应答
void IIC_Ack(void)
{
          SCL_L;
                I2C_delay();
                SDA_L;
                I2C_delay();
                SCL_H;
                I2C_delay();
                SCL_L;
                I2C_delay();
       
}
//不产生ACK应答                  
void IIC_NAck(void)
{
          SCL_L;
                I2C_delay();
                SDA_H;
                I2C_delay();
                SCL_H;
                I2C_delay();
                SCL_L;
                I2C_delay();
}                                                                            
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC_Send_Byte(u8 txd)
{                        
            u8 i=8;
                while(i--)
                {
                        SCL_L;
                        I2C_delay();
                        if(txd&0x80)
                                SDA_H;
                        else
                                SDA_L;   
                        txd<<=1;
                        I2C_delay();
                        SCL_H;
                        I2C_delay();
                }
                SCL_L;
//        return         IIC_Wait_Ack();
}           

u8 IIC_Read_Byte(void)
{
          u8 i=8;
                u8 ReceiveByte=0;
                SDA_H;
                while(i--)
                {
                        ReceiveByte<<=1;      
                        SCL_L;
                        I2C_delay();
                        SCL_H;
                        I2C_delay();
                        if(SDA_read)
                        {
                                ReceiveByte|=0x01;
                        }
                }
                SCL_L;
                return ReceiveByte;
}

以上是iic.c和iic.h 文件其中iic 发送数据的时候可以把主机发送后的等待加进去 这样写pcf8563的时候方便些 ,
这一部分是pcf8563.h 的文件


#ifndef __PCF8563_H
#define __PCF8563_H
#include "sys.h"
#include "myiic.h"
#include "string.h"
typedef struct
{
       
    unsigned charyear;                                                                       
          unsigned charmon;
    unsigned charweek;       
          unsigned charday;                                                                                              
          unsigned charhour;                                                                               
          unsigned charmin;                                                                               
                unsigned charsec;       

}sTime;

extern sTime time;

void Get_Time(void);
void Set_Time(void);


#endif
下面是pcf8563.c 的文件
#include "pcf8563.h"




/*-----------------------------------------------------------------
   函数名: ByteToPbcd
       功能: 将二进制数转换成BCD码.
       输入: 2进制数.
       输出: 无.
       返回: BCD码.
       BIN码就是二进制编码。
       比如十进制数的11,用BIN码表示就是1011;
       左边的1表示十制的8,左边第三位的1表示十制的2,
       左边第四位的1表示十制的1,
       (即 8+2+1=11)
   BCD码就是用四位二进制数表示一位十进制数的编码,
       比如十进制数11用BCE码表示就是00010001;
       前面的0001表示十进制的十位的1,
       后面买的0001表示十进制的个位的1.
--------------------------------------------------------------------*/   
                u8 PCF8563_ByteToPbcd(u8_ucHex/* 二进制数 */)   
               {   
                                return ((_ucHex / 10) << 4) + (_ucHex % 10);   
                       
                }   

/*------------------------------------------------------------------
* 函数名: PbcdToByte
* 功能: 将PBCD数据转换成HEX型数据.
* 输入: bPbcd 待转换的PBCD数据.
* 输出: 无.
* 返回: uint8_t 转换后的HEX数据.
       BIN码就是二进制编码。
       比如十进制数的11,用BIN码表示就是1011;
       左边的1表示十制的8,左边第三位的1表示十制的2,
       左边第四位的1表示十制的1,
       (即 8+2+1=11)
   BCD码就是用四位二进制数表示一位十进制数的编码,
       比如十进制数11用BCE码表示就是00010001;
       前面的0001表示十进制的十位的1,
       后面买的0001表示十进制的个位的1.               
---------------------------------------------------------------------*/   
               
               
u8 PCF8563_PbcdToByte(u8 _ucPbcd /* 待转换的PBCD数据 */)   
{   
    return ((10 * (_ucPbcd >> 4)) + (_ucPbcd & 0x0f));   
}   


/*******************************************************************************
* 文件名:void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
* 描述: PCF8563某寄存器写入一个字节数据
* 功能:REG_ADD:要操作寄存器地址          dat:    要写入的数据
* 作者:
* 版本号:
*******************************************************************************/
unsigned char PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
{
      if(!IIC_Start())
                                {
                                return 0;
                                }
      IIC_Send_Byte(0xA2);//读地址 A3 read A3H;写地址是A2write A2H
              if (!IIC_Wait_Ack())
                                {
                                        IIC_Stop();
                                        return 0;
                                }
                                IIC_Send_Byte(REG_ADD);
                                IIC_Wait_Ack();
                               
                                IIC_Send_Byte(dat);//发送数据
                                IIC_Wait_Ack();
                               
      IIC_Stop();
                                return 1;
}


/*******************************************************************************
* 文件名:unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
* 描述: PCF8563某寄存器读取一个字节数据
* 功能:REG_ADD:要操作寄存器地址          读取得到的寄存器的值
* 作者:
* 版本号:
*******************************************************************************/
unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
{
              u8ReData;
      IIC_Start();
      IIC_Send_Byte(0xA2);//读地址 A3 read A3H;写地址是A2write A2H
                      if (!IIC_Wait_Ack())
                                {
                                                       IIC_Stop();
                                }
                                IIC_Send_Byte(REG_ADD);//确定要操作的寄存器
              IIC_Wait_Ack();
                                IIC_Start();//重启总线
                                IIC_Send_Byte(0xA3);//发送读取命令
                                IIC_Wait_Ack();
                                ReData = IIC_Read_Byte();//读取数据
                                IIC_NAck();//发送非应答信号结束数据传送
      IIC_Stop();
                       
      return ReData;
}
/*******************************************************************************
* 文件名:void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
* 描述: PCF8563写入多组数据
* 功能:REG_ADD:要操作寄存器起始地址          num:    写入数据数量         *WBuff: 写入数据缓存
* 作者:
* 版本号:
*******************************************************************************/
u8 PCF8563_Write_nByte(u8* pBuffer, u16 WriteAddr, u16 Num)
{
      
            
      IIC_Start();
                                                  
      IIC_Send_Byte(0xA2);//读地址 A3 read A3H;写地址是A2write A2H
                     if (!IIC_Wait_Ack())
                                {
                                               IIC_Stop();
                             return 0;
                                }
                                IIC_Send_Byte(WriteAddr);//定位起始寄存器地址
                                IIC_Wait_Ack();
                                while(Num--)
                {
                        IIC_Send_Byte(* pBuffer);
                        IIC_Wait_Ack();
                        pBuffer++;
                }
      IIC_Stop();
                                return 1;
}
/*******************************************************************************
* 文件名:void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
* 描述: PCF8563读取多组数据
* 功能:REG_ADD:要操作寄存器起始地址          num:    读取数据数量         *RBuff: 读取数据缓存
* 作者:
* 版本号:
*******************************************************************************/
u8 PCF8563_Read_nByte(u8* pBuffer, u16 WriteAddr, u16 NumByteToRead)
{
   
           
      
      if(!IIC_Start())
                        {
                          return 0;
                       
                        }
                                       
       
      IIC_Send_Byte(0xA2);//读地址 A3 read A3H;写地址是A2write A2H
                     if (!IIC_Wait_Ack())
                                {
                                        IIC_Stop();
                          return 0;
                                }
       
                                IIC_Send_Byte(WriteAddr);//定位起始寄存器地址
                                if(!IIC_Wait_Ack())
                                {
                               
                                IIC_Stop();
                          return 0;
                                }
                                       
                                IIC_Start();
      IIC_Send_Byte(0xA3);                               
      IIC_Wait_Ack();

                               
                                while(NumByteToRead)
                                {
                                        *pBuffer = IIC_Read_Byte();
                                        if(NumByteToRead == 1)
                                        {
                                        IIC_NAck();
                                        }
                                        else
                                        {                               
                                        IIC_Ack();
                                        pBuffer++;
                                        }
                                        NumByteToRead--;
                                }
      IIC_Stop();
      return 1;                               
}


/*******************************************************************************
* 文件名:void Set_Time(sTime* time)
* 描述: PCF8563设置时间信息
* 功能:时间初始化
* 作者:
* 版本号:
*******************************************************************************/


void Set_Time(void)
{
          unsigned char ucBuf;
                        ucBuf = PCF8563_ByteToPbcd(time.sec);   //将字节转换为BCD码
                        ucBuf = PCF8563_ByteToPbcd(time.min);
                        ucBuf = PCF8563_ByteToPbcd(time.hour);
                        ucBuf = PCF8563_ByteToPbcd(time.day);
                        ucBuf = PCF8563_ByteToPbcd(time.mon);
                        ucBuf = PCF8563_ByteToPbcd(time.year);/* 年低位                 */      
          PCF8563_Write_nByte(ucBuf,0x02,7);
               
}
/*******************************************************************************
* 文件名:void Get_Time(sTime* time)
* 描述: PCF8563读取时间信息
* 功能:
* 作者:
* 版本号:
*******************************************************************************/

void Get_Time(void)
{   
    unsigned char ucaBuf;
          PCF8563_Read_nByte(ucaBuf,0x02,7);
    time.sec=ucaBuf & 0x7F;   
    time.min=ucaBuf & 0x7F;   
    time.hour =ucaBuf & 0x3F;   
    time.day=ucaBuf & 0x3F;
    time.mon=ucaBuf & 0x1F;   
    time.year =ucaBuf;


//        time.sec=PCF8563_PbcdToByte(ucaBuf & 0x7F);   
//    time.min=PCF8563_PbcdToByte(ucaBuf & 0x7F);   
//    time.hour =PCF8563_PbcdToByte(ucaBuf & 0x3F);   
//    time.day=PCF8563_PbcdToByte(ucaBuf & 0x3F);
//    time.mon=PCF8563_PbcdToByte(ucaBuf & 0x1F);   
//    time.year =PCF8563_PbcdToByte(ucaBuf);

}


下面是主函数的调用
#include "HEAD.h"


sTime time;

int main(void)
{       
                                u8 key;
       time.year=18;
             time.mon=12;
             time.day=17;
             time.hour=9;
             time.min =55;
             time.sec =15;
   
                                delay_init();                       //延时函数初始化          
                                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
                                uart_init(9600);                  //串口初始化为9600
                                IIC_Init();       //IIC初始化
      Set_Time();
             
                        while(1)
           {
                       
      Get_Time();
                        key=time.year;
                        key=time.mon;
                        key=time.day;
                        key=time.hour;
                        key=time.min;
                        key=time.sec;
                        RS232_Send_Data(key,6);
          delay_ms(500);

                               
                        }
}
为了显示方便 把pcf8563最后的读取部分做了修改,使得显示是BCD码格式的,然后通过串口助手的16进制读取 显示的时间就是具体的时间了

页: 1 [2] 3
查看完整版本: stm103vct6与8563通讯