这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » feiante 的ST L035进程贴(SSD1331显示)

共5条 1/1 1 跳转至

feiante 的ST L035进程贴(SSD1331显示)

专家
2015-12-07 09:03:17     打赏

今天通过SPI实现SSD1331显示屏显示,同时也熟悉使用了SPI功能。

第一步:配置相应的管脚,选择SPI1PA1SSD1331RESPA3SSD1331DCPB5SSD1331CS接口。

第二步:选择SPI1的模式ModeFull-Duplex Master

第三步:配置SPI参数,根据SSD1331手册选择CPOLCPHA

第四步:程序编写

首先在主程序中添加如下程序,完成用绿色清屏,然后用不同字体和颜色显示“WaveShare”“01””0”

SSD1331的驱动代码如下:

#include "SSD1331.h"
#include "gpio.h"
#include "spi.h"
#include "Fonts.h"

static uint8_t s_ucGRAM[8][128];

void ssd1331_init(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1,GPIO_PIN_SET); /* SET RES */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_SET);  /* SET CS */
ssd1331_Write_Cmd(DISPLAY_OFF);
ssd1331_Write_Cmd(SET_CONTRAST_A);       //Set contrast for color A
    ssd1331_Write_Cmd(0xFF);           //145 0x91  /* 这个是设置对比度(亮度)的值 */
    ssd1331_Write_Cmd(SET_CONTRAST_B);       //Set contrast for color B
    ssd1331_Write_Cmd(0xFF);                     //80 0x50 /* 这个是设置对比度(亮度)的值 */
    ssd1331_Write_Cmd(SET_CONTRAST_C);       //Set contrast for color C
    ssd1331_Write_Cmd(0xFF);                     //125 0x7D /* 这个是设置对比度(亮度)的值 */
    ssd1331_Write_Cmd(MASTER_CURRENT_CONTROL);//master current control
    ssd1331_Write_Cmd(0x06);                     //6
    ssd1331_Write_Cmd(SET_PRECHARGE_SPEED_A);//Set Second Pre-change Speed For ColorA
    ssd1331_Write_Cmd(0x64);                     //100 64
    ssd1331_Write_Cmd(SET_PRECHARGE_SPEED_B);//Set Second Pre-change Speed For ColorB
    ssd1331_Write_Cmd(0x78);                     //120 78
    ssd1331_Write_Cmd(SET_PRECHARGE_SPEED_C);//Set Second Pre-change Speed For ColorC
    ssd1331_Write_Cmd(0x64);                     //100 64
    ssd1331_Write_Cmd(SET_REMAP);            //set remap & data format
    ssd1331_Write_Cmd(0x72);                     //0x72              
    ssd1331_Write_Cmd(SET_DISPLAY_START_LINE);//Set display Start Line
    ssd1331_Write_Cmd(0x0);
    ssd1331_Write_Cmd(SET_DISPLAY_OFFSET);   //Set display offset
    ssd1331_Write_Cmd(0x0);
    ssd1331_Write_Cmd(NORMAL_DISPLAY);       //Set display mode
    ssd1331_Write_Cmd(SET_MULTIPLEX_RATIO);  //Set multiplex ratio
    ssd1331_Write_Cmd(0x3F);
    ssd1331_Write_Cmd(SET_MASTER_CONFIGURE); //Set master configuration
    ssd1331_Write_Cmd(0x8E);
    ssd1331_Write_Cmd(POWER_SAVE_MODE);      //Set Power Save Mode
    ssd1331_Write_Cmd(0x00);                     //0x00
    ssd1331_Write_Cmd(PHASE_PERIOD_ADJUSTMENT);//phase 1 and 2 period adjustment
    ssd1331_Write_Cmd(0x31);                     //0x31
    ssd1331_Write_Cmd(DISPLAY_CLOCK_DIV);    //display clock divider/oscillator frequency
    ssd1331_Write_Cmd(0xF0);
    ssd1331_Write_Cmd(SET_PRECHARGE_VOLTAGE);//Set Pre-Change Level
    ssd1331_Write_Cmd(0x3A);
    ssd1331_Write_Cmd(SET_V_VOLTAGE);        //Set vcomH
    ssd1331_Write_Cmd(0x3E);
    ssd1331_Write_Cmd(DEACTIVE_SCROLLING);   //disable scrolling
    ssd1331_Write_Cmd(NORMAL_BRIGHTNESS_DISPLAY_ON);//set display on

ssd1331_clear_screen(GREEN);
}

static void ssd1331_Write_Cmd(uint8_t Cmd)
{

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_RESET); 

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_RESET); /* RESET CS */
HAL_SPI_Transmit(&hspi1, &Cmd,1,10);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_SET); /* SET CS */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET); /* SET DC */
}

static void ssd1331_Write_Data(uint8_t Data)
{

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET); 

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_RESET); /* RESET CS */
HAL_SPI_Transmit(&hspi1, &Data,1,10);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_SET); /* SET CS */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET); /* SET DC */
}

/*
********************************************************************************
* 函 数 名: ssd1331_clear_screen
* 功能说明: 指定颜色清屏
* 形    参:
* Color  :像素颜色
* 返 回 值: 无
********************************************************************************
*/
void ssd1331_clear_screen(uint16_t Color)  
{
uint16_t i, j;

for(i = 0; i < OLED_HEIGHT; i ++){
for(j = 0; j < OLED_WIDTH; j ++){
ssd1331_draw_point(j, i, Color);
}
}
}

/*
********************************************************************************
* 函 数 名: ssd1331_draw_point
* 功能说明: 在指定位置画1个像素点
* 形    参:
* chXpos,chYpos : 像素坐标
* hwColor  :像素颜色
* 返 回 值: 无
********************************************************************************
*/
void ssd1331_draw_point(uint8_t chXpos, uint8_t chYpos, uint16_t hwColor) 
{
if (chXpos >= OLED_WIDTH || chYpos >= OLED_HEIGHT) {
return;
}
    //set column point
    ssd1331_Write_Cmd(SET_COLUMN_ADDRESS);       /* 这个指令设置起始和结束COLUMN地址 */
    ssd1331_Write_Cmd(chXpos); /* 起始地址 */
    ssd1331_Write_Cmd(chXpos); /* 结束地址 */
    //set row point
    ssd1331_Write_Cmd(SET_ROW_ADDRESS); /* 这个指令设置起始和结束ROW地址 */
    ssd1331_Write_Cmd(chYpos);
    ssd1331_Write_Cmd(chYpos);
    
    //fill 16bit colour
ssd1331_Write_Data(hwColor >> 8);
ssd1331_Write_Data(hwColor);   
}

/*
********************************************************************************
* 函 数 名: ssd1331_DrawLine
* 功能说明: 采用 Bresenham 算法,在2点间画一条直线。
* 形    参:
* _usX1, _usY1 :起始点坐标
* _usX2, _usY2 :终止点Y坐标
* _ucColor  :像素颜色
* 返 回 值: 无
********************************************************************************
*/
void ssd1331_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _ucColor)
{
int32_t dx , dy ;
int32_t tx , ty ;
int32_t inc1 , inc2 ;
int32_t d , iTag ;
int32_t x , y ;

/* 采用 Bresenham 算法,在2点间画一条直线 */

ssd1331_draw_point(_usX1 , _usY1 , _ucColor);

/* 如果两点重合,结束后面的动作。*/
if ( _usX1 == _usX2 && _usY1 == _usY2 )
{
return;
}

iTag = 0 ;
/* dx = abs ( _usX2 - _usX1 ); */
if (_usX2 >= _usX1)
{
dx = _usX2 - _usX1;
}
else
{
dx = _usX1 - _usX2;
}

/* dy = abs ( _usY2 - _usY1 ); */
if (_usY2 >= _usY1)
{
dy = _usY2 - _usY1;
}
else
{
dy = _usY1 - _usY2;
}

if ( dx < dy )   /*如果dy为计长方向,则交换纵横坐标。*/
{
uint16_t temp;

iTag = 1 ;
temp = _usX1; _usX1 = _usY1; _usY1 = temp;
temp = _usX2; _usX2 = _usY2; _usY2 = temp;
temp = dx; dx = dy; dy = temp;
}
tx = _usX2 > _usX1 ? 1 : -1 ;    /* 确定是增1还是减1 */
ty = _usY2 > _usY1 ? 1 : -1 ;
x = _usX1 ;
y = _usY1 ;
inc1 = 2 * dy ;
inc2 = 2 * ( dy - dx );
d = inc1 - dx ;
while ( x != _usX2 )     /* 循环画点 */
{
if ( d < 0 )
{
d += inc1 ;
}
else
{
y += ty ;
d += inc2 ;
}
if ( iTag )
{
ssd1331_draw_point ( y , x , _ucColor) ;
}
else
{
ssd1331_draw_point ( x , y , _ucColor) ;
}
x += tx ;
}
}

/*
********************************************************************************
* 函 数 名: ssd1331_DrawCircle
* 功能说明: 绘制一个圆。
* 形    参:
* _usX, _usY :圆心坐标
* _usRadius :半径
* _ucColor  :像素颜色
* 返 回 值: 无
********************************************************************************
*/
void ssd1331_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _ucColor)
{
int32_t  D; /* Decision Variable */
uint32_t  CurX; /* 当前 X 值 */
uint32_t  CurY; /* 当前 Y 值 */

D = 3 - (_usRadius << 1);
CurX = 0;
CurY = _usRadius;

while (CurX <= CurY)
{
ssd1331_draw_point(_usX + CurX, _usY + CurY, _ucColor);
ssd1331_draw_point(_usX + CurX, _usY - CurY, _ucColor);
ssd1331_draw_point(_usX - CurX, _usY + CurY, _ucColor);
ssd1331_draw_point(_usX - CurX, _usY - CurY, _ucColor);
ssd1331_draw_point(_usX + CurY, _usY + CurX, _ucColor);
ssd1331_draw_point(_usX + CurY, _usY - CurX, _ucColor);
ssd1331_draw_point(_usX - CurY, _usY + CurX, _ucColor);
ssd1331_draw_point(_usX - CurY, _usY - CurX, _ucColor);

if (D < 0)
{
D += (CurX << 2) + 6;
}
else
{
D += ((CurX - CurY) << 2) + 10;
CurY--;
}
CurX++;
}
}

