📄 lib_twi.c
字号:
#include "lib_twi.h"
#include "lib_AT91SAM7S64.h"
#define ERROR (AT91C_TWI_NACK)//状态寄存器的一位,如果置1表示从机未应答
//*============================================================================
//* TWI初始化
//*============================================================================
//*----------------------------------------------------------------------------
//* 函数名: AT91F_SetTwiClock
//* 功能: 设置TWI时钟波形发生寄存器
//*----------------------------------------------------------------------------
void AT91F_SetTwiClock(void)
{
int sclock;
sclock = (10*MCK /AT91C_TWI_CLOCK);
if (sclock % 10 >= 5)
sclock = (sclock /10) - 5;
else
sclock = (sclock /10)- 6;
sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
AT91C_BASE_TWI->TWI_CWGR = ( 1<<16 ) | (sclock << 8) | sclock ;
}
//*----------------------------------------------------------------------------
//*函数名: AT91F_TWI_Open
//* 功能: 初始化TWI接口
//*----------------------------------------------------------------------------
void AT91F_TWI_Open(void)
{
// 配置I/O口作为TWI功能
AT91F_TWI_CfgPIO ();
// 将TWD和TWCK定义为开路
AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA,Twd_Twck);
// 开TWI时钟源
AT91F_TWI_CfgPMC ();
// 配置TWI工作在主模式,禁止TWI中断,采用查询读写方式
AT91F_TWI_Configure (AT91C_BASE_TWI);
// 设置TWI时钟波形发生寄存器
AT91F_SetTwiClock();
}
//*=============================================================================
//* 写EPROM
//*=============================================================================
//*----------------------------------------------------------------------------
//* 函数名:AT91F_TWI_WriteByte
//* 功能: 发送(以字节为单位)数据到设备(EPROM)
//*参数说明:
// pTwi:指向TWI结构的首地址-----设为AT91C_BASE_TWI
// mode:TWI的工作模式----用于设置WTI的主模式寄存器(内部器件地址长度,主机读写方向,器件地址),见DATASHEET
// int_address:器件的内部地址(要写入的位置)
// data2send:代写的数据缓冲区地址
// nb:写入的字节数
//*----------------------------------------------------------------------------
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb)
{
unsigned int status,counter=0,error=0;
// 设置TWI内部地址寄存器---可设为0,1,2,3位内部地址
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// 设置TWI的主模式寄存器(此处为主机写)
pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;
// 如果只写1个字节
if(nb <2)
{
//发送START状态,使能传输,传输完后发送STOP状态
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
//将数据写入发送保持寄存器
pTwi->TWI_THR = *data2send;
}
//如果一次写入多个字节
else
{
for(counter=0;counter<nb;counter++)
{
//发送START状态,使能传输
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
//最后一个数据发送完后,接着发送STOP状态
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
//读取状态寄存器
status = pTwi->TWI_SR;
//如果发送完一个字节后没收到应答信号,则表明有一次传输错误
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXRDY))
{
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
} //END while
//传输下一个字节
pTwi->TWI_THR = *(data2send+counter);
}//END for
}//END else
//读取状态寄存器
status = pTwi->TWI_SR;
//如果发送完一个字节后没收到应答信号,则表明有一次传输错误
if ((status & ERROR) == ERROR) error++;
//等待数据发送完
while (!(status & AT91C_TWI_TXCOMP))
{
//读取状态寄存器
status = pTwi->TWI_SR;
//如果发送完一个字节后没收到应答信号,则表明有一次传输错误
if ((status & ERROR) == ERROR) error++;
}//END while
return error;
}
//*=============================================================================
//* 读(EPROM)
//*=============================================================================
//*----------------------------------------------------------------------------
//* 函数名:AT91F_TWI_ReadByte
//* 功能: 从设备(EPROM)中读取一个字节的数据
//*参数说明:
// pTwi:指向TWI结构的首地址-----设为AT91C_BASE_TWI
// mode:TWI的工作模式----用于设置WTI的主模式寄存器(内部器件地址长度,主机读写方向,器件地址),见DATASHEET
// int_address:器件的内部地址(要写入的位置)
// data2read:数据缓冲区地址
// nb:要读出的字节数
//* Creation : 张正锋 2005-12-30 zhangzf@baite-group.com
//*----------------------------------------------------------------------------
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2read, int nb)
{
unsigned int status,counter=0,error=0;
// 设置TWI内部地址寄存器---可设为0,1,2,3位内部地址
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// 设置TWI的主模式寄存器(此处为主机读)
pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;
//如果只读取一个字节
if (nb == 1)
{
//发送START状态,接收完后发送STOP状态
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
//读取状态寄存器
status = pTwi->TWI_SR;
//如果没收到应答信号,则表明有一次传输错误
if ((status & ERROR) == ERROR) error++;
//等待操作完
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
//将数据放入缓冲区
*(data2read) = pTwi->TWI_RHR;
} //END if
//如果读取多个字节
else
{
//发送START状态,接收完后发送STOP状态
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
//读取状态寄存器
status = pTwi->TWI_SR;
//如果没收到应答信号,则表明有一次传输错误
if ((status & ERROR) == ERROR) error++;
//等待操作完
while (!(status & AT91C_TWI_TXCOMP))
{
status = pTwi->TWI_SR;
if ((status & ERROR )== ERROR) error++;
//查看是否收到一个字节数据
if(status & AT91C_TWI_RXRDY)
{
//将数据放入缓从区
*(data2read+counter++) = pTwi->TWI_RHR;
//如果是最后一次读取则发送STOP 状态
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
} //END if
} //END while
} //END else
return error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -