325|2

1125

帖子

0

资源

纯净的硅(中级)

msp430g2331 ds1302时钟模块 [复制链接]

 手上有块ds1302时钟模块,也有些数码管,于是试着做了个时钟,当然因为是手工,所以没有淘宝上买的好看,当然自己做的成本也高,所以无法相比,只是作为一种学习方式。做着送人了,所以照片只有一张,也没有显示。

image.png
         这是我用手机拍的,只有一张,没有多拍几张,样子太丑了,没有淘宝上做的美观,被同学批了一顿。
  程序很简单,不是很占用空间,io资源,所以只用了msp430g2231,我后来想用xin,xout做io口时,发现不行,所以就只用了8个io口。
数码管直接显示年月日小时,分钟,秒,星期,每30秒刷新一次。用hc164做片选数码管断码显示芯片。

部分程序预览:
#include"io430.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CLK0  P1OUT&=~BIT6
#define CLK1   P1OUT|=BIT6
#define CPU_F ((double)1000000)   //外部高频晶振16MHZ
//#define CPU_F ((double)32768)   //外部低频晶振32.768KHZ
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))


unsigned char const code_hex[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39,0x79,0x0e,0x3e,0x00};//0,1,2,3,4,5,6,7,8,9,c,e,j,u, ,
uchar t,t1,t2,t3;
uchar dis_play[4];


//数码管显示函数

void extern_16m()
{
  WDTCTL = WDTPW + WDTHOLD;
    if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF)
        {
                while(1);                // If calibration constants erased, trap CPU!!
        }
DCOCTL |= DCO0 + DCO1+DCO2;                                                                   //SMCLK选择LFXT1CLK
// BCSCTL2 |= SELM_0;//MCLK采用1M的内部DCO   
// BCSCTL2 |= DIVS_0;//SMCLK采用内部的时钟


}

void hc164_init()
{
  P1DIR |=BIT6+BIT7+BIT0+BIT1+BIT2+BIT3;                            // P1.0 output
  
}

void sendbyte(uchar byte)
{            
uchar c,num;   
num=byte;
for(c=0;c<8;c++)        
{     
P1OUT&=~0x80;
CLK0;   
P1OUT|=num&0x80; //(0x80即十进制的128, 二进制的10000000 按位发送
CLK1;         
num<<=1;   
}
}


void send_char(uchar weizhi,uchar byte)
{
  
  P1OUT |= 0x0f;   
  uchar c,send_byte;
  send_byte=code_hex[byte];
//  if((weizhi==0)&&(xianshi_flag==0))
//   send_byte|=0x80;
  sendbyte(send_byte);
  c=weizhi&0x03;
  P1OUT&=~(1<<c);
}

void init_TA()
{

  TACCR0 = 1000;                            //8ms中断一次
  TACTL = TASSEL_2 + MC_1+ID_3;              // SMCLK, upmode,8分频,
  TACCTL0 = CCIE;                           // TACCR0 interrupt enabled
}


void shumaguan()
{
   ++t;
if(t>=4)
   t=0;
  send_char(t,dis_play[t]);
}


////时钟模块
#define DS1302_DIR  P1DIR
#define DS1302_IN    P1IN
#define DS1302_OUT  P1OUT

#define DS1302_RST  BIT7
#define DS1302_SCLK  BIT4
#define DS1302_SDI  BIT5  //定义MSP320的端口

#define DS1302_RST_LO  DS1302_OUT &= ~DS1302_RST
#define DS1302_RST_HI  DS1302_OUT |= DS1302_RST
#define DS1302_SCLK_LO  DS1302_OUT &= ~DS1302_SCLK
#define DS1302_SCLK_HI  DS1302_OUT |= DS1302_SCLK
#define DS1302_SDI_LO  DS1302_OUT &= ~DS1302_SDI
#define DS1302_SDI_HI  DS1302_OUT |= DS1302_SDI


void DS1302_Reset(void);
void DS1302_WriteOneByte(unsigned char w_dat);
void DS1302_WriteData(unsigned char addr,unsigned char w_dat);
void DS1302_SettingData(void);
void DS1302_GetData(unsigned char *str);
unsigned char DS1302_ReadOneByte(void);
unsigned char DS1302_ReadData(unsigned char addr);

unsigned char Setting_Time[7]={ //bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0x15,    //--------十位-------|-------个位--------|年份(当前07年)
0x04,    //                        |-----个位-----|星期(当前周日)
0x09,    //              |十位|-------个位--------|月份(当前07月)
0x10,    //         |--十位---|-------个位--------|日期(当前01号)
0x13,    //-12H|    |--十位---|-------个位--------|小时(当前18点)
0x00,    //    |-----十位-----|-------个位--------|分钟(当前20分)
0x21    //    |-----十位-----|-------个位--------|秒钟(当前30秒)
};
unsigned char ReadingData[7];  //读出来的数据,同SettingData定义与格式

