九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
65 linux spi設(shè)備驅(qū)動(dòng)之spi LCD屏驅(qū)動(dòng)

SPI的控制器驅(qū)動(dòng)由平臺(tái)設(shè)備與平臺(tái)驅(qū)動(dòng)來(lái)實(shí)現(xiàn). 驅(qū)動(dòng)后用spi_master對(duì)象來(lái)描述.在設(shè)備驅(qū)動(dòng)中就可以通過(guò)函數(shù)spi_write, spi_read, spi_w8r16, spi_w8r8等函數(shù)來(lái)調(diào)用控制器.

"include/linux/spi/spi.h"http://讓spi->master指向的控制器對(duì)象發(fā)出len個(gè)字節(jié)數(shù)據(jù),數(shù)據(jù)緩沖區(qū)地址由buf指針指向static inline int spi_write(struct spi_device *spi, const void *buf, size_t len);//讓spi->master指向的控制器對(duì)象接收l(shuí)en個(gè)字節(jié)數(shù)據(jù),由buf指向指向的數(shù)據(jù)緩沖區(qū)存放static inline int spi_read(struct spi_device *spi, void *buf, size_t len);//讓spi->master指向的控制器對(duì)象發(fā)出數(shù)據(jù)后再接收數(shù)據(jù)int spi_write_then_read(struct spi_device *spi, const void *txbuf, unsigned n_tx,        void *rxbuf, unsigned n_rx);//讓spi->master控制器對(duì)象同時(shí)收發(fā)8位數(shù)據(jù)static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd);//讓spi->master控制器對(duì)象同時(shí)發(fā)8位,接收16位數(shù)據(jù).static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd);

////////////////////////////////////////////////////////////////
屏:

流程: 命令/數(shù)據(jù) –> spi控制器 —> 屏驅(qū)動(dòng)ic的spi接口 —> ILI9340C(屏的驅(qū)動(dòng)ic) –> 屏
屏的驅(qū)動(dòng)ic的作用:根據(jù)接收到的命令和數(shù)據(jù),配置屏的時(shí)序參數(shù)及在屏上刷出相應(yīng)的像素?cái)?shù)據(jù).
也就是我們只要通過(guò)spi接口把屏的命令和數(shù)據(jù)交給屏的驅(qū)動(dòng)ic即可, 讓驅(qū)動(dòng)IC完成刷屏的操作.
//所有的lcd屏都會(huì)用到驅(qū)動(dòng)IC的

//ILI9340C驅(qū)動(dòng)ic內(nèi)部有配置寄存器,我們需要通過(guò)spi接口配置驅(qū)動(dòng)ic內(nèi)部寄存器的值
模塊的引腳與板的連接:

 reset --> PA8   //用于復(fù)位模塊 D/C   --> PA7   //通過(guò)高低電平來(lái)區(qū)分?jǐn)?shù)據(jù)線(xiàn)上的數(shù)據(jù)類(lèi)型, command:0, data:1 .        //command其實(shí)就是表示數(shù)據(jù)線(xiàn)上發(fā)過(guò)去的是驅(qū)動(dòng)ic內(nèi)部寄存器的地址            //data表示數(shù)據(jù)線(xiàn)上發(fā)過(guò)去的數(shù)據(jù)就是寄存器要設(shè)的值 CS    --> spi0_CS0  //片選線(xiàn) SDI   --> spi0_MOSI   //數(shù)據(jù)線(xiàn),發(fā)出驅(qū)動(dòng)ic的寄存器地址和要設(shè)置的值 SDO   --> spi0_MISO // 如不需要讀取驅(qū)動(dòng)ic寄存器的值,可不接 SCLK  --> spi0_CLK  //時(shí)鐘線(xiàn) LED   --> 3.3v      //背光電源 VCC   --> 3.3v GND   --> GND  

//通過(guò)時(shí)序圖可得知,模塊支持三線(xiàn)/四線(xiàn)的工作方式,四線(xiàn)是用D/C線(xiàn)區(qū)分?jǐn)?shù)據(jù)線(xiàn)上的數(shù)據(jù)是寄存器地址或數(shù)據(jù). spi的工作時(shí)序方式是SPI_MODE_0(CPOL=0, CPHA=0), 也可以得知傳輸是以8位為單位.

//在內(nèi)核里描述spi屏設(shè)備,并通過(guò)spi_board_info的platform_data提供連接屏reset和D/C引腳的GPIO.
描述設(shè)備的代碼:

#include <linux/spi/spi.h>#include <mach/gpio.h>struct sunxi_spi_config {    int bits_per_word; //8bit    int max_speed_hz;  //80MHz    int mode; // pha,pol,LSB,etc..} sunxi_data =  {    8, 10000000, SPI_MODE_0};struct myspi_lcd_pdata {        int dc_io;        int reset_io;}spi_lcd_pdata = {     GPIOA(7), GPIOA(8), };struct spi_board_info spi_infos[] = {     {           .modalias = "myspi_lcd",        .platform_data = &spi_lcd_pdata,            .controller_data = &sunxi_data,        .max_speed_hz = 10000000,        .bus_num = 0,        .chip_select = 0,        .mode = SPI_MODE_0,    },};static void __init sunxi_dev_init(void){    ...    // 在最后一行    spi_register_board_info(spi_infos, ARRAY_SIZE(spi_infos));}

//////////////////////////設(shè)備驅(qū)動(dòng)的實(shí)現(xiàn)//////////////////////////////////

店家提供的c51里初始化屏的驅(qū)動(dòng)代碼:void  write_command(uchar c)  //發(fā)送驅(qū)動(dòng)ic的寄存器地址{    cs=0;    rs=0;  // D/C 低電平    bitdata=c;    sda=bit7;scl=0;scl=1;    sda=bit6;scl=0;scl=1;    sda=bit5;scl=0;scl=1;    sda=bit4;scl=0;scl=1;    sda=bit3;scl=0;scl=1;    sda=bit2;scl=0;scl=1;    sda=bit1;scl=0;scl=1;    sda=bit0;scl=0;scl=1;    cs=1;      }void  write_data(uchar d) //給驅(qū)動(dòng)ic傳輸數(shù)據(jù)使用{    cs=0;    rs=1; //  D/C 高電平    bitdata=d;    sda=bit7;scl=0;scl=1;    sda=bit6;scl=0;scl=1;    sda=bit5;scl=0;scl=1;    sda=bit4;scl=0;scl=1;    sda=bit3;scl=0;scl=1;    sda=bit2;scl=0;scl=1;    sda=bit1;scl=0;scl=1;    sda=bit0;scl=0;scl=1;    cs=1;}void lcd_initial(){        reset=0;        delay(100);        reset=1;        delay(100);        write_command(0xCB);          write_data(0x39);         write_data(0x2C);         write_data(0x00);         write_data(0x34);         write_data(0x02);         write_command(0xCF);          write_data(0x00);         write_data(0XC1);         write_data(0X30);         write_command(0xE8);          write_data(0x85);         write_data(0x00);         write_data(0x78);         write_command(0xEA);          write_data(0x00);         write_data(0x00);         write_command(0xED);          write_data(0x64);         write_data(0x03);         write_data(0X12);         write_data(0X81);         write_command(0xF7);          write_data(0x20);         write_command(0xC0);    //Power control         write_data(0x23);   //VRH[5:0]         write_command(0xC1);    //Power control         write_data(0x10);   //SAP[2:0];BT[3:0]         write_command(0xC5);    //VCM control         write_data(0x3e); //??±è?èμ÷?ú        write_data(0x28);         write_command(0xC7);    //VCM control2         write_data(0x86);  //--        write_command(0x36);    // Memory Access Control         //??2?êy?aoá?áêú?áé??è·?ê??D??1??ü2?êy        //0x48 0x68êú?á        //0x28 0xE8 oá?á        write_data(0x48); //éè????è?êú?áé??è·?ê?        write_command(0x3A);            write_data(0x55);         write_command(0xB1);            write_data(0x00);          write_data(0x18);         write_command(0xB6);    // Display Function Control         write_data(0x08);         write_data(0x82);        write_data(0x27);          write_command(0xF2);    // 3Gamma Function Disable         write_data(0x00);         write_command(0x26);    //Gamma curve selected         write_data(0x01);         write_command(0xE0);    //Set Gamma         write_data(0x0F);         write_data(0x31);         write_data(0x2B);         write_data(0x0C);         write_data(0x0E);         write_data(0x08);         write_data(0x4E);         write_data(0xF1);         write_data(0x37);         write_data(0x07);         write_data(0x10);         write_data(0x03);         write_data(0x0E);         write_data(0x09);         write_data(0x00);         write_command(0XE1);    //Set Gamma         write_data(0x00);         write_data(0x0E);         write_data(0x14);         write_data(0x03);         write_data(0x11);         write_data(0x07);         write_data(0x31);         write_data(0xC1);         write_data(0x48);         write_data(0x08);         write_data(0x0F);         write_data(0x0C);         write_data(0x31);         write_data(0x36);         write_data(0x0F);         write_command(0x11);    //Exit Sleep         delay(120);         write_command(0x29);    //Display on         write_command(0x2c); } 

///////////////////////////////////////
參考上面驅(qū)動(dòng)代碼實(shí)現(xiàn)的linux設(shè)備驅(qū)動(dòng):

#include <linux/init.h>#include <linux/module.h>#include <linux/spi/spi.h>#include <linux/delay.h>#include <linux/gpio.h>struct myspi_lcd_pdata {        int dc_io;        int reset_io;};struct spi_lcd_cmd{    u8  reg_addr; // command    u8  len;  //需要從spi_lcd_datas數(shù)組里發(fā)出數(shù)據(jù)字節(jié)數(shù)    int delay_ms; //此命令發(fā)送數(shù)據(jù)完成后,需延時(shí)多久}cmds[] = {    {0xCB, 5, 0},    {0xCF, 3, 0},    {0xEB, 3, 0},    {0xEA, 2, 0},    {0xED, 4, 0},    {0xF7, 1, 0},    {0xC0, 1, 0},    {0xC1, 1, 0},    {0xC5, 2, 0},    {0xC7, 1, 0},    {0x36, 1, 0},    {0x3A, 1, 0},    {0xB1, 2, 0},    {0xB6, 3, 0},    {0xF2, 1, 0},    {0x26, 1, 0},    {0xE0, 15, 0},    {0xE1, 15, 0},    {0x11, 0,  120},    {0x29, 0, 0},    {0x2c, 0, 0},};u8 spi_lcd_datas[] = {    0x39, 0x2c, 0x00, 0x34, 0x20,           // command: 0xCB要發(fā)出的數(shù)據(jù)    0x00, 0xC1, 0x30,                       // command: 0xCF    0x85, 0x00, 0x78,                       // command: 0xEB    0x00, 0x00,                             // command: 0xEA    0x64, 0x03, 0x12, 0x81,                 // command: 0xED     0x20,                                   // command: 0xF7    0x23,                                   // command: 0xC0    0x10,                                   // command: 0xC1    0x3e, 0x28,                             // command: 0xC5    0x86,                                   // command: 0xC7    0x48,                                   // command: 0x36    0x55,                                   // command: 0x3A    0x00, 0x18,                             // command: 0xB1    0x08, 0x82, 0x27,                       // command: 0xB6    0x00,                                   // command: 0xF2    0x01,                                   // command: 0x26    0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,                           //command: 0xE0    0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, //command: 0xE1};void write_command(struct spi_device *spi, u8 cmd){    struct myspi_lcd_pdata *pdata = spi->dev.platform_data;    // dc , command:0    gpio_direction_output(pdata->dc_io, 0);     spi_write(spi, &cmd, 1);}void write_data(struct spi_device *spi, u8 data){    struct myspi_lcd_pdata *pdata = spi->dev.platform_data;    // dc , data:1    gpio_direction_output(pdata->dc_io, 1);     spi_write(spi, &data, 1);}//初始化spi_lcdvoid spi_lcd_init(struct spi_device *spi){    struct myspi_lcd_pdata *pdata = spi->dev.platform_data;    int i, j, n;    // 屏復(fù)位    gpio_direction_output(pdata->reset_io, 0);    mdelay(100);    gpio_set_value(pdata->reset_io, 1);    mdelay(100);    n = 0; // n用于記錄數(shù)據(jù)數(shù)組spi_lcd_datas的位置    //發(fā)命令,并發(fā)出命令所需的數(shù)據(jù)    for (i = 0; i < ARRAY_SIZE(cmds); i++) //命令    {        write_command(spi, cmds[i].reg_addr);        for (j = 0; j < cmds[i].len; j++) //發(fā)出命令后,需要發(fā)出的數(shù)據(jù)            write_data(spi, spi_lcd_datas[n++]);        if (cmds[i].delay_ms) //如有延時(shí)則延時(shí)            mdelay(cmds[i].delay_ms);    }}//設(shè)置要刷屏的開(kāi)始坐標(biāo)void addset(struct spi_device *spi, unsigned int x,unsigned int y){        write_command(spi, 0x2a); //發(fā)出x坐標(biāo)        write_data(spi, x>>8);        write_data(spi, x&0xff);        write_command(spi, 0x2b); //發(fā)出y坐標(biāo)        write_data(spi, y>>8);        write_data(spi, y&0xff);        write_command(spi, 0x2c);}int myprobe(struct spi_device *spi){       struct myspi_lcd_pdata *pdata = spi->dev.platform_data;    int ret;    int x, y;    u16 color0 = 0x001f; // RGB565, blue        u16 color1 = 0xf800; // red    u16 color2 = 0x07e0; // green    u16 color3 = 0xffff; // white    u16 color;    ret = gpio_request(pdata->reset_io, spi->modalias);    if (ret < 0)        goto err0;    ret = gpio_request(pdata->dc_io, spi->modalias);    if (ret < 0)        goto err1;    spi_lcd_init(spi); //初始化屏    addset(spi, 0, 0); //從屏的0,0坐標(biāo)開(kāi)始刷//刷屏, 把整屏分成4塊,每塊顏色不同//  gpio_direction_output(pdata->dc_io, 1);     for (y = 0; y < 320; y++)    {        for (x = 0; x < 240; x++)        {            if (x < 120)                color = (y < 160) ? color0 : color1;             else                color = (y < 160) ? color2 : color3;             write_data(spi, color >> 8);            write_data(spi, color & 0xff);        }    }    printk("probe ...%s\n", spi->modalias);    return 0;err1:    gpio_free(pdata->reset_io);err0:    return ret;}int myremove(struct spi_device *spi){    struct myspi_lcd_pdata *pdata = spi->dev.platform_data;    gpio_free(pdata->dc_io);    gpio_free(pdata->reset_io);    printk("%s remove\n", spi->modalias);    return 0;}struct spi_device_id ids[] = {    {"myspi_lcd"},    {},};struct spi_driver myspi_drv = {    .driver = {        .owner = THIS_MODULE,        .name = "myspi_drv",    },    .probe = myprobe,    .remove = myremove,    .id_table = ids,};module_spi_driver(myspi_drv);MODULE_LICENSE("GPL");

效果圖:

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
lpc1788移植u
I2C總線(xiàn)傳輸協(xié)議
超全!UART、SPI、I2C通信協(xié)議入門(mén)教程
SPI 與 I2C 協(xié)議的差異和需要考慮的事項(xiàng)
Micron sensor 驅(qū)動(dòng)與調(diào)試小結(jié)
arm 課堂復(fù)習(xí)筆記 day06
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服