国民技术-N32G43XCL-SPI DMA来驱动240X240的ST7789的一个小LCD~LCD电路:
// GND 电源地
// VCC 3.3v电源
// SCL PA5(SCLK)
// SDA PA7(MOSI)
// RES PA1
// DC PA2
// BLK PA3
其中仅用到SPI1的SCLK 及MOSI ,即仅发送模式。
下面配置SPI:
	void SPI1_Init(void)
	{
	        GPIO_InitType GPIO_InitStructure;
	        SPI_InitType SPI_InitStructure;
	  RCC_ConfigPclk2(RCC_HCLK_DIV2);
	        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_SPI1, ENABLE);//使能SPI1
	        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA|RCC_APB2_PERIPH_AFIO, ENABLE);//使能GPIOA
	  GPIO_InitStruct(&GPIO_InitStructure);
	        GPIO_InitStructure.Pin =GPIO_PIN_5|GPIO_PIN_7;
	        GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
	        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         //复用推挽输出
	  GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_SPI1;
	        GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure); //初始化GPIOA
	        GPIO_SetBits(GPIOA,GPIO_PIN_5|GPIO_PIN_7);
	        SPI_InitStructure.DataDirection = SPI_DIR_SINGLELINE_TX;//只发送模式
	        SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;//设置SPI工作模式:主机模式
	        SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;//设置SPI数据大小:8位帧结构
	        SPI_InitStructure.CLKPOL        = SPI_CLKPOL_HIGH;//串行同步时钟空闲时SCLK位高电平
	        SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;//串行同步时钟空第二个时钟沿捕获
	        SPI_InitStructure.NSS           = SPI_NSS_SOFT;//NSS信号由软件管理
	        SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_2;//波特率预分频值:波特率预分频值为2
	        SPI_InitStructure.FirstBit      = SPI_FB_MSB;//数据传输高位先行
	        SPI_InitStructure.CRCPoly = 7;//CRC值计算的多项式
	        SPI_Init(SPI1,&SPI_InitStructure);//初始化SPI
	        SPI_Enable(SPI1, ENABLE);//使能SPI
	}
	参看产品手册SPI1挂在APB2总线  最高54M,这里用最大的2分频~
下面进行DMA配置,这了我们配置2种模式:
1、正常的数据地址递增,外设地址不变 这种模式发送大量数据刷屏
2、正常数据地址固定,外设地址固定 这种情况适合单一颜色刷屏
	
		 
	
		        
	
		                  
	
		 
	
		        
	
		 
	
下面进行DMA配置,这了我们配置2种模式:
1、正常的数据地址递增,外设地址不变 这种模式发送大量数据刷屏
2、正常数据地址固定,外设地址固定 这种情况适合单一颜色刷屏
		DMA_InitType DMA_InitStructure;
	
		u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度          单次最大65535   
	
		//DMA1的各通道配置
	
		//这里的传输形式是固定的,这点要根据不同的情况来修改
	
		//从存储器->外设模式/8位数据宽度/存储器增量模式
	
		//DMA_CHx:DMA通道CHx
	
		//cpar:外设地址
	
		//cmar:存储器地址
	
		//cndtr:数据传输量 
	
		void MYDMA_Config(DMA_ChannelType* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
	
		{
	
		         RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);        //使能DMA传输
	
		  DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	
		        DMA1_MEM_LEN=cndtr;
	
		        DMA_InitStructure.PeriphAddr      = cpar;  //DMA外设ADC基地址
	
		        DMA_InitStructure.MemAddr         = cmar;  //DMA内存基地址
	
		        DMA_InitStructure.Direction       = DMA_DIR_PERIPH_DST;  //数据传输方向,从内存读取发送到外设
	
		        DMA_InitStructure.BufSize         = cndtr;  //DMA通道的DMA缓存的大小
	
		        DMA_InitStructure.PeriphInc       = DMA_PERIPH_INC_DISABLE;  //外设地址寄存器不变
	
		        DMA_InitStructure.DMA_MemoryInc   = DMA_MEM_INC_ENABLE;  //内存地址寄存器递增
	
		        DMA_InitStructure.PeriphDataSize  = DMA_PERIPH_DATA_SIZE_BYTE;  //数据宽度为8位
	
		        DMA_InitStructure.MemDataSize     = DMA_MemoryDataSize_Byte; //数据宽度为8位
	
		        DMA_InitStructure.CircularMode    = DMA_MODE_NORMAL;  //工作在正常缓存模式
	
		        DMA_InitStructure.Priority        = DMA_PRIORITY_MEDIUM; //DMA通道 x拥有中优先级 
	
		        DMA_InitStructure.Mem2Mem         = DMA_M2M_DISABLE;  //DMA通道x没有设置为内存到内存传输
	
		        DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
	
		} 
	
		void MYDMA_Config1(DMA_ChannelType* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
	
		{
	
		         RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);        //使能DMA传输
	
		  DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	
		        DMA1_MEM_LEN=cndtr;
	
		        DMA_InitStructure.PeriphAddr      = cpar;  //DMA外设ADC基地址
	
		        DMA_InitStructure.MemAddr         = cmar;  //DMA内存基地址
	
		        DMA_InitStructure.Direction       = DMA_DIR_PERIPH_DST;  //数据传输方向,从内存读取发送到外设
	
		        DMA_InitStructure.BufSize         = cndtr;  //DMA通道的DMA缓存的大小
	
		        DMA_InitStructure.PeriphInc       = DMA_PERIPH_INC_DISABLE;  //外设地址寄存器不变
	
		        DMA_InitStructure.DMA_MemoryInc   = DMA_MEM_INC_DISABLE;  //内存地址寄存器不变
	
		        DMA_InitStructure.PeriphDataSize  = DMA_PERIPH_DATA_SIZE_HALFWORD;  //数据宽度为16位
	
		        DMA_InitStructure.MemDataSize     = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
	
		        DMA_InitStructure.CircularMode    = DMA_MODE_NORMAL;  //工作在正常缓存模式
	
		        DMA_InitStructure.Priority        = DMA_PRIORITY_MEDIUM; //DMA通道 x拥有中优先级 
	
		        DMA_InitStructure.Mem2Mem         = DMA_M2M_DISABLE;  //DMA通道x没有设置为内存到内存传输
	
		        DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
	
		} 
	
		//开启一次DMA传输
	
		void MYDMA_Enable(DMA_ChannelType*DMA_CHx)
	
		{ 
	
		        DMA_EnableChannel(DMA_CHx, DISABLE );
	
		  /*从新设置发送数量*/
	
		         DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);
	
		  /* Enable DMA ChannelX */
	
		  DMA_RequestRemap(DMA_REMAP_SPI1_TX,DMA, DMA_CHx, ENABLE);
	
		         DMA_EnableChannel(DMA_CHx, ENABLE);
	
		}        
	
		下面对屏幕进行操作:
屏幕基本操作相关:
		
			 
		
			  
		
			  
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			        
		
			        
		
			        
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
			 
		
屏幕基本操作相关:
			#include "lcd_init.h"
		
			#include "delay.h"
		
			#include "spi.h"
		
			void LCD_GPIO_Init(void)
		
			{
		
			        GPIO_InitType  GPIO_InitStructure;
		
			         RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);         //使能A端口时钟
		
			  GPIO_InitStruct(&GPIO_InitStructure);
		
			        GPIO_InitStructure.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;         
		
			         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
		
			        GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
		
			         GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);          //初始化GPIOA
		
			         GPIO_SetBits(GPIOA,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
		
			}
		
			void delay(int t)
		
			{
		
			        while(t--);
		
			}
		
			/******************************************************************************
		
			      函数说明:LCD串行数据写入函数
		
			      入口数据:dat  要写入的串行数据
		
			      返回值:  无
		
			******************************************************************************/
		
			void LCD_Writ_Bus(u8 dat) 
		
			{        
		
			  while(SPI_I2S_GetStatus(SPI1, SPI_I2S_TE_FLAG) == RESET);//检查接收标志位
		
			        SPI_I2S_TransmitData(SPI1,dat);
		
			        delay(1);
		
			}
		
			/******************************************************************************
		
			      函数说明:LCD写入数据
		
			      入口数据:dat 写入的数据
		
			      返回值:  无
		
			******************************************************************************/
		
			void LCD_WR_DATA8(u8 dat)
		
			{
		
			        LCD_Writ_Bus(dat);
		
			}
		
			/******************************************************************************
		
			      函数说明:LCD写入数据
		
			      入口数据:dat 写入的数据
		
			      返回值:  无
		
			******************************************************************************/
		
			void LCD_WR_DATA(u16 dat)
		
			{
		
			        LCD_Writ_Bus(dat>>8);
		
			        LCD_Writ_Bus(dat);
		
			}
		
			/******************************************************************************
		
			      函数说明:LCD写入命令
		
			      入口数据:dat 写入的命令
		
			      返回值:  无
		
			******************************************************************************/
		
			void LCD_WR_REG(u8 dat)
		
			{
		
			        LCD_DC_Clr();//写命令
		
			        LCD_Writ_Bus(dat);
		
			        LCD_DC_Set();//写数据
		
			}
		
			/******************************************************************************
		
			      函数说明:设置起始和结束地址
		
			      入口数据:x1,x2 设置列的起始和结束地址
		
			                y1,y2 设置行的起始和结束地址
		
			      返回值:  无
		
			******************************************************************************/
		
			void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
		
			{
		
			        if(USE_HORIZONTAL==0)
		
			        {
		
			                LCD_WR_REG(0x2a);//列地址设置
		
			                LCD_WR_DATA(x1);
		
			                LCD_WR_DATA(x2);
		
			                LCD_WR_REG(0x2b);//行地址设置
		
			                LCD_WR_DATA(y1);
		
			                LCD_WR_DATA(y2);
		
			                LCD_WR_REG(0x2c);//储存器写
		
			        }
		
			        else if(USE_HORIZONTAL==1)
		
			        {
		
			                LCD_WR_REG(0x2a);//列地址设置
		
			                LCD_WR_DATA(x1);
		
			                LCD_WR_DATA(x2);
		
			                LCD_WR_REG(0x2b);//行地址设置
		
			                LCD_WR_DATA(y1+80);
		
			                LCD_WR_DATA(y2+80);
		
			                LCD_WR_REG(0x2c);//储存器写
		
			        }
		
			        else if(USE_HORIZONTAL==2)
		
			        {
		
			                LCD_WR_REG(0x2a);//列地址设置
		
			                LCD_WR_DATA(x1);
		
			                LCD_WR_DATA(x2);
		
			                LCD_WR_REG(0x2b);//行地址设置
		
			                LCD_WR_DATA(y1);
		
			                LCD_WR_DATA(y2);
		
			                LCD_WR_REG(0x2c);//储存器写
		
			        }
		
			        else
		
			        {
		
			                LCD_WR_REG(0x2a);//列地址设置
		
			                LCD_WR_DATA(x1+80);
		
			                LCD_WR_DATA(x2+80);
		
			                LCD_WR_REG(0x2b);//行地址设置
		
			                LCD_WR_DATA(y1);
		
			                LCD_WR_DATA(y2);
		
			                LCD_WR_REG(0x2c);//储存器写
		
			        }
		
			}
		
			void LCD_Init(void)
		
			{
		
			        SPI1_Init();
		
			        LCD_GPIO_Init();//初始化GPIO
		
			        LCD_RES_Clr();//复位
		
			        delay_ms(100);
		
			        LCD_RES_Set();
		
			        delay_ms(100);
		
			        LCD_BLK_Set();//打开背光
		
			  delay_ms(100);
		
			        //************* Start Initial Sequence **********//
		
			        LCD_WR_REG(0x11); //Sleep out 
		
			        delay_ms(120);              //Delay 120ms 
		
			        //************* Start Initial Sequence **********// 
		
			        LCD_WR_REG(0x36);
		
			        if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
		
			        else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
		
			        else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
		
			        else LCD_WR_DATA8(0xA0);
		
			        LCD_WR_REG(0x3A); 
		
			        LCD_WR_DATA8(0x05);
		
			        LCD_WR_REG(0xB2);
		
			        LCD_WR_DATA8(0x0C);
		
			        LCD_WR_DATA8(0x0C);
		
			        LCD_WR_DATA8(0x00);
		
			        LCD_WR_DATA8(0x33);
		
			        LCD_WR_DATA8(0x33); 
		
			        LCD_WR_REG(0xB7); 
		
			        LCD_WR_DATA8(0x35);  
		
			        LCD_WR_REG(0xBB);
		
			        LCD_WR_DATA8(0x19);
		
			        LCD_WR_REG(0xC0);
		
			        LCD_WR_DATA8(0x2C);
		
			        LCD_WR_REG(0xC2);
		
			        LCD_WR_DATA8(0x01);
		
			        LCD_WR_REG(0xC3);
		
			        LCD_WR_DATA8(0x12);   
		
			        LCD_WR_REG(0xC4);
		
			        LCD_WR_DATA8(0x20);  
		
			        LCD_WR_REG(0xC6); 
		
			        LCD_WR_DATA8(0x0F);    
		
			        LCD_WR_REG(0xD0); 
		
			        LCD_WR_DATA8(0xA4);
		
			        LCD_WR_DATA8(0xA1);
		
			        LCD_WR_REG(0xE0);
		
			        LCD_WR_DATA8(0xD0);
		
			        LCD_WR_DATA8(0x04);
		
			        LCD_WR_DATA8(0x0D);
		
			        LCD_WR_DATA8(0x11);
		
			        LCD_WR_DATA8(0x13);
		
			        LCD_WR_DATA8(0x2B);
		
			        LCD_WR_DATA8(0x3F);
		
			        LCD_WR_DATA8(0x54);
		
			        LCD_WR_DATA8(0x4C);
		
			        LCD_WR_DATA8(0x18);
		
			        LCD_WR_DATA8(0x0D);
		
			        LCD_WR_DATA8(0x0B);
		
			        LCD_WR_DATA8(0x1F);
		
			        LCD_WR_DATA8(0x23);
		
			        LCD_WR_REG(0xE1);
		
			        LCD_WR_DATA8(0xD0);
		
			        LCD_WR_DATA8(0x04);
		
			        LCD_WR_DATA8(0x0C);
		
			        LCD_WR_DATA8(0x11);
		
			        LCD_WR_DATA8(0x13);
		
			        LCD_WR_DATA8(0x2C);
		
			        LCD_WR_DATA8(0x3F);
		
			        LCD_WR_DATA8(0x44);
		
			        LCD_WR_DATA8(0x51);
		
			        LCD_WR_DATA8(0x2F);
		
			        LCD_WR_DATA8(0x1F);
		
			        LCD_WR_DATA8(0x1F);
		
			        LCD_WR_DATA8(0x20);
		
			        LCD_WR_DATA8(0x23);
		
			        LCD_WR_REG(0x21); 
		
			        LCD_WR_REG(0x29); 
		
			} 
		
			屏幕显示字符图片等相关,这里用到DMA发送大量数据:
	
	#include "lcd.h"
	#include "lcd_init.h"
	#include "lcdfont.h"
	#include "delay.h"
	#include "spi.h"
	#include "dma.h"
	/******************************************************************************
	      函数说明:在指定区域填充颜色
	      入口数据:xsta,ysta   起始坐标
	                xend,yend   终止坐标
	                                                                color       要填充的颜色
	      返回值:  无
	******************************************************************************/
	void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
	{          
	        u16 color1[1],t=1;
	        u32 num,num1;
	        color1[0]=color;
	        num=(xend-xsta)*(yend-ysta);
	        LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
	        //SPI1->CTRL1|=1<<11;//设置SPI16位传输模式
	  SPI_Enable(SPI1, DISABLE);//使能SPI
	  SPI_ConfigDataLen(SPI1, SPI_DATA_SIZE_16BITS);
	        SPI_Enable(SPI1, ENABLE);//使能SPI
	        while(t)
	        {
	                if(num>65534)
	                {
	                        num-=65534;
	                        num1=65534;
	                }
	                else
	                {
	                        t=0;
	                        num1=num;
	                }
	                MYDMA_Config1(DMA_CH3,(u32)&SPI1->DAT,(u32)color1,num1);
	    //MYDMA_Config1(DMA_CH3,(u32)SPI_MASTER_DR_Base,(u32)color1,num1);
	                SPI_I2S_EnableDma(SPI1,SPI_I2S_DMA_TX,ENABLE);
	    //SPI_Enable(SPI1, ENABLE);
	                MYDMA_Enable(DMA_CH3);
	                while(1)
	                {
	                        if(DMA_GetFlagStatus(DMA_FLAG_TC3,DMA)!=RESET)//等待通道4传输完成
	                        {
	                                DMA_ClearFlag(DMA_FLAG_TC3,DMA);//清除通道3传输完成标志
	                                break;
	                        }
	                }
	  }
	//        while(1)
	//        {
	////DMA单次最大65535
	//    num1=240*240;//57600
	//                MYDMA_Config1(DMA_CH3,(u32)&SPI1->DAT,(u32)color1,num1);
	//    //MYDMA_Config1(DMA_CH3,(u32)SPI_MASTER_DR_Base,(u32)color1,num1);
	//                SPI_I2S_EnableDma(SPI1,SPI_I2S_DMA_TX,ENABLE);
	//    //SPI_Enable(SPI1, ENABLE);
	//                MYDMA_Enable(DMA_CH3);
	//                while(1)
	//                {
	//                        if(DMA_GetFlagStatus(DMA_FLAG_TC3,DMA)!=RESET)//等待通道3传输完成
	//                        {
	//                                DMA_ClearFlag(DMA_FLAG_TC3,DMA);//清除通道3传输完成标志
	//                                break;
	//                        }
	//                }
	//  }
	//        SPI1->CTRL1=~SPI1->CTRL1;
	//        SPI1->CTRL1|=1<<11;
	//        SPI1->CTRL1=~SPI1->CTRL1;//设置SPI8位传输模式
	//  SPI1->CTRL1&=~(1<<11);
	  SPI_Enable(SPI1, DISABLE);//使能SPI
	  SPI_ConfigDataLen(SPI1, SPI_DATA_SIZE_8BITS);
	        SPI_Enable(SPI1, ENABLE);//使能SPI
	}
	/******************************************************************************
	      函数说明:在指定位置画点
	      入口数据:x,y 画点坐标
	                color 点的颜色
	      返回值:  无
	******************************************************************************/
	void LCD_DrawPoint(u16 x,u16 y,u16 color)
	{
	        LCD_Address_Set(x,y,x,y);//设置光标位置 
	        LCD_WR_DATA(color);
	} 
	/******************************************************************************
	      函数说明:画线
	      入口数据:x1,y1   起始坐标
	                x2,y2   终止坐标
	                color   线的颜色
	      返回值:  无
	******************************************************************************/
	void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
	{
	        u16 t; 
	        int xerr=0,yerr=0,delta_x,delta_y,distance;
	        int incx,incy,uRow,uCol;
	        delta_x=x2-x1; //计算坐标增量 
	        delta_y=y2-y1;
	        uRow=x1;//画线起点坐标
	        uCol=y1;
	        if(delta_x>0)incx=1; //设置单步方向 
	        else if (delta_x==0)incx=0;//垂直线 
	        else {incx=-1;delta_x=-delta_x;}
	        if(delta_y>0)incy=1;
	        else if (delta_y==0)incy=0;//水平线 
	        else {incy=-1;delta_y=-delta_x;}
	        if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 
	        else distance=delta_y;
	        for(t=0;t<distance+1;t++)
	        {
	                LCD_DrawPoint(uRow,uCol,color);//画点
	                xerr+=delta_x;
	                yerr+=delta_y;
	                if(xerr>distance)
	                {
	                        xerr-=distance;
	                        uRow+=incx;
	                }
	                if(yerr>distance)
	                {
	                        yerr-=distance;
	                        uCol+=incy;
	                }
	        }
	}
	/******************************************************************************
	      函数说明:画矩形
	      入口数据:x1,y1   起始坐标
	                x2,y2   终止坐标
	                color   矩形的颜色
	      返回值:  无
	******************************************************************************/
	void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
	{
	        LCD_DrawLine(x1,y1,x2,y1,color);
	        LCD_DrawLine(x1,y1,x1,y2,color);
	        LCD_DrawLine(x1,y2,x2,y2,color);
	        LCD_DrawLine(x2,y1,x2,y2,color);
	}
	/******************************************************************************
	      函数说明:画圆
	      入口数据:x0,y0   圆心坐标
	                r       半径
	                color   圆的颜色
	      返回值:  无
	******************************************************************************/
	void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
	{
	        int a,b;
	        a=0;b=r;          
	        while(a<=b)
	        {
	                LCD_DrawPoint(x0-b,y0-a,color);             //3           
	                LCD_DrawPoint(x0+b,y0-a,color);             //0           
	                LCD_DrawPoint(x0-a,y0+b,color);             //1                
	                LCD_DrawPoint(x0-a,y0-b,color);             //2             
	                LCD_DrawPoint(x0+b,y0+a,color);             //4               
	                LCD_DrawPoint(x0+a,y0-b,color);             //5
	                LCD_DrawPoint(x0+a,y0+b,color);             //6 
	                LCD_DrawPoint(x0-b,y0+a,color);             //7
	                a++;
	                if((a*a+b*b)>(r*r))//判断要画的点是否过远
	                {
	                        b--;
	                }
	        }
	}
	/******************************************************************************
	      函数说明:显示汉字串
	      入口数据:x,y显示坐标
	                *s 要显示的汉字串
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号 可选 16 24 32
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
	{
	        while(*s!=0)
	        {
	                if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
	                else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
	                else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
	                else return;
	                s+=2;
	                x+=sizey;
	        }
	}
	/******************************************************************************
	      函数说明:显示单个16x16汉字
	      入口数据:x,y显示坐标
	                *s 要显示的汉字
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
	{
	        u8 i,j;
	        u16 k;
	        u16 HZnum;//汉字数目
	        u16 TypefaceNum;//一个字符所占字节大小
	        u16 x0=x;
	        TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
	                                  //也建议用户使用这样大小的字,否则显示容易出问题!
	        HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //统计汉字数目
	        for(k=0;k<HZnum;k++) 
	        {
	                if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
	                {         
	                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
	                        for(i=0;i<TypefaceNum;i++)
	                        {
	                                for(j=0;j<8;j++)
	                                {        
	                                        if(!mode)//非叠加方式
	                                        {
	                                                if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
	                                                else LCD_WR_DATA(bc);
	                                        }
	                                        else//叠加方式
	                                        {
	                                                if(tfont16[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
	                                                x++;
	                                                if((x-x0)==sizey)
	                                                {
	                                                        x=x0;
	                                                        y++;
	                                                        break;
	                                                }
	                                        }
	                                }
	                        }
	                }                                          
	                continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
	        }
	} 
	/******************************************************************************
	      函数说明:显示单个24x24汉字
	      入口数据:x,y显示坐标
	                *s 要显示的汉字
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
	{
	        u8 i,j;
	        u16 k;
	        u16 HZnum;//汉字数目
	        u16 TypefaceNum;//一个字符所占字节大小
	        u16 x0=x;
	        TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
	                                  //也建议用户使用这样大小的字,否则显示容易出问题!
	        HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);        //统计汉字数目
	        for(k=0;k<HZnum;k++) 
	        {
	                if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
	                {         
	                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
	                        for(i=0;i<TypefaceNum;i++)
	                        {
	                                for(j=0;j<8;j++)
	                                {        
	                                        if(!mode)//非叠加方式
	                                        {
	                                                if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
	                                                else LCD_WR_DATA(bc);
	                                        }
	                                        else//叠加方式
	                                        {
	                                                if(tfont24[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
	                                                x++;
	                                                if((x-x0)==sizey)
	                                                {
	                                                        x=x0;
	                                                        y++;
	                                                        break;
	                                                }
	                                        }
	                                }
	                        }
	                }                                          
	                continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
	        }
	} 
	/******************************************************************************
	      函数说明:显示单个32x32汉字
	      入口数据:x,y显示坐标
	                *s 要显示的汉字
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
	{
	        u8 i,j;
	        u16 k;
	        u16 HZnum;//汉字数目
	        u16 TypefaceNum;//一个字符所占字节大小
	        u16 x0=x;
	        TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
	                                  //也建议用户使用这样大小的字,否则显示容易出问题!
	        HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);        //统计汉字数目
	        for(k=0;k<HZnum;k++) 
	        {
	                if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
	                {         
	                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
	                        for(i=0;i<TypefaceNum;i++)
	                        {
	                                for(j=0;j<8;j++)
	                                {        
	                                        if(!mode)//非叠加方式
	                                        {
	                                                if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
	                                                else LCD_WR_DATA(bc);
	                                        }
	                                        else//叠加方式
	                                        {
	                                                if(tfont32[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
	                                                x++;
	                                                if((x-x0)==sizey)
	                                                {
	                                                        x=x0;
	                                                        y++;
	                                                        break;
	                                                }
	                                        }
	                                }
	                        }
	                }                                          
	                continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
	        }
	}
	/******************************************************************************
	      函数说明:显示单个字符
	      入口数据:x,y显示坐标
	                num 要显示的字符
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
	{
	        u8 temp,sizex,t;
	        u16 i,TypefaceNum;//一个字符所占字节大小
	        u16 x0=x;
	        sizex=sizey/2;
	        TypefaceNum=sizex/8*sizey;
	        num=num-' ';    //得到偏移后的值
	        LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置 
	        for(i=0;i<TypefaceNum;i++)
	        { 
	                if(sizey==16)temp=ascii_1608[num][i];                       //调用8x16字体
	                else if(sizey==32)temp=ascii_3216[num][i];                 //调用16x32字体
	                else return;
	                for(t=0;t<8;t++)
	                {
	                        if(!mode)//非叠加模式
	                        {
	                                if(temp&(0x01<<t))LCD_WR_DATA(fc);
	                                else LCD_WR_DATA(bc);
	                        }
	                        else//叠加模式
	                        {
	                                if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
	                                x++;
	                                if((x-x0)==sizex)
	                                {
	                                        x=x0;
	                                        y++;
	                                        break;
	                                }
	                        }
	                }
	        }                      
	}
	/******************************************************************************
	      函数说明:显示字符串
	      入口数据:x,y显示坐标
	                *p 要显示的字符串
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	                mode:  0非叠加模式  1叠加模式
	      返回值:  无
	******************************************************************************/
	void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
	{         
	        while(*p!='\0')
	        {       
	                LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
	                x+=sizey/2;
	                p++;
	        }  
	}
	/******************************************************************************
	      函数说明:显示数字
	      入口数据:m底数,n指数
	      返回值:  无
	******************************************************************************/
	u32 mypow(u8 m,u8 n)
	{
	        u32 result=1;         
	        while(n--)result*=m;
	        return result;
	}
	/******************************************************************************
	      函数说明:显示整数变量
	      入口数据:x,y显示坐标
	                num 要显示整数变量
	                len 要显示的位数
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	      返回值:  无
	******************************************************************************/
	void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
	{                 
	        u8 t,temp;
	        u8 enshow=0;
	        u8 sizex=sizey/2;
	        for(t=0;t<len;t++)
	        {
	                temp=(num/mypow(10,len-t-1))%10;
	                if(enshow==0&&t<(len-1))
	                {
	                        if(temp==0)
	                        {
	                                LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
	                                continue;
	                        }else enshow=1; 
	                }
	                 LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
	        }
	} 
	/******************************************************************************
	      函数说明:显示两位小数变量
	      入口数据:x,y显示坐标
	                num 要显示小数变量
	                len 要显示的位数
	                fc 字的颜色
	                bc 字的背景色
	                sizey 字号
	      返回值:  无
	******************************************************************************/
	void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
	{                 
	        u8 t,temp,sizex;
	        u16 num1;
	        sizex=sizey/2;
	        num1=num*100;
	        for(t=0;t<len;t++)
	        {
	                temp=(num1/mypow(10,len-t-1))%10;
	                if(t==(len-2))
	                {
	                        LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
	                        t++;
	                        len+=1;
	                }
	                 LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
	        }
	}
	/******************************************************************************
	      函数说明:显示图片
	      入口数据:x,y起点坐标
	                length 图片长度
	                width  图片宽度
	                pic[]  图片数组    
	      返回值:  无
	******************************************************************************/
	void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
	{
	        u8 t=1;
	        u32 num=length*width*2,num1;
	        LCD_Address_Set(x,y,x+length-1,y+width-1);
	        while(t)
	        {
	          if(num>65534)
	                {
	                        num-=65534;
	                        num1=65534;
	                }
	                else
	                {
	                        t=0;
	                        num1=num;
	                }
	                MYDMA_Config(DMA_CH3,(u32)&SPI1->DAT,(u32)pic,num1);
	    //MYDMA_Config(DMA_CH3,(u32)SPI_MASTER_DR_Base,(u32)pic,num1);
	                SPI_I2S_EnableDma(SPI1,SPI_I2S_DMA_TX,ENABLE);
	    //SPI_Enable(SPI1, ENABLE);
	                MYDMA_Enable(DMA_CH3);
	                while(1)
	                {
	                        if(DMA_GetFlagStatus(DMA_FLAG_TC3,DMA)!=RESET)//等待通道3传输完成
	                        {
	                                DMA_ClearFlag(DMA_FLAG_TC3,DMA);//清除通道3传输完成标志
	                                break; 
	                        }
	                }
	                pic+=65534;
	        }
	}
	其中LCD_Fill 为单一颜色刷屏,用到DMA配置1,其余均用DMA默认配置。
我们在MAIN函数里面调用:
	
		  
	
		 
我们在MAIN函数里面调用:
		int main(void)
	
		{
	
		  u8 t,i,j;
	
		        u8 len;        
	
		        u16 times=0;  
	
		  float m=0;
	
		  /*SystemInit() function has been called by startup file startup_n32g43x.s*/
	
		        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	
		        delay_init(108);                //延时初始化 
	
		        DBG_UART_Init(115200);        //串口初始化波特率为115200
	
		        LED_Init();                                  //初始化与LED连接的硬件接口  
	
		  LCD_Init();//LCD初始化
	
		        LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		  LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		  LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		//  while(1){}
	
		  while(1)
	
		        {
	
		//                LCD_ShowPicture(0,0,240,240,gImage_2);
	
		//                delay_ms(1000);
	
		                LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		                LCD_ShowChinese(0,0,"国民技术论坛",RED,WHITE,32,0);
	
		                LCD_ShowString(0,40,"LCD_W:",RED,WHITE,16,0);
	
		                LCD_ShowIntNum(48,40,LCD_W,3,RED,WHITE,16);
	
		                LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
	
		                LCD_ShowIntNum(128,40,LCD_H,3,RED,WHITE,16);
	
		                LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
	
		                LCD_ShowString(0,70,"Increaseing Nun:",RED,WHITE,16,0);
	
		                LCD_ShowFloatNum1(128,70,m,4,RED,WHITE,16);
	
		                m+=0.11;
	
		                for(j=0;j<3;j++)
	
		                {
	
		                        for(i=0;i<6;i++)
	
		                        {
	
		                                LCD_ShowPicture(40*i,120+j*40,40,40,gImage_1);
	
		                        }
	
		                }
	
		                delay_ms(5000);
	
		                LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		//    delay_ms(200);
	
		//    LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	
		        }
	
		}
显示如下:
	显示如下:

 
   
   
   
  