TLLED 发表于 昨天 08:24

【瑞萨BLE/WIFI模块测评】+ SPI驱动LCD屏

测试开发板的SPI输出,驱动LCD。



一、硬件电路

使用SCI2配置为SPI的引脚和LCD的其他控制引脚。



二、软件配置


2.1、配置SCI2的SPI端口



2.2、配置SPI参数



三、软件部分


3.1、fun_spi.c
#include "hal_data.h"
#include "spi/fun_spi.h"

volatile bool g_transfer_complete = false;

void sci_spi_callback(spi_callback_args_t *p_args)
{
if(p_args->event == SPI_EVENT_TRANSFER_COMPLETE)
{
    g_transfer_complete = true;
}
}

void sci_spi_init(void)
{
    fsp_err_t err = R_SCI_SPI_Open(&g_spi0_ctrl, &g_spi0_cfg);
    assert(FSP_SUCCESS == err);
}


bool SPIWaitgtc(void)
{
unsigned short wTimeout = 100;
while(!g_transfer_complete && wTimeout)
{
      R_BSP_SoftwareDelay(1u, BSP_DELAY_UNITS_MICROSECONDS);
      wTimeout--;
}
g_transfer_complete = false;
if(g_transfer_complete==false && wTimeout==0)
      return false;
return true;
}


3.2、fun_st7735s.c
#include "hal_data.h"
#include "systick/bsp_systick.h"
#include "spi/fun_spi.h"
#include "lcd/st7735s/fun_st7735s.h"

void lcd_writebyte(uint8_t dat)
{
        lcd_st7735s_cs_l();
        R_SCI_SPI_Write(&g_spi0_ctrl,&dat,1,SPI_BIT_WIDTH_8_BITS);
SPIWaitgtc();
        lcd_st7735s_cs_h();
}

void lcd_st7735s_write_dat8(uint8_t dat)
{
        lcd_writebyte(dat);
}

void lcd_st7735s_write_dat16(uint16_t dat)
{
        //lcd_st7735s_cs_l();
        lcd_writebyte(dat>>8);
        lcd_writebyte(dat);
        //lcd_st7735s_cs_h();
}

void lcd_st7735s_write_dat(uint8_t cmd)
{
        uint8_t i=0;
        lcd_st7735s_cs_l();
        lcd_writebyte(cmd);
        lcd_st7735s_cs_h();
}

void lcd_st7735s_write_reg(uint8_t reg)
{
        lcd_st7735s_rs_l();   //写命令
        lcd_writebyte(reg);
        lcd_st7735s_rs_h();                //写数据
}


void lcd_st7735s_write_cmd(uint8_t cmd)
{
        uint8_t i=0;
        lcd_st7735s_cs_l();
        lcd_st7735s_rs_l();
       
        lcd_writebyte(cmd);
}


//设置起始和结束地址
void lcd_address_set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
        if(USE_HORIZONTAL==0)
        {
                lcd_st7735s_write_reg(0x2a);//列地址设置
                lcd_st7735s_write_dat16(x1+2);
                lcd_st7735s_write_dat16(x2+2);
                lcd_st7735s_write_reg(0x2b);//行地址设置
                lcd_st7735s_write_dat16(y1+1);
                lcd_st7735s_write_dat16(y2+1);
                lcd_st7735s_write_reg(0x2c);//储存器写
        }
        else if(USE_HORIZONTAL==1)
        {
                lcd_st7735s_write_reg(0x2a);//列地址设置
                lcd_st7735s_write_dat16(x1+2);
                lcd_st7735s_write_dat16(x2+2);
                lcd_st7735s_write_reg(0x2b);//行地址设置
                lcd_st7735s_write_dat16(y1+1);
                lcd_st7735s_write_dat16(y2+1);
                lcd_st7735s_write_reg(0x2c);//储存器写
        }
        else if(USE_HORIZONTAL==2)
        {
                lcd_st7735s_write_reg(0x2a);//列地址设置
                lcd_st7735s_write_dat16(x1+1);
                lcd_st7735s_write_dat16(x2+1);
                lcd_st7735s_write_reg(0x2b);//行地址设置
                lcd_st7735s_write_dat16(y1+2);
                lcd_st7735s_write_dat16(y2+2);
                lcd_st7735s_write_reg(0x2c);//储存器写
        }
        else
        {
                lcd_st7735s_write_reg(0x2a);//列地址设置
                lcd_st7735s_write_dat16(x1+1);
                lcd_st7735s_write_dat16(x2+1);
                lcd_st7735s_write_reg(0x2b);//行地址设置
                lcd_st7735s_write_dat16(y1+2);
                lcd_st7735s_write_dat16(y2+2);
                lcd_st7735s_write_reg(0x2c);//储存器写
        }
}

void init_lcd_st7735s(void)
{
        //init_lcd_st7735s_pins();
        //lcd_init_spi();
        lcd_st7735s_cs_h();
        lcd_st7735s_rst_l();
        SysTick_Delay_Ms(100);
        lcd_st7735s_rst_h();
        SysTick_Delay_Ms(100);
       
        //************* Start Initial Sequence **********//
        lcd_st7735s_write_reg(0x11); //Sleep out
        SysTick_Delay_Ms(120);            //Delay 120ms
        //------------------------------------ST7735S Frame Rate-----------------------------------------//
        lcd_st7735s_write_reg(0xB1);
        lcd_st7735s_write_dat8(0x05);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_reg(0xB2);
        lcd_st7735s_write_dat8(0x05);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_reg(0xB3);
        lcd_st7735s_write_dat8(0x05);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_dat8(0x05);
        lcd_st7735s_write_dat8(0x3C);
        lcd_st7735s_write_dat8(0x3C);
        //------------------------------------End ST7735S Frame Rate---------------------------------//
        lcd_st7735s_write_reg(0xB4); //Dot inversion
        lcd_st7735s_write_dat8(0x03);
        //------------------------------------ST7735S Power Sequence---------------------------------//
        lcd_st7735s_write_reg(0xC0);
        lcd_st7735s_write_dat8(0x28);
        lcd_st7735s_write_dat8(0x08);
        lcd_st7735s_write_dat8(0x04);
        lcd_st7735s_write_reg(0xC1);
        lcd_st7735s_write_dat8(0XC0);
        lcd_st7735s_write_reg(0xC2);
        lcd_st7735s_write_dat8(0x0D);
        lcd_st7735s_write_dat8(0x00);
        lcd_st7735s_write_reg(0xC3);
        lcd_st7735s_write_dat8(0x8D);
        lcd_st7735s_write_dat8(0x2A);
        lcd_st7735s_write_reg(0xC4);
        lcd_st7735s_write_dat8(0x8D);
        lcd_st7735s_write_dat8(0xEE);
        //---------------------------------End ST7735S Power Sequence-------------------------------------//
        lcd_st7735s_write_reg(0xC5); //VCOM
        lcd_st7735s_write_dat8(0x1A);
        lcd_st7735s_write_reg(0x36); //MX, MY, RGB mode
        if(USE_HORIZONTAL==0)lcd_st7735s_write_dat8(0x00);
        else if(USE_HORIZONTAL==1)lcd_st7735s_write_dat8(0xC0);
        else if(USE_HORIZONTAL==2)lcd_st7735s_write_dat8(0x70);
        else lcd_st7735s_write_dat8(0xA0);
        //------------------------------------ST7735S Gamma Sequence---------------------------------//
        lcd_st7735s_write_reg(0xE0);
        lcd_st7735s_write_dat8(0x04);
        lcd_st7735s_write_dat8(0x22);
        lcd_st7735s_write_dat8(0x07);
        lcd_st7735s_write_dat8(0x0A);
        lcd_st7735s_write_dat8(0x2E);
        lcd_st7735s_write_dat8(0x30);
        lcd_st7735s_write_dat8(0x25);
        lcd_st7735s_write_dat8(0x2A);
        lcd_st7735s_write_dat8(0x28);
        lcd_st7735s_write_dat8(0x26);
        lcd_st7735s_write_dat8(0x2E);
        lcd_st7735s_write_dat8(0x3A);
        lcd_st7735s_write_dat8(0x00);
        lcd_st7735s_write_dat8(0x01);
        lcd_st7735s_write_dat8(0x03);
        lcd_st7735s_write_dat8(0x13);
        lcd_st7735s_write_reg(0xE1);
        lcd_st7735s_write_dat8(0x04);
        lcd_st7735s_write_dat8(0x16);
        lcd_st7735s_write_dat8(0x06);
        lcd_st7735s_write_dat8(0x0D);
        lcd_st7735s_write_dat8(0x2D);
        lcd_st7735s_write_dat8(0x26);
        lcd_st7735s_write_dat8(0x23);
        lcd_st7735s_write_dat8(0x27);
        lcd_st7735s_write_dat8(0x27);
        lcd_st7735s_write_dat8(0x25);
        lcd_st7735s_write_dat8(0x2D);
        lcd_st7735s_write_dat8(0x3B);
        lcd_st7735s_write_dat8(0x00);
        lcd_st7735s_write_dat8(0x01);
        lcd_st7735s_write_dat8(0x04);
        lcd_st7735s_write_dat8(0x13);
        //------------------------------------End ST7735S Gamma Sequence-----------------------------//
        lcd_st7735s_write_reg(0x3A); //65k mode
        lcd_st7735s_write_dat8(0x05);
        lcd_st7735s_write_reg(0x29); //Display on
}