/****************************
void main(void) {
WDTCTL = WDTPW + WDTHOLD;
DS1302_Reset();
//DS1302_SettingData();
while(1){
  DS1302_GetData(ReadingData);
  _NOP();
};
}
****************************/


//DS1302复位
void DS1302_Reset(void) {
DS1302_DIR |=  DS1302_SCLK;

DS1302_SCLK_LO;
DS1302_RST_LO;
// delay_us(10);
DS1302_SCLK_HI;
}

//向DS1302写入一个字节
void DS1302_WriteOneByte(unsigned char w_dat) {
unsigned char temp;

DS1302_RST_HI;
DS1302_DIR |= DS1302_SDI;

for(temp=8;temp>0;temp--) {
  DS1302_SDI_LO;
  if(w_dat&BIT0) DS1302_SDI_HI;
  DS1302_SCLK_LO;
//  delay_us(10);
  DS1302_SCLK_HI;
//  delay_us(10);
  w_dat >>=1;
}
}

//从DS1302中读取一个字节
unsigned char DS1302_ReadOneByte(void) {
unsigned char temp,rdata;
rdata = 0x00;

DS1302_RST_HI;
DS1302_DIR &= ~DS1302_SDI;

for(temp=0;temp<8;temp++){rdata >>= 1;//将移位放到前面,否则读不到最高一位
  DS1302_SCLK_HI;
// delay_us(10);
  DS1302_SCLK_LO;
//  delay_us(10);
  if((DS1302_IN&DS1302_SDI)==DS1302_SDI)
   rdata |= BIT7;
  //rdata >>= 1;
}

return(rdata);
}

//向DS1302中写入地址后写入数据
void DS1302_WriteData(unsigned char addr,unsigned char w_dat) {
DS1302_RST_LO;
DS1302_SCLK_LO;
DS1302_RST_HI;

DS1302_WriteOneByte(addr);  //写入地址
DS1302_WriteOneByte(w_dat);  //写入数据

DS1302_SCLK_HI;
DS1302_RST_LO;
}

//向DS1302写入地址后,从DS1302中读取数据
unsigned char DS1302_ReadData(unsigned char addr) {
unsigned char r_dat;
DS1302_RST_LO;
DS1302_SCLK_LO;
DS1302_RST_HI;

DS1302_WriteOneByte(addr);  //写入地址
r_dat = DS1302_ReadOneByte();  //读出数据

DS1302_SCLK_LO;
DS1302_RST_LO;

return(r_dat);
}

//按照SettingData的设置设置DS1302的时间
void DS1302_SettingData(void) {
unsigned char temp;
unsigned char addr = 0x8C;

DS1302_WriteData(0x8E,0x00);  //写入控制命令,禁用写保护

for(temp=0;temp<7;temp++) {
  DS1302_WriteData(addr,Setting_Time[temp]);
  addr -= 2;
}

DS1302_WriteData(0x8E,0x80);  //写入控制命令,启用写保护
}

//读取DS1302时间到ReadingData中
void DS1302_GetData(unsigned char *str) {
unsigned char temp;
unsigned char addr = 0x8D;

for(temp=0;temp<7;temp++) {
  str[temp] = DS1302_ReadData(addr);//年
  addr -= 2;
}
}

void shumaguan_buff(void)
{
  if(++t3==30)
  t3=0;
  if(t3<5)t2=1;
  else if(t3<10)t2=2;
  else if(t3<20)t2=3;
  else t2=4;
  switch(t2)
  {
  case 1:dis_play[0]=2;dis_play[1]=0;dis_play[2]=ReadingData[0]/16;dis_play[3]=ReadingData[0]%16;break;                                       //显示年份
  case 2:dis_play[0]=ReadingData[2]/16;dis_play[1]=ReadingData[2]%16;dis_play[2]=ReadingData[3]/16;dis_play[3]=ReadingData[3]%16;break;       //显示月份日期
  case 3:dis_play[0]=ReadingData[4]/16;dis_play[1]=ReadingData[4]%16;dis_play[2]=ReadingData[5]/16;dis_play[3]=ReadingData[5]%16;break;       //显示时分
  case 4:dis_play[0]=ReadingData[1]%16;dis_play[1]=14;dis_play[2]=ReadingData[6]/16;dis_play[3]=ReadingData[6]%16;break;                      //显示星期秒
  default:break;
  }
  
}


#pragma vector=TIMER0_A0_VECTOR  
__interrupt void TIMERA0_ISR() // the interrupt source is CC0
{
  ++t1;
  if(t1>=125)
    t1=0;
  if(t1==0)
  {
    DS1302_GetData(ReadingData);
    shumaguan_buff();
  }  
else
shumaguan();
}
 


回复

3068

帖子

0

资源

纯净的硅(高级)

学习了


回复

3325

帖子

1

资源

五彩晶圆(初级)

确实不好看

个人签名人已离开,无事别找,找也找不到。

回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/6 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表