📄 func_shi.c
字号:
/*********************************************************************
SHI Communication Function Version 1.2 (Copyright(c) VXIS Inc. 2002)
v1.0
Data:2002.08.02
by P.J. Yang
v1.1
Data:2002.08.07
by P.J. Yang
v1.2
Data:2002.08.14
by P.J. Yang
Modify:1. Modify DelayXms Function's input mode. char => unsigned char
2. Change shi_sub_write Function's variable from "buf_data_temp"
to "buf_data_temp1".
v1.3
Data:2002.09.12
by P.J. Yang
Modify:1. Remove delay to speed SHI's SCL clock.
SHI Frequency = 53kHz
*********************************************************************/
#include <intrins.h>
#include "config.h"
#if _debug
#include <stdio.h>
#endif
#include <reg51.h>
#include "pindef.h"
#include "func_shi.h"
void delay_nop();
void stop_con();
void start_con();
void nack_con();
void ack_con();
bit send_con(char);
bit send_con1(char bytedata);
char receive_con();
char receive_con1();
char bytedata = 0; // 8 bits buffer for both send and receive
bit ack; // Ack = 0 => Acknowledge
// Ack = 1 => No Acknowledge
/*********************************************************************
Readdata Function
Input Factor:
device => 7 bits , Device number (LSB must be zero)
address => 8 bits , Reg address
num_data => 8 bits , (Number of received data)-1
buf_data => 8 bits , A index point to receive data buffer
Output Factor:
None
Motion:
1.Program will read "num_data" datum from the "address" of "device"
to the register of "buf_data" address.
*********************************************************************/
void shi_sub_read(char device,char address,char num_data,char *buf_data)
{
unsigned char data count = 0;
char *buf_data_temp;
bit EA_temp;
bit com = 0; // A flag to indicate whether the read motion is complete
// com = 0 => Not complete
// com = 1 => Complete
EA_temp=EA;
EA=0;
while (!com)
{
stop_con(); // Master send Stop command
delay_nop();
start_con(); // Master send Start command
ack = send_con(device++); // Send the device number and Set the R/W bit
if (!ack)
{
ack = send_con(address); // Send the address of reg
// if(!ack){printf("read ack addr is ok\n");}
if (!ack)
{
com = 1; // Motion is complete
}
}
}
// delay_nop();
// Ready for receive data
com = 0;
while (!com)
{
buf_data_temp = buf_data;
stop_con(); // Master send Stop command
delay_nop();
start_con(); // Master send Start command
ack = send_con(device); // Send the device number and Set the R/W bit
if (!ack)
{
// ack=send_con(address);
// if(!ack){printf("read ack addr is ok\n");} while(1);
for (count = 0;count <= num_data;count++)
{
*buf_data_temp = receive_con(); // Save received data to buf_data
buf_data_temp++; // Address index increase
if (count != num_data) // Check whether the data is the last
{
ack_con();
}
else
{
nack_con();
com = 0; //printf("com=0\n");
goto Com_Received;
}
}
}
}
Com_Received:
delay_nop();
stop_con();
delay_nop();
EA=EA_temp;
}
/*********************************************************************
Writedata Function
Input Factor:
device => 7 bits , Device number (LSB must be zero)
address => 8 bits , Reg address
num_data => 8 bits , (Number of transmitted data) - 1
buf_data => 8 bits , A index to point transmit data buffer
Output Factor:
None
Motion:
1.Program will write "num_data" datum from the register of "buf_data" address
to the "address" of "device".
*********************************************************************/
void shi_sub_write(char device,char address,unsigned char num_data,char *buf_data)
{
bit com = 0;
unsigned char data count = 0;
char *buf_data_temp1;
bit EA_temp;
EA_temp=EA;
EA=0;
while (!com)
{
buf_data_temp1 = buf_data;
stop_con(); // Master send Stop command
delay_nop();
start_con(); // Master send Start command
ack = send_con(device); // Send the device number and Set the R/W bit
//if(!ack){printf("write ack addr is ok\n");} while(1);
if (!ack)
{
ack = send_con(address); // Send the address of reg
//if(!ack){printf("write ack addr is ok\n");} while(1);
for (count=0;count <= num_data;count++)
{
if (!ack)
{
ack = send_con(*buf_data_temp1); // Send the data pointed the buf_data index
buf_data_temp1++; // Address index increase
if (count == num_data && !ack )
{
com = 1;
//printf("com=1 exec\n");
break;
}
}
else
{
break;
}
}
}
}
delay_nop();
stop_con(); // Master send Stop command
delay_nop();
EA=EA_temp;
}
/*********************************************************************
Receivebyte Function
*********************************************************************/
char receive_con()
{
char count = 0;
for (count=0;count<8;count++)
{
bytedata <<= 1;
scl = 1; // scl high
delay_nop();
if (sda)
{
bytedata |= 0x01;
}
scl = 0; // scl low
delay_nop();
}
return (bytedata);
}
/*********************************************************************
Sendbyte Function
*********************************************************************/
bit send_con(char bytedata)
{
char data count = 0;
scl = 0;
delay_nop();
for (count=0;count<8;count++)
{
//sda = 0; // sda low
if (bytedata & 0x80)
sda = 1; // sda high
else
sda = 0;
delay_nop();
bytedata <<= 1; // bytedata left shift
// Generate SCLK
scl = 1; // scl high
//_nop_ ();
delay_nop();
scl = 0; // scl low
delay_nop();
}
//delay_nop(); //CSWU2005.11.6
// Readback ack
sda = 1; // sda high //CSWU2005.11.15 1->0
delay_nop();
scl = 1; // scl high
delay_nop();
delay_nop();
delay_nop();
ack = sda; // Read ack
// Ack = 0 => Acknowledge
// Ack = 1 => No Acknowledge
delay_nop();
scl = 0; // scl low
delay_nop();
return (ack);
}
/*********************************************************************
Acknowledge Function
*********************************************************************/
void ack_con()
{
sda = 0; // sda low
delay_nop();
scl = 1; // scl high
_nop_ ();
delay_nop();
scl = 0; // scl low
delay_nop();
sda = 1; // sda high
delay_nop();
}
/*********************************************************************
Not Acknowledge Function
*********************************************************************/
void nack_con()
{
// Acknowledge active
sda = 0; // sda low
delay_nop();
scl = 1; // scl high
delay_nop();
//Stop active
sda = 1; // sda high
delay_nop();
scl = 0; // scl low
delay_nop();
}
/*********************************************************************
Start Function
*********************************************************************/
void start_con()
{
sda = 1; // sda high
delay_nop();
scl = 1; // scl high
delay_nop();
//if(scl&sda){printf("this is stop ");};
sda = 0; // sda low
delay_nop();
// if(scl&!sda){printf("this is stop 0");};
scl = 0; // scl low
delay_nop();
}
/*********************************************************************
Stop Function
*********************************************************************/
void stop_con()
{
bit end = 0; // A Flag => 0:Repeat stop motion
// 1:Complete stop motion
while (end == 0)
{
scl = 0; // scl low
delay_nop();
sda = 0; // sda low
delay_nop();
// if(!scl&!sda){printf("this is stop 0");};
scl = 1; // scl high
delay_nop();
sda = 1; // sda high
delay_nop();
// if(scl&sda){printf("this is stop 1");};
if (sda == 1) // Check the device response
{
end = 1; // Set "Complete" Flag
}
}
}
/*********************************************************************
Delay Function
Machine cycle = 24x2 + 12x3 = 84
Crystal Frequency = 20 MHz
Delay Time: 4.2us
*********************************************************************/
void delay_nop()
{
_nop_ ();
// _nop_ ();
// _nop_ ();
}
/********************************************************************
Delay x ms Function
Crystal Frequency = 20 MHz
Delay Time: count x 1ms
********************************************************************/
void DelayXms(unsigned char count)
{
unsigned char data i,j;
for (i = 0;i < count;i++)
{
for (j = 0;j < 0xc8;j++)
{
_nop_();
}
}
}
void shi_sub_read1(char device,char num_data,char *buf_data)
{
unsigned char data count = 0;
char *buf_data_temp;
bit EA_temp;
bit com = 0; // A flag to indicate whether the read motion is complete
// com = 0 => Not complete
// com = 1 => Complete
EA_temp=EA;
EA=0;
com = 0;
buf_data_temp = buf_data;
stop_con(); // Master send Stop command
delay_nop();
start_con(); // Master send Start command
ack = send_con(++device); // Send the device number and Set the R/W bit
{
for (count = 0;count <= num_data;count++)
{
*buf_data_temp = receive_con1(); // Save received data to buf_data
buf_data_temp++; // Address index increase
if (count != num_data) // Check whether the data is the last
{
ack_con();
}
else
{
nack_con();
com = 0; //printf("com=0\n");
goto Com_Received;
}
}
}
//}*/
Com_Received:
delay_nop();
stop_con();
delay_nop();
EA=EA_temp;
}
/********************************************************
s-35390Atimer.by zld.2005.12
********************************************************/
void shi_sub_write1(char device,unsigned char num_data,char *buf_data)
{
bit com = 0;
unsigned char data count = 0;
char *buf_data_temp1;
bit EA_temp;
EA_temp=EA;
EA=0;
_nop_();
while (!com)
{
buf_data_temp1 = buf_data;
stop_con(); // Master send Stop command
delay_nop();
start_con(); // Master send Start command
ack = send_con(device); // Send the device number and Set the R/W bit
for (count=0;count <= num_data;count++)
{
if (!ack)
{
ack = send_con1(*buf_data_temp1); // Send the data pointed the buf_data index
buf_data_temp1++; // Address index increase
if (count == num_data && !ack )
{
com = 1;
//printf("com=1 exec\n");
break;
}
}
else
{
break;
}
}
}
delay_nop();
stop_con(); // Master send Stop command
delay_nop();
EA=EA_temp;
}
char receive_con1()
{
char count = 0;
unsigned char byte=0;
for (count=0;count<8;count++)
{
// printf("receive=%bx\n",byte);
byte>>= 1;
scl = 1; // scl high
delay_nop();
if (sda)
{
byte|= 0x80;
}
scl = 0; // scl low
delay_nop();
}
return (byte);
}
bit send_con1(char bytedata)
{
char data count = 0;
scl = 0;
delay_nop();
for (count=0;count<8;count++)
{
//sda = 0; // sda low
if (bytedata & 0x01)
sda = 1; // sda high
else
sda = 0;
delay_nop();
bytedata >>= 1; // bytedata left shift
//printf("bytedata=%bx",bytedata);
// Generate SCLK
scl = 1; // scl high
//_nop_ ();
delay_nop();
scl = 0; // scl low
delay_nop();
}
//delay_nop(); //CSWU2005.11.6
// Readback ack
sda = 1; // sda high //CSWU2005.11.15 1->0
delay_nop();
scl = 1; // scl high
delay_nop();
//delay_nop();
//delay_nop();
ack = sda; // Read ack
// Ack = 0 => Acknowledge
// Ack = 1 => No Acknowledge
delay_nop();
scl = 0; // scl low
delay_nop();
return (ack);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -