时实时钟RTC驱动移植(PCF5863)


参考网址:http://blog.chinaunix.net/uid-23404636-id-2369606.html

由于产品板中没有PCF8563驱动,需要写驱动程序。

PCF8563驱动其实并不多,主要就是两个函数。
pcf8563_get_datetime 和 pcf8563_set_datetime。 写完这两个也是基本完成了。
参考rtc_pcf8563.c rtc_pcf8563.rar   代码改写。

改写后部分内容如下:

pcf8563.h内容:
  1. #ifndef _PCF8563_H
  2. #define _PCF8563_H    



  3. #define RTC_RD_TIME 0
  4. #define RTC_SET_TIME 1


  5. typedef struct 
  6. {
  7.     int tm_sec; 
  8.     int tm_min; 
  9.     int tm_hour;
  10.     int tm_mday;
  11.     int tm_wday;
  12.     int tm_mon; 
  13.     int tm_year;
  14. }rtc_time_t;

  15. #endif



pcf8563.c内容:

主要也就是pcf8563_get_datetime 和 pcf8563_set_datetime两个函数和一个控制调用函数(pcf8563_rtc_ioctl),现就列这几个吧,其他就不贴出来了。
一些宏定义:
  1. #define PCF8563_REG_ST1 0x00 /* status */
  2. #define PCF8563_REG_ST2 0x01

  3. #define PCF8563_REG_SC 0x02 /* datetime */
  4. #define PCF8563_REG_MN 0x03
  5. #define PCF8563_REG_HR 0x04
  6. #define PCF8563_REG_DM 0x05
  7. #define PCF8563_REG_DW 0x06
  8. #define PCF8563_REG_MO 0x07
  9. #define PCF8563_REG_YR 0x08

  10. #define PCF8563_REG_AMN 0x09 /* alarm */
  11. #define PCF8563_REG_AHR 0x0A
  12. #define PCF8563_REG_ADM 0x0B
  13. #define PCF8563_REG_ADW 0x0C

  14. #define PCF8563_REG_CLKO 0x0D /* clock out */
  15. #define PCF8563_REG_TMRC 0x0E /* timer control */
  16. #define PCF8563_REG_TMR 0x0F /* timer */

  17. #define PCF8563_SC_LV 0x80 /* low voltage */
  18. #define PCF8563_MO_C 0x80 /* century */

  19. #define I2C_PCF8563 0xA2

static inline
int bin2bcd (int x)
{
return (x%10) | ((x/10) << 4);
}


static inline
int bcd2bin (int x)
{
return (x >> 4) * 10 + (x & 0x0f);
}


读RTC pcf8563数据:
  1. static int pcf8563_get_datetime(int i2c_devaddress , rtc_time_t *tm)
  2. {
  3.         unsigned char buf[PCF8563_REG_YR+1] = { PCF8563_REG_ST1 };
  4.         /* status */
  5.         //buf[PCF8563_REG_ST1] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST1); 
  6.         //buf[PCF8563_REG_ST2] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST2); 
  7.          
  8.         /* datetime */ 
  9.         buf[PCF8563_REG_SC] = hi_i2c_read(i2c_devaddress, PCF8563_REG_SC); 
  10.         buf[PCF8563_REG_MN] = hi_i2c_read(i2c_devaddress, PCF8563_REG_MN); 
  11.         buf[PCF8563_REG_HR] = hi_i2c_read(i2c_devaddress, PCF8563_REG_HR); 
  12.         buf[PCF8563_REG_DM] = hi_i2c_read(i2c_devaddress, PCF8563_REG_DM); 
  13.         buf[PCF8563_REG_DW] = hi_i2c_read(i2c_devaddress, PCF8563_REG_DW); 
  14.         buf[PCF8563_REG_MO] = hi_i2c_read(i2c_devaddress, PCF8563_REG_MO); 
  15.         buf[PCF8563_REG_YR] = hi_i2c_read(i2c_devaddress, PCF8563_REG_YR); 
  16.         buf[PCF8563_REG_ST1] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST1); 
  17.         
  18.         tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
  19.         tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F);
  20.         tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
  21.         tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F);
  22.         tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
  23.         tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
  24.         tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]);

  25.       #if 0
  26.         printk("%s: secs=%d, mins=%d, hours=%d, "
  27.                 "mday=%d, mon=%d, year=%d, wday=%d\n",
  28.                 __func__,
  29.                 tm->tm_sec, tm->tm_min, tm->tm_hour,
  30.                 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
  31.       #endif 
  32.         
  33.         // Century bit. C = 0; indicates the century is 20xx.
  34.      // C = 1; indicates the century is 19xx. 
  35.         if(buf[PCF8563_REG_MO] & PCF8563_MO_C) 
  36.             tm->tm_year += 1900; 
  37.         else
  38.             tm->tm_year += 2000; 
  39.         return 0;
  40. }

