TI-TMS320F2812(DSP2812)实现DS1308时钟芯片功能
TI-TMS320F2812(DSP2812)实现DS1308时钟芯片功能DS1308使用I2C通信,在使用时需注意时序及寄存器的准确性。
·
前言
TI-TMS320F2812(DSP2812)实现DS1308时钟芯片功能
一、原理图
依据数据手册(datasheet)参考设计:采用上拉电阻10K,晶振32.768kHz。
二、代码相关知识(需注意点)
1.串口初始化配置
2.读写时序及寄存器需注意点
三、代码
代码如下.h部分:
/*
* DS1308.h
*
* Created on: 2024-9-10
* Author: Administrator
*/
#ifndef DS1308_H_
#define DS1308_H_
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
//I2C的IO口宏定义
#define IIC_SCL_SETH (GpioDataRegs.GPASET.bit.GPIOA8=1) //将引脚输出为高电平
#define IIC_SCL_SETL (GpioDataRegs.GPACLEAR.bit.GPIOA8=1) //将引脚输出为低电平
#define IIC_SDA_SETH (GpioDataRegs.GPASET.bit.GPIOA9=1) //将引脚输出为高电平
#define IIC_SDA_SETL (GpioDataRegs.GPACLEAR.bit.GPIOA9=1) //将引脚输出为低电平
#define READ_SDA (GpioDataRegs.GPADAT.bit.GPIOA9)
//DS1308宏定义
typedef struct
{
Uint16 sec;
Uint16 min;
Uint16 hour;
Uint16 week;
Uint16 day;
Uint16 month;
Uint16 year;
} _calendar_part; //时间结构体
extern _calendar_part calendar;
#define DS1308_Write_Address 0xD0 //写地址
#define DS1308_Read_Address 0xD1 //读地址
#define DS1308_SEC_REG 0x00 //秒
#define DS1308_MIN_REG 0x01 //分
#define DS1308_HOUR_REG 0x02 //时
#define DS1308_WDAY_REG 0x03 //星期
#define DS1308_MDAY_REG 0x04 //天
#define DS1308_MONTH_REG 0x05 //月
#define DS1308_YEAR_REG 0x06 //年
//IIC所有操作函数
void IICA_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(unsigned char txd); //IIC发送一个字节
unsigned char IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
unsigned char IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
//DS1308操作函数
void DS1308_IIC_Write(u8 addr,u8 data) ;
u8 DS1308_IIC_Read(u8 addr);
void ModifyTime(u8 year,u8 month,u8 day,u8 hour,u8 min,u8 sec);
void get_time(void);
u8 BCD_DEC(u8 val);
u8 DEC_BCD(u8 val);
#endif /* IIC_H_ */
代码如下.c部分:
/*
* DS1308.c
*
* Created on: 2024-9-9
* Author: Administrator
*/
#include "DS1308.h"
/*******************************************************************************
* 函 数 名 : IIC_Init
* 函数功能 : IIC初始化
* 输 入 : 无
* 输 出 : 无
*
*******************************************************************************/
void IICA_Init(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.bit.CAP1Q1_GPIOA8=0; //将其设置为GPIO
GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=0; //将其设置为GPIO
GpioMuxRegs.GPADIR.bit.GPIOA8=1;// 输出端口
GpioMuxRegs.GPADIR.bit.GPIOA9=1;// 输出端口
GpioMuxRegs.GPAQUAL.all=0x0000;//输入采样限定关闭// GPIOA
EDIS;
}
/*******************************************************************************
* 函 数 名 : SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_OUT(void)
{
EALLOW;
GpioMuxRegs.GPADIR.bit.GPIOA9=1; //Output. SDA
EDIS;
}
/*******************************************************************************
* 函 数 名 : SDA_IN
* 函数功能 : SDA输入配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_IN(void)
{
EALLOW;
GpioMuxRegs.GPADIR.bit.GPIOA9=0; //Input, SDA
EDIS;
}
/*******************************************************************************
* 函 数 名 : IIC_Start
* 函数功能 : 产生IIC起始信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA_SETH;
IIC_SCL_SETH;
DELAY_US(14);
IIC_SDA_SETL;//START:when CLK is high,DATA change form high to low
DELAY_US(14);
IIC_SCL_SETL;//钳住I2C总线,准备发送或接收数据
}
/*******************************************************************************
* 函 数 名 : IIC_Stop
* 函数功能 : 产生IIC停止信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL_SETL;
IIC_SDA_SETL;//STOP:when CLK is high DATA change form low to high
DELAY_US(14);
IIC_SCL_SETH;
// DELAY_US(6);
IIC_SDA_SETH;//发送I2C总线结束信号
DELAY_US(14);
}
/*******************************************************************************
* 函 数 名 : IIC_Wait_Ack
* 函数功能 : 等待应答信号到来
* 输 入 : 无
* 输 出 : 1,接收应答失败
0,接收应答成功
*******************************************************************************/
unsigned char IIC_Wait_Ack(void)
{
unsigned char tempTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA_SETH;
DELAY_US(10);
IIC_SCL_SETH;
DELAY_US(10);
while(READ_SDA)
{
tempTime++;
if(tempTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_SETL;//时钟输出0
return 0;
}
/*******************************************************************************
* 函 数 名 : IIC_Ack
* 函数功能 : 产生ACK应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Ack(void)
{
IIC_SCL_SETL;
SDA_OUT();
IIC_SDA_SETL;
DELAY_US(22);
IIC_SCL_SETH;
DELAY_US(22);
IIC_SCL_SETL;
}
/*******************************************************************************
* 函 数 名 : IIC_NAck
* 函数功能 : 产生NACK非应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_NAck(void)
{
IIC_SCL_SETL;
SDA_OUT();
IIC_SDA_SETH;
DELAY_US(22);
IIC_SCL_SETH;
DELAY_US(22);
IIC_SCL_SETL;
}
/*******************************************************************************
* 函 数 名 : IIC_Send_Byte
* 函数功能 : IIC发送一个字节
* 输 入 : txd:发送一个字节
* 输 出 : 无
*******************************************************************************/
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t;
SDA_OUT();
IIC_SCL_SETL;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
// if((txd&0x80)>0) //0x80 1000 0000
// IIC_SDA_SETH;
// else
// IIC_SDA_SETL;
// txd<<=1;
if((txd&0x80)>>7) IIC_SDA_SETH;
else IIC_SDA_SETL;
txd<<=1;
DELAY_US(22);
IIC_SCL_SETH;
DELAY_US(22);
IIC_SCL_SETL;
DELAY_US(22);
}
}
/*******************************************************************************
* 函 数 名 : IIC_Read_Byte
* 函数功能 : IIC读一个字节
* 输 入 : ack=1时,发送ACK,ack=0,发送nACK
* 输 出 : 应答或非应答
*******************************************************************************/
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_SETL;
DELAY_US(22);
IIC_SCL_SETH;
receive<<=1;
if(READ_SDA)receive++;
DELAY_US(20);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
//DS1308操作函数
void DS1308_IIC_Write(u8 addr,u8 data) //写数据
{
IIC_Start();
IIC_Send_Byte(DS1308_Write_Address);
IIC_Wait_Ack();
DELAY_US(5);
IIC_Send_Byte(addr);
IIC_Wait_Ack();
DELAY_US(5);
IIC_Send_Byte(data);
IIC_Wait_Ack();
DELAY_US(5);
IIC_Stop();
}
u8 DS1308_IIC_Read(u8 addr) //读数据
{
u8 data_s;
IIC_Start();
IIC_Send_Byte(DS1308_Write_Address);
IIC_Wait_Ack();
DELAY_US(15);
IIC_Send_Byte(addr);
IIC_Wait_Ack();
DELAY_US(5);
IIC_Start();
IIC_Send_Byte(DS1308_Read_Address);
IIC_Wait_Ack();
DELAY_US(50);
data_s = IIC_Read_Byte(0);
IIC_Stop();
return data_s;
}
void ModifyTime(u8 year,u8 month,u8 day,u8 hour,u8 min,u8 sec)//修改时间
{
u8 temp;
temp = DEC_BCD(year);
DS1308_IIC_Write(DS1308_YEAR_REG,temp);
temp = DEC_BCD(month);
DS1308_IIC_Write(DS1308_MONTH_REG,temp);
temp = DEC_BCD(day);
DS1308_IIC_Write(DS1308_MDAY_REG,temp);
temp = DEC_BCD(hour);
DS1308_IIC_Write(DS1308_HOUR_REG,temp);
temp = DEC_BCD(min);
DS1308_IIC_Write(DS1308_MIN_REG,temp);
temp = DEC_BCD(sec);
DS1308_IIC_Write(DS1308_SEC_REG,temp);
}
void get_time(void)//获取时间
{
calendar.year = DS1308_IIC_Read(DS1308_YEAR_REG);
calendar.year = BCD_DEC(calendar.year);
calendar.month = DS1308_IIC_Read(DS1308_MONTH_REG);
calendar.month = BCD_DEC(calendar.month);
calendar.day = DS1308_IIC_Read(DS1308_MDAY_REG);
calendar.day = BCD_DEC(calendar.day);
calendar.hour = DS1308_IIC_Read(DS1308_HOUR_REG);
calendar.hour &= 0x3f;
calendar.hour = BCD_DEC(calendar.hour);
calendar.min = DS1308_IIC_Read(DS1308_MIN_REG);
calendar.min = BCD_DEC(calendar.min);
calendar.sec = DS1308_IIC_Read(DS1308_SEC_REG);
calendar.sec = BCD_DEC(calendar.sec);
}
u8 BCD_DEC(u8 val)//BCD码转化为十进制
{
u8 temp;
temp=val&0x0f;
val>>=4;
val&=0x0f;
val*=10;
temp+=val;
return temp;
}
u8 DEC_BCD(u8 val)//十进制转化为BCD码
{
u8 i,j,k;
i=val/10;
j=val%10;
k=j+(i<<4);
return k;
}
2.main调用代码部分(仅展示有DS1308部分)
代码如下:
#include "DS1308.h"
_calendar_part calendar;//DS1308声明时钟结构体
void main(void)
{
IICA_Init();
ModifyTime(24,9,12,12,58,45); //写入DS1308时钟芯片时间的初始值
while (1)
{
get_time();
SendString(" DATA: ");
SendUint16DecAscii(calendar.year);
SendString(" 年 ");
SendUint16DecAscii(calendar.month);
SendString(" 月 ");
SendUint16DecAscii(calendar.day);
SendString(" 日 ");
SendUint16DecAscii(calendar.hour);
SendString(" : ");
SendUint16DecAscii(calendar.min);
SendString(" : ");
SendUint16DecAscii(calendar.sec);
SendString("\n\r");
}
}
总结
DS1308使用I2C通信,在使用时需注意时序及寄存器的准确性。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)