hlxldb

单片机控制诺基亚2600彩屏(五)

0
阅读(1887)

 

Step 5AVR - Outputting 9-bit SPI with Inline Assembly

To implement the 9-bit protocol using an AVR, I found a nice ASM function in the SparkFun example code.  I modified the code some to clean it up and adapt it for the Phillips controller.  This ASM code is more efficient than using regular C and allows faster LCD writes.

It uses ATMega168 pins 11, 12, 13, and 14.
11 - Data
12 - Clock
13 - Chip Select
14 - Reset (not covered by this function)

void soft_spi_send_byte(char cmd, char data)
{
     // enable chip_sel
    asm("cbi %0, 7" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send the command flag bit
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 0" : : "a" (cmd));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send Bit 7 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 7" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send Bit 6 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 6" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 5 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 5" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 4 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 4" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 3 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 3" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 2 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 2" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 1 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 1" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // Send bit 0 of data
    asm("cbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("cbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbrc %0, 0" : : "a" (data));
    asm("sbi %0, 5" : : "I" (_SFR_IO_ADDR(PORTD)));
    asm("sbi %0, 6" : : "I" (_SFR_IO_ADDR(PORTD)));

    // disable chip_sel
    asm("sbi %0, 7" : : "I" (_SFR_IO_ADDR(PORTD)));
}

The following defines are used to make sending data and commands easier:

#define color_lcd_send_cmd(cmd)    soft_spi_send_byte(0, cmd)
#define color_lcd_send_data(data)    soft_spi_send_byte(1, data)