广告

原创 c8051f020 ds1302

2008-10-29 19:56 2735 1 1 分类: MCU/ 嵌入式

         C8051F020片内含CIP-51的CPU内核,它的指令系统与MCS-51完全兼容。


         其中的C8051F020单片机含有64kB片内Flash程序存储器,4352B的RAM、8个I/O端口共64根I/O口线、一个12位A/D转换器和一个8位A/D转换器以及一个双12位D/A转换器、2个比较器、5个16位通用定时器、5个捕捉/比较模块的可编程计数/定时器阵列、看门狗定时器、VDD监视器和温度传感部分.


     所以c51的程序很容易拿到c8051f来。基本不用修改。


源码:


/*******************************************************************


 DS1302


********************************************************************/
#include "c8051f020.h" 
#include "stdio.h"
 
#define uchar unsigned char
long result;


#define BAUDRATE     19200            // Baud rate of UART in bps
#define SYSCLK       22118400          // SYSCLK frequency in Hz


sbit SCLK = P3^4;
sbit IO   = P3^3;
sbit RSTB = P3^5;


/**************************** 函数原型说明 ****************************/
uchar rbyte_3w();    // 字节读取函数
void reset_3w();    // 复位函数
void wbyte_3w(uchar);   // 字节写入函数
void initialize_DS1302(); // DS1302初始化函数
void disp_clk_regs(uchar); // 显示时钟寄存器内容函数


/*******************SYSCLK_Init函数*************************************/


void SYSCLK_Init (void)
{
   int i;                              /*延时计数器*/


   OSCXCN = 0x67;                      /*打开外部晶体振荡器*/
   for (i=0; i < 256; i++) ;           /*延时*/


   while (!(OSCXCN & 0x80)) ;          /*查询外部晶体是否稳定起振*/


   OSCICN = 0x88;                      /*用外部晶体作为系统时钟,并使能时钟丢失检测*/
}
/***************************UART0_Init函数***************************/
void UART0_Init (void)
{
   SCON0   = 0x50;                     /*SCON0:模式1,8位UART,时能RX*/
   TMOD    = 0x20;                     /*TMOD: 定时器工作再模式2, 8位重载*/
   TH1    = -(SYSCLK/BAUDRATE/16);     /*设置定时1用作波特率的重载值*/
   TR1    = 1;                         /*开定时器1*/
   CKCON |= 0x10;                      /*定时器1用系统时钟作为它的时基*/
   PCON  |= 0x80;                      /*SMOD00 = 1*/
}
/****************************PORT_Init函数**************************/
void PORT_Init (void)
{
   XBR0    = 0x04;                     /*使能UART0*/
   XBR1    = 0x00;
   XBR2    = 0x40;                     /*使能交叉开关和弱上拉*/
   P0MDOUT |= 0x01;                    /*使能TX0作为推挽输出*/
   P1MDOUT |= 0x40;                    /*时能P1.6 (LED)作为推挽输出*/
   P3MDOUT |= 0xff;
}
/***************************** 复位函数 ******************************/
void reset_3w() {
   SCLK = 0;
   RSTB = 0;
   RSTB = 1;
}


/****************************** 字节写入函数 ***************************/
void wbyte_3w(uchar W_Byte) {
uchar i;
 for(i = 0; i < 8; ++i) {
  IO = 0;
  if(W_Byte & 0x01) IO = 1;
  SCLK = 0;
  SCLK = 1;
  W_Byte >>= 1;
    }
}


/****************************** 字节读取函数 ****************************/
uchar rbyte_3w() {
uchar i;
uchar R_Byte;
uchar TmpByte;


 R_Byte = 0x00;
 IO = 1;
 for(i=0; i<8; ++i) {
  SCLK = 1;
  SCLK = 0;
  TmpByte = (uchar)IO;
  TmpByte <<= 7;
  R_Byte >>= 1;
  R_Byte |= TmpByte;
 }
 return R_Byte;
}
/************************* 显示时钟寄存器内容函数 ***********************/
void disp_clk_regs(uchar loop) {
uchar lsec = 99, sec, min, hrs, dte, mon, day, yr;


do {     // 读取并显示时钟寄存器的内容
  reset_3w();
  wbyte_3w(0xBF);  // 以多字节突发方式读取时钟数据
  sec = rbyte_3w(); // 秒
  min = rbyte_3w(); // 分
  hrs = rbyte_3w(); // 小时
  dte = rbyte_3w(); // 日期
  mon = rbyte_3w(); // 月份
  day = rbyte_3w(); // 星期
  yr  = rbyte_3w(); // 年
  reset_3w();
  if(sec != lsec || !loop) { // 每秒显示一次  
   printf("\nYr   Day  Mon  Dte  Hrs  Min  Sec");
   printf("\n%2.bX   %2.bX   %2.bX   %2.bX", yr, day, mon, dte);
   printf("   %2.bX   %2.bX   %2.bX", hrs, min, sec);
   lsec = sec;
 }
 while(1); 
}
/**************************** DS1302初始化函数 **************************/
void initialize_DS1302() {
uchar yr, mn, date, dy, hr, min, sec;


 printf("\nEnter the year (0-99): ");
 scanf("%bx", &yr);
 printf("\nEnter the month (1-12): ");
 scanf("%bx", &mn);
 printf("\nEnter the date (1-31): ");
 scanf("%bx", &date);
 printf("\nEnter the day (1-7): ");
 scanf("%bx", &dy);
 printf("\nEnter the hour (1-24): ");
 scanf("%bx", &hr);
 hr = hr & 0x3f;    // 设置时钟为24小时方式
 printf("\nEnter the minute (0-59): ");
 scanf("%bx", &min);
 printf("\nEnter the second (0-59): ");
 scanf("%bx", &sec);


 reset_3w();
 wbyte_3w(0x8e);    // 写保护控制寄存器
 wbyte_3w(0);    // 允许写入
 reset_3w();
 wbyte_3w(0x90);    // 涓流充电控制寄存器
 wbyte_3w(0xab);    // 允许充电, 双二极管, 8K 电阻
 reset_3w();
 wbyte_3w(0xbe);    // 以多字节突发方式写入时钟数据(8个字节)
 wbyte_3w(sec);
 wbyte_3w(min);
 wbyte_3w(hr);
 wbyte_3w(date);
 wbyte_3w(mn);
 wbyte_3w(dy);
 wbyte_3w(yr);
 wbyte_3w(0);    // 以多字节突发方式写入时钟数据时
                                // 必须对写保护控制寄存器写入0值
 reset_3w();
}


/****************************** 主函数 *********************************/
main (void) 

    WDTCN = 0xde;                       /*关看门狗*/
    WDTCN = 0xad;


    SYSCLK_Init ();                     /*初始化系统时钟*/
    PORT_Init ();                       /*初始挂交叉开关和I/O口*/
    UART0_Init ();                      /*初始化UART0*/       
 while (1) {  
 printf("\r***********C51 PROGRAM FOR DS1302***********\n\n");
 printf("I. initialize DS1302\n");
 printf("CW. Write Byte  CR. Read Time\n");
 printf("RW. Write RAM   RR. Read RAM\n");
 printf("\nEnter Menu Selection:");
 initialize_DS1302();
 disp_clk_regs(1);
 }
}


 


运行结果:


 


32c18bba-c2c8-4313-a8fa-610d93fb6ebb.jpg


 


 




   

 

广告

文章评论 0条评论)

登录后参与讨论
相关推荐阅读
412922521_325344472 2009-11-15 00:44
通用按键消抖函数 -- 数据与过程分离
AUTO:  nicksean 不务正业          项目里经常处理按键消抖, 本来这个消抖的过程是与具体按下的键无关的, 可以前的代码总是在消抖的同时处理具体的按键值, 再加上长按 短按 组合...
412922521_325344472 2009-11-13 13:16
液晶ST7920串行显示
液晶显示128*64以7920为主控制器,采用3线制,比较经济简单。代码如下.....
412922521_325344472 2009-11-13 13:11
DS18B20 C51完整版
使用WINBOND W78C516单片机,11.0592MHZ晶振,用共阳LED数码管P0口输出段码,P1口扫描/*******************************************...
412922521_325344472 2009-11-12 13:19
74HC164驱动数码管
          74HC164是串行输入,并行输出接口器件,可用在单向的并行输出/并行地址锁存等. 74HC164因为价格便宜,容易使用特别适合使用在在需要用到数码管显示IO口又比较紧张的电子产品...
412922521_325344472 2009-11-10 20:13
at24c512多字节读写函数 欢迎测试
刚写的at24c512多字节读写函数,欢迎测试。/********************************************************************函数功能:EE...
412922521_325344472 2009-11-10 19:59
旋转编码器
    很好的旋转编码器的读码程序,设旋转编码器的输出波形如下                 ______        ______        ______        ______正转时:...
我要评论
0
1
广告