📄 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 <stdio.h>
#include <reg51.h>
extern void delay_nop();
extern void stop_con();
extern void start_con();
extern void nack_con();
extern void ack_con();
extern bit send_con(char);
extern char receive_con();
sbit sda = P0^0;
sbit scl = P0^1;
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 count = 0;
// char temp = num_data;
char *buf_data_temp;
bit com = 0; // A flag to indicate whether the read motion is complete
// com = 0 => Not complete
// com = 1 => Complete
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)
{
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)
{
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;
goto Com_Received;
}
}
}
}
Com_Received:
delay_nop();
stop_con();
delay_nop();
}
/*********************************************************************
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 count = 0;
// unsigned char temp = num_data;
char *buf_data_temp1;
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)
{
ack = send_con(address); // Send the address of reg
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;
break;
}
}
else
{
break;
}
}
}
}
delay_nop();
stop_con(); // Master send Stop command
delay_nop();
}
/*********************************************************************
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 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();
// Readback ack
sda = 1; // sda high
delay_nop();
scl = 1; // scl high
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();
sda = 0; // sda low
delay_nop();
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();
scl = 1; // scl high
delay_nop();
sda = 1; // sda high
delay_nop();
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 i,j;
for (i = 0;i < count;i++)
{
for (j = 0;j < 0xc8;j++)
{
_nop_();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -