今天用maplab仿真一个DS1302的程序,复位后点开始单步运行,结果点了三下,PC值就跳到0X621处,不是PC值0x3,这是怎么回事?是不是哪里设置有问题?芯片是PIC16F877A
程序如下:
#include<pic.h>
__CONFIG(0xff32);
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define uchar unsigned char
#define uint unsigned int
#define rst RC2
#define clk RC3
#define sda RC4
#define write_second 0x80 //秒的写寄存器地址
#define write_minute 0x82 //分的写寄存器地址
#define write_hour 0x84 //时的写寄存器地址
#define read_second 0x81 //秒的读寄存器地址
#define read_minute 0x83 //分的读寄存器地址
#define read_hour 0x85 //时的读寄存器地址
#define write_protect 0x8e //写保护寄存器地址
void delayms(uint x);
void delayus(uint x);
void port_init();
void ds1302_init();
void write_byte(uchar data);
void write_ds1302(uchar addr,uchar data);
void disp();
void get_time();
uchar read_ds1302(uchar addr);
uchar read_byte();
uchar hour,min,sec;
uchar num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
///////////////////主程序///////////////////
void main()
{
port_init();
ds1302_init();
while(1)
{
get_time();
disp();
}
}
//////////////////ms级延时函数///////////////
void delayms(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=78;j>0;j--);
}
//////////////////////us级延时函数//////////////////
void delayus(uint x)
{
uint i;
for(i=x;i>0;i--);
}
//////////////////IO口初始化///////////////////
void port_init()
{
TRISD=0;
TRISA=0;
TRISC=0;
PORTD=0;
PORTA=0;
PORTC=0;
}
//////////////////////DS1302初始化////////////////////
void ds1302_init()
{
write_ds1302(write_protect,0x00);
write_ds1302(write_second,0x12);
write_ds1302(write_minute,0x12);
write_ds1302(write_hour,0x12);
}
/////////////////////往1302里写一个字节////////////////////
void write_byte(uchar data)
{
uint i;
for(i=0;i<8;i++)
{
clk=0;
sda=data&(0x01);
data=data>>1;
clk=1;
}
clk=0;
}
////////////////////从1302中读一个字节/////////////////////////
uchar read_byte()
{
uchar data;
uint i;
TRISC4=1;
for(i=0;i<8;i++)
{
clk=0;
data=data>>1;
if(sda==1)
{
data=data|0x80;
}
clk=0;
}
clk=0;
TRISC4=0;
return data;
}
////////////往1302中写地址和数据;先写地址,后写数据/////////
void write_ds1302(uchar addr,uchar data)
{
rst=0;
rst=1;
write_byte(addr);
write_byte(data);
rst=0;
}
////////////从1302中读出指定地址中的数据/////////////////
uchar read_ds1302(uchar addr)
{
uchar data;
rst=0;
rst=1;
write_byte(addr);
data=read_byte();
rst=0;
return data;
}
/////////////从1302中读出时,分,秒////////////////
void get_time()
{
hour=read_ds1302(read_hour);
min=read_ds1302(read_minute);
sec=read_ds1302(read_second);
}
/////////////////////显示////////////////////////
void disp()
{
uchar hour1,hour0,min1,min0,sec1,sec0; //定义查表变量
hour0=hour&0x0f; //求时的个位
hour1=hour>>4;
PORTD=num[hour0]|0x80; //送D口显示,并加上小数点(与80相或,就等于加了一个小数点)
PORTA = 0x10; //点亮时的个位
delayms(2); //延时一定时间,保证亮度
PORTD=num[hour1]; //送D口显示
PORTA = 0x20; //点亮时的十位
delayms(2); //延长一段时间,保证亮度
min0=min&0x0f; //求时的个位
min1=min>>4;
PORTD=num[min0]|0x80; //送D口显示,并加上小数点(与80相或,就等于加了一个小数点)
PORTA = 0x04; //点亮时的个位
delayms(2); //延时一定时间,保证亮度
PORTD=num[min1]; //送D口显示
PORTA = 0x08; //点亮时的十位
delayms(2); //延长一段时间,保证亮度
sec0=sec&0x0f; //求时的个位
sec1=sec>>4;
PORTD=num[sec0]|0x80; //送D口显示,并加上小数点(与80相或,就等于加了一个小数点)
PORTA = 0x01; //点亮时的个位
delayms(2); //延时一定时间,保证亮度
PORTD=num[sec1]; //送D口显示
PORTA = 0x02; //点亮时的十位
delayms(2); //延长一段时间,保证亮度
}
此帖出自
小平头技术问答
一周热门 更多>