pentagon 发表于 2012-3-28 09:05:14

blackfin bf531 +ds1302 时钟 调通了 用了 近10天(庆贺新论坛)


ds 1302 晚上的程序多了去了
但是能在bf531上用的没有几个。。。
参考别人的程序 自己把手册看了好多遍。。
现在共享下程序,,
硬件平台:blackfin bf531    ds1302   日本kds 6pf32,768k 晶振,不加电容。电路图传不上来。
软件       visualdsp ++ 5.0
仿真器: 东方迪码。。。

希望大家批评指正;对程序中的不足和可改进之处 大家要不吝赐教,呵呵
这个验证可以完美运行。











/*****************************************************************************
* ds1302.c
*time :2012.2.29.
*by jinn
*no rights reserved
*ds1302 内部有7个寄存器和时钟日期有关,存放的数据是bcd码形式。
**uart.c(main)中程序在line 1240


note:延时都用示波器做了准确的调校,按照英文ds1302 使用说明书。

*****************************************************************************/
#include <ccblkfn.h>             //内嵌宏定义
#include <sysreg.h>            //系统寄存器
#include <sys/exception.h>       //异常中断的定义

#include <sys/05000311.h>
#include <defBF533.h>
#include <ds1302.h>
#include <services/services.h>//系统服务程序
#include <drivers/adi_dev.h>      //设备管理
#include"dm_cpu.h"
//#include"dm_bf5xx.h"                //重复出现sda 67.68行被注释掉。
#include <string.h>
#include "SSD1963.h"
#include "Graphics.h"
#include "SYS_ZK.H"
#include "button.h"
#include "bmp.h"
//#include "nandflash_k9f1g08.h"
#include "uart1.h"
#include "PublicData.h"
#include "time.h"


//测试用 部分 -----开始
uchar bb=0;//测试用,写入读出用


//测试用 部分 -----结束
#define RED                  0xF800
#define GUI_GREEN      0x07E0
#define BLUE               0x001F
#define WHITE                0xFFFF
#define BLACK                0x0000
//#define YELLOW         0xFFE0

#define GUI_BACK          0xE6C0A3
#define GUI_MYBLUE      0x7D6C66
#define GUI_BLUE         0x001F
#define GUI_DARKGRAY      0x4204
#define GUI_BLACK         0x7F0000
#define      GUI_RED         0xF800
#define GUI_CYAN          0xffff00
#define GUI_MAGENTA       0x8b008b
#define GUI_BROWN         0x2a2aa5
#define GUI_GRAY          0x808080
#define GUI_LIGHTGRAY   0xd3d3d3
#define GUI_LIGHTBLUE   0xff8080
#define GUI_LIGHTGREEN    0x80ff80
#define GUI_LIGHTCYAN   0x80ffff
#define GUI_LIGHTRED      0x8080ff
#define GUI_LIGHTMAGENTA0xff80ff
#define GUI_YELLOW      0x00ffff
#define GUI_WHITE         0xffff
#define GUI_INVALID_COLOR 0xfffffff




#define uchar unsigned char
#define uintunsigned int
uchar Calendar[]={0x12,0x03,0x27,0x18,0x31,0x00};//年月日时分秒2012.3.26
//uchar Calendar[]={0x01,0x00,0x00,0x00,0x00,0x00};//年月日时分秒2010.4.4 15:25

uchar Calendar1={0,0,0,0,0,0};//读取的时间存放
uchar con_result={0,0,0,0,0,0,0};//数据转换结果,原来是 16.


// RST PF12                //使能端                //只是用了 bf531的 pf 12,13,14端口
// SDA PF13                //数据端
// SCL PF14                //时钟端
#define RST (1<<12)
#define SDA (1<<13)
#define SCL (1<<14)

#define      READ_SECOND                0x81                //读写秒
#define WRITE_SECOND    0x80

#define READ_MINUTE   0x83                //读写分钟
#define WRITE_MINUTE    0x82

#define READ_HOUR       0x85                //读写小时
#define WRITE_HOUR      0x84

#define READ_DAY                0x87                //读写天
#define WRITE_DAY                0x86

#define READ_MOUTH                0x89                //读写月      
#define WRITE_MOUTH                0x88

#define READ_WEEK                0x8b                //读写周
#define WRITE_WEEK                0x8a

#define READ_YEAR                0x8d                //读写年
#define WRITE_YEAR                0x8c

#define WRITE_PROTECT   0x8e                //写保护,最高位 :1 写保护开,禁止写入,0关闭

//dir   0 for input.   1 for output.
//flag-d0 for 0      1for 1

#define FIO_RST_0UT_EN((*pFIO_DIR)|= RST)                        //RST 端口输出使能
#define FIO_RST_H                ((*pFIO_FLAG_D)|=RST)                //RST 端口输出高电平
#define FIO_RST_L               ((*pFIO_FLAG_D)&=~RST)                //RST 端口输出低电平

#define FIO_SDA_0UT_EN((*pFIO_DIR)|=SDA)                        //SDA 端口输出使能
#define FIO_SDA_H                ((*pFIO_FLAG_D)|=SDA)                //SDA 端口输出高电平
#define FIO_SDA_L               ((*pFIO_FLAG_D)&=~SDA)                //SDA 端口输出低电平

#define FIO_SCL_0UT_EN((*pFIO_DIR)|=SCL)                        //SCL 端口输出使能
#define FIO_SCL_H                ((*pFIO_FLAG_D)|=SCL)                //SCL 端口输出高电平
#define FIO_SCL_L               ((*pFIO_FLAG_D)&=~SCL)                //SCL端口输出低电平

#define FIO_SDA_IN                ((*pFIO_DIR)&=~SDA)                        //设置为输入
#define FIO_SDA_INEN      ((*pFIO_INEN)|=SDA)                        //输入使能
#define FIO_SDA_INEN_RESET      ((*pFIO_INEN)&=~SDA)      //输入使能

/*********************************
//             函数声明:
**********************************/

void delay1302(unsigned int dly);
void DS1302_ByteWrite(uchar command,uchar Byte);
uchar DS1302_ByteRead(uchar command);
void Initial_DS1302(void);
void Calendar_ReadBack_Con(void);


//* =====================FUNCTION==================================*   
//             Name:delay* Description:延时函数
//            程序内部延时都是准确延时,不要改动。
// * ==================================================================*/
void delay1302(unsigned int dly)
{            
          for(;dly>0;dly--);
          }

      
/*************************************************
//                  DS1302字节写入函数
//      上升沿写入命令,每次都是写入最后一个位。
//      上降沿写入数据,每次都是写入最后一个位。
*************************************************/
void DS1302_ByteWrite(uchar command,uchar Byte)
{      
      *pFIO_FLAG_S=0x0000;
      *pFIO_FLAG_C=0x0000;
      *pFIO_FLAG_T=0x0000;
      *pFIO_POLAR=0x0000;
      
      
      FIO_RST_0UT_EN;
      FIO_SDA_0UT_EN;      
      FIO_SCL_0UT_EN;
      delay(3);      
                                                      
      FIO_RST_L;
      FIO_SCL_L;                        //只有在SCLK为低电平时,才能将RST置为高电平。--百度百科      
      delay1302(10);
      FIO_RST_H;      
      delay1302(100);                //ce to clk 最少需要4us,
      
      uchar n=0;
      for(n=0;n<8;n++)
      {
                delay1302(2);
                if(command&0x01)
                {      
                        FIO_SDA_H;                        
                }                              
                else
                {
                        FIO_SDA_L;               
               }
               delay1302(25);
               FIO_SCL_L;               
                delay1302(50);                // scl 高低电平需要维持最少 1000ns
               FIO_SCL_H;
               delay1302(25);                // scl 高低电平需要维持最少 1000ns两个 25在一起也是50 /
                command>>=1;                        

         }

      for(n=0;n<8;n++)
      {      
                delay1302(2);
                if(Byte&0x01)
                {
                        FIO_SDA_H;               
               }
                else
                {      
                         FIO_SDA_L;               
            }               
                delay1302(25);
               FIO_SCL_L;               
                delay1302(50);
               FIO_SCL_H;
               delay1302(25);
                Byte>>=1;
      }
      
      delay1302(40);
      FIO_RST_L;                        //写数据的时候,最后需要RST 4us的一个拉底的过程
      FIO_SCL_L;                        //英文版本的数据手册上有。
      delay1302(100);
      FIO_RST_H;

}

/*DS1302初始化函数*/
void Initial_DS1302(void)
{      
      *pFIO_FLAG_S=0x0000;
      *pFIO_FLAG_C=0x0000;
      *pFIO_FLAG_T=0x0000;
      *pFIO_POLAR=0x0000;
      
      uchar aa=0;
      aa=DS1302_ByteRead(0xc1);
      if(aa!=0x01)                //只在第一次启动的时候赋值,然后写ram区 0x01,
      {
                DS1302_ByteWrite(WRITE_PROTECT,0x00);      //关闭写保护,准备写入数据
               
                DS1302_ByteWrite(WRITE_SECOND,0x80);      //停止
               
                DS1302_ByteWrite(0xC0,0x01);
               
                bb=DS1302_ByteRead(0xC1);                              //测试写入读出用
               
                DS1302_ByteWrite(0x90,0xa9);                        //使能充电,双二极管,2K电阻

                DS1302_ByteWrite(WRITE_YEAR,Calendar);

                DS1302_ByteWrite(WRITE_MOUTH,Calendar);
      
                                                                                                      //      DS1302_ByteWrite(WRITE_WEEK,Calendar);//周三

                DS1302_ByteWrite(WRITE_DAY,Calendar);

                DS1302_ByteWrite(WRITE_HOUR,Calendar);

                DS1302_ByteWrite(WRITE_MINUTE,Calendar);

                DS1302_ByteWrite(WRITE_SECOND,0x00);//设置为00,0x80第7位置零启动1302
      
                DS1302_ByteWrite(WRITE_PROTECT,0x80);//开启写保护
      }
      DS1302_ByteWrite(WRITE_SECOND,0x00);//设置为00,0x80第7位置零启动1302
}
/*********************************************************
/DS1302字节读取函数,注意下降沿读出数据和第八个下降沿
/读取时分为两个部分:先上升沿写入命令,每次都是先写入低字节。
/然后是在下升沿读出数据。

***********************************************************/
uchar DS1302_ByteRead(uchar command)
{      
      *pFIO_FLAG_S=0x0000;
      *pFIO_FLAG_C=0x0000;
      *pFIO_FLAG_T=0x0000;
      *pFIO_POLAR=0x0000;
      
      uchar i=0,n=0;
      uchar readback=0;         

      FIO_RST_0UT_EN;
      FIO_SDA_0UT_EN;                   // PF12,13,14设置为输出
      FIO_SCL_0UT_EN;      
      
      FIO_RST_L;
      FIO_SCL_L;
      delay1302(10);
      FIO_RST_H;
      delay1302(100);

      for(n=0;n<8;n++)
      {      
                delay1302(2);
                if(command&0x01)               //每次都是写入最低位字节
               {
                         FIO_SDA_H;               
               }      
                else
               {               
                         FIO_SDA_L;
               }
               
               delay1302(25);
               FIO_SCL_L;
               delay1302(50);
               FIO_SCL_H;
               delay1302(25);
               
               command>>=1;
               
      }
/*****这个以下位置比较困惑。。。。******/
/*****读数据部分    下降沿读取数据******/

      FIO_SDA_INEN;
      FIO_SDA_IN;                              // PF13 输入使能
      delay1302(20);      
                                                                //*pFIO_FLAG_C|=SDA;      //后加的 不知道端口是不是要清零。            
      for(i=0;i<8;i++)
      {      
                delay1302(10);
                readback>>=1;
               
                delay1302(25);                         //标准值延时值为:25.50.25                                                                                          
               FIO_SCL_H;                              //SCL 先H 后L 关键更改。先L后H 不行。
               delay1302(50);      
      FIO_SCL_L;
      delay1302(25);
      
      if((*pFIO_FLAG_D)&SDA)      //及其重要的改动。
               {      
                         readback+=0x80;                //readback|=0x80;//最开始的是这个表达式
                                                               //如果口上是高电平就是1 。如果口上是低电平就是0.
                         }
      }
      
      delay1302(10);
      FIO_SDA_INEN_RESET;                        //关键的改动,关闭输入功能。
      FIO_SDA_0UT_EN;                        
      return(readback);
}
/*****************************************
读取DS1302数据,分别是年月周日时分秒,并且进行转化,
注意读取ds1302 的BCD 码 需要进行 BCD 到 10进制的转化。高四位求出来是十位,
低四位是各位。

*******************************************/
void Calendar_ReadBack_Con(void)
{      
      uint i;
    //
      for(i=0;i<6;i++)
      {      
                uchar addr={0x8d,0x89,0x87,0x85,0x83,0x81}; // year,month,day.hour,minute,second
               
                Calendar1=DS1302_ByteRead(addr);
               
                con_result=(10*((Calendar1>> 4)&0x07)+(Calendar1 & 0x0f));      //bcd转化为10进制。

      }

}      


/****************************************************
                                 主   函   数
                                 屏幕尺寸为800×480
                                 显示位置在右上角:
******************************************************/
   
void ds1302( void )
{      
      
      Calendar_ReadBack_Con();
      
/*=======dsplay:year month dayhour min second   ======*/
// 一个字符占用 9个字节。
      DrawString(600,10,(unsigned char *)"20--      ::", RED,WHITE,TRANSP);
      GUI_DispDecAt((con_result),600+18,10,2,BLUE,WHITE);
      GUI_DispDecAt((con_result),600+45,10,2,BLUE,WHITE);
      
      GUI_DispDecAt((con_result),600+72,10,2,BLUE,WHITE);
      GUI_DispDecAt((con_result),600+106,10,2,BLUE,WHITE);//根据实际调小 2
      GUI_DispDecAt((con_result),600+133,10,2,BLUE,WHITE);//根据实际调小 2
      GUI_DispDecAt((con_result),600+160,10,2,BLUE,WHITE);//根据实际调小 2
}

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
附件怎么传不上去??

头文件 部分
/**********************************
*name: ds1302.h
*time:2012.2.28
*do by wanjin rxpe
*
*
**********************************/


#ifndef __ds1302_h__
#define __ds1302_h__

extern void ds1302(void);//wanjin +      

extern void Initial_DS1302(void);

#endif




网站使用 问题zip文件上传不了,,, 图片上传了 找不到等以后再上传图片吧。。



pentagon 发表于 2012-3-28 09:14:44


这个是数据和时钟的图片是可以显示时间的图片。。。。

pentagon 发表于 2012-3-28 09:17:39

开始使用别的晶振 还添加了电容,但是 起振不明显,,

后来申请了 日本kds的晶振样片。。
效果还是不错的;;;

pentagon 发表于 2012-3-28 09:22:56

对ds1302 进行 读取操作的时候。。。没有读出数据 只有写入命令的 时钟和数据线;;

时钟参考吧

yanjs1016 发表于 2012-3-28 09:42:28

同贺呀            

armok 发表于 2012-3-28 14:54:07

cool !

pentagon 发表于 2012-3-28 16:12:29

armok 发表于 2012-3-28 14:54 static/image/common/back.gif
cool !

谢谢老大支持

aureole 发表于 2012-3-28 16:17:03

pentagon 发表于 2012-3-28 09:22 static/image/common/back.gif
对ds1302 进行 读取操作的时候。。。没有读出数据 只有写入命令的 时钟和数据线;;

时钟参考吧


恭喜恭喜,搞定了!!

first_blood 发表于 2012-3-28 19:18:08

BF531本身不就是有RTC,能直接读取年月日,星期,外加个DS1302干什么

pentagon 发表于 2012-3-28 19:59:51

first_blood 发表于 2012-3-28 19:18 static/image/common/back.gif
BF531本身不就是有RTC,能直接读取年月日,星期,外加个DS1302干什么

呵呵这也是了解531的高手,我只是菜鸟,
加 ds1302 是为了记录系统异常的一些信息。。他有个 ram区主要是利用这个。

pentagon 发表于 2012-3-28 20:07:46

本帖最后由 pentagon 于 2012-3-28 20:08 编辑

回复 小马哥

谢谢 小马哥,参考你的fpga的例子了,还有你说的 端口的设置。攒钱买你的板子中,,

880705lpdhr 发表于 2012-11-15 16:22:00

MARK ii   

f43 发表于 2012-12-11 18:46:56

开发板如果能便宜些就好了
页: [1]
查看完整版本: blackfin bf531 +ds1302 时钟 调通了 用了 近10天(庆贺新论坛)