LPC824-SPI interface (continued three)

Publisher:温馨家园Latest update time:2023-05-24 Source: elecfansKeywords:LPC824 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

In the SPI interface, judging the level of the transmitted data bits is measured by the clock. According to the rising edge/falling edge of the clock and the maintenance/change of the data level, 4 methods can be combined, as shown in the figure below Show.

As can be seen from the above figure, the clock phase CPHA determines when the transmitted data level is sampled and when it can be changed, and the clock polarity CPOL determines whether the clock is low-level idle or high-level idle. In the figure above, when CPHA=0, when the clock jumps from the idle state (CPOL=0 is an up jump, CPOL=1 is a down jump), the level of the data bit is sampled. When the clock jumps to the idle state When (CPOL=0 is a down jump, CPOL=1 is an up jump), the level change on the data bit is allowed. When CPHA=1, when the clock jumps from the idle state (CPOL=0 is an up jump, CPOL=1 is a down jump), the level on the data bit is allowed to change. When the clock jumps to the idle state (CPOL =0 for down jump, CPOL=1 for up jump), sampling the level of data bits. The specific 4 modes are shown in the table below.

As for which mode to use for SPI, it depends on the actual SPI device. Generally speaking, mode 3 is more common.

Next let's look at a practical example of using the SPI interface. LPC824 is used to drive an SPI interface LCD screen for image display. Nokia's 5110 LCD screen is used here, and a five-pointed star graphic is required to be displayed on the screen.
The 5110 LCD screen has 4032 pixels and can display 15 Chinese characters or 84 ASCII characters at the same time. It has a simple SPI interface, ultra-low power consumption, and ultra-fast speed, so it is very popular. During actual wiring, since the SPI0 interface pin of LPC824 is not led to a physical pin by default, the physical pin can be flexibly selected according to the specific situation during actual configuration. In addition, the SPI interface of the 5110 LCD screen does not have a MISO port, so you do not need to connect this port when connecting. In this example, the specified connection method is defined as follows:
SCK<——>SCK0 (PIO0_20)
DIN<——>MOSI0 (PIO0_21)
SCE<——>SSEL0 (PIO0_14)
DC<——>PIO0_6
RST<—— >PIO0_22
Finally, connect the power supply to the LCD screen. The working voltage of the LCD screen is 3.3V.

The reference program code is as follows:

#include

#define SPI_CFG_ENABLE (0x1)

#define SPI_CFG_MASTER (0x4)

#define SPI_STAT_RXRDY (0x1)

#define SPI_STAT_TXRDY (0x2)

#define SPI_STAT_SSD (0x20)

#define SPI_STAT_MSTIDLE (0x100)

#define SPI_TXDATCTL_SSEL_N(s) ((s) << 16)

#define SPI_TXDATCTL_EOT (1 << 20)

#define SPI_TXDATCTL_EOF (1 << 21)

#define SPI_TXDATCTL_RXIGNORE (1 << 22)

#define SPI_TXDATCTL_FLEN(l) ((l) << 24)


uint8_t const bmp[]={0xE0,0xF0,0xF0,0xF0,0xF0,0xFC,0xFE,0xFF,0xFF,0xFF,0xFC,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x01,0x7B,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x7F,0x7F,0xFF,0xFF,0x7F,0x01,0x00};


void Port_init(void)

{

    LPC_GPIO_PORT->DIR0 |= 0x400040; //Set the port as the output direction

}    

    

void Spi0_init(void)

{

    LPC_SYSCON->SYSAHBCLKCTRL|=1<<7; //Enable SWM clock

    LPC_SWM->PINASSIGN3 &= ~0xFFFFFFFF;

    LPC_SWM->PINASSIGN3 |= 0x14<<24;

    LPC_SWM->PINASSIGN4 &= ~0xFFFFFFFF;

    LPC_SWM->PINASSIGN4 |= 0x15 | (0x0e<<16);

    LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<7); //Turn off the SWM clock (remember to turn it off after use to save power consumption)

    LPC_SYSCON->SYSAHBCLKCTRL |= 1<<11; //Turn on the SPI0 clock

    LPC_SYSCON->PRESETCTRL &= ~(1<<0); //Turn on reset SPI0

    LPC_SYSCON->PRESETCTRL |= (1<<0); //Close reset SPI0

    LPC_SPI0->DIV = 6;

    LPC_SPI0->CFG = SPI_CFG_MASTER | SPI_CFG_ENABLE;

}


