搜索
bottom↓
回复: 5

PIC16F877A 控制DS1302 在数码管上显示时间 怎么都调不出来 高手来帮我

[复制链接]

出0入0汤圆

发表于 2010-7-2 17:52:13 | 显示全部楼层 |阅读模式
这是我的源程序,一运行6位数码管全部显示0,是不是因为IO不该用RC4啊,因为我看网上好多人都用RC5作为IO,求救啊,最近要交货了,连这个小程序都弄不出来 哎呀
附:源代码
#include "pic.h"
#include"math.h"
#define IO       RC4                                             //定义DS1302的数据口
#define CLK      RC3                                               //定义DS1302的时钟口
#define RST       RC2                                             //定义DS1302的复位口

#define uchar unsigned char        //宏定义uchar为无符号字符型
#define uint unsigned int //宏定义uint为无符号整型

uchar ACC;
const uchar  table2[]={0x22,0x22,0x10,0x11,0x00,0x11,0x00};  //初值显示
uchar table1[7];        //总缓存数组
uchar set_tab[7];        //调整时间后的缓存数组
const char table[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char TABLE_BIT_SELECT[]={0x01,0x02,0x04,0x20,0x10,0x08};
//unsigned char TABLE_NUMBER[]={ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE};
unsigned char TABLE_NUMBER[]={0x00,0x08,0x01,0x09,0x02,0x0a,0x03,0x0b,0x04,0x0c};
char sec,min,hou,day,month,week,year,weekadd,week1;//秒,分,时,日,月,星期,年,星期时间选择参数
uchar count,i; //用于计数button2的次数;用于延时计数
uchar a,b;         //用于十六进制码转换成BCD码的寄存变量
uchar *pda;         //用于设置时间的指针变量
void delay(uchar dly);   //延时函数n毫秒


/*******************************************/               
//                                   ds1302模块
/*******************************************/


/****************八位数据写入函数*********************/
void inputbyte(uchar cdata)                  
{
  uchar i;
TRISC=0;
ACC=cdata;
  for(i=8;i>0;i--)
  {               
if(ACC&0x01==1)
    IO=0x01;
else
IO=0;
CLK=1;   
CLK=0;   
//delay(50);
        ACC=ACC>>1;                          //在时钟上升沿写入一位数据
  }
//CLK=0;////
}

/***************八位数据读出函数*********************/
uchar outputbyte(void)                                 
{
   uchar i;
  // uchar cdata=0;
TRISC=0x10;
   for(i=8;i>0;i--)
   {       
      ACC =ACC >> 1;
if(PORTC&0x10==0x10)
{
ACC|=0x80;
}          
else ACC&=0x7f;
CLK = 1;
CLK = 0;
   }
   return(ACC);
TRISC=0;
}

/*************************************************************/
//名称:re_1302
//功能:读出对应寄存器的内容
//调用:inputbyte(uchar cdata)、outputbyte(void)
/***************************************************************/
uchar re_1302(uchar add)               
{
  uchar cdata;
TRISC=0;
  RST=0;
  CLK=0;
  RST=1;
  inputbyte(add);
  cdata = outputbyte();
CLK=1;
  RST=0;
delay(40);
  return(cdata);
}

/*********************************************************/
//名称:wr_1302
//功能:将指令或数据写入对应寄存器
//调用:inputbyte(uchar cdata)
/******************************************************************/
void wr_1302(uchar add,uchar cdata)          
{
TRISC=0;  
RST=0;
  CLK=0;
  RST=1;
  inputbyte(add);
  inputbyte(cdata);

  CLK=1;
  RST=0;
//delay(40);
}

/**************************************************************/
//名称:set_1302
//功能:设置时间初值
//调用:wr_1302(uchar add,uchar cdata)
/***************************************************************/
void set_1302(uchar *pda)               
{
  uchar i;
  uchar add=0x80;
  wr_1302(0x8e,0x00);         //将控制寄存器值设为零,最高位WP=0允许写
  for(i=7;i>0;i--)                 //将七个时间初值写入对应寄存器
  {
    wr_1302(add,*pda++);          //写对应时钟寄存器的值
        add+=2;
  }
  wr_1302(0x8e,0x80);        //写保护,防止干扰影响时间值??????????
}



/*******************************************************************/
//名称:get_1302                               
//功能:读取当前时间值
//调用函数:re_1302() 、 BCD_transform()
/*******************************************************************/
void get_1302()
{
  uchar i;
  uchar add=0x81;
  for(i=0;i<7;i++)
  {
    table1=re_1302(add);  //读对应时钟寄存器的值
    add+=2;
  }
                 

}


/****************************************************************************
* 名    称:display()
* 功    能:数码管显示
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void display()
{
        int i, temp, temp1;                         //定义查表变量

i = table1[0] & 0x0f;                     //求秒的个位
        PORTD = TABLE_NUMBER;                                //点亮秒的个位
        //PORTD=i;
PORTA = TABLE_BIT_SELECT[0];
        delay(10);                              //延长一段时间,保证亮度
        i = table1[0] & 0xf0;                     //求秒的十位
        i = i >> 4;                               //右移4位
        PORTD =TABLE_NUMBER;                      //送D口显示
//PORTD=i;       
PORTA = TABLE_BIT_SELECT[1];                           //点亮秒的十位
        delay(10);                              //延长一段时间,保证亮度

        i = table1[1] & 0x0f;                     //求分的个位
        PORTD =TABLE_NUMBER ;                 //送D口显示,并显示小数点
//PORTD=i;       
PORTA = TABLE_BIT_SELECT[2];                           //点亮分的个位
        delay(10);                              //延时一定时间,保证亮度
        i = table1[1] & 0xf0;                     //求分的十位
        i = i >> 4;
        PORTD = TABLE_NUMBER;                      //送D口显示
//PORTD=i;
        PORTA = TABLE_BIT_SELECT[3];                           //点亮分的十位
        delay(10);                              //延长一段时间,保证亮度

        i = table1[2] & 0x0f;                     //求时的个位
        PORTD = TABLE_NUMBER ;                 //送D口显示,并加上小数点
//PORTD=i;
        PORTA = TABLE_BIT_SELECT[4];                           //点亮时的个位
        delay(10);                              //延时一定时间,保证亮度
        i = table1[2] & 0xf0;                     //求时的十位
        i = i >> 4;
        PORTD =TABLE_NUMBER;
        //送D口显示
//PORTD=i;       
PORTA = TABLE_BIT_SELECT[5];                           //点亮时的十位
        delay(10);                              //延长一段时间,保证亮度


}
/****************************************************************************
* 名    称:ds1302_init()
* 功    能:DS1302初始化
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void ds1302_init()
{
        CLK=0;                            //拉低时钟信号
        RST=0;                            //复位DS1302
RST=1;                             //使能DS1302
//inputbyte(0x8e);                //发控制命令
//inputbyte(0);                   //允许写DS1302
RST=0;                             //复位
}
/****************************************************************************
* 名    称:port_init()
* 功    能:引脚初始化
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void port_init()
{
        ADCON1 = 0X07;                       //设置A口为普通I/O口
        //TRISB = 0X0F;                                          //设置B口低4位为输入//高四位为输出
        SSPCON=0;
TRISD = 0;                                          //portd 输出
        TRISA = 0;                                          //porta 输出
        PORTA = 0x3f;                                        //先关闭所有显示
        PORTD = 0x08;
        TRISC = 0X00;                                        //rc输出
}


/****************************************************************************
* 名    称:delay()   
* 功    能:延时
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void delay(uchar dly)                                      //延时程序
{                                         //定义整形变量
        for (;dly>0;dly--);                        //延时
}


       
/***********************************************************/
//功能:主函数
//调用:set_1302()、get_1302()、display()
/************************************************************/
void main()
{
        port_init();                     //调用引脚初始化函数
        ds1302_init();                   //调用DS1302初始化函数
        set_1302(table);                      //调用设置时间函数
        while (1)
        {        get_1302();
                         //调用取时间函数
                display();                  //调用显示函数
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-7-2 20:03:30 | 显示全部楼层
PIC单片机端口操作时,如果操作的两个端口都为C口且都为输出,如果单独操作控制两个端口,需在操作中间加入几个空指令,这是由PIC单片机的端口结构所决定的,多看看以前的帖子吧,如下面的程序在 RST=0与CLK=0连续操作,则应更改为

RST = 0;
Nop();     //加入2条空指令
Nop();
CLK = 0;

你的几个底层端口操作函数中都有这种情况,你修改下,至于其他的逻辑功能我没有仔细查看,而且DS1302网上例程很多,自己参考下吧。

出0入0汤圆

发表于 2010-7-9 22:09:36 | 显示全部楼层
按这个调试步骤你看可否帮到你
*   先不管DS1302的实际数据, 你将这个数据固定为12.34, 看显示是否正确, 再将数据改为56.78, 再看一下显示结果,确保你的显示程序是正确的。
*   读出DS1302的数据, 直接显示, 不要做任何转换, 对照手册, 检查读出的数据是否正确。
*   将数据转换为温度数据, 显示
-----------------------------------------------------------------
程序是一步步走的, 你一上来就一个完整的程序, 谁能确定是那里的问题呢, 要把功能分开, 分别调试成功后再组合

出0入0汤圆

发表于 2010-7-9 23:21:09 | 显示全部楼层
this is an incredibly good example as to how not to program any project.

if you are trained as a programmer, you should ask the school for a full refund of your tuition.

having said that, I would suggest that divide up the program in three blocks:

1) display - make sure that if you send it data, it can properly display;
2) 3-wire - make sure that you have a working set of 3-wire routines to communicate to the chip
3) ds1302 - make sure that you can talk to the chip utilizing the 3-wire routines.

