你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm103vct6与8563通讯

[复制链接]
hhhhhhhaa 提问时间:2018-8-9 14:34 /
阅读主题, 点击返回1楼
收藏 评论20 发布时间:2018-8-9 14:34
20个回答
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

不会用定时中断
回答时间: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--);
}

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 结帖奖励

查看全部评分

hhhhhhhaa 回答时间:2018-12-17 11:15:23
  1. IIC.h文件
  2. #ifndef __MYIIC_H
  3. #define __MYIIC_H
  4. #include "sys.h"
  5. #include "delay.h"


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


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

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


  15. #endif
复制代码

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


  2. #define SCL_PIN       GPIO_Pin_6
  3. #define SDA_PIN       GPIO_Pin_7

  4. #define SCL_H         GPIOB->BSRR = SCL_PIN
  5. #define SCL_L         GPIOB->BRR  = SCL_PIN
  6.    
  7. #define SDA_H         GPIOB->BSRR = SDA_PIN
  8. #define SDA_L         GPIOB->BRR  = SDA_PIN

  9. #define SCL_read      GPIOB->IDR  & SCL_PIN
  10. #define SDA_read      GPIOB->IDR  & SDA_PIN


  11. #define  FALSE  (0)
  12. #define  TRUE   (1)

  13. #define I2C_delay()   delay_ms(4)





  14. //第一步  初始化IIC
  15. void IIC_Init(void)
  16. {                                             
  17.         GPIO_InitTypeDef GPIO_InitStructure;
  18.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
  19.           
  20.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  21.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ;   
  22.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  23.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  24. }



  25. //产生IIC起始信号
  26. u8 IIC_Start(void)
  27. {
  28.                                 SDA_H;
  29.               delay_ms(10);
  30.                                 SCL_H;
  31.                                 delay_ms(10);
  32. //                                if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
  33.                                 SDA_L;
  34.                                 delay_ms(10);
  35. //                                if(SDA_read)return FALSE; //SDA线为高电平则总线出错,退出
  36.                                 SCL_L;
  37.                                 delay_ms(10);
  38.                                 return TRUE;
  39. }          
  40. //产生IIC停止信号
  41. void IIC_Stop(void)
  42. {
  43.           SCL_L;
  44.                 I2C_delay();
  45.                 SDA_L;
  46.                 I2C_delay();
  47.                 SCL_H;
  48.                 I2C_delay();
  49.                 SDA_H;
  50.                 I2C_delay();
  51.           SCL_L;
  52.           I2C_delay();
  53.                                                                   
  54. }
  55. //等待应答信号到来
  56. //返回值:1,接收应答失败
  57. //        0,接收应答成功
  58. u8 IIC_Wait_Ack(void)
  59. {
  60.           SCL_L;
  61.                 I2C_delay();
  62.                 SDA_H;
  63.                 I2C_delay();
  64.                 SCL_H;
  65.                 I2C_delay();
  66.                 if(SDA_read)
  67.                 {
  68.                         SCL_L;
  69.                         return FALSE;
  70.                 }
  71.                 SCL_L;
  72.                 return TRUE;
  73.        
  74. }
  75. //产生ACK应答
  76. void IIC_Ack(void)
  77. {
  78.           SCL_L;
  79.                 I2C_delay();
  80.                 SDA_L;
  81.                 I2C_delay();
  82.                 SCL_H;
  83.                 I2C_delay();
  84.                 SCL_L;
  85.                 I2C_delay();
  86.        
  87. }
  88. //不产生ACK应答                    
  89. void IIC_NAck(void)
  90. {
  91.           SCL_L;
  92.                 I2C_delay();
  93.                 SDA_H;
  94.                 I2C_delay();
  95.                 SCL_H;
  96.                 I2C_delay();
  97.                 SCL_L;
  98.                 I2C_delay();
  99. }                                                                              
  100. //IIC发送一个字节
  101. //返回从机有无应答
  102. //1,有应答
  103. //0,无应答                          
  104. void IIC_Send_Byte(u8 txd)
  105. {                        
  106.             u8 i=8;
  107.                 while(i--)
  108.                 {
  109.                         SCL_L;
  110.                         I2C_delay();
  111.                         if(txd&0x80)
  112.                                 SDA_H;  
  113.                         else
  114.                                 SDA_L;   
  115.                         txd<<=1;
  116.                         I2C_delay();
  117.                         SCL_H;
  118.                         I2C_delay();
  119.                 }
  120.                 SCL_L;
  121. //        return         IIC_Wait_Ack();
  122. }             
  123.   
  124. u8 IIC_Read_Byte(void)
  125. {
  126.           u8 i=8;
  127.                 u8 ReceiveByte=0;
  128.                 SDA_H;
  129.                 while(i--)
  130.                 {
  131.                         ReceiveByte<<=1;      
  132.                         SCL_L;
  133.                         I2C_delay();
  134.                         SCL_H;
  135.                         I2C_delay();
  136.                         if(SDA_read)
  137.                         {
  138.                                 ReceiveByte|=0x01;
  139.                         }
  140.                 }
  141.                 SCL_L;
  142.                 return ReceiveByte;
  143. }

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


  2. #ifndef __PCF8563_H
  3. #define __PCF8563_H
  4. #include "sys.h"
  5. #include "myiic.h"
  6. #include "string.h"
  7. typedef struct
  8. {
  9.        
  10.     unsigned char  year;                                                                         
  11.           unsigned char  mon;
  12.     unsigned char  week;       
  13.           unsigned char  day;                                                                                                
  14.           unsigned char  hour;                                                                                 
  15.           unsigned char  min;                                                                                 
  16.                 unsigned char  sec;       

  17. }sTime;

  18. extern sTime time;

  19. void Get_Time(void);
  20. void Set_Time(void);


  21. #endif
