For LCD: For I2C : For EEPROM:
8051 interfacing with EEPROM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "Includes.h"
// Main function
void main()
{
unsigned char RxByte = 0;
unsigned char TxArray[4] = { '1', '2', '3', '4' };
unsigned char RxArray[4] = { 0 };
// Initialize LCD
InitLCD();
// Initialize i2c pins
InitI2C();
// Write '5' at 0x0001 address in EEPROM
Write_Byte_To_24LC64_EEPROM(0x0001, '5');
// Read from 0x0001 address from EEPROM
RxByte = Read_Byte_From_24LC64_EEPROM(0x0001);
// Write 4 bytes of TxArray starting from 0x0020 address in EEPROM
Write_Page_To_24LC64_EEPROM(0x0020, TxArray, 4);
// Read 4 bytes starting from 0x0020 address in EEPROM, save these bytes into RxArray
Read_Bytes_From_24LC64_EEPROM(0x0020, RxArray, 4);
// Display received values on LCD display
WriteDataToLCD(RxArray[0]);
WriteDataToLCD(RxArray[1]);
WriteDataToLCD(RxArray[2]);
WriteDataToLCD(RxArray[3]);
WriteDataToLCD(RxByte);
while(1)
{
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "Includes.h"
void ToggleEpinOfLCD(void)
{
E = 1; // Give a pulse on E pin
__delay_us(E_Delay); // so that LCD can latch the
E = 0; // data from data bus
__delay_us(E_Delay);
}
void WriteDataToLCD(char t)
{
RS = 1; // This is data
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= (t&0xF0); // Write Upper nibble of data
ToggleEpinOfLCD(); // Toggle E pin to send data
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= ((t<<4)&0xF0);// Write Lower nibble of data
ToggleEpinOfLCD(); // Toggle E pin to send data
}
void WriteCommandToLCD(int z)
{
RS = 0; // This is command
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= (z&0xF0); // Write Upper nibble of data
ToggleEpinOfLCD(); // Toggle E pin to send data
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= ((z<<4)&0xF0);// Write Lower nibble of data
ToggleEpinOfLCD(); // Toggle E pin to send data
}
void InitLCD(void)
{
RS = 0; // Make pin zero
E = 0; // Make Pin zero
///////////// Reset process from datasheet /////////
__delay_us(15000);
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= 0x30; // Write 0x3
ToggleEpinOfLCD(); // Toggle E pin to send data
__delay_us(4500);
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= 0x30; // Write 0x3
ToggleEpinOfLCD(); // Toggle E pin to send data
__delay_us(300);
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= 0x30; // Write 0x3
ToggleEpinOfLCD(); // Toggle E pin to send data
__delay_us(650);
P2 &= 0x0F; // Make P2.4 to P2.7 zero
P2 |= 0x20; // Write 0x2
ToggleEpinOfLCD(); // Toggle E pin to send data
__delay_us(650);
/////////////////////////////////////////////////////
WriteCommandToLCD(0x28); //function set
WriteCommandToLCD(0x0c); //display on,cursor off,blink off
WriteCommandToLCD(0x01); //clear display
WriteCommandToLCD(0x06); //entry mode, set increment
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "Includes.h"
// Function Purpose: Produce approximate delay in given uSecs.
void __delay_us(unsigned int d)
{
unsigned int i, limit;
limit = d/15;
for(i=0;i<limit;i++);
}
// Function Purpose: Set initial values of SCK and SDA pins
void InitI2C(void)
{
// Make SDA and SCK pins input initially
SDA = 1;
SCK = 1;
}
// Function Purpose: I2C_Start sends start bit sequence
void I2C_Start(void)
{
Set_SCK_High; // Make SCK pin high
Set_SDA_High; // Make SDA pin High
__delay_us(HalfBitDelay); // Half bit delay
Set_SDA_Low; // Make SDA Low
__delay_us(HalfBitDelay); // Half bit delay
}
// Function Purpose: I2C_ReStart sends start bit sequence
void I2C_ReStart(void)
{
Set_SCK_Low; // Make SCK pin low
__delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_High; // Make SDA pin High
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SDA_Low; // Make SDA Low
__delay_us(HalfBitDelay/2); // 1/4 bit delay
}
//Function : I2C_Stop sends stop bit sequence
void I2C_Stop(void)
{
Set_SCK_Low; // Make SCK pin low
__delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA pin low
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SDA_High; // Make SDA high
__delay_us(HalfBitDelay/2); // 1/4 bit delay
}
//Function : I2C_Send_ACK sends ACK bit sequence
void I2C_Send_ACK(void)
{
Set_SCK_Low; // Make SCK pin low
__delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_Low; // Make SDA Low
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
__delay_us(HalfBitDelay); // Half bit delay
}
//Function : I2C_Send_NACK sends NACK bit sequence
void I2C_Send_NACK(void)
{
Set_SCK_Low; // Make SCK pin low
__delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
Set_SDA_High; // Make SDA high
__delay_us(HalfBitDelay/2); // 1/4 bit delay
Set_SCK_High; // Make SCK pin high
__delay_us(HalfBitDelay); // Half bit delay
}
// Function Purpose: I2C_Write_Byte transfers one byte
bit I2C_Write_Byte(unsigned char Byte)
{
unsigned char i; // Variable to be used in for loop
for(i=0;i<8;i++) // Repeat for every bit
{
Set_SCK_Low; // Make SCK pin low
__delay_us(HalfBitDelay/2); // Data pin should change it's value,
// when it is confirm that SCK is low
if((Byte<<i)&0x80) // Place data bit value on SDA pin
Set_SDA_High; // If bit is high, make SDA high
else // Data is transferred MSB first
Set_SDA_Low; // If bit is low, make SDA low
__delay_us(HalfBitDelay/2); // Toggle SCK pin
Set_SCK_High; // So that slave can
__delay_us(HalfBitDelay); // latch data bit
}
// Get ACK from slave
Set_SCK_Low;
Set_SDA_High;
__delay_us(HalfBitDelay);
Set_SCK_High;
__delay_us(HalfBitDelay);
return SDA;
}
// Function Purpose: I2C_Read_Byte reads one byte
unsigned char I2C_Read_Byte(void)
{
unsigned char i, d, RxData = 0;
for(i=0;i<8;i++)
{
Set_SCK_Low; // Make SCK pin low
Set_SDA_High; // Don't drive SDA
__delay_us(HalfBitDelay); // Half bit delay
Set_SCK_High; // Make SCK pin high
__delay_us(HalfBitDelay/2); // 1/4 bit delay
d = SDA; // Capture Received Bit
RxData = RxData|(d<<(7-i)); // Copy it in RxData
__delay_us(HalfBitDelay/2); // 1/4 bit delay
}
return RxData; // Return received byte
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "Includes.h"
// Function Purpose: Write_Byte_To_24LC64_EEPROM writes a single byte on given address
// Address can have any value fromm 0 to 0x1FFF, and DataByte can have a value of 0 to 0xFF.
void Write_Byte_To_24LC64_EEPROM(unsigned int Address, unsigned char DataByte)
{
I2C_Start(); // Start i2c communication
// Send i2c address of 24LC64 with write command
while(I2C_Write_Byte(Device_Address_24LC64_EEPROM + 0) == 1)// Wait until device is free
{ I2C_Start(); }
I2C_Write_Byte(Address>>8); // Write Address upper byte
I2C_Write_Byte((unsigned char)Address); // Write Address lower byte
I2C_Write_Byte(DataByte); // Write data byte
I2C_Stop(); // Stop i2c communication
}
// Function Purpose: Read_Byte_From_24LC64_EEPROM reads a single byte from given address
// Address can have any value fromm 0 to 0x1FFF.
unsigned char Read_Byte_From_24LC64_EEPROM(unsigned int Address)
{
unsigned char Byte = 0; // Variable to store Received byte
I2C_Start(); // Start i2c communication
// Send i2c address of 24LC64 with write command
while(I2C_Write_Byte(Device_Address_24LC64_EEPROM + 0) == 1)// Wait until device is free
{ I2C_Start(); }
I2C_Write_Byte(Address>>8); // Write Address upper byte
I2C_Write_Byte((unsigned char)Address); // Write Address lower byte
I2C_ReStart(); // Restart i2c
// Send i2c address of 24LC64 EEPROM with read command
I2C_Write_Byte(Device_Address_24LC64_EEPROM + 1);
Byte = I2C_Read_Byte(); // Read byte from EEPROM
// Make SCK low, so that slave can stop driving SDA pin
// Send a NACK to indiacate single byte read is complete
I2C_Send_NACK();
// Send start bit and then stop bit to stop transmission
Set_SDA_Low; // Make SDA Low
__delay_us(HalfBitDelay); // Half bit delay
Set_SDA_High; // Make SDA high
__delay_us(HalfBitDelay); // Half bit delay
return Byte; // Return the byte received from 24LC64 EEPROM
}
// Function Purpose: Write_Page_To_24LC64_EEPROM writes a page on given address
// Address can have value 0, 32, 64, .... only and pData is pointer to the array
// containing NoOfBytes bytes in it. NoOfBytes can have a value from 1 to 32 only.
void Write_Page_To_24LC64_EEPROM(unsigned int Address,unsigned char* pData,unsigned char NoOfBytes)
{
unsigned int i;
I2C_Start(); // Start i2c communication
// Send i2c address of 24LC64 with write command
while(I2C_Write_Byte(Device_Address_24LC64_EEPROM + 0) == 1)// Wait until device is free
{ I2C_Start(); }
I2C_Write_Byte(Address>>8); // Write Address upper byte
I2C_Write_Byte((unsigned char)Address); // Write Address lower byte
for(i=0;i<NoOfBytes;i++) // Write NoOfBytes
I2C_Write_Byte(pData[i]); // Write data byte
I2C_Stop(); // Stop i2c communication
}
// Function Purpose: Read_Bytes_From_24LC64_EEPROM reads a NoOfBytes bytes from given starting address.
// Address can have any value fromm 0 to 0x1FFF. Also, NoOfBytes can have any value 0 to 0x1FFF.
// Read bytes are returned in pData array.
void Read_Bytes_From_24LC64_EEPROM(unsigned int Address, unsigned char* pData, unsigned int NoOfBytes)
{
unsigned int i;
I2C_Start(); // Start i2c communication
// Send i2c address of 24LC64 with write command
while(I2C_Write_Byte(Device_Address_24LC64_EEPROM + 0) == 1)// Wait until device is free
{ I2C_Start(); }
I2C_Write_Byte(Address>>8); // Write Address upper byte
I2C_Write_Byte((unsigned char)Address); // Write Address lower byte
I2C_ReStart(); // Restart i2c
// Send i2c address of 24LC64 EEPROM with read command
I2C_Write_Byte(Device_Address_24LC64_EEPROM + 1);
pData[0] = I2C_Read_Byte(); // Read First byte from EEPROM
for(i=1;i<NoOfBytes;i++) // Read NoOfBytes
{
I2C_Send_ACK(); // Give Ack to slave to start receiving next byte
pData[i] = I2C_Read_Byte(); // Read next byte from EEPROM
}
// Make SCK low, so that slave can stop driving SDA pin
// Send a NACK to indiacate read operation is complete
I2C_Send_NACK();
// Send start bit and then stop bit to stop transmission
Set_SDA_Low; // Make SDA Low
__delay_us(HalfBitDelay); // Half bit delay
Set_SDA_High; // Make SDA high
__delay_us(HalfBitDelay); // Half bit delay
}