写RTC pcf8563数据:
  1. static int pcf8563_set_datetime(int i2c_devaddress , rtc_time_t tm)
  2. {
  3.         unsigned char buf[9];
  4.         int Centurybit;
  5. #if 0
  6.         printk("%s: secs=%d, mins=%d, hours=%d, "
  7.                 "mday=%d, mon=%d, year=%d, wday=%d\n",
  8.                 __func__,
  9.                 tm.tm_sec, tm.tm_min, tm.tm_hour,
  10.                 tm.tm_mday, tm.tm_mon, tm.tm_year, tm.tm_wday);
  11. #endif

  12.         /* hours, minutes and seconds */
  13.         buf[PCF8563_REG_SC] = bin2bcd(tm.tm_sec);
  14.         buf[PCF8563_REG_MN] = bin2bcd(tm.tm_min);
  15.         buf[PCF8563_REG_HR] = bin2bcd(tm.tm_hour);

  16.         buf[PCF8563_REG_DM] = bin2bcd(tm.tm_mday);

  17.         /* month, 1 - 12 */
  18.         buf[PCF8563_REG_MO] = bin2bcd(tm.tm_mon + 1);

  19.         /* year and century */
  20.         buf[PCF8563_REG_YR] = bin2bcd(tm.tm_year % 100);
  21.         
  22.         if (tm.tm_year >= 1900 && tm.tm_year < 2000)
  23.             Centurybit = PCF8563_MO_C;
  24.         else if (tm.tm_year >= 2000 && tm.tm_year < 3000)
  25.             Centurybit = 0;
  26.         else
  27.             return -1;
  28.         
  29.         // Century bit. C = 0; indicates the century is 20xx.
  30.      // C = 1; indicates the century is 19xx.    
  31.         buf[PCF8563_REG_MO] |= Centurybit; //add Century bit    

  32.         buf[PCF8563_REG_DW] = tm.tm_wday & 0x07;

  33.         /* write register's data */
  34.         hi_i2c_write(i2c_devaddress, PCF8563_REG_SC, buf[PCF8563_REG_SC]);
  35.         hi_i2c_write(i2c_devaddress, PCF8563_REG_MN, buf[PCF8563_REG_MN]);
  36.         hi_i2c_write(i2c_devaddress, PCF8563_REG_HR, buf[PCF8563_REG_HR]);
  37.         hi_i2c_write(i2c_devaddress, PCF8563_REG_DM, buf[PCF8563_REG_DM]);
  38.         hi_i2c_write(i2c_devaddress, PCF8563_REG_MO, buf[PCF8563_REG_MO]);
  39.         hi_i2c_write(i2c_devaddress, PCF8563_REG_YR, buf[PCF8563_REG_YR]);
  40.         hi_i2c_write(i2c_devaddress, PCF8563_REG_DW, buf[PCF8563_REG_DW]);

  41.         return 0;
  42. }

相关控制调用函数:
  1. static int pcf8563_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  2. {
  3. rtc_time_t tm;
  4. switch (cmd)
  5. {
  6. case RTC_RD_TIME:
  7. pcf8563_get_datetime(i2c_pcf8563, &tm);
  8. return copy_to_user((void *)arg, &tm, sizeof(tm)) ? -EFAULT : 0;
  9. case RTC_SET_TIME:
  10. if (copy_from_user(&tm, (struct rtc_time_t *) arg, sizeof(tm)))
  11. return -EFAULT;
  12. return pcf8563_set_datetime(i2c_pcf8563, tm);
  13. }
  14. return 0;
  15. }
  16. static struct file_operations pcf8563_fops = {
  17. .owner = THIS_MODULE,
  18. .ioctl = pcf8563_rtc_ioctl,
  19. .open = pcf8563_open,
  20. .release = pcf8563_close
  21. };
  22. static struct miscdevice pcf8563_dev = {
  23. MISC_DYNAMIC_MINOR,
  24. "pcf8563",
  25. &pcf8563_fops,
  26. };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
I2C接口RTC实时时钟pcf8563读写Verilog驱动源码Quartus工程文件,FPGA型号Cyclone4E系列中的EP4CE10F17C8,Quartus版本18.0。 module rtc( //system clock input sys_clk , // 系统时钟 input sys_rst_n , // 系统复位 //pcf8563 interface output rtc_scl , // i2c时钟线 inout rtc_sda , // i2c数据线 //user interface input key2 , // 开关按键 output [5:0] sel , // 数码管位选 output [7:0] seg_led // 数码管段选 ); //parameter define parameter SLAVE_ADDR = 7'h51 ; // 器件地址 parameter BIT_CTRL = 1'b0 ; // 字地址位控制参数(16b/8b) parameter CLK_FREQ = 26'd50_000_000; // i2c_dri模块的驱动时钟频率(CLK_FREQ) parameter I2C_FREQ = 18'd250_000 ; // I2C的SCL时钟频率 parameter POINT = 6'b010100 ; // 控制点亮数码管小数点的位置 //初始时间设置,从高到低为年到秒,各占8bit parameter TIME_INI = 48'h18_05_23_09_30_00; //wire define wire clk ; // I2C操作时钟 wire i2c_exec ; // i2c触发控制 wire [15:0] i2c_addr ; // i2c操作地址 wire [ 7:0] i2c_data_w; // i2c写入的数据 wire i2c_done ; // i2c操作结束标志 wire i2c_ack ; // I2C应答标志 0:应答 1:未应答 wire i2c_rh_wl ; // i2c读写控制 wire [ 7:0] i2c_data_r; // i2c读出的数据 wire [23:0] num ; // 数码管要显示的数据 wire key_value ; // 按键消抖后的数据 //***************************************************** //** main code //***************************************************** //例化i2c_dri,调用IIC协议 i2c_dri #( .SLAVE_ADDR (SLAVE_ADDR), // slave address从机地址,放此处方便参数传递 .CLK_FREQ (CLK_FREQ ), // i2c_dri模块的驱动时钟频率(CLK_FREQ) .I2C_FREQ (I2C_FREQ ) // I2C的SCL时钟频率 ) u_i2c_dri( //global clock .clk (sys_clk ), // i2c_dri模块的驱动时钟(CLK_F
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a746742897

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值