[PIC®/AVR®/dsPIC®产品] PIC18F46K8读写PCF8563程序的问题

[复制链接]
1623|3
 楼主| 比神乐 发表于 2024-10-6 18:47 | 显示全部楼层 |阅读模式
代码:
PCF8563.C
  1. #include <xc.h>
  2. #include"PCF8563.h"





  3. uchar ack;
  4. uchar get_time[9];

  5. uchar send[2]={0xAA,0x55};
  6. uchar year[4],mon[2],day[2],hour[2],minute[2],sec[2];

  7. void start_i2c()
  8. {
  9.         SDA=1;
  10.         nop();
  11.         SCL=1;
  12.         nop();nop();nop();nop();nop();
  13.         SDA=0;//发送起始信号
  14.         nop();nop();nop();nop();nop();
  15.         SCL=0;//钳住I2C总线,准备发送数据或接收数据
  16.         nop();nop();       
  17. }
  18. void stop_i2c()
  19. {
  20.         SDA=0;
  21.         nop();
  22.         SCL=1;
  23.         nop();nop();nop();nop();nop();
  24.         SDA=1;
  25.         nop();nop();nop();nop();nop();       
  26. }
  27. void i2c_ack()
  28. {
  29. SDA=0;
  30. nop();
  31. SCL=1;
  32. nop();nop();
  33. SCL=0;
  34. nop();nop();       
  35. }
  36. void i2c_noack()
  37. {
  38. SCL=0;
  39. nop();nop();       
  40. SDA=1;
  41. nop();
  42. SCL=1;
  43. nop();nop();
  44. SCL=0;
  45. nop();nop();       
  46. }
  47. void send_i2c_byte(uchar dat)
  48. {
  49.         uchar i;
  50.         for(i=0;i<8;i++)
  51.         {
  52.                 if(dat&0x80)
  53.                 {
  54.                         SDA=1;
  55.                 }
  56.                 else
  57.                 SDA=0;
  58.                 nop();nop();
  59.                 dat<<=1;
  60.                 SCL=1;
  61.                 nop();nop();nop();nop();nop();nop();
  62.                 SCL=0;       
  63.         }
  64.         nop();
  65.         TRISC4=1;
  66.         SDA=1;
  67.         nop();nop();
  68.         SCL=1;
  69.         nop();nop();
  70.         if(LATCbits.LATC4==1)
  71.         ack=1;
  72.         else
  73.         ack=0;
  74.         SCL=0;
  75.         nop();nop();
  76.         TRISC4=0;       
  77. }
  78. read_i2c_byte()
  79. {
  80.         uchar i;
  81.         uchar read_data;
  82.         for(i=0;i<8;i++)
  83.         {
  84.                 TRISC4=1;
  85.                 nop();nop();
  86.                 SCL=1;
  87.                 read_data<<=1;
  88.                 if(LATCbits.LATC4==1)
  89.                 read_data=read_data+1;
  90.                 nop();
  91.                 SCL=0;
  92.                 nop();       
  93.         }
  94.         TRISC4=0;
  95.         return(read_data);
  96. }
  97. void write_i2c_data(uchar address,uchar data)
  98. {
  99.         uchar i;
  100.         start_i2c();//启动IIC
  101.         send_i2c_byte(0XA2);//写操作指令
  102.         if(ack==1)
  103.         return;
  104.         send_i2c_byte(address);//写寄存器地址
  105.         if(ack==1)
  106.         return;
  107.         send_i2c_byte(data);
  108.         stop_i2c();//结束IIC
  109.         ms_delay(1);       
  110. }
  111. int read_i2c_data(uchar address)
  112. {
  113.         uchar i;
  114.         uchar receive;
  115.         start_i2c();//启动IIC
  116.         send_i2c_byte(0XA2);//写操作指令
  117.         if(ack==1)
  118.         return 1;
  119.         send_i2c_byte(address);//写寄存器地址
  120.         if(ack==1)
  121.         return 1;
  122.         start_i2c();//重新启动IIC
  123.         send_i2c_byte(0XA3);//读操作指令
  124.         if(ack==1)
  125.         return 1;
  126.         receive=read_i2c_byte();
  127.         stop_i2c();//结束IIC
  128.         ms_delay(1);
  129.         return(receive);
  130. }
  131. void set_time()
  132. {
  133.         write_i2c_data(0x00,0x00);
  134.         write_i2c_data(0x02,0x00);
  135.         write_i2c_data(0x03,0x00);
  136.         write_i2c_data(0x04,0x09);
  137.         write_i2c_data(0x05,0x18);
  138.         write_i2c_data(0x06,0x02);
  139.         write_i2c_data(0x07,0x10);
  140.         write_i2c_data(0x08,0x16);
  141.         ms_delay(1);
  142. }
  143. void ms_delay(uint xms)
  144. {
  145. int i,j;
  146. for(i=0;i<xms;i++)
  147.   {for(j=0;j<50;j++);}
  148. }

