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.
Previous article:LPC824-I2C interface
Next article:LPC824-SPI interface (continued 2)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Evaluation Weekly Report 20220207: How many days are left to apply for Qinheng ch582 and Pingtouge Linux RISC-V kit
- About Modbus slave response packet address
- ESD resistance of capacitors
- Date in spring + small flowers blooming in the spring bushes
- [Sipeed LicheeRV 86 Panel Review] Debian Python + Serial Communication
- What is the 5G battle about?
- Zero-based development of WIFI devices
- A detailed description of the development history of Bluetooth technology from 1.0 to 5.0
- Fundamentals of mmWave Sensors (mmWave Training Series)
- Tuya Smart Module SDK Development Course Series - 2. Introduction to Tuya IoT Platform