void ssd1331_display_string(uint8_t chXpos, uint8_t chYpos, const uint8_t *pchString, uint8_t chSize, uint16_t hwColor)
{
if (chXpos >= OLED_WIDTH || chYpos >= OLED_HEIGHT) 
{
return;
}

    while (*pchString != '\0') 
{       
        if (chXpos > (OLED_WIDTH - chSize / 2)) 
{
chXpos = 0;
chYpos += chSize;
if (chYpos > (OLED_HEIGHT - chSize)) 
{
chYpos = chXpos = 0;
ssd1331_clear_screen(0x00);
}
}

        ssd1331_display_char(chXpos, chYpos, *pchString, chSize, hwColor);
        chXpos += chSize / 2;
        pchString ++;
    } 
}

void ssd1331_display_char(uint8_t chXpos, uint8_t chYpos, uint8_t chChr, uint8_t chSize, uint16_t hwColor)
{      
uint8_t i, j, chTemp;
uint8_t chYpos0 = chYpos;

if (chXpos >= OLED_WIDTH || chYpos >= OLED_HEIGHT) {
return;
}
  
    for (i = 0; i < chSize; i ++) 
{   
if (FONT_1206 == chSize) 
{
chTemp = c_chFont1206[chChr - 0x20][i];  

else if (FONT_1608 == chSize) 

chTemp = c_chFont1608[chChr - 0x20][i];
}

        for (j = 0; j < 8; j ++) 
{
    if (chTemp & 0x80) 
{
ssd1331_draw_point(chXpos, chYpos, hwColor);
    }
chTemp <<= 1;
chYpos ++;
if ((chYpos - chYpos0) == chSize) 
{
chYpos = chYpos0;
chXpos ++;
break;
}
}    
    } 
}

/* 显示宽度和高度都是32的字符 */
void ssd1331_draw_3216char(uint8_t chXpos, uint8_t chYpos, uint8_t chChar, uint16_t hwColor)
{
uint8_t i, j;
uint8_t chTemp = 0, chYpos0 = chYpos;

for (i = 0; i < 64; i ++) {
chTemp = c_chFont3216[chChar - 0x30][i];
for (j = 0; j < 8; j ++) {
if (chTemp & 0x80) {
ssd1331_draw_point(chXpos, chYpos, hwColor);
    }
chTemp <<= 1;
chYpos ++;
if ((chYpos - chYpos0) == 32) {
chYpos = chYpos0;
chXpos ++;
break;
}
}
}
}
/*
********************************************************************************
* 函 数 名: ssd1331_draw_bitmap
* 功能说明: 在指定位置画一个图片
* 形    参:
* chXpos,chYpos : 像素坐标
* pchBmp:像素指针
* chWidth,chHeight:图片大小
* hwColor  :像素颜色
* 返 回 值: 无
*   说    明:取模软件采用pctolcd2002,图片大小就是新建图片时图片的宽度和高度
*  取模方式:逐行式,顺向
********************************************************************************
*/
void ssd1331_draw_bitmap(uint8_t chXpos, uint8_t chYpos, const uint8_t *pchBmp, uint8_t chWidth, uint8_t chHeight, uint16_t hwColor)
{
uint16_t i, j, byteWidth = (chWidth + 7) / 8;

    for(j = 0; j < chHeight; j ++)
{
        for(i = 0; i < chWidth; i ++ ) 
{
            if(*(pchBmp + j * byteWidth + i / 8) & (128 >> (i & 7))) /* 用于判断字模中哪些位是1,就用相应颜色点亮 */
{
                ssd1331_draw_point(chXpos + i, chYpos + j, hwColor);
            }
        }
    }
}






专家
2015-12-07 11:13:05     打赏
2楼
不错

院士
2015-12-10 21:48:16     打赏
3楼

楼主啊~~

这个代码您帖出来,自己看着都难受吧~~

另 第一行第6个图标就是“插入代码”功能,这样分享的代码就非常舒服了。


专家
2015-12-11 08:48:40     打赏
4楼
好的,以后有分享的时候注意,原来没有看到有“插入代码”功能

助工
2015-12-29 13:29:12     打赏
5楼
信息量有点大

共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]