这是在ABC_PN板上做NIOS2实验,基于DS1302的数字时钟。不过这次还没有用到其他模块,直接是将时间通过JTAG_UART读回到PC机上显示的。下面将帖出在NIOS2中读写DS1302的函数,希望对大家有用哦!!
开发环境:quartus2 10.1 sp1 , nios2 10.1 sp1, nios2 command shell 10.1
系统基本环境: 为了配合DS1302这个慢速设备,所以系统时钟设为了20Mhz
SYS_CLK : 20Mhz
Processor : Nios2 Standard
Ex_Mem : K4S643232C
Ex_Device : DS1302 ( T_CLK, T_CE, T_DATA)
/* DS1302 READ,WRITE,SET REGISER,READ TIME REGISTER
* ds1302.h
*
* Created on: 2012-2-26
* Author: williamhuawu
*/
#ifndef DS1302_H_
#define DS1302_H_
#include <system.h>
#include <io.h>
#define uchar unsigned char
void Delay(int m){
short i;
short j;
for(i=0;i<m;i++)
for(j=0;j<500;j++)
;
}
//write one byte into ds1302
void ds1302_byte_write(uchar wdata){
uchar i;
IOWR(T_DATA_BASE,1,1);
for(i=0;i<8;i++)
{
if((wdata&0x01) == 1)
IOWR(T_DATA_BASE,0,1);
else
IOWR(T_DATA_BASE,0,0);
IOWR(T_CLK_BASE,0,1);
Delay(1);
IOWR(T_CLK_BASE,0,0);
wdata >>= 1;
}
}
//read one byte from ds1302
uchar ds1302_byte_read(void){
uchar i,rdata;
IOWR(T_DATA_BASE,1,0);
for(i=0;i<8;i++)
{
Delay(1);
rdata >>= 1;
if(IORD(T_DATA_BASE,0))
rdata+=0x80;
IOWR(T_CLK_BASE,0,1);
Delay(1);
IOWR(T_CLK_BASE,0,0);
}
return rdata;
}
//set one register of ds1302
void ds1302_write_register(uchar register_addr, uchar wdata){
IOWR(T_CLK_BASE,0,0);
IOWR(T_CE_BASE,0,0); //very import procedure
IOWR(T_CE_BASE,0,1);
ds1302_byte_write(register_addr);
ds1302_byte_write(wdata);
IOWR(T_CLK_BASE,0,1);
IOWR(T_CE_BASE,0,0);
}
//read one register of ds1302
uchar ds1302_read_register(uchar register_addr){
uchar rd_data_tmp;
IOWR(T_CLK_BASE,0,0);
IOWR(T_CE_BASE,0,0);
IOWR(T_CE_BASE,0,1);
ds1302_byte_write(register_addr);
rd_data_tmp = ds1302_byte_read();
IOWR(T_CLK_BASE,0,1);
IOWR(T_CE_BASE,0,0);
return rd_data_tmp;
}
//set ds1302's 7 time register by burst mode
void ds1302_time_burst_write(char write_time_table[]){
uchar i ;
IOWR(T_CLK_BASE,0,0);
IOWR(T_CE_BASE,0,0); //very import procedure
IOWR(T_CE_BASE,0,1);
ds1302_byte_write(0xbe);
for(i=0;i<8;i++) {
ds1302_byte_write(write_time_table[i]);
}
IOWR(T_CLK_BASE,0,1);
IOWR(T_CE_BASE,0,0);
}
//read 7 time regiser value by burst mode
void ds1302_time_burst_read(char read_time_table[] ) { // 返回指针的函数
uchar i ;
IOWR(T_CLK_BASE,0,0);
IOWR(T_CE_BASE,0,0); //very import procedure
IOWR(T_CE_BASE,0,1);
ds1302_byte_write(0xbf);
for(i=0;i<8;i++) {
read_time_table[i] = ds1302_byte_read() ;
}
IOWR(T_CLK_BASE,0,1);
IOWR(T_CE_BASE,0,0);
}
// transfer the bcd format time into ascii format to display on the lcd screen
void ds1302_time_bcd2ascii(char *read_time_table,char time_table_ascii[]) { time_table_ascii[0] = ((*read_time_table)&0x0f) + 48 ;
time_table_ascii[1] = (((*read_time_table) >> 4)&0x07) + 48 ;
time_table_ascii[2] = ((*(read_time_table+1))&0x0f) + 48 ;
time_table_ascii[3] = (((*(read_time_table+1)) >> 4)&0x07) + 48 ;
time_table_ascii[4] = ((*(read_time_table+2))&0x0f) + 48 ;
time_table_ascii[5] = (((*(read_time_table+2)) >> 4)&0x03) + 48 ;
time_table_ascii[6] = ((*(read_time_table+3))&0x0f) + 48 ;
time_table_ascii[7] = (((*(read_time_table+3)) >> 4)&0x03) + 48 ;
time_table_ascii[8] = ((*(read_time_table+4))&0x0f) + 48 ;
time_table_ascii[9] = (((*(read_time_table+4)) >> 4)&0x01) + 48 ;
time_table_ascii[10] = ((*(read_time_table+5))&0x07) + 48 ;
time_table_ascii[11] = ((*(read_time_table+6))&0x0f) + 48 ;
time_table_ascii[12] = (((*(read_time_table+6)) >> 4)) + 48 ;
}
#endif /* DS1302_H_ */