otherwise, you are going to have a hard time getting there.

出0入0汤圆

发表于 2010-7-9 23:32:15 | 显示全部楼层
本站有CCS下载。上面有LIB
--------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
////                               DS1302.C                           ////
////                     Driver for Real Time Clock                   ////
////                                                                  ////
////  rtc_init()                                   Call after power up////
////                                                                  ////
////  rtc_set_datetime(day,mth,year,dow,hour,min)  Set the date/time  ////
////                                                                  ////
////  rtc_get_date(day,mth,year,dow)               Get the date       ////
////                                                                  ////
////  rtc_get_time(hr,min,sec)                     Get the time       ////
////                                                                  ////
////  rtc_write_nvr(address,data)                  Write to NVR       ////
////                                                                  ////
////  data = rtc_read_nvr(address)                 Read from NVR      ////
////                                                                  ////
////  get_bcd(data)                              Convert data to BCD  ////
////                                                                  ////
////  rm_bcd(data)                               Convert data to int  ////
////                                                                  ////
//////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services          ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler.  This source code may only be distributed to other     ////
//// licensed users of the CCS C compiler.  No other use, reproduction////
//// or distribution is permitted without written permission.         ////
//// Derivative programs created using this software in object code   ////
//// form are not restricted in any way.                              ////
//////////////////////////////////////////////////////////////////////////

