龙芯技术社区
直播中

jf_48561352

未满1年用户 30经验值
擅长:嵌入式技术
私信 关注
[2K系列]

【龙芯2K0300蜂鸟板试用】10 i2c控制lcd字符驱动

i2c是最常用的通信接口或协议,在龙芯2k0300中蜂鸟开发板上,引出了4路i2c,相对来说,还是比较充足的,本文使用i2c2来驱动lcd模块

硬件电路

i2c电路

QQ_1724683173944.png
QQ_1724683859821.png

lcd模块

采用Grove - 16x2 LCD模块,如下图所示,它是i2c接口,支持显示16x2个字符,

QQ_1724683481018.png

Grove - 16x2 LCD | Seeed Studio Wiki
Grove - 16X2 LCD RGB Backlight - Seeed Studio

驱动适配

设备树

无,使用传统或原始的方法适配

驱动代码

板级文件

#define I2C_BUS_AVAILABLE   (2)    

#define LCD_ADDRESS 0x3E
#define RGB_ADDRESS 0x62
static struct i2c_client *rgb_client;

static struct i2c_board_info lcd_board_info = {
    I2C_BOARD_INFO("lcd", LCD_ADDRESS)
};

static struct i2c_board_info rgb_board_info = {
    I2C_BOARD_INFO("rgb", RGB_ADDRESS)
};

probe

static int i2c_driver_probe(struct i2c_client *client, const struct i2c_device_id *id) {
    pr_info("Grove LCD RGB Backlight V4.0 driver probe\n");

    if (client->addr == RGB_ADDRESS) {
        pr_info("client->addr is RGB\n");
        initialize_rgb(client);
        rgb_client = client;
    } else if (client->addr == LCD_ADDRESS) {
        pr_info("client->addr is LCD\n");
        initialize_lcd(client);
        lcd_write_string(client, lcd_text);
        lcd_client = client;
    }

    return 0;
}

static const struct i2c_device_id i2c_driver_id[] = {
    { "lcd", 0 },
    { "rgb", 0 },
    { }
};

MODULE_DEVICE_TABLE(i2c, i2c_driver_id);

static struct i2c_driver etx_i2c_driver = {
    .driver = {
        .name = "grove_lcd_rgb",
        .owner = THIS_MODULE,
    },
    .probe = i2c_driver_probe,
    .remove = i2c_driver_remove,
    .id_table = i2c_driver_id,
};

控制代码

/*
** Initialize the RGB backlight
*/
static void initialize_rgb(struct i2c_client *client) {
    pr_info("Initilize of RGB starting...\n");
    
    i2c_write_data(client, rgb_reg_reset, rgb_val_reset);
    i2c_write_data(client, rgb_reg_clock, rgb_val_clock);
    i2c_write_data(client, rgb_reg_led, rgb_val_led);
    i2c_write_data(client, rgb_reg_red, rgb_val_red);
    i2c_write_data(client, rgb_reg_green, rgb_val_green);
    i2c_write_data(client, rgb_reg_blue, rgb_val_blue);

    pr_info("Initilize of RGB Completed\n");
}

/*
** Write string to the LCD
*/
static void lcd_write_string(struct i2c_client *client, const char *str) {
    
    pr_info("Writing is start on display\n");
    i2c_write_data(client, COMMAND_MODE, 0x80);  // Set DDRAM address to 0x00 (start of second line)
    
    i = 0;
    while ((i < LCD_MAX_CHARS_PER_LINE) && (*str)) {
        i2c_write_data(client, DATA_MODE, *str++);
	i++;
    }

    // Move the cursor to the beginning of the second line if there are more characters to display
    if (*str) {
        i2c_write_data(client, COMMAND_MODE, 0xC0);  // Set DDRAM address to 0x40 (start of second line)

        while (*str) {
            i2c_write_data(client, DATA_MODE, *str++);
        }
    }

    pr_info("Writing is completed on display\n");
}

应用测试

while (1) {
        printf("\nChoose an operation:\n");
        printf("1. Read RGB values\n");
        printf("2. Write RGB values\n");
        printf("3. Read LCD text value\n");
        printf("4. Write LCD text value\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &option);

        switch (option) {
            case 1:
                // Read RGB values from driver
                printf("Reading RGB Values from Driver...\n");
                ioctl(fd, RD_RGB_VALUE, (struct rgb_value*) &read_data);
                printf("RGB Values are R: %d, G: %d, B: %d\n", read_data.red, read_data.green, read_data.blue);
                break;
            case 2:
                
		// Write RGB values to driver
		
		printf("Enter the RGB values (0-255) to send: \n");
                printf("Red: ");
                scanf("%d", &Red);
                printf("Green: ");
                scanf("%d", &Green);
                printf("Blue: ");
                scanf("%d", &Blue);

		if(Red > 255 || Red < 0){
		    printf("Red > 255\nTaking default value of Red : 255\n");
		    rgb_data.red = 255;
		} else {
		    rgb_data.red = Red;	
		}

		if(Green > 255 || Green < 0){
		    printf("Green > 255\nTaking default value of Green : 255\n");
		    rgb_data.green = 255;
		} else {
		    rgb_data.green = Green;	
		}

		if(Blue > 255 || Blue < 0){
		    printf("Blue > 255\nTaking default value of Blue : 255\n");
		    rgb_data.blue = 255;
		} else {
		    rgb_data.blue = Blue;	
		}

		// Print RGB values before writing to driver
                printf("RGB Values to write: R: %d, G: %d, B: %d\n", rgb_data.red, rgb_data.green, rgb_data.blue);

                printf("Writing RGB Values to Driver...\n");
                ioctl(fd, WR_RGB_VALUE, (struct rgb_value*) &rgb_data);
                break;
            case 3:
                // Read LCD text from driver
                printf("Reading LCD Text from Driver...\n");
                ioctl(fd, RD_LCD_TEXT, read_lcd_text);
                printf("LCD Text is: %s\n", read_lcd_text);
                break;
            case 4:
                // Get LCD text from user
                printf("Enter the LCD text to send: \n");
                getchar(); // Clear newline character left by previous scanf
                fgets(lcd_text, sizeof(lcd_text), stdin);
                lcd_text[strcspn(lcd_text, "\n")] = 0; // Remove newline character

                // Print LCD text before writing to driver
                printf("LCD Text to write: %s\n", lcd_text);

                // Write LCD text to driver
                printf("Writing LCD Text to Driver...\n");
                ioctl(fd, WR_LCD_TEXT, lcd_text);
                break;
            case 5:
                printf("Exiting...\n");
                close(fd);
                return 0;
            default:
                printf("Invalid option. Please try again.\n");
                break;
        }
    }

验证效果

加载驱动

[root@LS-GD home]# insmod i2clcd.ko [   46.470496] audit: type=1334 audit(1612279826.283:6): prog-id=8 op=UNLOAD
[   46.478288] audit: type=1334 audit(1612279826.283:7): prog-id=7 op=UNLOAD

[   53.668027] i2clcd: loading out-of-tree module taints kernel.
[   53.686544] Major = 242 Minor = 0
[   53.698072] Grove LCD RGB Backlight V4.0 driver probe
[   53.718396] client->addr is LCD
[   53.725472] Initilize of LCD starting...
[   53.786414] Sending data to I2C device: register=0x00, data=0x28
[   53.792549] send bytes 2
[   53.844383] Sending data to I2C device: register=0x00, data=0x08
[   53.853055] send bytes 2
[   53.904395] Sending data to I2C device: register=0x00, data=0x01
[   53.913068] send bytes 2
[   53.964392] Sending data to I2C device: register=0x00, data=0x06
[   53.973063] send bytes 2
[   54.026405] Sending data to I2C device: register=0x00, data=0x0C
[   54.041318] send bytes 2
[   54.094400] Initilize of LCD Completed
[   54.106413] Writing is start on display
[   54.112216] Sending data to I2C device: register=0x00, data=0x80
[   54.118883] send bytes 2
[   54.118890] Sending data to I2C device: register=0x40, data=0x48
[   54.127889] send bytes 2
[   54.127896] Sending data to I2C device: register=0x40, data=0x65
[   54.136886] send bytes 2
[   54.136892] Sending data to I2C device: register=0x40, data=0x6C
[   54.166404] send bytes 2
[   54.166417] Sending data to I2C device: register=0x40, data=0x6C
[   54.185393] send bytes 2
[   54.185406] Sending data to I2C device: register=0x40, data=0x6F
[   54.204449] send bytes 2
[   54.204463] Sending data to I2C device: register=0x40, data=0x2C
[   54.218419] send bytes 2
[   54.218429] Sending data to I2C device: register=0x40, data=0x20
[   54.237657] send bytes 2
[   54.237671] Sending data to I2C device: register=0x40, data=0x57
[   54.246956] send bytes 2
[   54.246963] Sending data to I2C device: register=0x40, data=0x6F
[   54.255949] send bytes 2
[   54.255956] Sending data to I2C device: register=0x40, data=0x72
[   54.264947] send bytes 2
[   54.264953] Sending data to I2C device: register=0x40, data=0x6C
[   54.273941] send bytes 2
[   54.273948] Sending data to I2C device: register=0x40, data=0x64
[   54.282929] send bytes 2
[   54.282936] Sending data to I2C device: register=0x40, data=0x21
[   54.292053] send bytes 2
[   54.292059] Writing is completed on display
[   54.311541] Grove LCD RGB Backlight V4.0 driver probe
[   54.320552] client->addr is RGB
[   54.324138] Initilize of RGB starting...
[   54.328254] Sending data to I2C device: register=0x00, data=0x00
[   54.334548] send bytes 2
[   54.334554] Sending data to I2C device: register=0x01, data=0x00
[   54.343553] send bytes 2
[   54.343560] Sending data to I2C device: register=0x08, data=0xAA
[   54.352582] send bytes 2
[   54.352588] Sending data to I2C device: register=0x04, data=0xFF
[   54.371555] send bytes 2
[   54.371569] Sending data to I2C device: register=0x03, data=0xFF
[   54.380868] send bytes 2
[   54.380874] Sending data to I2C device: register=0x02, data=0xFF
[   54.389834] send bytes 2
[   54.389839] Initilize of RGB Completed
[   54.400809] Driver Added!!!

运行应用

[root@LS-GD home]# ./i2clcd-app
Opening Driver..[   68.766573] Device File Opened...!!!
.

Choose an operation:
1. Read RGB values
2. Write RGB values
3. Read LCD text value
4. Write LCD text value
5. Exit
Enter your choice: 2
Enter the RGB values (0-255) to send:
Red: 255
Green: 0
Blue: 0
RGB Values to wr[   80.754240] Initilize of RGB starting...
ite: R: 255, G: [   80.759637] Sending data to I2C device: register=0x00, data=0x00
0, B: 0
Writing[   80.767984] send bytes 2
 RGB Values to D[   80.767991] Sending data to I2C device: register=0x01, data=0x00
river...
[   80.778808] send bytes 2
[   80.778814] Sending data to I2C device: register=0x08, data=0xAA
[   80.788212] send bytes 2
[   80.788219] Sending data to I2C device: register=0x04, data=0xFF
[   80.797205] send bytes 2
[   80.797212] Sending data to I2C device: register=0x03, data=0x00
[   80.806215] send bytes 2
[   80.806221] Sending data to I2C device: register=0x02, data=0x00
[   80.825188] send bytes 2
[   80.825199] Initilize of RGB Completed

Choose an operation:
1. Read RGB values
2. Write RGB values
3. Read LCD text value
4. Write LCD text value
5. Exit
Enter your choice: 4
Enter the LCD text to send:
hello elecfans,hello loongson
LCD Text to writ[   91.184806] Initilize of LCD starting...
e: hello elecfans,hello loongson
Writing LCD Text to Driver...
[   91.242396] Sending data to I2C device: register=0x00, data=0x28
[   91.248529] send bytes 2
[   91.300437] Sending data to I2C device: register=0x00, data=0x08
[   91.309196] send bytes 2
[   91.360426] Sending data to I2C device: register=0x00, data=0x01
[   91.369768] send bytes 2
[   91.421389] Sending data to I2C device: register=0x00, data=0x06
[   91.430061] send bytes 2
[   91.482509] Sending data to I2C device: register=0x00, data=0x0C
[   91.497159] send bytes 2
[   91.548506] Initilize of LCD Completed
[   91.558420] Writing is start on display
[   91.564048] Sending data to I2C device: register=0x00, data=0x80
[   91.570684] send bytes 2
[   91.570691] Sending data to I2C device: register=0x40, data=0x68
[   91.579699] send bytes 2
[   91.579707] Sending data to I2C device: register=0x40, data=0x65
[   91.588690] send bytes 2
[   91.588697] Sending data to I2C device: register=0x40, data=0x6C
[   91.597687] send bytes 2
[   91.597693] Sending data to I2C device: register=0x40, data=0x6C
[   91.606663] send bytes 2
[   91.606669] Sending data to I2C device: register=0x40, data=0x6F
[   91.625655] send bytes 2
[   91.625669] Sending data to I2C device: register=0x40, data=0x20
[   91.634937] send bytes 2
[   91.634943] Sending data to I2C device: register=0x40, data=0x65
[   91.644088] send bytes 2
[   91.644094] Sending data to I2C device: register=0x40, data=0x6C
[   91.653094] send bytes 2
[   91.653100] Sending data to I2C device: register=0x40, data=0x65
[   91.662148] send bytes 2
[   91.662154] Sending data to I2C device: register=0x40, data=0x63
[   91.671143] send bytes 2
[   91.671149] Sending data to I2C device: register=0x40, data=0x66
[   91.680125] send bytes 2
[   91.680131] Sending data to I2C device: register=0x40, data=0x61
[   91.699214] send bytes 2
[   91.699229] Sending data to I2C device: register=0x40, data=0x6E
[   91.708579] send bytes 2
[   91.708586] Sending data to I2C device: register=0x40, data=0x73
[   91.717576] send bytes 2
[   91.717582] Sending data to I2C device: register=0x40, data=0x2C
[   91.726581] send bytes 2
[   91.726587] Sending data to I2C device: register=0x40, data=0x68
[   91.735574] send bytes 2
[   91.735580] Sending data to I2C device: register=0x00, data=0xC0
[   91.744527] send bytes 2
[   91.744534] Sending data to I2C device: register=0x40, data=0x65
[   91.763547] send bytes 2
[   91.763561] Sending data to I2C device: register=0x40, data=0x6C
[   91.772813] send bytes 2
[   91.772819] Sending data to I2C device: register=0x40, data=0x6C
[   91.781802] send bytes 2
[   91.781809] Sending data to I2C device: register=0x40, data=0x6F
[   91.790764] send bytes 2
[   91.790771] Sending data to I2C device: register=0x40, data=0x20
[   91.799732] send bytes 2
[   91.799738] Sending data to I2C device: register=0x40, data=0x6C
[   91.808726] send bytes 2
[   91.808732] Sending data to I2C device: register=0x40, data=0x6F
[   91.817846] send bytes 2
[   91.817853] Sending data to I2C device: register=0x40, data=0x6F
[   91.836783] send bytes 2
[   91.836797] Sending data to I2C device: register=0x40, data=0x6E
[   91.846079] send bytes 2
[   91.846086] Sending data to I2C device: register=0x40, data=0x67
[   91.855079] send bytes 2
[   91.855085] Sending data to I2C device: register=0x40, data=0x73
[   91.864069] send bytes 2
[   91.864076] Sending data to I2C device: register=0x40, data=0x6F
[   91.873033] send bytes 2
[   91.873040] Sending data to I2C device: register=0x40, data=0x6E
[   91.882004] send bytes 2
[   91.882010] Writing is completed on display

效果

147b45cac4624661498e11b4aa283a25

更多回帖

发帖
×
20
完善资料,
赚取积分