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

stm103vct6与8563通讯

[复制链接]
hhhhhhhaa 提问时间:2018-8-9 14:34 /
阅读主题, 点击返回1楼
收藏 评论20 发布时间:2018-8-9 14:34
20个回答
废鱼 回答时间: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进制读取 显示的时间就是具体的时间了

串口助手的显示部分

串口助手的显示部分
hhhhhhhaa 回答时间:2018-12-17 11:20:36
4个月后再看,感觉以前的自己太小白了。。。。。虽然现在也挺小白的 哈啊哈
12
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版