반응형

Raspberry Pi Pico 에 연결된 I2C slave address 읽기.

 

아래 링크의 자료를 참고로 하여 확인.

https://remnant24c.tistory.com/305

 

RaspberryPi Pico에 연결된 I2C 모듈의 주소 알아내기

안녕하세요. RaspberryPi Pico에 연결된 모듈의 I2C 주소를 모를 경우 데이터를 가지고 올 수 없습니다. 만약 데이터 시트를 가지고 있다면 큰 문제가 되지 않지만, 모를 경우 간단한 코드로 확인할 수

remnant24c.tistory.com

 

아래 사진과 같이 배선 연결. 3.3V, GND, I2C0 SDA, I2C0 SCL.

 

아래와 같이 I2C EEPROM의 slave address로 0x50 주소가 읽혔다.

 

 

왼쪽은 console 에 입력하여 결과 확인, 오른쪽은 Pico module 에 소스를 다운로드 하여 실행한 결과이다.

 

from machine import Pin, I2C

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000)

print("I2C Address : " + hex(i2c.scan()[0]).upper())

 

 

 

 

728x90
반응형
반응형

 

 

 

Serial EEPROM CAT24C32 (32kbit)

STM32F103을 이용한 I2C Byte read 기능 구현.

 

환경) Compiler : System Workbench, CMSIS library

 

Sequence는 아래를 참조하여 구현한다.

 

 

구현한 코드

 

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
int EEPROM_i2c_readByte(uint8_t slaveAddr, uint16_t regAddr, uint8_t * retByte) {
 
    I2C_AcknowledgeConfig(I2C2, ENABLE);
 
    I2C_GenerateSTART(I2C2, ENABLE);
 
    int timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) {
        if((timeout--== 0) {
            return -1;
        }
        delay_us(1);
    }
 
    I2C_Send7bitAddress(I2C2, slaveAddr, I2C_Direction_Transmitter);
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
        if((timeout--== 0) {
            return -2;
        }
        delay_us(1);
    }
 
    // Register Address 15-8
    I2C_SendData(I2C2, (uint8_t)((regAddr >> 8& 0x00FF));
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        if((timeout--== 0) {
            return -3;
        }
        delay_us(1);
    }
 
    // Register Address 7-0
    I2C_SendData(I2C2, (uint8_t)(regAddr & 0x00FF));
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        if((timeout--== 0) {
            return -4;
        }
        delay_us(1);
    }
 
    I2C_GenerateSTART(I2C2, ENABLE);
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) {
        if((timeout--== 0) {
            return -5;
        }
        delay_us(1);
    }
 
    I2C_Send7bitAddress(I2C2, slaveAddr, I2C_Direction_Receiver);
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
        if((timeout--== 0) {
            return -6;
        }
        delay_us(1);
    }
 
    timeout = I2C_TIMEOUT;
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)) {
        if((timeout--== 0) {
            return -7;
        }
        delay_us(1);
    }
 
    *retByte = I2C_ReceiveData(I2C2);
 
    I2C_AcknowledgeConfig(I2C2, DISABLE);
 
    I2C_GenerateSTOP(I2C2, ENABLE);
 
    timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)) {
        if((timeout--== 0) {
            return -8;
        }
        delay_us(1);
    }
 
    delay_us(100);
 
    return 0;
}
 
 
void delay_us(int us)
{
    volatile u32 i;
 
    for(i = us; i > 0; i--// 72clock = 1us
    {
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop");
    }
}
 
 
// Use example
uint8_t addr = 0xA0;    // Device address
uint8_t value = 0;
int  targetaddr = 0x00;
EEPROM_i2c_readByte(addr, targetaddr, &value);
 
cs

 

 

 

 

 

728x90
반응형

'공부 > HW' 카테고리의 다른 글

210626 PADS 부품 분산  (0) 2021.06.27
210324 멀티탭의 정격 사양 (AC250V 16A)  (0) 2021.03.25
210318 C data types (C99 Standard)  (0) 2021.03.18
210316 Serial EEPROM CAT24C32 (I2C 펌웨어)  (0) 2021.03.17
210316 Serial EEPROM CAT24C32  (0) 2021.03.16
반응형

 

 

 

 

 

 

Serial EEPROM CAT24C32를 I2C interface로 STM32F103를 이용하여 제어.

Compiler는 System WorkbenchCMSIS library를 사용.

 

Byte Write를 우선 구현. Sequence는 아래와 같다.

 

 

 

I2C 설정 부터 한다.

 

아래의 순서로 구현.

1. IO 설정.

2. I2C 초기화.

3. Serial EEPROM Byte write sequence 구현. 

 

아래의 코드 참고

1. IO 설정.

1
2
3
4
5
6
7
8
9
10
11
GPIO_InitTypeDef GPIO_InitStructure;
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
// PORTB
// Alternate Output Push Pull
GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin    = PIN_I2C_SCL | PIN_I2C_SDA;
GPIO_Init(GPIOB, &GPIO_InitStructure);
 
cs

 

2. I2C 초기화.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void hal_i2c_init() {
    I2C_DeInit(I2C2);
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
 
    I2C_InitTypeDef i2c_initStruct;
    I2C_StructInit(&i2c_initStruct);
 
    i2c_initStruct.I2C_Mode = I2C_Mode_I2C;
    i2c_initStruct.I2C_DutyCycle = I2C_DUTYCYCLE;
    i2c_initStruct.I2C_ClockSpeed = I2C_SPEED;
 
    I2C_Init(I2C2, &i2c_initStruct);
 
    I2C_Cmd(I2C2, ENABLE);
}
 
cs

 

3. Serial EEPROM Byte write sequence 구현. 

Device address는 0xA0로 하였다. A2, A2, A0에 모두 0 연결

 

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
int hal_i2c_writeByte(uint8_t slaveAddr, uint16_t regAddr, uint8_t byte) {
 
    I2C_AcknowledgeConfig(I2C2, ENABLE);
 
    I2C_GenerateSTART(I2C2, ENABLE);
 
    int timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) {
        if((timeout--== 0) {
            // Error
            return -1;
        }
        delay_us(1);
    }
 
    I2C_Send7bitAddress(I2C2, slaveAddr, I2C_Direction_Transmitter);
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
        if((timeout--== 0) {
            // Error
            return -2;
        }
        delay_us(1);
    }
 
    // Register Address 15-8
    I2C_SendData(I2C2, (uint8_t)((regAddr >> 8& 0x00FF));
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        if((timeout--== 0) {
            // Error 
            return -3;
        }
        delay_us(1);
    }
 
    // Register Address 7-0
    I2C_SendData(I2C2, (uint8_t)(regAddr & 0x00FF));
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        if((timeout--== 0) {
            // Error
            return -4;
        }
        delay_us(1);
    }
 
    I2C_SendData(I2C2, byte);
 
    timeout = I2C_TIMEOUT;
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        if((timeout--== 0) {
            // Error
            return -5;
        }
        delay_us(1);
    }
 
    I2C_GenerateSTOP(I2C2, ENABLE);
 
    timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)) {
        if((timeout--== 0) {
            // Error
            return -6;
        }
        delay_us(1);
    }
 
    delay_us(100);
 
    return 0;
}
 
 
cs

 

 

 

 

 

728x90
반응형
반응형

 

 

 

 

Serial EEPROM CAT24C32 Read/Write 구현

 

32-Kb I2C CMOS Serial EEPROM

즉, 4KByte 용량이다.

 

 

현재 회로 구현에서 A2, A1, A0를 Low로 연결하였기에 

Slave address로 0xA0 를 사용한다.

 

 

Byte write sequence는 아래와 같다.

주의할 것은 Address가 두 번 전송된다는 것이다.

다른 EEPROM의 소스를 그대로 적용하였다가 안되어서 보니 이 부분의 차이가 있었다.

 

Write Cycle Timing은 아래와 같다.

5 ms 이니 Byte Write sequence를 연속으로 쓸 때는 주의해서 사용하자.

 

 

 

Read Sequence는 아래와 같다.

Selective Read Sequence는 주소를 지정하여 한 Byte를 읽는 것이다.

Immediate Read Sequence는 현재 지정된 주소의 다음 주소를 한 Byte 읽는 것이다.

즉, Selective Read (3번 주소) 를 한 후 Immediate Read를 하면, 4번 주소의 데이터가 읽힌다.

 

 

위의 자료를 토대로 하여 펌웨어를 구현하면 된다.

오래간만에 이것을 다시 보니 실수를 많이 했다. ㅡ.ㅡ;

소스코드는 다음에...

 

 

 

 

 

 

728x90
반응형

+ Recent posts