#ifndef RTC_SCLK

#define RTC_SCLK PIN_B1
#define RTC_IO   PIN_B3
#define RTC_RST  PIN_B2

#endif

void write_ds1302_byte(BYTE cmd) {
   BYTE i;

   for(i=0;i<=7;++i) {
      output_bit(RTC_IO, shift_right(&cmd,1,0) );
      output_high(RTC_SCLK);
      output_low(RTC_SCLK);
   }
}

void write_ds1302(BYTE cmd, BYTE data) {

   output_high(RTC_RST);
   write_ds1302_byte(cmd);
   write_ds1302_byte(data);
   output_low(RTC_RST);
}

BYTE read_ds1302(BYTE cmd) {
   BYTE i,data;

   output_high(RTC_RST);
   write_ds1302_byte(cmd);
   
   input(RTC_IO);
   delay_us(1);
         
   for(i=0;i<=7;++i) {
      shift_right(&data,1,input(RTC_IO));
      output_high(RTC_SCLK);
      delay_us(2);
      output_low(RTC_SCLK);
      delay_us(2);
   }
   output_low(RTC_RST);

   return(data);
}

void rtc_init() {
   BYTE x;
   output_low(RTC_RST);
   delay_us(2);
   output_low(RTC_SCLK);
   write_ds1302(0x8e,0);
   write_ds1302(0x90,0xa4);
   x=read_ds1302(0x81);
   if((x & 0x80)!=0)
     write_ds1302(0x80,0);
}

byte get_bcd(BYTE data)
{
   byte nibh;
   byte nibl;

   nibh=data/10;
   nibl=data-(nibh*10);

   return((nibh<<4)|nibl);
}

byte rm_bcd(BYTE data)
{
   byte i;

   i=data;
   data=(i>>4)*10;
   data=data+(i<<4>>4);

   return data;
}

void rtc_set_datetime(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min) {

   write_ds1302(0x86,get_bcd(day));
   write_ds1302(0x88,get_bcd(mth));
   write_ds1302(0x8c,get_bcd(year));
   write_ds1302(0x8a,get_bcd(dow));
   write_ds1302(0x84,get_bcd(hr));
   write_ds1302(0x82,get_bcd(min));
   write_ds1302(0x80,get_bcd(0));
}

void rtc_get_date(BYTE& day, BYTE& mth, BYTE& year, BYTE& dow) {
   day = rm_bcd(read_ds1302(0x87));
   mth = rm_bcd(read_ds1302(0x89));
   year = rm_bcd(read_ds1302(0x8d));
   dow = rm_bcd(read_ds1302(0x8b));
}

void rtc_get_time(BYTE& hr, BYTE& min, BYTE& sec) {
   hr = rm_bcd(read_ds1302(0x85));
   min = rm_bcd(read_ds1302(0x83));
   sec = rm_bcd(read_ds1302(0x81));
}

void rtc_write_nvr(BYTE address, BYTE data) {
   write_ds1302(address|0xc0,data);
}

BYTE rtc_read_nvr(BYTE address) {
    return(read_ds1302(address|0xc1));
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 10:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表