看了一些资料,说什么DS1302不能利用I2C通信,可是买的开发板却是连接在RC2-4这三个脚上,最可恨的是操作DS1302一开始操作就要写八个字节,然后每次都必须读七个字节。如果I2C不能通信,那么里面的SSPBUF,SSPSR这两个寄存器可以用吗?如果不能用那读写这七、八个字节是怎么操作的。真的是一位一位的移过去吗?
目前我写程序还是处于用汇编去组建架构,C只能看看。在开发板自带的C程序里面,看不明白他是怎么移到RC4里面的。哪位前辈可以帮忙解释下吗?
/***************************************************************************
* 文件名:ds1302.c
* 功 能:时钟芯片DS1302在数码管上显示时间和星期
* 作 者:
* 日 期:
* 备 注:
//软件思路:先设置时间和日期为:秒(00),分(28),时(12),日(08),
//月(09),年(08)六位数码观显示时间和日期,默认显示的是时间,
//通过小数点区分时与分、分与秒,按下K1键不放,显示切换到日期显示。
****************************************************************************/
#include<pic.h> //包含单片机内部资源预定义
__CONFIG(0xFF32);
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define i_o RC4 //定义DS1302的数据口
#define sclk RC3 //定义DS1302的时钟口
#define rst RC2 //定义DS1302的复位口
unsigned char time_rx @ 0x30; //定义接收寄存器
static volatile bit time_rx7 @ (unsigned)&time_rx*8 + 7; //接收寄存器的最高位
void port_init(); //申明引脚初始化函数
void ds1302_init(); //申明DS1302初始化函数
void set_time(); //申明设置时间函数
void get_time(); //申明读取时间函数
void display(); //申明显示函数
void time_write_1(unsigned char time_tx); //申明写一个字节函数
unsigned char time_read_1(); //申明读一个字节函数
void delay(); //申明延时函数
//定义待设置的时间: 秒、 分、 时、 日、月、星期、年、控制字
const char table[] = {0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x00};
//定义读取时间和日期存放表格
char table1[7];
//定义0-9的显示代码
const unsigned char TABLE[10] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f}
; //,0x77,0x7c,0x39,0x5e,0x79,0x71};
/****************************************************************************
* 名 称:main()
* 功 能:主函数
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void main()
{
port_init(); //调用引脚初始化函数
ds1302_init(); //调用DS1302初始化函数
set_time(); //调用设置时间函数
while (1)
{
get_time(); //调用取时间函
display(); //调用显示函数
}
}
/****************************************************************************
* 名 称:ds1302_init()
* 功 能:DS1302初始化
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void ds1302_init()
{
sclk = 0; //拉低时钟信号
rst = 0; //复位DS1302
rst = 1; //使能DS1302
time_write_1(0x8e); //发控制命令
time_write_1(0); //允许写DS1302
rst = 0; //复位
}
/****************************************************************************
* 名 称:set_time()
* 功 能:设置时间
* 入口参数:
* 出口参数:
* 说 明:出示时间在table[]数组中,时间格式一日期为例:
bit7——bit4 bit3——bit0
十天 天
****************************************************************************/
void set_time()
{
int i; //定义循环变量
rst = 1; //使能DS1302
time_write_1(0xbe); //时钟多字节写命令
for (i = 0;i < 8;i++) //连续写8个字节数据
{
time_write_1(table); //调用写一个字节函数
}
rst = 0; //复位
}
/****************************************************************************
* 名 称:set_time1()
* 功 能:设置时间
* 入口参数:
* 出口参数:
* 说 明:出示时间在table[]数组中,时间格式一日期为例:
bit7——bit4 bit3——bit0
十天 天
****************************************************************************/
void set_time1()
{
int i; //定义循环变量
rst = 1; //使能DS1302
time_write_1(0xbe); //时钟多字节写命令
for (i = 0;i < 7;i++) //连续写8个字节数据
{
time_write_1(table1); //调用写一个字节函数
}
time_write_1(0x00);
rst = 0; //复位
}
/****************************************************************************
* 名 称:get_time()
* 功 能:读取时间
* 入口参数:
* 出口参数:
* 说 明:结果放在全局数组中table1[]
****************************************************************************/
void get_time()
{
int i; //设置循环变量
rst = 1; //使能DS1302
time_write_1(0xbf); //发送多字节读取命令
for (i = 0;i < 7;i++) //连续读取7个字节数据
{
table1 = time_read_1(); //调用读取1个字节数据的函数
}
rst = 0; //复位DS1302
}
/****************************************************************************
* 名 称:time_write_1()
* 功 能:写一个字节数据
* 入口参数:unsigned char time_tx 待写数据
* 出口参数:
* 说 明:
****************************************************************************/
void time_write_1(unsigned char time_tx)
{
int j; //设置循环变量
for (j = 0;j < 8;j++) //连续写8bit
{
i_o = 0; //先设置数据为0
sclk = 0; //时钟信号拉低
if (time_tx&0x01) //判断待发送的数据位是0或1
{
i_o = 1; //待发送数据位是1
}
time_tx = time_tx >> 1; //待发送的数据右移1位
sclk = 1; //拉高时钟信号
}
sclk = 0; //写完一个字节,拉低时钟信号
}
/****************************************************************************
* 名 称:time_read_1()
* 功 能:读一个字节
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
unsigned char time_read_1()
{
int j; //设置循环变量
TRISC4 = 1; //设置数据口方向为输入
for (j = 0;j < 8;j++) //连续读取8bit
{
sclk = 0; //拉低时钟信号
time_rx = time_rx >> 1; //接收寄存器右移1位
time_rx7 = i_o; //把接收到的数据放到接收寄存器的最高位
sclk = 1; //拉高时钟信号
}
TRISC4 = 0; //恢复数据口方向为输出
sclk = 0; //拉低时钟信号
return (time_rx); //返回读取到的数据
}
/****************************************************************************
* 名 称:port_init()
* 功 能:引脚初始化
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void port_init()
{
ADCON1 = 0X07; //设置A口为普通I/O口
TRISB = 0X0F; //设置B口低4位为输入//高四位为输出
TRISD = 0; //portd 输出
TRISA = 0; //porta 输出
PORTA = 0x3f; //先关闭所有显示
PORTD = 0xff;
TRISC = 0X00; //rc输出
}
/****************************************************************************
* 名 称:display()
* 功 能:数码管显示
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void display()
{
int i; //定义查表变量
if(RB0==0) //判断K1是否按下,如果按下的话显示日期,不按下显示时间
{
table1[0]=table1[3];
table1[1]=table1[4];
table1[2]=table1[6];
}
i = table1[0] & 0x0f; //求秒的个位
PORTD = TABLE; //点亮秒的个位
PORTA = 0x01;
delay(); //延长一段时间,保证亮度
i = table1[0] & 0xf0; //求秒的十位
i = i >> 4; //右移4位
PORTD = TABLE; //送D口显示
PORTA = 0x02; //点亮秒的十位
delay(); //延长一段时间,保证亮度
i = table1[1] & 0x0f; //求分的个位
PORTD = TABLE | 0x80; //送D口显示,并显示小数点
PORTA = 0x04; //点亮分的个位
delay(); //延时一定时间,保证亮度
i = table1[1] & 0xf0; //求分的十位
i = i >> 4;
PORTD = TABLE; //送D口显示
PORTA = 0x08; //点亮分的十位
delay(); //延长一段时间,保证亮度
i = table1[2] & 0x0f; //求时的个位
PORTD = TABLE | 0x80; //送D口显示,并加上小数点
PORTA = 0x10; //点亮时的个位
delay(); //延时一定时间,保证亮度
i = table1[2] & 0xf0; //求时的十位
i = i >> 4;
PORTD = TABLE;
//送D口显示
PORTA = 0x20; //点亮时的十位
delay(); //延长一段时间,保证亮度
}
/****************************************************************************
* 名 称:delay()
* 功 能:延时
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void delay() //延时程序
{
int i; //定义整形变量
for (i = 150;i--;); //延时
}
|