复制代码
下面是pcf8563.c 的文件
  1. #include "pcf8563.h"




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

  23. /*------------------------------------------------------------------
  24. * 函数名: PbcdToByte  
  25. * 功  能: 将PBCD数据转换成HEX型数据.  
  26. * 输  入: bPbcd 待转换的PBCD数据.  
  27. * 输  出: 无.  
  28. * 返  回: uint8_t 转换后的HEX数据.
  29.          BIN码就是二进制编码。
  30.          比如十进制数的11,用BIN码表示就是1011;
  31.          左边的1表示十制的8,左边第三位的1表示十制的2,
  32.          左边第四位的1表示十制的1,
  33.          (即 8+2+1=11)
  34.    BCD码就是用四位二进制数表示一位十进制数的编码,
  35.          比如十进制数11用BCE码表示就是00010001;
  36.          前面的0001表示十进制的十位的1,
  37.          后面买的0001表示十进制的个位的1.               
  38. ---------------------------------------------------------------------*/   
  39.                
  40.                
  41. u8 PCF8563_PbcdToByte(u8 _ucPbcd /* 待转换的PBCD数据 */)   
  42. {   
  43.     return ((10 * (_ucPbcd >> 4)) + (_ucPbcd & 0x0f));   
  44. }   


  45. /*******************************************************************************
  46. * 文件名:void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  47. * 描  述: PCF8563某寄存器写入一个字节数据
  48. * 功  能:REG_ADD:要操作寄存器地址          dat:    要写入的数据
  49. * 作  者:
  50. * 版本号:
  51. *******************************************************************************/
  52. unsigned char PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  53. {
  54.         if(!IIC_Start())
  55.                                 {
  56.                                 return 0;
  57.                                 }
  58.         IIC_Send_Byte(0xA2);  //读地址 A3 read A3H;  写地址是A2  write A2H
  59.               if (!IIC_Wait_Ack())
  60.                                 {
  61.                                         IIC_Stop();
  62.                                         return 0;
  63.                                 }
  64.                                 IIC_Send_Byte(REG_ADD);
  65.                                 IIC_Wait_Ack();
  66.                                
  67.                                 IIC_Send_Byte(dat);  //发送数据
  68.                                 IIC_Wait_Ack();
  69.                                
  70.         IIC_Stop();
  71.                                 return 1;
  72. }


  73. /*******************************************************************************
  74. * 文件名:unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  75. * 描  述: PCF8563某寄存器读取一个字节数据
  76. * 功  能:REG_ADD:要操作寄存器地址          读取得到的寄存器的值
  77. * 作  者:
  78. * 版本号:
  79. *******************************************************************************/
  80. unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  81. {
  82.               u8  ReData;
  83.         IIC_Start();
  84.         IIC_Send_Byte(0xA2);  //读地址 A3 read A3H;  写地址是A2  write A2H
  85.                       if (!IIC_Wait_Ack())
  86.                                 {
  87.                                                          IIC_Stop();
  88.                                 }
  89.                                 IIC_Send_Byte(REG_ADD);  //确定要操作的寄存器
  90.               IIC_Wait_Ack();
  91.                                 IIC_Start();  //重启总线
  92.                                 IIC_Send_Byte(0xA3);  //发送读取命令
  93.                                 IIC_Wait_Ack();
  94.                                 ReData = IIC_Read_Byte();  //读取数据
  95.                                 IIC_NAck();  //发送非应答信号结束数据传送
  96.         IIC_Stop();
  97.                          
  98.         return ReData;
  99. }
  100. /*******************************************************************************
  101. * 文件名:void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  102. * 描  述: PCF8563写入多组数据
  103. * 功  能:REG_ADD:要操作寄存器起始地址          num:    写入数据数量           *WBuff: 写入数据缓存
  104. * 作  者:
  105. * 版本号:
  106. *******************************************************************************/
  107. u8 PCF8563_Write_nByte(u8* pBuffer, u16 WriteAddr, u16 Num)
  108. {
  109.       
  110.             
  111.         IIC_Start();
  112.                                                   
  113.         IIC_Send_Byte(0xA2);  //读地址 A3 read A3H;  写地址是A2  write A2H
  114.                      if (!IIC_Wait_Ack())
  115.                                 {
  116.                                                  IIC_Stop();
  117.                                return 0;
  118.                                 }
  119.                                 IIC_Send_Byte(WriteAddr);  //定位起始寄存器地址
  120.                                 IIC_Wait_Ack();
  121.                                 while(Num--)
  122.                 {
  123.                         IIC_Send_Byte(* pBuffer);
  124.                         IIC_Wait_Ack();
  125.                         pBuffer++;
  126.                 }
  127.         IIC_Stop();
  128.                                 return 1;
  129. }
  130. /*******************************************************************************
  131. * 文件名:void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  132. * 描  述: PCF8563读取多组数据
  133. * 功  能:REG_ADD:要操作寄存器起始地址          num:    读取数据数量           *RBuff: 读取数据缓存
  134. * 作  者:
  135. * 版本号:
  136. *******************************************************************************/
  137. u8 PCF8563_Read_nByte(u8* pBuffer, u16 WriteAddr, u16 NumByteToRead)
  138. {
  139.      
  140.            
  141.         
  142.       if(!IIC_Start())
  143.                         {
  144.                           return 0;
  145.                        
  146.                         }
  147.                                        
  148.        
  149.         IIC_Send_Byte(0xA2);  //读地址 A3 read A3H;  写地址是A2  write A2H
  150.                      if (!IIC_Wait_Ack())
  151.                                 {
  152.                                         IIC_Stop();
  153.                             return 0;
  154.                                 }
  155.        
  156.                                 IIC_Send_Byte(WriteAddr);  //定位起始寄存器地址
  157.                                 if(!IIC_Wait_Ack())
  158.                                 {
  159.                                
  160.                                 IIC_Stop();
  161.                             return 0;
  162.                                 }
  163.                                        
  164.                                 IIC_Start();
  165.         IIC_Send_Byte(0xA3);                               
  166.         IIC_Wait_Ack();

  167.                                
  168.                                 while(NumByteToRead)
  169.                                 {
  170.                                         *pBuffer = IIC_Read_Byte();
  171.                                         if(NumByteToRead == 1)
  172.                                         {
  173.                                         IIC_NAck();
  174.                                         }
  175.                                         else
  176.                                         {                               
  177.                                         IIC_Ack();
  178.                                         pBuffer++;
  179.                                         }
  180.                                         NumByteToRead--;
  181.                                 }
  182.         IIC_Stop();
  183.         return 1;                               
  184. }


  185. /*******************************************************************************
  186. * 文件名:void Set_Time(sTime* time)
  187. * 描  述: PCF8563设置时间信息
  188. * 功  能:时间初始化
  189. * 作  者:
  190. * 版本号:
  191. *******************************************************************************/


  192. void Set_Time(void)
  193. {
  194.             unsigned char ucBuf[7];
  195.                         ucBuf[0] = PCF8563_ByteToPbcd(time.sec);   //将字节转换为BCD码
  196.                         ucBuf[1] = PCF8563_ByteToPbcd(time.min);
  197.                         ucBuf[2] = PCF8563_ByteToPbcd(time.hour);
  198.                         ucBuf[3] = PCF8563_ByteToPbcd(time.day);
  199.                         ucBuf[5] = PCF8563_ByteToPbcd(time.mon);
  200.                         ucBuf[6] = PCF8563_ByteToPbcd(time.year);  /* 年低位                 */      
  201.             PCF8563_Write_nByte(ucBuf,0x02,7);
  202.                
  203. }
  204. /*******************************************************************************
  205. * 文件名:void Get_Time(sTime* time)
  206. * 描  述: PCF8563读取时间信息
  207. * 功  能:
  208. * 作  者:
  209. * 版本号:
  210. *******************************************************************************/

  211. void Get_Time(void)
  212. {   
  213.     unsigned char ucaBuf[7];
  214.           PCF8563_Read_nByte(ucaBuf,0x02,7);
  215.     time.sec  =  ucaBuf[0] & 0x7F;   
  216.     time.min  =  ucaBuf[1] & 0x7F;   
  217.     time.hour =  ucaBuf[2] & 0x3F;   
  218.     time.day  =  ucaBuf[3] & 0x3F;
  219.     time.mon  =  ucaBuf[5] & 0x1F;   
  220.     time.year =  ucaBuf[6];

  221.   
  222. //        time.sec  =  PCF8563_PbcdToByte(ucaBuf[0] & 0x7F);   
  223. //    time.min  =  PCF8563_PbcdToByte(ucaBuf[1] & 0x7F);   
  224. //    time.hour =  PCF8563_PbcdToByte(ucaBuf[2] & 0x3F);   
  225. //    time.day  =  PCF8563_PbcdToByte(ucaBuf[3] & 0x3F);
  226. //    time.mon  =  PCF8563_PbcdToByte(ucaBuf[5] & 0x1F);   
  227. //    time.year =  PCF8563_PbcdToByte(ucaBuf[6]);

  228. }


复制代码
下面是主函数的调用
  1. #include "HEAD.h"


  2. sTime time;

  3. int main(void)
  4. {         
  5.                                 u8 key[6];
  6.        time.year=18;
  7.              time.mon=12;
  8.              time.day=17;
  9.              time.hour=9;
  10.              time.min =55;
  11.              time.sec =15;
  12.      
  13.                                 delay_init();                         //延时函数初始化          
  14.                                 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  15.                                 uart_init(9600);                    //串口初始化为9600
  16.                                 IIC_Init();         //IIC初始化
  17.         Set_Time();
  18.                
  19.                         while(1)
  20.            {
  21.                        
  22.       Get_Time();
  23.                         key[0]=time.year;
  24.                         key[1]=time.mon;
  25.                         key[2]=time.day;
  26.                         key[3]=time.hour;
  27.                         key[4]=time.min;
  28.                         key[5]=time.sec;
  29.                         RS232_Send_Data(key,6);
  30.             delay_ms(500);

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

串口助手的显示部分

串口助手的显示部分
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版