3.3、fun_lcd.c
#include "hal_data.h"
#include "lcd/st7735s/fun_st7735s.h"
#include "lcd/st7735s/lcdfont.h"

void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
{         
        uint16_t i,j;
        lcd_address_set(xsta,ysta,xend-1,yend-1);
        for(i=ysta;i<yend;i++)
        {                                                                                                                         
                for(j=xsta;j<xend;j++)
                {
                        lcd_st7735s_write_dat16(color);
                }
        }                                                     
}

void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
{
        lcd_address_set(x,y,x,y);                                //设置光标位置
        lcd_st7735s_write_dat16(color);
}

void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
{
        uint16_t 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_y;}
        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;
                }
        }
}

void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t 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);
}

void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t 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--;
                }
        }
}

void LCD_ShowChinese12x12(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        uint8_t i,j,m=0;
        uint16_t k;
        uint16_t HZnum;//汉字数目
        uint16_t TypefaceNum;//一个字符所占字节大小
        uint16_t x0=x;
        TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
                               
        HZnum=sizeof(tfont12)/sizeof(typFNT_GB12);        //统计汉字数目
        for(k=0;k<HZnum;k++)
        {
                if((tfont12.Index==*(s))&&(tfont12.Index==*(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(tfont12.Msk&(0x01<<j))lcd_st7735s_write_dat16(fc);
                                                else lcd_st7735s_write_dat16(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                        m=0;
                                                        break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont12.Msk&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                        x=x0;
                                                        y++;
                                                        break;
                                                }
                                        }
                                }
                        }
                }                                         
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
        }
}

void LCD_ShowChinese16x16(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        uint8_t i,j,m=0;
        uint16_t k;
        uint16_t HZnum;//汉字数目
        uint16_t TypefaceNum;//一个字符所占字节大小
        uint16_t x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
        HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //统计汉字数目
        for(k=0;k<HZnum;k++)
        {
                if ((tfont16.Index==*(s))&&(tfont16.Index==*(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.Msk&(0x01<<j))lcd_st7735s_write_dat16(fc);
                                                else lcd_st7735s_write_dat16(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                        m=0;
                                                        break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont16.Msk&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                        x=x0;
                                                        y++;
                                                        break;
                                                }
                                        }
                                }
                        }
                }                                         
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
        }
}

