SPI简介
SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。 SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。
- SDO(MOSI): 主设备数据输出,从设备数据输入
- SDI(MISO):主设备数据输入,从设备数据输出
- SCLK : 时钟信号,由主设备产生
- CS :从设备使能信号,由主设备控制
SCPH=0,SCPOL=0 的 SPI 协议时序图
SCPH=1,SCPOL=0 的 SPI 协议时序图
SCPH=0,SCPOL=1 的 SPI 协议时序图
SCPH=1,SCPOL=1 的 SPI 协议时序图
GPIO模拟
定义出MISO、MOSI、CS、CLK等
#define CS_GPIO (0)
#define CLK_GPIO (1)
#define MOSI_GPIO (2)
#define MISO_GPIO (3)
#define IRQ_GPIO (4)
#define CS(a) Set_SPI_Related_Gpio(a, CS_GPIO)
#define DCLK(a) Set_SPI_Related_Gpio(a, CLK_GPIO)
#define DIN(a) Set_SPI_Related_Gpio(a, MOSI_GPIO)
#define DOUT() Get_SPI_Related_Gpio(MISO_GPIO)
往从设备发送数据
void WriteByteSPI(unsigned char byte)
{
unsigned char buf;
unsigned char i;
CS(0);
for(i=0;i<8;i++)
{
buf=(byte>>(7-i))&0x1;
DIN(buf);
DCLK(0);
DCLK(1);
}
CS(1);
}
从设备读取数据
static unsigned short ReadByteSPI(void)
{
unsigned short buf=0,temp;
unsigned char i;
uint level = 0;
DIN(0);
DCLK(1);
CS(0);
for(i=0;i<8;i++)
{
DCLK(0);
level = DOUT();
temp= (level) ? 1:0;
buf|=(temp<<(7-i));
DCLK(0);
DCLK(1);
}
CS(1);
buf&=0xff;
return(buf);
}
stm32上完整demo
#include "HAL_conf.h"
#define SPI_CS(a) \
if (a) \
GPIOA->BSRR = GPIO_Pin_4; \
else \
GPIOA->BRR = GPIO_Pin_4;
#define SPI_DCLK(a) \
if (a) \
GPIOA->BSRR = GPIO_Pin_5; \
else \
GPIOA->BRR = GPIO_Pin_5;
#define SPI_SDA(a) \
if (a) \
GPIOA->BSRR = GPIO_Pin_7; \
else \
GPIOA->BRR = GPIO_Pin_7;
#define lcd_RS(a) \
if (a) \
GPIOA->BSRR = GPIO_Pin_3; \
else \
GPIOA->BRR = GPIO_Pin_3;
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40
#define BRRED 0XFC07
#define GRAY 0X8430
void LCD_Initial(void);
void Delayms(unsigned short time);
void LCD_WriteRegIndex(unsigned char Index);
void LCD_WriteData(unsigned short dat);
void LCD_WR_REG(u16 Index,u16 CongfigTemp);
void Lcd_SetCursor(u16 x,u16 y);
void SPILCD_SetWindow(unsigned short xstat,unsigned short xend,unsigned short ystat,unsigned short yend);
void SPILCD_DrawPoint(unsigned short x,unsigned short y,unsigned short color);
void SPILCD_Clear(unsigned short Color);
void SPILCD_Clear_Fast(unsigned char single_Color);
void SPILCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color);
void SPILCD_DrawLine(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short color);
void SPILCD_ShowChar(unsigned short x,unsigned short y,unsigned char num, unsigned int fColor, unsigned int bColor,unsigned char flag) ;
void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int fColor, unsigned int bColor,unsigned char flag);
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic);
#include "LCD.h"
#include "ASCII.h"
#include "GB1616.h"
#define SPILCD_W 176
#define SPILCD_H 220
void Delayms(unsigned short time)
{
unsigned short i,j;
for(i=0;i<time;i++)
for(j=0;j<5000;j++) ;
}
void LCD_WriteByteSPI(unsigned char byte)
{
unsigned char buf;
unsigned char i;
for(i=0;i<8;i++)
{
buf=(byte>>(7-i))&0x1;
SPI_SDA(buf);
SPI_DCLK(0);
SPI_DCLK(1);
}
}
void LCD_WriteoneSPI(unsigned char byte)
{
unsigned char buf;
unsigned char i;
for(i=0;i<4;i++)
{
buf=(byte>>(3-i))&0x1;
SPI_SDA(buf);
SPI_DCLK(0);
SPI_DCLK(1);
}
}
void WriteComm(unsigned char dat)
{
lcd_RS(0);
LCD_WriteByteSPI(dat);
lcd_RS(1);
}
void LCD_WriteRegIndex(unsigned char Index)
{
lcd_RS(0);
LCD_WriteByteSPI(Index);
lcd_RS(1);
}
void LCD_WriteData(unsigned short dat)
{
LCD_WriteByteSPI(dat>>8);
LCD_WriteByteSPI(dat);
}
void LCD_WR_REG(u16 Index,u16 CongfigTemp)
{
LCD_WriteRegIndex(Index);
LCD_WriteByteSPI(CongfigTemp);
}
void LCD_Initial(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_2);
LCD_WR_REG(0x1A,0x02);
LCD_WR_REG(0x1B,0x88);
LCD_WR_REG(0x23,0x00);
LCD_WR_REG(0x24,0xEE);
LCD_WR_REG(0x25,0x15);
LCD_WR_REG(0x2D,0x03);
LCD_WR_REG(0x18,0x1E);
LCD_WR_REG(0x19,0x01);
LCD_WR_REG(0x01,0x00);
LCD_WR_REG(0x1F,0x88);
Delayms(5);
LCD_WR_REG(0x1F,0x80);
Delayms(5);
LCD_WR_REG(0x1F,0x90);
Delayms(5);
LCD_WR_REG(0x1F,0xD0);
Delayms(5);
LCD_WR_REG(0x2F,0x00);
LCD_WR_REG(0x17,0x05);
LCD_WR_REG(0x16,0xA0);
LCD_WR_REG(0x36,0x09);
LCD_WR_REG(0x29,0x31);
LCD_WR_REG(0x71,0x1A);
LCD_WR_REG(0x40,0x01);
LCD_WR_REG(0x41,0x08);
LCD_WR_REG(0x42,0x04);
LCD_WR_REG(0x43,0x2D);
LCD_WR_REG(0x44,0x30);
LCD_WR_REG(0x45,0x3E);
LCD_WR_REG(0x46,0x02);
LCD_WR_REG(0x47,0x69);
LCD_WR_REG(0x48,0x07);
LCD_WR_REG(0x49,0x0E);
LCD_WR_REG(0x4A,0x12);
LCD_WR_REG(0x4B,0x14);
LCD_WR_REG(0x4C,0x17);
LCD_WR_REG(0x50,0x01);
LCD_WR_REG(0x51,0x0F);
LCD_WR_REG(0x52,0x12);
LCD_WR_REG(0x53,0x3B);
LCD_WR_REG(0x54,0x37);
LCD_WR_REG(0x55,0x3E);
LCD_WR_REG(0x56,0x16);
LCD_WR_REG(0x57,0x7D);
LCD_WR_REG(0x58,0x08);
LCD_WR_REG(0x59,0x0B);
LCD_WR_REG(0x5A,0x0D);
LCD_WR_REG(0x5B,0x11);
LCD_WR_REG(0x5C,0x18);
LCD_WR_REG(0x5D,0xFF);
LCD_WR_REG(0x1B,0x001a);
LCD_WR_REG(0x25,0x0055);
LCD_WR_REG(0x1A,0x0010);
LCD_WR_REG(0x1E,0x0038);
LCD_WR_REG(0x28,0x38);
Delayms(40);
LCD_WR_REG(0x28,0x3C);
WriteComm(0x22);
}
void Lcd_SetCursor(u16 x,u16 y)
{
LCD_WriteRegIndex(0x20);
LCD_WriteData(x);
LCD_WriteRegIndex(0x21);
LCD_WriteData(y);
}
void SPILCD_SetWindow(unsigned short xstat,unsigned short xend,unsigned short ystat,unsigned short yend)
{
LCD_WR_REG(0x02,xstat>>8);
LCD_WR_REG(0x03,xstat&0xff);
LCD_WR_REG(0x04,xend>>8);
LCD_WR_REG(0x05,xend&0xff);
LCD_WR_REG(0x06,ystat>>8);
LCD_WR_REG(0x07,ystat&0xff);
LCD_WR_REG(0x08,yend>>8);
LCD_WR_REG(0x09,yend&0xff);
WriteComm(0x22);
}
void SPILCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color)
{
unsigned short i,j;
SPILCD_SetWindow(xsta,xend-1,ysta,yend-1);
for(i=xsta;i<=xend;i++)
for(j=ysta;j<=yend;j++)
{
LCD_WriteData(color);
}
}
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic)
{
unsigned long i,j;
j=pic_H*pic_V*2;
SPILCD_SetWindow(x,x+pic_H-1,y,y+pic_V-1);
for (i = 0; i < j; i++)
{
LCD_WriteByteSPI(pic[i]);
}
}
void DrawPixel(u16 x, u16 y, int Color)
{
SPILCD_SetWindow(x,x,y,y);
LCD_WriteData(Color);
}
void SPILCD_ShowChar(unsigned short x,unsigned short y,unsigned char num, unsigned int fColor, unsigned int bColor,unsigned char flag)
{
unsigned char temp;
unsigned int pos,i,j;
num=num-' ';
i=num*16;
for(pos=0;pos<16;pos++)
{
temp=nAsciiDot[i+pos];
for(j=0;j<8;j++)
{
if(temp&0x80)
DrawPixel(x+j,y,fColor);
else
if(flag) DrawPixel(x+j,y,bColor);
temp<<=1;
}
y++;
}
}
void PutGB1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int fColor,unsigned int bColor,unsigned char flag)
{
unsigned int i,j,k;
unsigned short m;
for (k=0;k<64;k++) {
if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1]))
{
for(i=0;i<32;i++)
{
m=codeGB_16[k].Msk[i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80) {
DrawPixel(x+j,y,fColor);
}
else {
if(flag) DrawPixel(x+j,y,bColor);
}
m=m<<1;
}
if(i%2){y++;x=x-8;}
else x=x+8;
}
}
}
}
void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int fColor, unsigned int bColor,unsigned char flag)
{
unsigned char l=0;
while(*s)
{
if( *s < (char)0x80)
{
SPILCD_ShowChar(x+l*8,y,*s,fColor,bColor,flag);
s++;l++;
}
else
{
PutGB1616(x+l*8,y,(unsigned char*)s,fColor,bColor,flag);
s+=2;l+=2;
}
}
}
|