반응형

 

 

 

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
반응형
반응형

 

개발환경) System workbench

 

// PortD
#define PIN_WIPER_PWM_IN GPIO_Pin_13 // PD13

void InitGPIO(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = PIN_Z_CLK_CNT | PIN_UNWIND_PWM_IN1 | PIN_UNWIND_PWM_IN2 | PIN_WIPER_PWM_IN ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}


void InitTimer_Pwm(void) 
{ //TIMER4
	/* TIM4 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	/* Time base configuration */
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure_TIM4;
	TIM_TimeBaseStructure_TIM4.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure_TIM4.TIM_Prescaler = 3-1;	// 72Mhz / 3 = 24Mhz
	TIM_TimeBaseStructure_TIM4.TIM_Period = 1000-1;	// 24Mhz / 1000 = 24Khz (PWM 주기는 24Khz)
	TIM_TimeBaseStructure_TIM4.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure_TIM4);

	/* PWM1 Mode configuration */
	TIM_OCInitTypeDef TIM_OCInitStructure_WIPER;
	TIM_OCInitStructure_WIPER.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure_WIPER.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure_WIPER.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure_WIPER.TIM_Pulse = (int)(nFanDuty * 10); // Duty 설정. nFanDuty (0 ~ 100)
	TIM_OC2Init(TIM4, &TIM_OCInitStructure_WIPER);
	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
	TIM_Cmd(TIM4, ENABLE);
}

728x90
반응형

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

201123 불량사례 ULN2803 파손  (0) 2020.11.25
201112 NAND vs. NOR flash  (0) 2020.11.12
201013 백래시  (0) 2020.10.13
200928 SystemWorkbench - 문자열 연결  (0) 2020.09.28
200925 스텝 모터 드라이버 (TB6560AHQ) excitation mode  (0) 2020.09.26
반응형

세밀하게 검사하는 거래처와 일하면서 진행한 보드 검증.

STM32F103의 외부 Clock 사양에 대한 검증.

HW 설계하여 보드 제작이 된 후 clock 이 제대로 인가되고 있는지 확인하기 위해 보드 검증을 한다.

Clock 회로 설계는 아래와 같다.

외부 Oscillator를 사용하여 clock을 인가하도록 설계.

전원 (Vdd 는 3.3V)

검증할 내용을 데이터시트의 관련 내용을 찾아서 확인.

측정 기준

1. 8 MHz clock.

2. OCS_IN high leve : Max. Vdd = 3.3V

3. OCS_IN low level : Max. 0.3Vdd = 0.99V

4. OSC_IN High or Low width : 5 ns 이상.

5. OSC_IN rise or fall time : 20 ns 이하.

32.768 kHz Crystal osillator에 대해서도 검증하려 했으나 이에 대한 사양은 데이터시트에서 못 찾았다.

728x90
반응형

+ Recent posts