void SPI_MasterTransmit(uint8_t Data)

{

    while(~LPC_SPI0->STAT & SPI_STAT_TXRDY);

    LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FLEN(7) | SPI_TXDATCTL_RXIGNORE | SPI_TXDATCTL_EOT | SPI_TXDATCTL_SSEL_N(0xe) | Data;

    while(~LPC_SPI0->STAT & SPI_STAT_MSTIDLE);

}


void LCD_write_byte(uint8_t dat,uint8_t command)

{

    if(command==0)

        LPC_GPIO_PORT->PIN0 &= ~(1<<6);

    else

            LPC_GPIO_PORT->PIN0 |= (1<<6);

    SPI_MasterTransmit(dat); //Send data 

}    

    

void LCD_set_XY(uint8_t X,uint8_t Y)

{

    LCD_write_byte(0x40|Y,0); //Write the vertical coordinate address (refer to the basic command, the 6th bit must be written as 1, so 0x40 is required)

    LCD_write_byte(0x80|

}


void LCD_draw_bmp_pixel(uint8_t X,uint8_t Y,uint8_t const *map,uint8_t Pix_x,uint8_t Pix_y)

{

    uint16_t i,n;

    uint8_t row;

    if(Pix_y%8 == 0)

        row = Pix_y/8; //If the vertical pixel coordinate is less than 8, the row value is 1

    else

        row = Pix_y/8+1; //If the vertical pixel coordinate is greater than 8, the row value is a multiple of 8 plus 1

    LCD_set_XY(X,Y);

    for(n=0;n        {

            for(i=0;i                 {

                        LCD_set_XY(X+i,Y+n); //Set the coordinates of the display area

                        LCD_write_byte(map[i+n*Pix_x],1); //Get values ​​from the image array in order to display

                 }

         }

}


void LCD_clear(void)

{

    uint8_t t,k;

    LCD_set_XY(0,0); //Start from the upper left corner

    for(t=0;t<=6;t++)

        {

            for(k=0;k<84;k++) //all the way to the bottom right corner

                LCD_write_byte(0,1); //Write display data 0 to clear the screen

         }

}


void delay_us(uint32_t us)

{

    SysTick->LOAD = (((12)*us)-1); //Load initial value

    SysTick->VAL = 0; //Write the current value register to clear it.

    SysTick->CTRL |= (1<<0); //Start the timer and select half system clock

    while(!(SysTick->CTRL & 0x10000)); //Loop query and wait for the timer to expire

    SysTick->CTRL &= ~(1<<0); //Close the timer

}


void delay_ms(uint32_t ms)

{

    SysTick->LOAD = (((12000)*ms)-1); //Load initial value

    SysTick->VAL = 0; //Write the current value register to clear it.

    SysTick->CTRL |= (1<<0); //Start the timer and select half system clock

    while(!(SysTick->CTRL & 0x10000)); //Loop query and wait for the timer to expire

    SysTick->CTRL &= ~(1<<0); //Close the timer

}


void LCD_init(void)

{

    LPC_GPIO_PORT->PIN0 &= ~(1<<22);

    delay_us(5); //Reset width

    LPC_GPIO_PORT->PIN0 |= (1<<22);

    LCD_write_byte(0x21,0); //Power-on mode, horizontal addressing, extended instruction set

    LCD_write_byte(0xbe,0); //Set the bias voltage

    LCD_write_byte(0x06,0); //Set the temperature coefficient

    LCD_write_byte(0x13,0); //Set the 1:48 mixing ratio

    LCD_write_byte(0x20,0); //Restore to basic instruction set mode

    LCD_clear(); //Clear the screen

    LCD_write_byte(0x0c,0); //Normal display mode

}


int main(void)

{

    Port_init(); //Port initialization

    Spi0_init(); //SPI initialization

    LCD_init(); //LCD initialization

    delay_ms(15); //Delay

    LCD_draw_bmp_pixel(0,0,bmp,16,16); //Display a five-pointed star in the upper left corner

    while(1)

        ;

}

Compile the above program and download it to LPC824. Connect the 5110 LCD screen according to the above requirements and power on the system. You can see the following pattern on the display, indicating that the SPI interface is working properly.

 


Keywords:LPC824 Reference address:LPC824-SPI interface (continued three)

Previous article:LPC824-I2C interface
Next article:LPC824-SPI interface (continued 2)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号