郭天祥的10天学会51单片机_第十一节
时间:2023-01-15 07:30:00
参考第十节课件DS12887
RTC就是Real Time Clock实时时钟
DS12887芯片是保持时间是的,当前设定时间,然后切断电源,芯片还在走
DS12887-5指的是5伏,DS12887-33指的是3.3伏
OSC是时钟振荡器(为时钟提供频率),以下是电源控制和自动断电保护,下是总线接口
DIVID BY 8是八分频
MOT是总线类型的选择,本节让MOT用于接地或不接地Intel模式
NC就是Not Connect不连接
AD0到AD7接单片机的P0口
TX-1C24型单片机实验板原理图C02(图中标错误,标成24C00)是EEPROM
AS就是Address strobe(地址闸门),连接P1^5口、高电平写地址、低电平锁数据
DS就是Data strobe(数据闸门),连接P1^7口,高电平写数据
R/W连到P1^6口
找个口,这里用P1^4口,操作时拉低,不操作时拉高
IRQ(Interrupt Reques)是中断,接P3^2口(只能中断单片机的外部1口P3^3口与外中断0口P3^2当中断发生时,口)用于定时闹钟IRQ从高电平到低电平,送到单片机,让单片机控制蜂鸣器的声音
RESET接VCC(高电平1)
SQW是方波输出,见DS12887的P20表3,这里没用到所以不接
一般时钟是32.768KHZ石英晶体
见DS12CR887-DS12R887_cn的PDF的P14表2A,时分秒的地址,Second Alarm以秒定时器为例Second,秒的地址是00H,可以从00H读出秒的值,只BIT0到BIT5;0A到0D是四个定时器;读取时,先给地址,再给数据
写程序时要考虑时间,见DS12887的P4时间表,指令时间宽度为纳秒,机器周期至少为毫秒,必须确保指令能够在机器时间内完成,因此纳秒可以忽略
见DS12887的P17将B寄存器设置为26打开闹钟
蜂鸣器是P2^3口
见DS12CR887-DS12R887_cn的PDF的P18.如果你不读C寄存器,它会被允许IRQ保持低电平,只触发一次中断,而不是下一次中断
延迟消抖时间1毫秒不能消抖,可设置为5毫秒
TX-1C单片机试验板原理图PL2303是下载口
点击Options for Target按钮,在Output在菜单页面将Browse Information 点钩的作用取决于函数的定义或用可以用鼠标右键选择最后两项
标记,鼠标右键选择Toggle Bookmark,然后按F2即可选择标记所在的行
添加头文件,写完头文件,保存完头文件,再添加时,保存类型选择ALL Files,出现的对话框中的Type选择Text Document File,再确定
以后可以把每个模块都写成头文件,在源文件中添加即可
学完单片机要多练,单片机熟练后可以学嵌入式ARM7,然后ARM9,多锻炼多实践
我犯的错误:外部中断0接3^2口,外部中断1接3^3口,把时钟芯片的IRQ接单片机的3^2口
Shizhong.c:
#include
#include
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void didi()
{
beep=0;
delay(50);
beep=1;
delay(100);
beep=0;
delay(50);
beep=1;
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
EA=1;
EX0=1; //开外部中断0,使用内部中断时还需要启动内部中断,而外部的时钟芯片自己一直自动提供频率,不需要再启动外部中断
IT0=1; //外部中断0,下降沿触发方式
dula=0;
wela=0;
lcden=0;//先关闭外部中断,为时钟芯片的定时中断做准备
//set_time();//设置时钟芯片初始时间,这里如果设置,每次开启单片机就会重新设置时钟芯片的时间,如果不设置,时钟芯片会在关闭期间还在走,每次开启单片机时就会输出新时间,即上次关闭的时间加上再次开启之间的时间
set_alarm(14,13,10);
write_ds(0x0B,0x26);//向B寄存器里写26,开启闹钟
read_ds(0x0c);//读一下C寄存器,见DS12CR887-DS12R887_cn的PDF的P18,读一下C
//寄存器为了清除上次IRQ的状态;因为见DS12CR887-DS12R887_cn的PDF的P17的闹钟中断使能AIE,AIE置1时,寄存器C的闹钟中断标志AF位驱动产生IRQ信号,见DS12CR887-DS12R887_cn的PDF的P18,当AF=AIE=1时,IRQF为1,让IRQ变低,这样IRQ就不能产生下降沿进入中断,所以要读一下C寄存器清除IRQ低电平状态
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(flag1==1)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
flag1=0;
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
flag1=0;
}
}
}
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
flag=1;
flag1=0;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
flag=0;
write_ds(0,miao);
write_ds(2,fen);
write_ds(4,shi);
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(1);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(1);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/* if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void write_ds(uchar add,uchar date)
{
dscs=0;//片选置低电平使用时钟芯片
dsas=1;//准备给地址
dsds=1; //准备给数据
dsrw=1;//读
P0=add;//给地址
dsas=0;//锁存地址
dsrw=0;//写
P0=date;//写数据
dsrw=1;
dsas=1;
dscs=1;
}
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;//准备给地址
dsds=1; //准备给数据
dsrw=1;//读
dscs=0;
P0=add;//读入地址
dsas=0;//锁存地址
dsds=0;