目录
1.点灯
1.1点亮第一个LED(三种方法)
#include<REGX52.H>//点击右键来的
void main()
{
P2=0xfe;//1111 1110将其转为上面的16进制的数
//这个上面的0x是一个前缀,代表后面的是十六进制数
while(1){}
}
#include <REGX52.H>//点击右键来的
void main()
{
P2_0=0;//输出一个低电平0,这时,第一个led灯被点亮
//由于我的LED是通过正极接到单片机的某个引脚上,那么当引脚输出低电平(0)时,LED就会点亮;
//如果你的不同,那么就接在1试试;
//你要点亮其他的灯也可以P2_x=0;这个x在0到7之间,这个0->1号,1->2号,2->3号
}
#include"reg52.h"//这个一个自己打的头文件
sbit led1=P2^0;//定义一个名字为led1的名字,使其等于第一个灯的
void main()
{
while(1){
led1=0;//输出低电压
}
}
/*Sbit是C51单片机中位地址的定义指令。单片机的编程需要控制字节地址或位地址进行输入和输出,
以控制其它设备,而位地址定义sbit是基础。*/
//这个0->1号,1->2号,2->3号····
1.2LED闪烁
#include <REGX52.H>
//下面是延时函数
//------------------------------------------
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
//-------------------------------------------
void main(){
P2=0xfe;//亮
Delay(500);
P2=0xff;//灭
Delay(500);
}
1.3LED流水灯
#include <REGX52.H>
#include<intrins.h>
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();//只要你不是特别精确,这个可以删除
i = 4; // _nop_();需要加一个头文件#include<INTRINS.H>
j = 205;
k = 187;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{ while(1)
{
P2=0xfe;//1111 1110 第一个亮
Delay500ms();
P2=0xfd; //1111 1101 第二个亮
Delay500ms();
P2=0xfb; //1111 1011 第3个亮
Delay500ms();
P2=0xf7; //1111 0111 第4个亮
Delay500ms();
P2=0xef; //1110 1111 第5个亮
Delay500ms();
P2=0xdf; //1101 1111 第6个亮
Delay500ms();
P2=0xbf; //1011 1111 第7个亮
Delay500ms();
P2=0x7f; //0111 1111 第8个亮
Delay500ms();
}
}
1.4流水灯随意控制时间的形式
#include <REGX52.H>
void Delay1ms(unsigned int xms) //起一个函数x毫秒,这里有软件生产加一点改动
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms=xms-1;
}
}
void main()
{
while(1)
{
P2=0xfe;//1111 1110 第1灯亮
Delay1ms(500);//括号里面的500可以改为其他数字
P2=0xfd; //1111 1101 第2灯亮
Delay1ms(500);
P2=0xfb; //1111 1011 第3灯亮
Delay1ms(500);
P2=0xf7; //1111 0111 第4灯亮
Delay1ms(500);
P2=0xef; //1110 1111 第5灯亮
Delay1ms(500);
P2=0xdf; //1101 1111 第6灯亮
Delay1ms(500);
P2=0xbf; //1011 1111 第7灯亮
Delay1ms(500);
P2=0x7f; //0111 1111 第8灯亮
Delay1ms(500);
}
}
2.独立按键
2.1独立按键控制led灯亮灭
#include <REGX52.H>
void main()
{
//P2=0xfe; 操作一个寄存器8位的时给8位的数据
//P2_0=0;//操作寄存器1位时给1位的数据0/1(给2也相当是1)
//P2_0=1;//加一个这个是不是led就会熄灭
//第一个按键控制,按下时点亮执行P2_0=0;,松开时熄灭执行P2_0=1;
while(1)
{
if(P3_1==0)//第一个键时P3_1,第二个P3_0,第三个P3_2,第四个P3_3
{
P2_0=0;
}
else
{
P2_0=1;
}
}
}
2.2独立按键控制led状态
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main(){
while(1){
if(P3_1==0){
Delay(20);//消除按下抖动
while(P3_1==0);//检测松手
Delay(20);//消除松手抖动
P2_0=~P2_0;
}
}
}
2.3独立按键控制led显示二进制
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned int led=0;//定义一个变量
while(1){
if(P3_1==0){ //P3_1是第一个按键
Delay(20);
while(P3_1==0);
Delay(20);
//这里不能直接写成P2++,P2再加就会溢出,加到最大就变成最小的0000 0000
//P2=~P2,这里取反而变成1111 1111 ,从此循环,造成不能达到想要的结果
led++;
P2=~led;
}
}
}
2.4独立按键控制led移位
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned int led=0;//定义一个变量
while(1){
if(P3_1==0){
Delay(20);
while(P3_1==0);
Delay(20);
//下面三行是与上一个代码变化的部分
led++;
if(led>=8)led=0;
P2=~(0x01<<led);//<<代表向左移位,<<1代表左移一位 例如0000 0001变成0000 0010
}
}
}
增加一个方向的方法
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main(){
unsigned int led=0;//定义一个变量
while(1){
if(P3_1==0){
Delay(20);
while(P3_1==0);
Delay(20);
led++;
if(led>=8)led=0;
P2=~(0x01<<led);//<<代表向左移位,<<1代表左移一位 例如0000 0001变成0000 0010
}
//增加一个使得按该键向另一个方向移动---------
//--------------------增加的部分---------------
if(P3_0==0){
Delay(20);
while(P3_0==0);
Delay(20);
if(led==0)led=7;
else led--;
P2=~(0x01<<led);
}
//---------------------------------------------
}
}
3.数码管
3.1静态数码管显示
//要求:需要第三个数码管显示6
//第三个数码管是LED6,由图可知对于的是Y5,Y5转为二进制是101
//给到的信号要高位对高位,所以P2_4=1;(第一个1)P2_3=0;P2_2=1;
//其次因为要显示6,段码为1011 1110,
//高位对高位=0 1 1 1 1 1 0 1;转换成十六进制位输出=0x7D;
#include <REGX52.H>
void main(){
P2_4=1;
P2_3=0;
P2_2=1;
P0=0x7D;
while(1){}
}
#include <REGX52.H>
//下面这个函数用来实现输出在哪一个数码管上
void sumag(unsigned char Location,Number){
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;break;//led8
case 2: P2_4=1;P2_3=1;P2_2=0;break;//led7
case 3: P2_4=1;P2_3=0;P2_2=1;break;
case 4: P2_4=1;P2_3=0;P2_2=0;break;
case 5: P2_4=0;P2_3=1;P2_2=1;break;
case 6: P2_4=0;P2_3=1;P2_2=0;break;
case 7: P2_4=0;P2_3=0;P2_2=1;break;
case 8: P2_4=0;P2_3=0;P2_2=0;break;
}
P0=0x7d;
}
void main(){
sumag(7,2);//2会赋值给number,但现在上面并未处理
while(1){}
}
#include <REGX52.H>
unsigned char sumagtable[]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
void sumag(unsigned char Location,Number){
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;break;//led8
case 2: P2_4=1;P2_3=1;P2_2=0;break;//led7
case 3: P2_4=1;P2_3=0;P2_2=1;break;
case 4: P2_4=1;P2_3=0;P2_2=0;break;
case 5: P2_4=0;P2_3=1;P2_2=1;break;
case 6: P2_4=0;P2_3=1;P2_2=0;break;
case 7: P2_4=0;P2_3=0;P2_2=1;break;
case 8: P2_4=0;P2_3=0;P2_2=0;break;
}
P0=sumagtable[Number];//引用number的值
}
void main(){
sumag(6,2);//前面6代表是第6个数码管,2代表的是输出数字2
while(1){}
}
3.2动态数码管显示
#include <REGX52.H>
//下面是延时函数
//------------------------------------------
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
//-------------------------------------------
//下面一行定义一个数组方便调用
unsigned char sumagtable[]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
void sumag(unsigned char Location,Number){
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;break;//led8
case 2: P2_4=1;P2_3=1;P2_2=0;break;//led7
case 3: P2_4=1;P2_3=0;P2_2=1;break;
case 4: P2_4=1;P2_3=0;P2_2=0;break;
case 5: P2_4=0;P2_3=1;P2_2=1;break;
case 6: P2_4=0;P2_3=1;P2_2=0;break;
case 7: P2_4=0;P2_3=0;P2_2=1;break;
case 8: P2_4=0;P2_3=0;P2_2=0;break;
}
P0=sumagtable[Number];//引用number的值
Delay(1);//稳定一秒,让其稳定显示,如果立马清零就会变得很暗
P0=0x00;//清零
}
void main(){
while(1){
sumag(1,1);//前面6代表是第6个数码管,2代表的是输出数字2
sumag(2,2);
sumag(3,3);
//这里最多弄8个
}
}
4.模块化编程
借用3.2的代码将其模块化
首先建立5个新的文档,分别命名为main.c Delay.c Delay.h sumag.c sumag.h
再main.c中存放的代码是
#include <REGX52.H>
#include "Delay.h"//调用
#include "sumag.h"//调用
void main()
{
while(1){
sumag(1,1);
sumag(2,2);
sumag(3,3);
}
}
Delay.c中放的是
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
Delay.h中存放的是
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);//这里要写;结束
#endif
sumag.c存放的是
#include <REGX52.H>
#include "Delay.h"
unsigned char sumagtable[]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};//这是0~10
void sumag(unsigned char Location,Number)
{
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;break;//led8
case 2: P2_4=1;P2_3=1;P2_2=0;break;//led7
case 3: P2_4=1;P2_3=0;P2_2=1;break;
case 4: P2_4=1;P2_3=0;P2_2=0;break;
case 5: P2_4=0;P2_3=1;P2_2=1;break;
case 6: P2_4=0;P2_3=1;P2_2=0;break;
case 7: P2_4=0;P2_3=0;P2_2=1;break;
case 8: P2_4=0;P2_3=0;P2_2=0;break;
}
P0=sumagtable[Number];//引用number的值
Delay(1);//稳定一秒,让其稳定的显示,如果立马清零会导致变得很暗
P0=0x00;//清零
}
sumag.h存放的是
#ifndef __SUMAG_H__
#define __SUMAG_H__
void sumag(unsigned char Location,Number);
#endif
这样将每一部分都进行分开了,方便以后的调用
5.LCD1602
还是创建5个文档,mian.c lcd1602.c lcd1602.h Delay.c Delay.h
LCD_Init();//初始化
LCD_ShowChar(1,1,'a');//第一行第一列显示a
//显示字符
LCD_ShowString(1,3,"hello");//第一行第三列开始显示hello
//显示字符串
LCD_ShowNum(1,9,123,3);//第一行,第9列,开始显示123,长度为3
//显示十进制数字
LCD_ShowSignedNum(1,13,-66,2);
//显示带有符号的十进制数字
LCD_ShowHexNum(2,1,0xA8,2);
//显示16进制数字
LCD_ShowBinNum(2,4,0xAA,8);
//显示二进制数字
mian.c中含
#include <REGX52.H>
#include "lcd1602.h"
#include"Delay.h"
int result=0;
void main()
{
LCD_Init();//初始化
while(1){
result++;
Delay(1000);
LCD_ShowNum(1,1,result,3);
}
}
led1602.c中含(这个可以直接复制)
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
lcd1602.h中含
#ifndef __LCD1602_H__
#define __LCD1602_H__
//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
#endif
Delay.c和Delay.h可以将4.模块化编程的复制粘贴过来
6.键盘
6.1矩阵键盘
首先把前面Delay和lcd1602两个各自的两个文件复制在一个文件夹中,在创建一个main.c和
MatrixKey.c和MatrixKey.h几个文件
main.c
#include <REGX52.H>
#include"Delay.h"
#include"lcd1602.h"
#include"matrixkey.h"
unsigned char keynum;//什么函数
void main()
{
LCD_Init();//初始化
LCD_ShowString(1,1,"matrixkey:");//在1行第1列输出字符串matrixkey:
while(1){
keynum=matrixkey();//将获得的值给keynum
//如果没按键就是0,如果有按键就会卡在matrixkey,一旦松手就回返回给keynum
if(keynum){ //判断如果有按键按下,这里判断的是keynum!=0,在这里直接写keynum也行
LCD_ShowNum(2,1,keynum,2);//第2行第1列开始输出长度为2,值为keynum
}
}
}
MatrixKey
#include <REGX52.H>
#include"Delay.h"
/*矩阵键盘读取按键代码,
如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键代码
没有按键按下时,返回0
*/
unsigned char matrixkey(){
unsigned char keynumber=0;
P1=0xff;//全部位于高电伏
P1_3=0;//把第一列置零
//Delay(20);while(P1_7==0);Delay(20);keynumber=1;这个是用来消隐的
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynumber=1;}//while(P1_7==0);
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynumber=5;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynumber=9;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynumber=13;}
//因为只有第一位置 置零了,所以其他列的都不亮
//这时P1_7对s1,P1_6对s5,····
P1=0xff;//全部位于高电伏
P1_2=0;//把第二列置零
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynumber=2;}//while(P1_7==0);
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynumber=6;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynumber=10;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynumber=14;}
P1=0xff;//全部位于高电伏
P1_1=0;//把第三列置零
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynumber=3;}//while(P1_7==0);
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynumber=7;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynumber=11;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynumber=15;}
P1=0xff;//全部位于高电伏
P1_0=0;//把第四列置零
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynumber=4;}//while(P1_7==0);
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynumber=8;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynumber=12;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynumber=16;}
return keynumber;
}
MatrixKey.h
#ifndef __MATRIXKEY_H__
#define __MATRIXJEY_H__
unsigned char matrixkey();
#endif
6.2密码锁
只修改main.c的代码
#include <REGX52.H>
#include"Delay.h"
#include"lcd1602.h"
#include"MatrixKey.h"
unsigned char KeyNum;
unsigned int Password,count;//密码,后者用来计次
void main(){
LCD_Init();//初始化
LCD_ShowString(1,1,"Password");
while(1)
{
KeyNum=matrixKey();
if(KeyNum!=0)
{
if(KeyNum<=10)//如果s1~s10按键按下,输入密码
{
if(count<4){ //如果次数小于4
Password*=10; //密码左移一位
Password+=KeyNum%10;//获取一位密码
count++;//计次加一
}
LCD_ShowNum(2,1,Password,4);//更新显示
}
if(KeyNum==11)//如果s11键按下,为确认
{
if(Password==2345)
{ //如果密码等于正确密码
LCD_ShowString(1,14,"ok "); //显示ok
Password=0; //密码清0
count=0; //计次清零
LCD_ShowNum(2,1,Password,4); //更新显示
}
else //否则
{
LCD_ShowString(1,14,"not");//显示错误
Password=0; //密码清0
count=0; //计次清零
LCD_ShowNum(2,1,Password,4);//更新显示
}
}
if(KeyNum==12)//如何s12按键按下,为取消键
{
Password=0; //密码清0
count=0; //计次清零
LCD_ShowNum(2,1,Password,4); //更新显示
}
}
}
}
7.定时器
#include <REGX52.H>
void Timer0_Init()//初始化函数
{
//TMOD=0x01;//0000 0001 改为下面的,可以操作某些位,而不影响其他位
TMOD=TMOD&0xf0;//把TMOD低四位清零,高四位不变
//比如:1010 0011 1010 0011&1111 0000=1010 0000
TMOD=TMOD|0x01;//把TMOD的低四位放置1,高四位保持不变
//比如:1010 0000 1010 0000|0000 0001=1010 0001
TF0=0;//先清零
TR0=1; //开启,使其工作
//0~65535,每隔1us计数加1,总计65535us
//64535离计数器溢出差值1000,刚好1ms
TH0=64535/256;//取高位
TL0=64535/256; //取低位
//例如:123 -》123/100=1 123%100=23
ET0=1;
EA=1;
PT0=0;
}
void main()
{
Timer0_Init();
while(1)
{
}
}
//闹钟响之后,要跳转到下面这个子函数来,来执行中断任务
unsigned int T0Count;
void Timer0_Routine() interrupt 1
{
//定时器中断之后会溢出就变成0了,下次开机计数就不是从初始值开始了
//第一次是1ms,第二次就是从0开始就是65ms了
//所以,每次重新开始之后,都要重新给它赋一个初值
TH0=64535/256;//取高位
TL0=64535/256; //取低位
T0Count++;
if(T0Count>=1000){
T0Count=0;
P2_0=~P2_0;//造成每隔一秒闪一下
}
}
可以使用stc直接生成
调节地方
void Timer0_Init() //1毫秒@12.000MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式,这个在新系列的里面有
//在89C52里面没有,所以删除
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//stc生成的少了三个,把下面补充在下面
ET0=1;
EA=1;
PT0=0;
}
新的
#include <REGX52.H>
void Timer0_Init() //1毫秒@12.000MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式,这个在新系列的里面有
//在89C52里面没有,所以删除
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//stc生成的少了三个,把下面补充在下面
ET0=1;
EA=1;
PT0=0;
}
void main()
{
Timer0_Init();
while(1)
{
}
}
//闹钟响之后,要跳转到下面这个子函数来,来执行中断任务
unsigned int T0Count;
void Timer0_Routine() interrupt 1
{
//定时器中断之后会溢出就变成0了,下次开机计数就不是从初始值开始了
//第一次是1ms,第二次就是从0开始就是65ms了
//所以,每次重新开始之后,都要重新给它赋一个初值
//------------------修改地方-----------------------------------------
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
//-------------------------------------------------------------------
T0Count++;
if(T0Count>=1000){
T0Count=0;
P2_0=~P2_0;//造成每隔一秒闪一下
}
}
7.1按键控制led流水灯模式
mian.c
#include <REGX52.H>
#include"Timer0.h"
#include"Key.h"
#include"intrins.h"//提供左右循环移动函数的
unsigned char KeyNum,LEDMode;
void main()
{
P2=0xfe;//给一个初值,方便移动
Timer0_Init();
while(1)
{
KeyNum=key();
if(KeyNum!=0){
if(KeyNum==1){
LEDMode++;
if(LEDMode>=2)LEDMode=0;
//每次按下就是0 1 0 1的变化
}
}
}
}
//下面这个子函数代码闹钟响之后,它要跳转到这个子函数这来,执行中断
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;//static保留T0Count的值
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=500)//每隔500ms
{
T0Count=0;
//例如a=0x01 a=_crol_(a,1); //a的值左移一位之后赋给a,一直到0x08之后
//又回到0x01
if(LEDMode==0){
P2=_crol_(P2,1); //左移
}
if(LEDMode==1){
P2=_cror_(P2,1);//右移
}
}
}
Timer0.c
#include <REGX52.H>
/*
定时器0初始化,//1毫秒@12.000MHz
*/
void Timer0_Init() //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//-----下面的是需要自己加的-----------------------------
ET0=1;
EA=1;
PT0=0;
//------------------------------------------------------
}
/*
定时器中断函数模板
void Timer0_Init()//初始化函数
{
//TMOD=0x01;//0000 0001 改为下面的,可以操作某些位,而不影响其他位
TMOD=TMOD&0xf0;//把TMOD低四位清零,高四位不变
//比如:1010 0011 1010 0011&1111 0000=1010 0000
TMOD=TMOD|0x01;//把TMOD的低四位放置1,高四位保持不变
//比如:1010 0000 1010 0000|0000 0001=1010 0001
TF0=0;//先清零
TR0=1; //开启,使其工作
//0~65535,每隔1us计数加1,总计65535us
//64535离计数器溢出差值1000,刚好1ms
TH0=64535/256;//取高位
TL0=64535/256; //取低位
//例如:123 -》123/100=1 123%100=23
ET0=1;
EA=1;
PT0=0;
} */
Timer0.h
#ifndef __Timer0_H__
#define __Timer0_H__
Timer0_Init();
#endif
Key.c
#include <REGX52.H>
#include"Delay.h"
/*
* 目的:获取独立按键键码
* 参数:无
*返回值:按下按键的键码,范围:0~4,无按键按下时返回值为0
*/
unsigned char Key()
{
unsigned char KeyNumber=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}
Key.h
#ifndef __KEY_H__
#define __KEY_H__
unsigned char Key();
#endif
7.2定时器时钟
只修改了main.c中的代码,其他的复制过来
#include <REGX52.H>
#include"Delay.h"
#include"lcd1602.h"
#include"Timer0.h"
unsigned char Sec,Min,Hour;//秒,分钟,小时
void main(){
LCD_Init();
Timer0_Init();
LCD_ShowString(1,1,"Clock:");
LCD_ShowString(2,1," : :");//显示小时和分钟的: 分钟和秒的:
while(1){
LCD_ShowNum(2,1,Hour,2);
LCD_ShowNum(2,4,Min,2);
LCD_ShowNum(2,7,Sec,2);
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0=0x18;
TH0=0xFC;
T0Count++;
if(T0Count>=1000){
T0Count=0;
Sec++;
if(Sec>=60){
Sec=0;
Min++;
if(Min>=60){
Min=0;
Hour++;
if(Hour>=24){
Hour=0;
}
}
}
}
}
8.串口
8.1串口向电脑发送数据
main.c中
#include <REGX52.H>
#include"Delay.h"
#include"UART.h"
unsigned char Sec; //每隔一秒发送一个递增的数
void main(){
UART_Init();//初始化
while(1){
UART_SendByte(Sec);
Sec++;
Delay(1000);
}
}
UART.c
#include <REGX52.H>
/*
串口初始化,4800bps@12.000MHz
输入参数:无
返回值:无
*/
//波特率函数
//--------------------------------------
void UART_Init()
{
SCON=0x40;
PCON |= 0x80;
TMOD &= 0x0f; //设置定时器模式
TMOD |= 0x20; //模式变了,设定定时器1为8位自动重装方式
TL1 = 0xF3; //设定定时初值
TH1 = 0xF3; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
//---------------------------------------
//发送的函数
//---------------------------------------
void UART_SendByte(unsigned char Byte)
{ //只要把数据写到SBUF里面,就会发出去
SBUF=Byte;
//还需要检测是否完成,你刚写完不会立即发完,
//如果你连续发,就会出错
while(TI==0);
TI=0;
}
//---------------------------------------
UART.h
#ifndef __UART_H__
#define __UART_H__
void UART_Init();
void UART_SendByte(unsigned char Byte);
#endif
8.2电脑通过串口控制led
由8.1的修改而来
mian.c
UART.c
9.LED点阵屏
9.2.1led点阵屏显示图形
#include <REGX52.H>
#include"Delay.h"
#define MATRIX_LED_PORT P0//给P0口定义一下,方便修改
//74HC595
//-----------------------------------------------------------
sbit RCK=P3^5;//RCK是RCLK
sbit SCK=P3^6;//SCK是SRCLK
sbit SER=P3^4;//SER
/**
*@brief 74HC595写入一个字节(我的单片机上没有这个,但需要这个代码)
*@param 要写入一个字节
*@retval 无
*/
void _74HC595_WriteByte(unsigned char Byte){
//函数目的:运行一下这个函数,然后就会把里面参数这个数据给写入8个引脚
unsigned char i;
for(i=0;i<8;i++){
SER=Byte&(0x80>>i);//右边这个代表右移i位
SCK=1;
SCK=0;//移进去之后我们就直接清零,为下一次移位做准备
}
RCK=1;
RCK=0; //送到右边
}
//-------------------------------------------------------------
/**
*@brief led点阵屏显示一列数据
*@param Column 要选择的列,范围:0~7,0在最左边
*@param Data 选择列显示的数据,高位在上,1为亮,0为灭
*@retval
*/
void MatrixLED_ShowColumn(unsigned char Column,Data)//矩阵点阵屏
{ //图上左边的D0~D7称为Data,Column为列
_74HC595_WriteByte(Data);
/*
if(Column==0){P0=~0x80;}//~0x80是0111 1111
if(Column==1){P0=~0x40;}//~0x40是1011 1111
//就这么写下去就可以了,但我们可以换一种方法
*/
MATRIX_LED_PORT=~(0x80>>Column);
Delay(1);//延时
MATRIX_LED_PORT=0xff;//位清零,这两行相当与数码管当时的消影
}
void main()
{
SCK=0;
//因为要给SCK一个高电平让他移位,又因为单片机初始化后所有的l口都是高电平
//所以一上电之后要先把他复为0
RCK=0;//初始为低电平
while(1)
{
MatrixLED_ShowColumn(0,0x3c);//第0列显示1010 1010
MatrixLED_ShowColumn(1,0x42);//第1列
MatrixLED_ShowColumn(2,0xa9);//第2列
MatrixLED_ShowColumn(3,0x85);//第3列
MatrixLED_ShowColumn(4,0x85);//第4列
MatrixLED_ShowColumn(5,0xa9);//第5列
MatrixLED_ShowColumn(6,0x42);//第6列
MatrixLED_ShowColumn(7,0x3c);//第7列
}
}
/*
---------------------------------------------------------------------------
void _74HC595_WriteByte(unsigned char BYte){
//函数目的:运行一下这个函数,然后就会把里面参数这个数据给写入8个引脚
SER=Byte&0x80;
//先取第八位(最下面那一位),如果第八位是1,上面就是0x80,为0的化就是0,1就是高电平,0就是低电平
//如果我们对一位进行处理,那么后面这个操作数给1还是0,这是正常的
//非0即1:如果不是0随便任何一个数,都会置1
SCK=1;
SCK=0;//移进去之后我们就直接清零,为下一次移位做准备
//下面是最后从上到下第7位
SER=Byte&0x40; //0x40就是0100 0000
SCK=1;
SCK=0;
//下面是最后从上到下第6位
SER=Byte&0x20; //0x40就是0010 0000
SCK=1;
SCK=0;
//进行8次就可以把8位引进去了
}
---------------------------------------------------------------------------
*/
/*
---------------------------------------------------------------------------
void MatrixLED_ShowColumn(unsigned char Column,Data)//矩阵点阵屏
{ //图上左边的D0~D7称为Data,Column为列
_74HC595_WriteByte(Data);
if(Column==0){P0=~0x80;}//~0x80是0111 1111
if(Column==1){P0=~0x40;}//~0x40是1011 1111
}
----------------------------------------------------------------------------
*/
9.2.2LED点阵屏显示动画
打开取字模软件,点击新建图像,高度设为8,长度根据动画的长度来设计,进来后点击模拟动画的放大格点,放到自己觉得合适的大小,点击参数设置,点击其他选项
然后在画面上点出需要的,然后点击取模方式,点击C51格式,然后复制下面生成的数据,复制到我们代码动画那里
建造3个文档,分别是main.c MatrixLED.c MatrixLED.h
main.c中
#include <REGX52.H>
#include"Delay.h"
#include"MatrixLED.h"
unsigned char Animation[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//这里是自己加的
0xFF,0x08,0x08,0x08,0xFF,0x00,0x0E,0x15,
0x15,0x15,0x08,0x00,0x7E,0x01,0x02,0x00,
0x7E,0x01,0x02,0x00,0x0E,0x11,0x11,0x0E,
0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//这里是自己加的
};
void main()
{
unsigned char i,offset=0,Count=0;//offset表示偏移量,因为要使其右移动
//这里的两行东西重新定义了一个函数,放到MatrixLED.c里面去了
MatrixLED_Init();
while(1) //Count用来计次
{ for(i=0;i<8;i++){
MatrixLED_ShowColumn(i,Animation[i+offset]);//第i列显示,Animation[i]
}
Count++;
if(Count>10){
Count=0;
offset++;//扫描10遍之后,就右移动一位
//-----------------------------------
//如果想要显示逐帧的offset就一次要加8
//-----------------------------------
}
if(offset>40)//防止offset溢出,总共32个,取到最后一针的时候,应该是32-8
{ //因为自己加了16个,所以为40-8 ,原本是>32,因为要把感叹号全部不再后
//再显示下一轮,所以是40
offset=0;
}
}
}
/*-------------------------------------------------------
void main()
{
//这里的两行东西重新定义了一个函数,放到MatrixLED.c里面去了
MatrixLED_Init();
while(1)
{
MatrixLED_ShowColumn(0,Animation[0]);//第0列显示1010 1010
MatrixLED_ShowColumn(1,Animation[1]);//第1列
MatrixLED_ShowColumn(2,Animation[2]);//第2列
MatrixLED_ShowColumn(3,Animation[3]);//第3列
MatrixLED_ShowColumn(4,Animation[4]);//第4列
MatrixLED_ShowColumn(5,Animation[5]);//第5列
MatrixLED_ShowColumn(6,Animation[6]);//第6列
MatrixLED_ShowColumn(7,Animation[7]);//第7列
}
}
从上面的代码改为了下面的代码
//----------------------------------------------------------------
void MatrixLED_ShowColumn(unsigned char Column,Data)//矩阵点阵屏
{ //图上左边的D0~D7称为Data,Column为列
_74HC595_WriteByte(Data);
if(Column==0){P0=~0x80;}//~0x80是0111 1111
if(Column==1){P0=~0x40;}//~0x40是1011 1111
}
-------------------------------------------------------*/
MatrixLED.h
#ifndef _MATRIX_LED_H__
#define _MATRIX_LED_H__
void MatrixLED_ShowColumn(unsigned char Column,Data);
void MatrixLED_Init();
#endif
MatrixLED.c
#include <REGX52.H>
#include"Delay.h"
#define MATRIX_LED_PORT P0//给P0口定义一下,方便修改
//74HC595
//-----------------------------------------------------------
sbit RCK=P3^5;//RCK是RCLK
sbit SCK=P3^6;//SCK是SRCLK
sbit SER=P3^4;//SER
/**
*@brief 74HC595写入一个字节(我的单片机上没有这个,但需要这个代码)
*@param 要写入一个字节
*@retval 无
*/
void _74HC595_WriteByte(unsigned char Byte){
//函数目的:运行一下这个函数,然后就会把里面参数这个数据给写入8个引脚
unsigned char i;
for(i=0;i<8;i++){
SER=Byte&(0x80>>i);//右边这个代表右移i位
SCK=1;
SCK=0;//移进去之后我们就直接清零,为下一次移位做准备
}
RCK=1;
RCK=0; //送到右边
}
/**
*@brief 点阵屏初始化
*@param 无
*@retval 无
*/
void MatrixLED_Init(){ //初始化工作
SCK=0;
//因为要给SCK一个高电平让他移位,又因为单片机初始化后所有的l口都是高电平
//所以一上电之后要先把他复为0
RCK=0;//初始为低电平
}
//-------------------------------------------------------------
/**
*@brief led点阵屏显示一列数据
*@param Column 要选择的列,范围:0~7,0在最左边
*@param Data 选择列显示的数据,高位在上,1为亮,0为灭
*@retval
*/
void MatrixLED_ShowColumn(unsigned char Column,Data)//矩阵点阵屏
{ //图上左边的D0~D7称为Data,Column为列
_74HC595_WriteByte(Data);
/*
if(Column==0){P0=~0x80;}//~0x80是0111 1111
if(Column==1){P0=~0x40;}//~0x40是1011 1111
//就这么写下去就可以了,但我们可以换一种方法
*/
MATRIX_LED_PORT=~(0x80>>Column);
Delay(1);//延时
MATRIX_LED_PORT=0xff;//位清零,这两行相当与数码管当时的消影
}
10.DS1302实时时钟
10.1 DS1302时钟
5个文档,分别是DS1302.c DS1302.h main.c lcd1602.c lcd1602.h
main.c中
#include <REGX52.H>
#include"lcd1602.h"
#include"DS1302.h"
void main(){
LCD_Init();
DS1302_Init();
LCD_ShowString(1,1," - - ");
LCD_ShowString(2,1," : : ");
//————————————————————————————————————————
DS1302_WriteByte(0x8e,0x00);
// 如果读出时间为一个大于59的并且不动的数,则芯片可能是处在写保护
//状态,在这里加上上面一句的就可以解除芯片保护
//————————————————————————————————————————
DS1302_SetTime();
while(1){
DS1302_ReadTime();
//BCD码是用四位二进制数来表示1位10进制数
//BCD码转为十进制:DEC=BCD/16*10+BCD%16
LCD_ShowNum(1,1,DS1302_Time[0],2);//年
LCD_ShowNum(1,4,DS1302_Time[1],2);//月
LCD_ShowNum(1,7,DS1302_Time[2],2);//日
LCD_ShowNum(2,1,DS1302_Time[3],2);//小时
LCD_ShowNum(2,4,DS1302_Time[4],2);//分钟
LCD_ShowNum(2,7,DS1302_Time[5],2);//秒
}
}
DS1302.c
#include <REGX52.H>
//————————————————————————————
//下面三行对三个引脚进行了定义
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
//————————————————————————————
#define DS1302_SECOND 0x80//秒
#define DS1302_MINUTE 0x82//分钟
#define DS1302_HOUR 0x84//小时
#define DS1302_DATE 0x86//日
#define DS1302_MONTH 0x88//月
#define DS1302_DAY 0x8A//星期
#define DS1302_YEAR 0x8C//年
#define DS1302_WP 0x8E//写保护
unsigned char DS1302_Time[]={19,11,16,12,59,55,6};
//默认情况下CE是0,SCLK也是0,但我们单片机所有的L口默认都是1
void DS1302_Init(void)//初始化
{
DS1302_CE=0;
DS1302_SCLK=0;
}
//单字节写入(SINGLE-BYTE WRITE)
void DS1302_WriteByte(unsigned char Command,Data)//命令字Command,数据Data
{
unsigned char i;
DS1302_CE=1;//操作要CLK置1
/*————————————————————————————————————————————————————————————
DS1302_IO=Command&0x01;//取出Command的第0位
DS1302_SCLK=1;//因为51的速率是比较慢的,与下面一行之间所以不需要加延时
DS1302_SCLK=0;
DS1302_IO=Command&0x02;//0x02是0000 0010 取出Command中的第1位给左边
DS1302_SCLK=1;
DS1302_SCLK=0;
DS1302_IO=Command&0x04;//取出Command中的第2位给左边
DS1302_SCLK=1;
DS1302_SCLK=0;
.....
————————————————————————————————————————————————————————————————*/
//上面的可以用for循环代替
for(i=0;i<8;i++){
DS1302_IO=Command&(0x01<<i);//左移i位
DS1302_SCLK=1;//操作图中前八个,上升沿部分
DS1302_SCLK=0;//操作图中前八个,下升沿部分
}
for(i=0;i<8;i++){//操作图中后八个D0~D7
DS1302_IO=Data&(0x01<<i);//左移i位
DS1302_SCLK=1;
DS1302_SCLK=0;
}
DS1302_CE=0;//结束清零
}
//单字节读取(SINGLE-BYTE READ)
unsigned char DS1302_ReadByte(unsigned char Command)
{
unsigned char i,Data=0x00;
Command|=0x01;//
DS1302_CE=1;
for(i=0;i<8;i++){
DS1302_IO=Command&(0x01<<i);//左移i位
DS1302_SCLK=0;//因为上面只有15个脉冲,把图向间断向左移一点,这样左边都是与写入有关的
DS1302_SCLK=1;
}
/*
DS1302_SCLK=0;
DS1302_SCLK=1;
if(DS1302_IO){Data=Data|0x01;}//把Data的最低为置1
//if()相当于判断了一下是否为1,或0
DS1302_SCLK=0;
DS1302_SCLK=1;
if(DS1302_IO){Data=Data|0x02;}
......
*/
//可以换为for循环
for(i=0;i<8;i++){
DS1302_SCLK=1;//这里于上面重复置1,就可以把这个周期过滤掉
DS1302_SCLK=0;
if(DS1302_IO){Data|=(0x01<<i);}
}
DS1302_CE=0;//清零
DS1302_IO=0;
return Data;
}
void DS1302_SetTime(void)
{
DS1302_WriteByte(DS1302_WP,0x00);
//下面用了10进制转BCD码
DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);//年
DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);//月
DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);//日
DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);//小时
DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);//分钟
DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);//秒
DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);//星期
DS1302_WriteByte(DS1302_WP,0x80);//写保护
}
void DS1302_ReadTime(void)
{
//读取时间
unsigned char Temp;
Temp=DS1302_ReadByte(DS1302_YEAR);
DS1302_Time[0]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_MONTH);
DS1302_Time[1]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_DATE);
DS1302_Time[2]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_HOUR);
DS1302_Time[3]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_MINUTE);
DS1302_Time[4]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_SECOND);
DS1302_Time[5]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_DAY);
DS1302_Time[6]=Temp/16*10+Temp%16;
}
DS1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
extern unsigned char DS1302_Time[];//如果变量声明变量要加extern
void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command,Data);
unsigned char DS1302_ReadByte(unsigned char Command);
void DS1302_ReadTime(void);
void DS1302_SetTime(void);
#endif