Hi, Ich versuche gerade, ein I2C LCD mittels STM32F407 zum Laufen zu bringen. Nach Anstecken des LCDs sehe ich zwei Balken. Nach der Initialisierung bekomme ich aber lediglich in der ersten Reihe einen Balken anstatt einen blinkenden Cursor oder was auch immer. Was ich festellen kann: - Delays und I2C Schnittstelle funktionieren. - Adresse des LCDs wird auch mit einem ACK beantwortet. Die Adresse ist also die Richtige. IO Expander ist der PCF8574. Schaltplan befindet sich im Anhang und wurde von folgender Seite kopiert: https://alselectro.wordpress.com/2016/05/12/serial-lcd-i2c-module-pcf8574/ Bilder vom Logik Analyzer sind ebenfalls im Anhang; sowohl die gesamte Initialisierung als auch zu jedem einzelnem Kommando der Initialiserung. Der Datenaustausch sieht richtig für mich aus? Ich verwendet konstant 5ms Pause nach jedem Kommando, und 25us für den Enable Puls. Meine I2C Kommunikation ist so eingestellt, dass ich nach jeder Instruktion (z.B. LCD_cmd(0x28)) nachdem die Daten gesendet wurden das Stoppbit in der I2C setze. Mache ich bei der Initialisierung etwas grundlegend falsch? Die LCD Init Funktionen sowie die I2C Funktion sind hier:
1 | void LCD_init() |
2 | {
|
3 | GPIO_init(); |
4 | I2C_init(); |
5 | delay_init(); |
6 | |
7 | // Boot up
|
8 | delay_25us(200); // 25us*200=5ms |
9 | delay_25us(200); // 25us*200=5ms |
10 | delay_25us(200); // 25us*200=5ms |
11 | |
12 | LCD_cmd(0x30); // LCD soft reset |
13 | delay_25us(200); // 25us*200=5ms |
14 | |
15 | LCD_cmd(0x00); // LCD enable |
16 | delay_25us(200); // 25us*200=5ms |
17 | |
18 | LCD_cmd(0x00); // LCD enable |
19 | delay_25us(200); // 25us*200=5ms |
20 | |
21 | |
22 | LCD_cmd(0x28); // 4bit mode + Set function + 2 line |
23 | delay_25us(200); // 25us*200=5ms |
24 | |
25 | LCD_cmd(0x06); // increment automatically |
26 | delay_25us(200); // 25us*200=5ms |
27 | |
28 | LCD_cmd(0x0F); // Turn display on, cursor on, blinking on |
29 | delay_25us(200); // 25us*200=5ms |
30 | |
31 | LCD_cmd(0x01); // Clear display |
32 | delay_25us(200); // 25us*200=5ms |
33 | |
34 | LCD_cmd(0x02); // Cursor home |
35 | delay_25us(200); // 25us*200=5ms |
36 | }
|
1 | void LCD_cmd(uint8_t data) |
2 | {
|
3 | I2C_send(data, 0); |
4 | }
|
1 | void I2C_send(uint8_t data, uint8_t instruction) |
2 | {
|
3 | // Sending data
|
4 | // Generate start condition
|
5 | I2C1->CR1 |= (1<<I2C_CR1_START_Pos); // Generate repeated start condition |
6 | while(!(I2C1->SR1 & I2C_SR1_SB)); // Wait until Start bit is set |
7 | uint8_t tempAddress = 0; |
8 | uint8_t slaveAddress = 39; // 0x27 = 39dec = 0b0010 0111 |
9 | tempAddress = (slaveAddress<<1); // Make space on the 0th bit for R/W |
10 | tempAddress &= ~(1<<0); // Clear 0th bit for write |
11 | I2C1->DR = tempAddress; // Sends slave address |
12 | |
13 | while(!(I2C1->SR1 & I2C_SR1_ADDR)); // Wait until address is sent and acknowledged |
14 | uint32_t temp1 = 0; |
15 | temp1 = I2C1->SR1; |
16 | temp1 = I2C1->SR2; |
17 | (void)temp1; |
18 | |
19 | while(!(I2C1->SR1 & I2C_SR1_TXE)); // Wait for transmit ready |
20 | |
21 | |
22 | uint8_t command = 0x00; |
23 | // uint8_t command = 0x00; // 0b00000000. Sets RS=0, RW=0, EN=0, Backlight=Off
|
24 | if(instruction == 0) |
25 | {
|
26 | command = 0x08; // 0b00001000. Sets RS=0, RW=0, EN=0, Backlight=On |
27 | }
|
28 | else if(instruction == 1) |
29 | {
|
30 | command = 0x09; // 0b00001001. Sets RS=1, RW=0, EN=0, Backlight=On |
31 | }
|
32 | else
|
33 | {
|
34 | // Error
|
35 | }
|
36 | uint8_t Nibble_H = 0; |
37 | uint8_t Nibble_L = 0; |
38 | Nibble_H = data & 0xF0; |
39 | Nibble_L = data & 0x0F; |
40 | |
41 | I2C1->DR = Nibble_H | command; // Sends high Nibble together with command |
42 | |
43 | while(!(I2C1->SR1 & I2C_SR1_TXE)); |
44 | |
45 | while(!(I2C1->SR1 & I2C_SR1_BTF)); |
46 | |
47 | I2C1->DR = (Nibble_L << 4) | command; // Sends low Nibble |
48 | |
49 | while(!(I2C1->SR1 & I2C_SR1_TXE)); |
50 | |
51 | while(!(I2C1->SR1 & I2C_SR1_BTF)); |
52 | |
53 | I2C1->DR |= (1<<2); // Enables pulse to secure command |
54 | |
55 | while(!(I2C1->SR1 & I2C_SR1_TXE)); |
56 | |
57 | while(!(I2C1->SR1 & I2C_SR1_BTF)); |
58 | |
59 | delay_25us(1); // Waits 25us |
60 | |
61 | I2C1->DR &= ~(1<<2); // Disables pulse again |
62 | |
63 | while(!(I2C1->SR1 & I2C_SR1_TXE)); |
64 | |
65 | while(!(I2C1->SR1 & I2C_SR1_BTF)); |
66 | |
67 | I2C1->CR1 |= (1<<I2C_CR1_STOP_Pos); // Generate stop condition |
68 | |
69 | // I2C1->CR1 &= ~(1<<I2C_CR1_PE_Pos); // Turn off I2C1
|
70 | |
71 | }
|