i2c是最常用的通信接口或协议,在龙芯2k0300中蜂鸟开发板上,引出了4路i2c,相对来说,还是比较充足的,本文使用i2c2来驱动lcd模块
硬件电路
i2c电路
lcd模块
采用Grove - 16x2 LCD模块,如下图所示,它是i2c接口,支持显示16x2个字符,
Grove - 16x2 LCD | Seeed Studio Wiki
Grove - 16X2 LCD RGB Backlight - Seeed Studio
驱动适配
设备树
无,使用传统或原始的方法适配
驱动代码
板级文件
#defineI2C_BUS_AVAILABLE (2)#defineLCD_ADDRESS 0x3E#defineRGB_ADDRESS 0x62staticstructi2c_client *rgb_client;staticstructi2c_board_info lcd_board_info = { I2C_BOARD_INFO("lcd", LCD_ADDRESS) };staticstructi2c_board_info rgb_board_info = { I2C_BOARD_INFO("rgb", RGB_ADDRESS) };
probe
staticinti2c_driver_probe(structi2c_client *client,conststructi2c_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; }elseif(client->addr == LCD_ADDRESS) { pr_info("client->addr is LCD\n"); initialize_lcd(client); lcd_write_string(client, lcd_text); lcd_client = client; }return0; }staticconststructi2c_device_id i2c_driver_id[] = { {"lcd",0}, {"rgb",0}, { } }; MODULE_DEVICE_TABLE(i2c, i2c_driver_id);staticstructi2c_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, };
控制代码
staticvoid initialize_rgb(structi2c_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"); }staticvoid lcd_write_string(structi2c_client*client,constchar*str) { pr_info("Writing is start on display\n"); i2c_write_data(client, COMMAND_MODE,0x80);i =0;while((i < LCD_MAX_CHARS_PER_LINE) && (*str)) { i2c_write_data(client, DATA_MODE, *str++); i++; }if(*str) { i2c_write_data(client, COMMAND_MODE,0xC0);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) { case1://Read RGBvaluesfrom driverprintf("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; case2://Write RGBvaluesto driverprintf("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 RGBvaluesbefore writing to driverprintf("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; case3://Read LCD text from driverprintf("Reading LCD Text from Driver...\n");ioctl(fd, RD_LCD_TEXT, read_lcd_text);printf("LCD Text is: %s\n", read_lcd_text);break; case4://Get LCD text from userprintf("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 driverprintf("LCD Text to write: %s\n", lcd_text);//Write LCD text to driverprintf("Writing LCD Text to Driver...\n");ioctl(fd, WR_LCD_TEXT, lcd_text);break; case5:printf("Exiting...\n");close(fd);return0; 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=1334audit(1612279826.283:7): prog-id=7op=UNLOAD [53.668027] i2clcd: loadingout-of-tree module taints kernel. [53.686544] Major =242Minor =0[53.698072] Grove LCD RGB Backlight V4.0driver probe [53.718396] client->addrisLCD [53.725472] Initilize of LCD starting... [53.786414] Sending data to I2C device: register=0x00, data=0x28[53.792549] send bytes2[53.844383] Sending data to I2C device: register=0x00, data=0x08[53.853055] send bytes2[53.904395] Sending data to I2C device: register=0x00, data=0x01[53.913068] send bytes2[53.964392] Sending data to I2C device: register=0x00, data=0x06[53.973063] send bytes2[54.026405] Sending data to I2C device: register=0x00, data=0x0C[54.041318] send bytes2[54.094400] Initilize of LCD Completed [54.106413] Writingisstartondisplay [54.112216] Sending data to I2C device: register=0x00, data=0x80[54.118883] send bytes2[54.118890] Sending data to I2C device: register=0x40, data=0x48[54.127889] send bytes2[54.127896] Sending data to I2C device: register=0x40, data=0x65[54.136886] send bytes2[54.136892] Sending data to I2C device: register=0x40, data=0x6C[54.166404] send bytes2[54.166417] Sending data to I2C device: register=0x40, data=0x6C[54.185393] send bytes2[54.185406] Sending data to I2C device: register=0x40, data=0x6F[54.204449] send bytes2[54.204463] Sending data to I2C device: register=0x40, data=0x2C[54.218419] send bytes2[54.218429] Sending data to I2C device: register=0x40, data=0x20[54.237657] send bytes2[54.237671] Sending data to I2C device: register=0x40, data=0x57[54.246956] send bytes2[54.246963] Sending data to I2C device: register=0x40, data=0x6F[54.255949] send bytes2[54.255956] Sending data to I2C device: register=0x40, data=0x72[54.264947] send bytes2[54.264953] Sending data to I2C device: register=0x40, data=0x6C[54.273941] send bytes2[54.273948] Sending data to I2C device: register=0x40, data=0x64[54.282929] send bytes2[54.282936] Sending data to I2C device: register=0x40, data=0x21[54.292053] send bytes2[54.292059] Writingiscompletedondisplay [54.311541] Grove LCD RGB Backlight V4.0driver probe [54.320552] client->addrisRGB [54.324138] Initilize of RGB starting... [54.328254] Sending data to I2C device: register=0x00, data=0x00[54.334548] send bytes2[54.334554] Sending data to I2C device: register=0x01, data=0x00[54.343553] send bytes2[54.343560] Sending data to I2C device: register=0x08, data=0xAA[54.352582] send bytes2[54.352588] Sending data to I2C device: register=0x04, data=0xFF[54.371555] send bytes2[54.371569] Sending data to I2C device: register=0x03, data=0xFF[54.380868] send bytes2[54.380874] Sending data to I2C device: register=0x02, data=0xFF[54.389834] send bytes2[54.389839] Initilize of RGB Completed [54.400809] Driver Added!!!
运行应用
[root@LS-GDhome]# ./i2clcd-appOpeningDriver..[68.766573]DeviceFileOpened...!!! .Choosean operation:1.ReadRGBvalues2.WriteRGBvalues3.ReadLCDtext value4.WriteLCDtext value5.ExitEnteryour choice:2EntertheRGBvalues (0-255) to send:Red:255Green:0Blue:0RGBValuesto wr[80.754240]InitilizeofRGBstarting...ite:R:255,G: [80.759637]SendingdatatoI2Cdevice: register=0x00,data=0x000,B:0Writing[80.767984] send bytes2RGBValuestoD[80.767991]SendingdatatoI2Cdevice: register=0x01,data=0x00river... [80.778808] send bytes2[80.778814]SendingdatatoI2Cdevice: register=0x08,data=0xAA[80.788212] send bytes2[80.788219]SendingdatatoI2Cdevice: register=0x04,data=0xFF[80.797205] send bytes2[80.797212]SendingdatatoI2Cdevice: register=0x03,data=0x00[80.806215] send bytes2[80.806221]SendingdatatoI2Cdevice: register=0x02,data=0x00[80.825188] send bytes2[80.825199]InitilizeofRGBCompletedChoosean operation:1.ReadRGBvalues2.WriteRGBvalues3.ReadLCDtext value4.WriteLCDtext value5.ExitEnteryour choice:4EntertheLCDtext to send:helloelecfans,hello loongsonLCDTextto writ[91.184806]InitilizeofLCDstarting...e: hello elecfans,hello loongsonWritingLCDTexttoDriver... [91.242396]SendingdatatoI2Cdevice: register=0x00,data=0x28[91.248529] send bytes2[91.300437]SendingdatatoI2Cdevice: register=0x00,data=0x08[91.309196] send bytes2[91.360426]SendingdatatoI2Cdevice: register=0x00,data=0x01[91.369768] send bytes2[91.421389]SendingdatatoI2Cdevice: register=0x00,data=0x06[91.430061] send bytes2[91.482509]SendingdatatoI2Cdevice: register=0x00,data=0x0C[91.497159] send bytes2[91.548506]InitilizeofLCDCompleted[91.558420]Writingis start on display [91.564048]SendingdatatoI2Cdevice: register=0x00,data=0x80[91.570684] send bytes2[91.570691]SendingdatatoI2Cdevice: register=0x40,data=0x68[91.579699] send bytes2[91.579707]SendingdatatoI2Cdevice: register=0x40,data=0x65[91.588690] send bytes2[91.588697]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.597687] send bytes2[91.597693]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.606663] send bytes2[91.606669]SendingdatatoI2Cdevice: register=0x40,data=0x6F[91.625655] send bytes2[91.625669]SendingdatatoI2Cdevice: register=0x40,data=0x20[91.634937] send bytes2[91.634943]SendingdatatoI2Cdevice: register=0x40,data=0x65[91.644088] send bytes2[91.644094]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.653094] send bytes2[91.653100]SendingdatatoI2Cdevice: register=0x40,data=0x65[91.662148] send bytes2[91.662154]SendingdatatoI2Cdevice: register=0x40,data=0x63[91.671143] send bytes2[91.671149]SendingdatatoI2Cdevice: register=0x40,data=0x66[91.680125] send bytes2[91.680131]SendingdatatoI2Cdevice: register=0x40,data=0x61[91.699214] send bytes2[91.699229]SendingdatatoI2Cdevice: register=0x40,data=0x6E[91.708579] send bytes2[91.708586]SendingdatatoI2Cdevice: register=0x40,data=0x73[91.717576] send bytes2[91.717582]SendingdatatoI2Cdevice: register=0x40,data=0x2C[91.726581] send bytes2[91.726587]SendingdatatoI2Cdevice: register=0x40,data=0x68[91.735574] send bytes2[91.735580]SendingdatatoI2Cdevice: register=0x00,data=0xC0[91.744527] send bytes2[91.744534]SendingdatatoI2Cdevice: register=0x40,data=0x65[91.763547] send bytes2[91.763561]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.772813] send bytes2[91.772819]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.781802] send bytes2[91.781809]SendingdatatoI2Cdevice: register=0x40,data=0x6F[91.790764] send bytes2[91.790771]SendingdatatoI2Cdevice: register=0x40,data=0x20[91.799732] send bytes2[91.799738]SendingdatatoI2Cdevice: register=0x40,data=0x6C[91.808726] send bytes2[91.808732]SendingdatatoI2Cdevice: register=0x40,data=0x6F[91.817846] send bytes2[91.817853]SendingdatatoI2Cdevice: register=0x40,data=0x6F[91.836783] send bytes2[91.836797]SendingdatatoI2Cdevice: register=0x40,data=0x6E[91.846079] send bytes2[91.846086]SendingdatatoI2Cdevice: register=0x40,data=0x67[91.855079] send bytes2[91.855085]SendingdatatoI2Cdevice: register=0x40,data=0x73[91.864069] send bytes2[91.864076]SendingdatatoI2Cdevice: register=0x40,data=0x6F[91.873033] send bytes2[91.873040]SendingdatatoI2Cdevice: register=0x40,data=0x6E[91.882004] send bytes2[91.882010]Writingis completed on display
效果