本帖最后由 邪乎风云 于 2020-9-9 10:57 编辑
c文件
#include "V_IIC.h"
//#include "stdio.h"
__attribute__((weak)) void IIC_delay_us(unsigned int t)
{
unsigned int i =0;
for(i=0;i<t;i++){
}
}
void V_Master_IIC_Init(V_IIC_MasterHandle *master,unsigned char (*SDA_Read)(void),void (*SDA_Out)(unsigned char state),void (*SCL_Out)(unsigned char state),void (*SDA_DirSet)(unsigned char out))
{
master->SCL_Out = SCL_Out;
master->SDA_Out = SDA_Out;
master->SDA_Read = SDA_Read;
master->SDA_DirSet = SDA_DirSet;
}
void V_Master_IIC_Start(V_IIC_MasterHandle *master)
{
master->SDA_DirSet(1);
master->SDA_Out(1);
master->SCL_Out(1);
IIC_delay_us(4);
master->SDA_Out(0);
IIC_delay_us(4);
master->SCL_Out(0);
}
void V_Master_IIC_Stop(V_IIC_MasterHandle *master)
{
master->SDA_DirSet(1);
master->SCL_Out(0);
master->SDA_Out(0);
IIC_delay_us(4);
master->SCL_Out(1);
IIC_delay_us(2);
master->SDA_Out(1);
IIC_delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
unsigned char V_Master_IIC_Wait_Ack(V_IIC_MasterHandle *master)
{
unsigned char ucErrTime=0;
master->SDA_DirSet(0);
master->SDA_Out(1);
IIC_delay_us(1);
master->SCL_Out(1);
IIC_delay_us(1);
while(master->SDA_Read())
{
ucErrTime++;
if(ucErrTime>250)
{
V_Master_IIC_Stop(master);
return 1;
}
}
master->SCL_Out(0);
return 0;
}
void V_Master_IIC_Ack(V_IIC_MasterHandle *master)
{
master->SCL_Out(0);
master->SDA_DirSet(1);
master->SDA_Out(0);
IIC_delay_us(2);
master->SCL_Out(1);
IIC_delay_us(2);
master->SCL_Out(0);
}
//不产生ACK应答
void V_Master_IIC_NAck(V_IIC_MasterHandle *master)
{
master->SCL_Out(0);
master->SDA_DirSet(1);
master->SDA_Out(1);
IIC_delay_us(2);
master->SCL_Out(1);
IIC_delay_us(2);
master->SCL_Out(0);
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void V_Master_IIC_Send_Byte(V_IIC_MasterHandle *master,unsigned char txd)
{
unsigned char t;
master->SCL_Out(0);
master->SDA_DirSet(1);
for(t=0;t<8;t++)
{
master->SDA_Out((txd&0x80)>>7);
txd<<=1;
IIC_delay_us(2); //对TEA5767这三个延时都是必须的
master->SCL_Out(1);
IIC_delay_us(2);
master->SCL_Out(0);
IIC_delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char V_Master_IIC_Read_Byte(V_IIC_MasterHandle *master,unsigned char ack)
{
unsigned char i,receive=0;
master->SDA_DirSet(0);
for(i=0;i<8;i++ )
{
master->SCL_Out(0);
IIC_delay_us(2);
master->SCL_Out(1);
receive<<=1;
if(master->SDA_Read())receive++;
IIC_delay_us(1);
}
if (!ack)
V_Master_IIC_NAck(master);//发送nACK
else
V_Master_IIC_Ack(master); //发送ACK
return receive;
}
unsigned char V_Master_IIC_Read(V_IIC_MasterHandle *master,unsigned char slave_adr,AdrType adr,char *redata,unsigned short len)
{
unsigned short i =0;
unsigned char result = 0;
#if USE_OS
if(os_start_**){
os_protect_start_no_change();
}
#endif
V_Master_IIC_Stop(master);
V_Master_IIC_Start(master);
V_Master_IIC_Send_Byte(master,slave_adr<<1);
if(V_Master_IIC_Wait_Ack(master)){
result= 1;
goto IIC_Read_End;
}
for(i=0;i<sizeof(AdrType);i++){
V_Master_IIC_Send_Byte(master,adr>>((sizeof(AdrType)-i-1)*8));
if(V_Master_IIC_Wait_Ack(master)){
result= 2;
goto IIC_Read_End;
}
}
V_Master_IIC_Start(master);
V_Master_IIC_Send_Byte(master,(slave_adr<<1) +1);
if(V_Master_IIC_Wait_Ack(master)){
result = 3;
goto IIC_Read_End;
}
for(i=0;i<len;i++){
if( i ==(len -1)){
*redata++=V_Master_IIC_Read_Byte(master,0);
}else{
*redata++=V_Master_IIC_Read_Byte(master,1);
}
}
V_Master_IIC_Stop(master);
result=4;
goto IIC_Read_End;
IIC_Read_End:
#if USE_OS
if(os_start_**){
os_protect_end_no_change();
}
#endif
return result;
}
unsigned char V_Master_IIC_Write(V_IIC_MasterHandle *master,unsigned char slave_adr,AdrType adr,char *data,unsigned short len)
{
unsigned short i =0;
unsigned char result = 0;
#if USE_OS
if(os_start_**){
os_protect_start_no_change();
}
#endif
V_Master_IIC_Stop(master);
V_Master_IIC_Start(master);
V_Master_IIC_Send_Byte(master,slave_adr<<1);
if(V_Master_IIC_Wait_Ack(master)){
result= 1;
goto IIC_Write_End;
}
for(i=0;i<sizeof(AdrType);i++){
V_Master_IIC_Send_Byte(master,adr>>((sizeof(AdrType)-i-1)*8));
if(V_Master_IIC_Wait_Ack(master)){
result = 2;
goto IIC_Write_End;
}
}
for(i=0;i<len;i++){
V_Master_IIC_Send_Byte(master,*data++);
if(V_Master_IIC_Wait_Ack(master)){
result= 3;
goto IIC_Write_End;
}
}
V_Master_IIC_Stop(master);
result= 4;
goto IIC_Write_End;
IIC_Write_End:
#if USE_OS
if(os_start_**){
os_protect_end_no_change();
OS_IIC_Dealyms(10*len);
}else{
IIC_delay_us(10000*len);
}
#else
IIC_delay_us(10000*len);
#endif
return result;
}
|