共2条
1/1 1 跳转至页
12887 12887十分奇怪的问题
问
最近使用12887时碰到很奇怪的问题,我用中断读887里的秒、时、分、日、月、年的值,但奇怪的是程序有时能读出数据,但大多数情况下都读不出来,不能显示;我也用示波器看过波形,发现没有中断信号产生(12887是没有问题的,而且887上中断也开了的。然而我用查询的方式就可以把秒、时、分等读出并显示出来)!
有那位仁兄可以给我点意见,我想了很长时间还没有想出来啊!
顺附程序:
//要完成12887的读写功能,并设置显示的缓存!!
//
#include <reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define LEDSEG P1
#define LEDBIT P2
//y0 -- y13
uchar code BitOut[ ] =
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf5, 0xf6, 0xf7, 0xe8, 0xe9,
0xea, 0xeb, 0xec, 0xed
};
//共阳极 0--f
uchar code SegOut[ ] =
{
0xc0, 0xf9, 0xa4, 0xb0, 0x99, //0 - 4
0x92, 0x82, 0xf8, 0x80, 0x90, //5 - 9
0x88, 0x83, 0xc6, 0xa1, 0x86, //a - e
0x8e, 0xbf // f
};
//显示缓存
uchar data ShowBuffer[ ] =
{
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13,
};
//依次为
/*
ShowBuffer [ 0 ] = sec_l
ShowBuffer [ 1 ] = sec_h
ShowBuffer [ 2 ] = min_l
ShowBuffer [ 3 ] = min_h
ShowBuffer [ 4 ] = hou_l
ShowBuffer [ 5 ] = hou_h
ShowBuffer [ 6 ] = day_l
ShowBuffer [ 7 ] = day_h
ShowBuffer [ 8 ] = mon_l
ShowBuffer [ 9 ] = mon_h
ShowBuffer [ 10 ] = low
ShowBuffer [ 11 ] = mid
ShowBuffer [ 12 ] = high
ShowBuffer [ 13 ] = number
*/
/* 命令常量定义 */
#define CMD_START_DS12C887 0x20 /* 开启时钟芯片 */
#define CMD_START_OSCILLATOR 0x70 /* 开启振荡器,处于抑制状态 */
#define CMD_CLOSE_DS12C887 0x30 /* 关掉时钟芯片 *//* 所有的置位使用或操作,清除使用与操作 */
#define MASK_SETB_SET 0x80 /* 禁止刷新 */
#define MASK_CLR_SET 0x7f /* 使能刷新 */
#define MASK_SETB_UIE 0x10 /*更新周期中断允许(UIE=1) */
#define MASK_SETB_DM 0x04 /* 使用HEX格式 */
#define MASK_CLR_DM 0xfb /* 使用BCD码格式 */
#define MASK_SETB_2412 0x02 /* 使用24小时模式 */
#define MASK_CLR_2412 0xfd /* 使用12小时模式 */
#define MASK_SETB_DSE 0x01 /* 使用夏令时 */
#define MASK_CLR_DSE 0xfe /* 不使用夏令时 */
xdata uchar chSecondsChannel _at_ 0x7f00;
xdata uchar chMinutesChannel _at_ 0x7f02;
xdata uchar chHoursChannel _at_ 0x7f04;
xdata uchar chDateChannel _at_ 0x7f07;
xdata uchar chMonthChannel _at_ 0x7f08;
xdata uchar chCenturyChannel _at_ 0x7f32;
xdata uchar chRegA _at_ 0x7f0a;
xdata uchar chRegB _at_ 0x7f0b;
xdata uchar chRegC _at_ 0x7f0c;
xdata uchar chRegD _at_ 0x7f0d;
/*************************************************************
函数功能:该函数用来启动时钟芯片工作
应用范围:仅在时钟芯片首次使用时用到一次
入口参数:
出口参数:
*************************************************************/
void StartDs12c887(void)
{
chRegA = CMD_START_DS12C887; //0x20
}
void InitDs12c887()
{
StartDs12c887();
chRegB = chRegB | MASK_SETB_SET; /* 禁止刷新 */
chRegB = (((chRegB | MASK_SETB_UIE) & MASK_CLR_DM )| MASK_SETB_2412) & MASK_CLR_DSE ;
/* 使用BCD码格式、24小时模式、不使用夏令时,更新周期中断允许(UIE=1) */
//chSecondsChannel =0;
//chMinutesChannel = 30;
//chHoursChannel = 11;
// chDateChannel = 2;
// chMonthChannel = 4;
chCenturyChannel = 0x21; /* 设置为21世纪 */
chRegC = 0x00;
chRegB = chRegB & MASK_CLR_SET; /* 使能刷新 */
}
uchar Read_chRegC( void )
{
return( chRegC );
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取秒字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetSeconds(void)
{
ShowBuffer[ 0 ] = chSecondsChannel & 0x0f; // 取秒的低位
ShowBuffer[ 1 ] = (chSecondsChannel & 0xf0) >> 4; // 取秒的高位,
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取分字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetMinutes(void)
{
ShowBuffer[ 2 ] = chMinutesChannel & 0x0f; // 取分钟的低位
ShowBuffer[ 3 ] = (chMinutesChannel & 0xf0) >> 4; // 取分钟的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取小时字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetHours(void)
{
ShowBuffer[ 4 ] = chHoursChannel & 0x0f; // 取小时的低位
ShowBuffer[ 5 ] = (chHoursChannel & 0xf0) >> 4; // 取小时的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取日字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetDate(void)
{
ShowBuffer[ 6 ] = chDateChannel & 0x0f; // 取日期的低位
ShowBuffer[ 7 ] = (chDateChannel & 0xf0) >> 4; // 取日期的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取月字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetMonth(void)
{
ShowBuffer[ 8 ] = chMonthChannel & 0x0f; // 取月份的低位
ShowBuffer[ 9 ] = (chMonthChannel & 0xf0) >> 4; // 取月份的高位
}
void Int0( void ) interrupt 0
{
Read_chRegC( );
GetSeconds( );
GetMinutes( );
GetHours( );
GetDate( );
GetMonth( );
}
//延时 count * 1ms
void DelayXms( uint count )
{
uint i , j;
for (i = 0; i < count; i++)
for(j = 0; j < 120; j++)
{
;
}
}
void LedShow( void ) //实现14个数码管的动态扫描
{
uchar i;
for( i = 0; i < 14; i++)
{
LEDBIT = BitOut[ i ];
LEDSEG = SegOut[ ShowBuffer][ i ] ];
DelayXms( 1 );
}
}
void main()
{
IT0 = 0; //INT0下降沿中断
EX0 = 1; //允许INT0中断
InitDs12c887();
EA = 1;
while( 1 )
{
LedShow( );
}
}
那为仁兄可以帮我看看啦! 答 1: 怎么没有人回答的啊?怎么没有人回答的啊?
答 2: 是不是ds12887中断要设闹钟呀没有用过ds12887的中断,不过看资料上,好像ds12887要有中断输出要设闹钟才行的,不知道是不是这样,看你的程序,好像并没有设闹钟的程序 答 3: 已经开了更新周期中断了.在程序中:
chRegB = (((chRegB | MASK_SETB_UIE) & MASK_CLR_DM )| MASK_SETB_2412) & MASK_CLR_DSE ;
/* 使用BCD码格式、24小时模式、不使用夏令时,更新周期中断允许(UIE=1) */
就已经开了更新周期中断了. 答 4: 要不输出中断要加上拉? 答 5: 12887的中断是开漏极的,要加上拉电阻
有那位仁兄可以给我点意见,我想了很长时间还没有想出来啊!
顺附程序:
//要完成12887的读写功能,并设置显示的缓存!!
//
#include <reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define LEDSEG P1
#define LEDBIT P2
//y0 -- y13
uchar code BitOut[ ] =
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf5, 0xf6, 0xf7, 0xe8, 0xe9,
0xea, 0xeb, 0xec, 0xed
};
//共阳极 0--f
uchar code SegOut[ ] =
{
0xc0, 0xf9, 0xa4, 0xb0, 0x99, //0 - 4
0x92, 0x82, 0xf8, 0x80, 0x90, //5 - 9
0x88, 0x83, 0xc6, 0xa1, 0x86, //a - e
0x8e, 0xbf // f
};
//显示缓存
uchar data ShowBuffer[ ] =
{
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13,
};
//依次为
/*
ShowBuffer [ 0 ] = sec_l
ShowBuffer [ 1 ] = sec_h
ShowBuffer [ 2 ] = min_l
ShowBuffer [ 3 ] = min_h
ShowBuffer [ 4 ] = hou_l
ShowBuffer [ 5 ] = hou_h
ShowBuffer [ 6 ] = day_l
ShowBuffer [ 7 ] = day_h
ShowBuffer [ 8 ] = mon_l
ShowBuffer [ 9 ] = mon_h
ShowBuffer [ 10 ] = low
ShowBuffer [ 11 ] = mid
ShowBuffer [ 12 ] = high
ShowBuffer [ 13 ] = number
*/
/* 命令常量定义 */
#define CMD_START_DS12C887 0x20 /* 开启时钟芯片 */
#define CMD_START_OSCILLATOR 0x70 /* 开启振荡器,处于抑制状态 */
#define CMD_CLOSE_DS12C887 0x30 /* 关掉时钟芯片 *//* 所有的置位使用或操作,清除使用与操作 */
#define MASK_SETB_SET 0x80 /* 禁止刷新 */
#define MASK_CLR_SET 0x7f /* 使能刷新 */
#define MASK_SETB_UIE 0x10 /*更新周期中断允许(UIE=1) */
#define MASK_SETB_DM 0x04 /* 使用HEX格式 */
#define MASK_CLR_DM 0xfb /* 使用BCD码格式 */
#define MASK_SETB_2412 0x02 /* 使用24小时模式 */
#define MASK_CLR_2412 0xfd /* 使用12小时模式 */
#define MASK_SETB_DSE 0x01 /* 使用夏令时 */
#define MASK_CLR_DSE 0xfe /* 不使用夏令时 */
xdata uchar chSecondsChannel _at_ 0x7f00;
xdata uchar chMinutesChannel _at_ 0x7f02;
xdata uchar chHoursChannel _at_ 0x7f04;
xdata uchar chDateChannel _at_ 0x7f07;
xdata uchar chMonthChannel _at_ 0x7f08;
xdata uchar chCenturyChannel _at_ 0x7f32;
xdata uchar chRegA _at_ 0x7f0a;
xdata uchar chRegB _at_ 0x7f0b;
xdata uchar chRegC _at_ 0x7f0c;
xdata uchar chRegD _at_ 0x7f0d;
/*************************************************************
函数功能:该函数用来启动时钟芯片工作
应用范围:仅在时钟芯片首次使用时用到一次
入口参数:
出口参数:
*************************************************************/
void StartDs12c887(void)
{
chRegA = CMD_START_DS12C887; //0x20
}
void InitDs12c887()
{
StartDs12c887();
chRegB = chRegB | MASK_SETB_SET; /* 禁止刷新 */
chRegB = (((chRegB | MASK_SETB_UIE) & MASK_CLR_DM )| MASK_SETB_2412) & MASK_CLR_DSE ;
/* 使用BCD码格式、24小时模式、不使用夏令时,更新周期中断允许(UIE=1) */
//chSecondsChannel =0;
//chMinutesChannel = 30;
//chHoursChannel = 11;
// chDateChannel = 2;
// chMonthChannel = 4;
chCenturyChannel = 0x21; /* 设置为21世纪 */
chRegC = 0x00;
chRegB = chRegB & MASK_CLR_SET; /* 使能刷新 */
}
uchar Read_chRegC( void )
{
return( chRegC );
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取秒字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetSeconds(void)
{
ShowBuffer[ 0 ] = chSecondsChannel & 0x0f; // 取秒的低位
ShowBuffer[ 1 ] = (chSecondsChannel & 0xf0) >> 4; // 取秒的高位,
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取分字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetMinutes(void)
{
ShowBuffer[ 2 ] = chMinutesChannel & 0x0f; // 取分钟的低位
ShowBuffer[ 3 ] = (chMinutesChannel & 0xf0) >> 4; // 取分钟的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取小时字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetHours(void)
{
ShowBuffer[ 4 ] = chHoursChannel & 0x0f; // 取小时的低位
ShowBuffer[ 5 ] = (chHoursChannel & 0xf0) >> 4; // 取小时的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取日字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetDate(void)
{
ShowBuffer[ 6 ] = chDateChannel & 0x0f; // 取日期的低位
ShowBuffer[ 7 ] = (chDateChannel & 0xf0) >> 4; // 取日期的高位
}
/*************************************************************
函数功能:该函数用来从时钟芯片读取月字节
应用范围:
入口参数:
出口参数:
*************************************************************/
void GetMonth(void)
{
ShowBuffer[ 8 ] = chMonthChannel & 0x0f; // 取月份的低位
ShowBuffer[ 9 ] = (chMonthChannel & 0xf0) >> 4; // 取月份的高位
}
void Int0( void ) interrupt 0
{
Read_chRegC( );
GetSeconds( );
GetMinutes( );
GetHours( );
GetDate( );
GetMonth( );
}
//延时 count * 1ms
void DelayXms( uint count )
{
uint i , j;
for (i = 0; i < count; i++)
for(j = 0; j < 120; j++)
{
;
}
}
void LedShow( void ) //实现14个数码管的动态扫描
{
uchar i;
for( i = 0; i < 14; i++)
{
LEDBIT = BitOut[ i ];
LEDSEG = SegOut[ ShowBuffer][ i ] ];
DelayXms( 1 );
}
}
void main()
{
IT0 = 0; //INT0下降沿中断
EX0 = 1; //允许INT0中断
InitDs12c887();
EA = 1;
while( 1 )
{
LedShow( );
}
}
那为仁兄可以帮我看看啦! 答 1: 怎么没有人回答的啊?怎么没有人回答的啊?
答 2: 是不是ds12887中断要设闹钟呀没有用过ds12887的中断,不过看资料上,好像ds12887要有中断输出要设闹钟才行的,不知道是不是这样,看你的程序,好像并没有设闹钟的程序 答 3: 已经开了更新周期中断了.在程序中:
chRegB = (((chRegB | MASK_SETB_UIE) & MASK_CLR_DM )| MASK_SETB_2412) & MASK_CLR_DSE ;
/* 使用BCD码格式、24小时模式、不使用夏令时,更新周期中断允许(UIE=1) */
就已经开了更新周期中断了. 答 4: 要不输出中断要加上拉? 答 5: 12887的中断是开漏极的,要加上拉电阻
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |