- void LCD_SPI_Configure(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- SPI_InitTypeDef SPI_InitStruct;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
-
- SPI_StructInit(&SPI_InitStruct);
- SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
- SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
- SPI_InitStruct.SPI_DataWidth = 8;
- SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
- SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
- SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
- SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
- SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
- SPI_Init(SPI2, &SPI_InitStruct);
-
-
-
- SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Rx);
- SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Tx);
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
-
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_5); //SPI2_NSS PB12
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5); //SPI2_SCK PB13
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); //SPI2_MISO PB14
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5); //SPI2_MOSI PB15
-
-
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
-
-
- SPI_Cmd(SPI2, ENABLE);
-
-
- //初始化LCD_DC、LCD_RST、LCD_LED
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- }
二、DMA设置
1、首先申请一个内存做为DMA的源地址:
之所以申请256*16个地址,是因为ST7735是一个128*128分辨率的LCD,一行128个点,由于是彩屏,每个点color值用2个字节,一行就是256个字节;另外一个汉字点阵是16*16,所以申请256*16这么一个空间,可以显示一行汉字。
- #define DMABUFFERSIZE 256*16
- uint8_t DMA_TxBuffer[DMABUFFERSIZE];
2、DMA向发送SPI2数据
1)DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->TXREG);
DMA_PeripheralBaseAddr外设地址要这么设置,可以从DMA_TxBuffer地址发送到SPI2
2)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
外设地址是固定的
3)DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;源地址每次要增加,这样可以保障DMA_TxBuffer里的数据都发送给SPI2.
4)DMA_Cmd(DMA1_Channel4, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
根据数据手册DAM channel要这么设置
- void SPI_TxData_DMA_Polling(uint8_t *Buffer, uint16_t Length)
- {
- DMA_InitTypeDef DMA_InitStruct;
- uint8_t DataCache = 0;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- DMA_DeInit(DMA1_Channel4);
- DMA_DeInit(DMA1_Channel5);
- DMA_StructInit(&DMA_InitStruct);
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->RXREG);
- DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&DataCache;
- DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
- DMA_InitStruct.DMA_BufferSize = Length;
- DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
- DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
- DMA_InitStruct.DMA_Auto_Reload = DMA_Auto_Reload_Disable;
- DMA_Init(DMA1_Channel4, &DMA_InitStruct);
- DMA_StructInit(&DMA_InitStruct);
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->TXREG);
- DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Buffer;
- DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
- DMA_InitStruct.DMA_BufferSize = Length;
- DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
- DMA_InitStruct.DMA_Auto_Reload = DMA_Auto_Reload_Disable;
- DMA_Init(DMA1_Channel5, &DMA_InitStruct);
- DMA_Cmd(DMA1_Channel4, ENABLE);
- DMA_Cmd(DMA1_Channel5, ENABLE);
- SPI_DMACmd(SPI2, ENABLE);
- while (RESET == DMA_GetFlagStatus(DMA1_FLAG_TC4))
- {
- }
- while (RESET == DMA_GetFlagStatus(DMA1_FLAG_TC5))
- {
- }
- SPI_DMACmd(SPI2, DISABLE);
- DMA_Cmd(DMA1_Channel4, DISABLE);
- DMA_Cmd(DMA1_Channel5, DISABLE);
- }
3、对源数据控制函数:
把DMA+SPI发送函数包装下:
- void SPI_LCD_TxBuffer(uint8_t *Buffer, uint16_t Length)
- {
- if (Length)
- {
- SPI_TxData_DMA_Polling(Buffer, Length);
- }
- }
发送16行到LCD
- //16行
- void sendOneLineDataDMA(void)
- {
- LCD_CS_RESET();
- LCD_DC_SET();
- SPI_LCD_TxBuffer(DMA_TxBuffer,DMABUFFERSIZE);
- LCD_CS_SET();
- }
DMA方式清屏,
- void GUI_Clear(uint16_t Color) //清屏
- {
- uint16_t i,j;
-
- ST7735_SetWindow(0, 0, X_MAX_PIXEL, Y_MAX_PIXEL);
- for(i=0;i<DMABUFFERSIZE/2;i++){
- DMA_TxBuffer[i*2]=Color>>8;
- DMA_TxBuffer[i*2+1]=Color&0xFF;
- }
-
- for(i=0;i<Y_MAX_PIXEL/16;i++)
- {
- sendOneLineDataDMA();
- }
-
- }
在DMA_TxBuffer上画点,相当于在128*16区域设置每个点的颜色值
- void Gui_DrawPoint_DMA(uint16_t x,uint16_t y,uint16_t Data)
- {
- DMA_TxBuffer[2*x+y*256]=Data>>8;
- DMA_TxBuffer[2*x+y*256+1]=Data;
- }
用一个颜色值将整个源数据填满
- void set_DMA_TxBuffer(uint16_t Data)
- {
- uint16_t i,j;
- for(i=0;i<16;i++)
- {
- for(j=0;j<X_MAX_PIXEL;j++)
- {
- Gui_DrawPoint_DMA(j,i,Data);
- }
- }
- }
4、DMA方式发送汉字、ASCII- void GUI_WriteCN16x16DMA(uint16_t x, uint16_t y,const uint8_t *cn, uint16_t wordColor, uint16_t backColor)
- {
- uint16_t i, j, mx,my,wordByte;
- uint16_t zm;
- uint16_t color;
- uint8_t wordNum;
- mx=x;
- my=y;
- while (*cn != '\0')
- {
-
- if(mx>119){
- ST7735_SetWindow(0,my,X_MAX_PIXEL,16);
- sendOneLineDataDMA();
- mx=x;
- my+=16;
- memset(DMA_TxBuffer,0,sizeof(DMA_TxBuffer));
- }
- if(*cn<128){
- wordNum = *cn - 32;
-
- for (wordByte=0; wordByte<16; wordByte++)
- {
- color = Font_Data[wordNum].dat[wordByte];
- for (j=0; j<8; j++)
- {
- if ((color&0x80) == 0x80)
- {
- Gui_DrawPoint_DMA(mx+j,(my+wordByte)%16,wordColor);
- }
- else
- {
- Gui_DrawPoint_DMA(mx+j,(my+wordByte)%16,backColor);
- }
- color <<= 1;
- }
- }
- cn++;
- mx +=8;
- }
- else
- {
- zm=*cn;
- zm<<=8;
- zm|=*(cn+1);
- getMatrix(zm);
- for(i=0; i<32; i++)
- { //MSK的位数
- color=MatrixBuff[i];
- for(j=0;j<8;j++)
- {
- if((color&0x80)==0x80)
- {
- Gui_DrawPoint_DMA(mx+j+(i%2)*8,i/2,wordColor);
- }
- else
- {
- Gui_DrawPoint_DMA(mx+j+(i%2)*8,i/2,backColor);
- }
- color<<=1;
- }//for(j=0;j<8;j++)结束
- }
- cn += 2;
- mx += 16;
- }
- }
-
- ST7735_SetWindow(0,my,X_MAX_PIXEL, 16);
- sendOneLineDataDMA();
-
- set_DMA_TxBuffer(backColor);
- my+=16;
- while(my<(Y_MAX_PIXEL)){
- ST7735_SetWindow(0,my,X_MAX_PIXEL, 16);
- sendOneLineDataDMA();
- my+=16;
- }
-
- }
5、实验:
- void ST7735_Init(void)
- {
- char buf[16];
- LCD_LED_SET();
-
- LCD_SPI_Configure();
-
- ST7735_HardReset();
- ST7735_SendInitStr();
- GUI_Clear(COLOR_Red);
- sprintf(buf,"%d ",maxPage);
- GUI_WriteCN16x16(20,20,buf,COLOR_Red,COLOR_Black);
- PLATFORM_DelayMS(1000);
- GUI_Clear(COLOR_Blue);
- GUI_WriteCN16x16(20,20,buf,COLOR_Red,COLOR_Black);
- PLATFORM_DelayMS(1000);
- GUI_Clear(COLOR_Green);
- GUI_WriteCN16x16(20,20,buf,COLOR_Red,COLOR_Black);
- PLATFORM_DelayMS(1000);
- }
三、演示效果
四、源码
mini-f53330_USART_Polling.rar
(188.6 KB, 下载次数: 34)