标题:
中断方式显示DS1302时钟的问题,附单片机程序
[打印本页]
作者:
286730255
时间:
2021-11-4 22:41
标题:
中断方式显示DS1302时钟的问题,附单片机程序
51hei图片_20211104224000.jpg
(1.3 MB, 下载次数: 34)
下载附件
2021-11-4 22:41 上传
#include<reg52.h> // 定义头文件
#include<intrins.h> //定义函数文件
unsigned char Sce,Min,Hour;//Sce秒,Min分,Hour时
unsigned char y = 2; //定时器0中断时间y 设置ms
sbit wei = P2^7; //定义位选
sbit du = P2^6; //定义段选
sbit TSCLK = P1^0;//DS1302 时钟线 SCLK
sbit TIO = P1^1; //DS1302 数据线 IO
sbit TRST = P1^2;//DS1302 使能端 CE
/*共阴级数码管段选码*/
unsigned char code numdu_data[]= {
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
};
/*共阴级数码管位选码*/
unsigned char code numwei_data[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
/*共阴级数码管显示函数*/
void display(Sce,Min,Hour)
{
unsigned char Scege,Sceshi,Minge,Minshi,Hourge,Hourshi;
static unsigned char i;//静态变量
Scege = Sce%10;// 12/10=1_2 取余2
Sceshi = Sce/10;// 12/10=1_2 取商1
Minge = Min%10;// 12/10=1_2 取余2
Minshi = Min/10;// 12/10=1_2 取商1
Hourge = Hour%10;// 12/10=1_2 取余2
Hourshi = Hour/10;// 12/10=1_2 取商1
P0 = 0XFF;
wei = 1;//位选码打开
P0 = numwei_data[i];
wei = 0;//锁存位选码
switch(i)
{
// 如果是0 段选打开 P0等于数组里面的值 锁存段选 返回
case 0: du = 1; P0 = numdu_data[Scege]; du = 0; break;
case 1: du = 1; P0 = numdu_data[Sceshi]; du = 0; break;
case 2: du = 1; P0 = numdu_data[22]; du = 0; break;
case 3: du = 1; P0 = numdu_data[Minge]; du = 0; break;
case 4: du = 1; P0 = numdu_data[Minshi]; du = 0; break;
case 5: du = 1; P0 = numdu_data[22]; du = 0; break;
case 6: du = 1; P0 = numdu_data[Hourge]; du = 0; break;
case 7: du = 1; P0 = numdu_data[Hourshi]; du = 0; break;
}
i++; //i自加
if(i == 8)//因为numwei_data[]里面只有8个元素,所以只能加到8
i = 0;//清零
}
/*定时器0中断寄存器配置*/
void Timer_0()
{
TMOD = 0X01;//配置TMOD寄存器 定时器0在16位工作模式下
TH0 =((65535-921)*y)/256;//1ms 把初值放入高8位
TL0 =((65535-921)*y)%256;//1ms 把初值放入低8位
EA = 1;//总中断打开
ET0 = 1;//TO溢出中断允许位
TR0 = 1;//允许定时0开始计数
}
/*定时器0溢出中断函数*/
void Timer0_init() interrupt 1
{
TH0 =((65535-921)*y)/256;//1ms 把初值放入高8位
TL0 =((65535-921)*y)%256;//1ms 把初值放入低8位
display(Sce,Min,Hour);//共阴级数码管显示函数
}
/*DS1302写数据*/
void DS1302_wirte_dat(unsigned char cmd,unsigned char dat)
{
unsigned char i; //发送数据次数变量
TRST = 0;// CE 拉低使能端
TSCLK = 0;//SCLK 拉低时钟线
TRST = 1;//CE 拉高使能端 产生上升沿 允许开始写数据
for(i = 0; i < 8; i++) // 执行8次将8位字节的数据写入
{
TSCLK = 0; //SCLK 拉低时钟线
TIO = cmd & 0x01;//写入一位数据 从最低位开始写入
TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
cmd >>= 1;//右移一位
}
for(i = 0; i < 8; i++)//执行8次将8位字节的数据写入
{
TSCLK = 0;//SCLK 拉低时钟线
TIO = dat & 0x01;//写入一位数据 从最低位开始写入
TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
dat >>= 1;//右移一位
}
}
/*DS1302读数据*/
unsigned char DS1302_Read_dat(unsigned char cmd)
{
unsigned char i,dat;//i发送数据次数变量 dat存放读取数据的变量
TRST = 0;// CE 拉低使能端
TSCLK = 0;//SCLK 拉低时钟线
TRST = 1;//CE 拉高使能端 产生上升沿 允许开始写数据
for(i = 0; i < 8; i++) // 执行8次将8位字节的数据写入
{
TSCLK = 0; //SCLK 拉低时钟线
TIO = cmd & 0x01; //写入一位数据 从最低位开始写入
TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
cmd >>= 1; //右移一位
}
for(i = 0; i < 8; i++)// 执行8次将8位字节的数据写入
{
TSCLK = 0;//SCLK 拉低时钟线
dat >>= 1;//读取数据变量dat右移一位
if(TIO == 1) //如果TIO是高电平(为1)
dat |= 0x80;//那么读取数据变量dat或等于1000 0000
TSCLK = 1;//将SCLK时钟线拉高 准备下次通信
}
return dat;//得到的值返回
}
/*数据转换成BCD码 十进制转换成BCD码*/
unsigned char Dat_Chg_BCD(unsigned char dat)
{ //45
unsigned char dat1,dat2;
dat1 = dat / 10;// 45/10=4_5 取值4
dat2 = dat % 10;// 45/10=4_5 取值5
dat2 = dat2 + dat1 * 16;// 5+4*16=69
return dat2;//得到的值69返回
}
/*BCD码转换成数据 BCD码转换成十进制*/
unsigned char BCD_Chg_Dat(unsigned char dat)
{ //69
unsigned char dat1,dat2;
dat1 = dat /16;// 69/16 = 4_5取值4
dat2 = dat %16;// 69/16 = 4_5取值5
dat2 = dat2 + dat1 *10;//5+4*10=45
return dat2;//得到的值45返回
}
void main()
{
Timer_0();//定时器0寄存器配初始化
DS1302_wirte_dat(0x8e,0);//关闭DS1302的写保护 好方便往里面写数据
DS1302_wirte_dat(0x80,Dat_Chg_BCD(30));//写秒初始显示时间 往DS1302里面需要转换成BCD码才能写进去
DS1302_wirte_dat(0x82,Dat_Chg_BCD(15));//写分初始显示时间
DS1302_wirte_dat(0x84,Dat_Chg_BCD(12));//写分初始显示时间
DS1302_wirte_dat(0x8e,0x80);//打开DS1302的写保护 写不进数据
while(1)
{
DS1302_wirte_dat(0x8e,0);//关闭DS1302的写保护 好方便往里面写数据
Sce = BCD_Chg_Dat(DS1302_Read_dat(81));//读秒
Min = BCD_Chg_Dat(DS1302_Read_dat(83));//读分
Hour = BCD_Chg_Dat(DS1302_Read_dat(85));//读时
DS1302_wirte_dat(0x8e,0x80);//打开DS1302的写保护 写不进数据
}
}
复制代码
作者:
286730255
时间:
2021-11-4 22:46
数码管只显示,几个零,也不走时,不明白,程序哪里出了问题
作者:
286730255
时间:
2021-11-4 23:03
找到问题了,写读取的函数的时候,写的是十进制,前面忘记加0X了,
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1