PCF8563.H
  1. #ifndef _PCF8563_H_
  2. #define        _PCF8563_H_
  3. #define nop() asm("nop")
  4. #define uchar  unsigned char
  5. #define uint   unsigned int

  6. #define SCL LATCbits.LATC3
  7. #define SDA LATCbits.LATC4

  8. void us_delay(uint i);//
  9. void start_i2c();//启动IIC
  10. void stop_i2c();//停止信号
  11. void i2c_ack();//返回应答信号
  12. void i2c_noack();//无应答信号
  13. void send_i2c_byte(uchar dat);//IIC写8位字节数据
  14. int read_i2c_byte();//IIC读8位字节数据
  15. void write_i2c_data(uchar address,uchar data);
  16. void set_time();
  17. void ms_delay(uint xms);
  18. uchar read_i2c_data(uchar address);
  19. #ifdef        __cplusplus
  20. extern "C" {
  21. #endif




  22. #ifdef        __cplusplus
  23. }
  24. #endif

  25. #endif        /* NEWFILE_H */

主程序
  1. void main(void)
  2. {
  3.     u8 shi,ge;
  4.      ANCON0bits.ANSEL6=0;    //RE1(AN6)配置为数字IO
  5.      ANCON1=0x00;            //将部分带模拟输入功能的引脚设置为数字IO
  6.      //PADCFG1=0x80;
  7.      //输出使用LAT寄存器,输入使用PORT寄存器
  8.      TRISDbits.TRISD4=0;     //PORD4配置为输出
  9.      TRISEbits.TRISE1=0;     //PORE1配置为输出
  10.      //ODCON=0x80;
  11.      TRISC=0X00;
  12.      LCD_Init();
  13.      LCD_CLS();
  14.         //LCD_P8x16Str(45,5,(u8*)"EASEAR");
  15.         //LCD_P6x8Str(0,7,(u8*)"www.holteksupport.com");
  16.         //Draw_BMP(0,0,100,3,(u8*)Dot);
  17.      LCD_P8x16Char(13,3,'2');
  18.      LCD_P8x16Char(21,3,'0');
  19.      LCD_P8x16Char(45,3,'-');
  20.      LCD_P8x16Char(69,3,'-');
  21.      LCD_P8x16Char(45,5,':');
  22.      LCD_P8x16Char(69,5,':');
  23.      set_time();
  24.      ms_delay(1);
  25.      while(1)
  26.      {
  27.             get_time[0]=read_i2c_data(0x02);
  28.             get_time[1]=read_i2c_data(0x03);
  29.             get_time[2]=read_i2c_data(0x04);
  30.             get_time[3]=read_i2c_data(0x05);
  31.             get_time[4]=read_i2c_data(0x06);
  32.             get_time[5]=read_i2c_data(0x07);
  33.             get_time[6]=read_i2c_data(0x08);
  34.             ms_delay(1);
  35.           MS_delay(500);
  36.           shi=get_time[0]>>4;
  37.           ge=get_time[0]&0x0f;
  38.           LCD_P8x16Char(77,5,shi+0x30);
  39.           LCD_P8x16Char(85,5,ge+0x30);
  40.           shi=get_time[1]>>4;
  41.           ge=get_time[1]&0x0f;
  42.           LCD_P8x16Char(53,5,shi+0x30);
  43.           LCD_P8x16Char(61,5,ge+0x30);
  44.           shi=get_time[2]>>4;
  45.           ge=get_time[2]&0x0f;
  46.           LCD_P8x16Char(29,5,shi+0x30);
  47.           LCD_P8x16Char(37,5,ge+0x30);
  48.           shi=get_time[3]>>4;
  49.           ge=get_time[3]&0x0f;
  50.           LCD_P8x16Char(77,3,shi+0x30);
  51.           LCD_P8x16Char(85,3,ge+0x30);
  52.           shi=get_time[5]>>4;
  53.           ge=get_time[5]&0x0f;
  54.           LCD_P8x16Char(53,3,shi+0x30);
  55.           LCD_P8x16Char(61,3,ge+0x30);
  56.           shi=get_time[6]>>4;
  57.           ge=get_time[6]&0x0f;
  58.           LCD_P8x16Char(29,3,shi+0x30);
  59.           LCD_P8x16Char(37,3,ge+0x30);
  60.      }
  61. }



读出来全是1.
请问高手,哪里错了?谢谢
kzlzqi 发表于 2024-10-29 16:22 | 显示全部楼层
如果在发送字节时设备没有正确返回ACK(应答信号),那么后续的通信可能会失败。例如,在send_i2c_byte函数中,你有一个检查LATCbits.LATC4来判断是否收到ACK,但这段代码可能有问题。

c
复制代码
TRISC4 = 1;  // 将SDA设置为输入模式,以便读取ACK信号
...
if (LATCbits.LATC4 == 1)
    ack = 1;
else
    ack = 0;
在I2C中,ACK信号应该是由从设备(即PCF8563)拉低SDA引脚来表示的。所以,你应当读取的是PORTCbits.RC4而不是LATCbits.LATC4。
稳稳の幸福 发表于 2024-10-29 19:27 | 显示全部楼层
你可以看看I2C是否正确。示波器观测一下波形。估计这里错了。
稳稳の幸福 发表于 2024-10-29 19:27 | 显示全部楼层
先确认I2C是否能正确读写。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

470

主题

3537

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部