void LCD_ShowChinese24x24(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        uint8_t i,j,m=0;
        uint16_t k;
        uint16_t HZnum;//汉字数目
        uint16_t TypefaceNum;//一个字符所占字节大小
        uint16_t x0=x;
        TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
        HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);        //统计汉字数目
        for(k=0;k<HZnum;k++)
        {
                if ((tfont24.Index==*(s))&&(tfont24.Index==*(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.Msk&(0x01<<j))lcd_st7735s_write_dat16(fc);
                                                else lcd_st7735s_write_dat16(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                        m=0;
                                                        break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont24.Msk&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                        x=x0;
                                                        y++;
                                                        break;
                                                }
                                        }
                                }
                        }
                }                                         
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
        }
}

void LCD_ShowChinese32x32(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        uint8_t i,j,m=0;
        uint16_t k;
        uint16_t HZnum;//汉字数目
        uint16_t TypefaceNum;//一个字符所占字节大小
        uint16_t x0=x;
        TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
        HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);        //统计汉字数目
        for(k=0;k<HZnum;k++)
        {
                if ((tfont32.Index==*(s))&&(tfont32.Index==*(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.Msk&(0x01<<j))lcd_st7735s_write_dat16(fc);
                                                else lcd_st7735s_write_dat16(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                        m=0;
                                                        break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont32.Msk&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                        x=x0;
                                                        y++;
                                                        break;
                                                }
                                        }
                                }
                        }
                }                                         
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
        }
}

void LCD_ShowChinese(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        while(*s!=0)
        {
                if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
                else 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;
        }
}

void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
        uint8_t temp,sizex,t,m=0;
        uint16_t i,TypefaceNum;//一个字符所占字节大小
        uint16_t x0=x;
        sizex=sizey/2;
        TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
        num=num-' ';    //得到偏移后的值
        lcd_address_set(x,y,x+sizex-1,y+sizey-1);//设置光标位置
        for(i=0;i<TypefaceNum;i++)
        {
                if(sizey==12)temp=ascii_1206;                     //调用6x12字体
                else if(sizey==16)temp=ascii_1608;               //调用8x16字体
                else if(sizey==24)temp=ascii_2412;               //调用12x24字体
                else if(sizey==32)temp=ascii_3216;               //调用16x32字体
                else return;
                for(t=0;t<8;t++)
                {
                        if(!mode)//非叠加模式
                        {
                                if(temp&(0x01<<t))lcd_st7735s_write_dat16(fc);
                                else lcd_st7735s_write_dat16(bc);
                                m++;
                                if(m%sizex==0)
                                {
                                        m=0;
                                        break;
                                }
                        }
                        else//叠加模式
                        {
                                if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
                                x++;
                                if((x-x0)==sizex)
                                {
                                        x=x0;
                                        y++;
                                        break;
                                }
                        }
                }
        }                    
}

void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{         
        while(*p!='\0')
        {      
                LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
                x+=sizey/2;
                p++;
        }
}

uint32_t mypow(uint8_t m,uint8_t n)
{
        uint32_t result=1;       
        while(n--)result*=m;
        return result;
}

void LCD_ShowIntNum(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey)
{                
        uint8_t t,temp;
        uint8_t enshow=0;
        uint8_t 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);
        }
}

void LCD_ShowFloatNum1(uint16_t x,uint16_t y,float num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey)
{                
        uint8_t t,temp,sizex;
        uint16_t 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);
        }
}


//显示图片
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[])
{
        uint16_t i,j;
        uint32_t k=0;
        lcd_address_set(x,y,x+length-1,y+width-1);
        for(i=0;i<length;i++)
        {
                for(j=0;j<width;j++)
                {
                        lcd_st7735s_write_dat8(pic);
                        lcd_st7735s_write_dat8(pic);
                        k++;
                }
        }                       
}

四、运行结果


下载程序后,LCD显示内容

页: [1]
查看完整版本: 【瑞萨BLE/WIFI模块测评】+ SPI驱动LCD屏

Baidu
map