基于STM32F103的硬件SPI驱动OLED配置

#define        OLED_CS     PBout(7)  //片选CS
#define        OLED_RST    PAout(4)  //复位RST
#define        OLED_DC     PAout(15) //数据控制选择DC

/*******************************************************
*函数名:SPI2_Init
*功  能:SPI2初始化
*参  数:无
*返  回:无
*备  注:主模式 、MSB、CLK空闲时高电平,第二时钟边沿开始
PB13/14/15
********************************************************/
void SPI2_Init(void)
{        
        /* 配置时钟 */
        RCC->APB2ENR |= (1<<3);//PB时钟使能
        RCC->APB1ENR |= (1<<14);//SPI2时钟使能
        /* 配置GPIO */
        GPIOB->CRH&=0X000FFFFF; 
        GPIOB->CRH|=0XBBB00000;        //PB13/14/15复用             
        GPIOB->ODR|=0X7<<13;           //PB13/14/15上拉
        /* 配置SPI */
        SPI2->CR1|=1<<9;                 //软件nss管理(软件操控CS片选引脚)
        SPI2->CR1|=1<<8; 
        SPI2->CR1|=3<<3;                 //100: fPCLK/32
        SPI2->CR1|=1<<2;                 //SPI主机
        SPI2->CR1|=1<<1;                 //空闲模式下SCK为1 CPOL=1
        SPI2->CR1|=1<<0;                 //数据采样从第二个时间边沿开始,CPHA=1
        SPI2->CR1|=1<<6;                 //SPI设备使能
}

/*******************************************************
*函数名:SPI2_WriteReadByte 
*功  能:SPI2读写一个字节
*参  数:写入字节
*返  回:读出字节
*备  注:
********************************************************/
u8 SPI2_WriteReadByte(u8 data)
{
        //写功能        
        while((SPI2->SR&1<<1)==0);//等待发送区空                
        SPI2->DR=data;        //发送一个byte 
        //读功能
        while((SPI2->SR&1<<0)==0) ;//等待接收完一个byte                                              
        return SPI2->DR;  //返回收到的数据        
}


/*******************************************************
*函数名:OLED_Init
*功  能:OLED初始化
*参  数:无
*返  回:无
*备  注:
OLED_SCL   PB13(复位被SWJ占用)
OLED_MOSI  PB15
OLED_CS    PB7
OLED_DC    PA15
OLED_RST   PA4
********************************************************/
void OLED_Init (void)
{
        SPI2_Init();//SPI2初始化
        
        /* 时钟配置 */
        RCC->APB2ENR |= (1<<2);//PA时钟使能
        RCC->APB2ENR |= (1<<3);//PB时钟使能        
        RCC->APB2ENR |= (1<<0);//AFIO时钟使能
        /* 配置GPIO */
        AFIO->MAPR &=~ (7<<24);
        AFIO->MAPR |=  (2<<24); //复位后PB13被JTAG占用,关闭JTAG,使能SW 
        
        //片选引脚CS  PB7通用推挽输出
        GPIOB->CRL &=~((u32)0xF<<28);
        GPIOB->CRL |= (0x3<<28);
        
        //数据控制选择DC  PA15通用推挽输出
        GPIOA->CRH &=~((u32)0xF<<28);
        GPIOA->CRH |= (0x3<<(15-8)*4);
        
        //复位引脚RES  PA4通用推挽输出
        GPIOA->CRL &= ~(0xF<<4*4);
        GPIOA->CRL |=  (0x3<<4*4);
                
        OLED_RST=0;//硬复位OLED
        OLED_RST=1;  

        //OLED配置
        OLED_WriteCMD(0xAE);//--turn off oled panel
        OLED_WriteCMD(0x02);//---SET low column address
        OLED_WriteCMD(0x10);//---SET high column address
        OLED_WriteCMD(0x40);//--SET start line address  SET Mapping RAM Display Start Line (0x00~0x3F)
        OLED_WriteCMD(0x81);//--SET contrast control register
        OLED_WriteCMD(0xCF);// SET SEG Output Current Brightness
        OLED_WriteCMD(0xA1);//--SET SEG/Column Mapping     0xa0左右反置 0xa1正常
        OLED_WriteCMD(0xC8);//SET COM/Row Scan Direction   0xc0上下反置 0xc8正常
        OLED_WriteCMD(0xA6);//--SET normal display
        OLED_WriteCMD(0xA8);//--SET multiplex ratio(1 to 64)
        OLED_WriteCMD(0x3f);//--1/64 duty
        OLED_WriteCMD(0xD3);//-SET display offSET        Shift Mapping RAM Counter (0x00~0x3F)
        OLED_WriteCMD(0x00);//-not offSET
        OLED_WriteCMD(0xd5);//--SET display clock divide ratio/oscillator frequency
        OLED_WriteCMD(0x80);//--SET divide ratio, SET Clock as 100 Frames/Sec
        OLED_WriteCMD(0xD9);//--SET pre-charge period
        OLED_WriteCMD(0xF1);//SET Pre-Charge as 15 Clocks & Discharge as 1 Clock
        OLED_WriteCMD(0xDA);//--SET com pins hardware configuration
        OLED_WriteCMD(0x12);
        OLED_WriteCMD(0xDB);//--SET vcomh
        OLED_WriteCMD(0x40);//SET VCOM Deselect Level
        OLED_WriteCMD(0x20);//-SET Page Addressing Mode 
        OLED_WriteCMD(0x02);//0x02 页地址模式, 0x00水平地址模式,0x01垂直地址模式
        OLED_WriteCMD(0x8D);//--SET Charge Pump enable/disable
        OLED_WriteCMD(0x14);//--SET(0x10) disable
        OLED_WriteCMD(0xA4);// Disable Entire Display On (0xa4/0xa5)
        OLED_WriteCMD(0xA6);// Disable Inverse Display On (0xa6/a7) 
        OLED_WriteCMD(0xAF);//--turn on oled panel
        OLED_Clear();
}
/*******************************************************
*函数名:OLED_WriteCMD
*功  能:往OLED写入指令
*参  数:byte:要写入命令   
*返  回:无
*备  注:
********************************************************/
void OLED_WriteCMD(u8 byte)
{
        OLED_CS=0;//片选
        OLED_DC=0;//数据指令线拉低,表示往CR写入指令
        SPI2_WriteReadByte(byte);//传输一个字节数据
        OLED_CS=1;//取消片选
}

/*******************************************************
*函数名:OLED_WriteDATA
*功  能:往OLED写入指令
*参  数:byte:要写入的数据   
*返  回:无
*备  注:
********************************************************/
void OLED_WriteDATA(u8 byte)
{
        OLED_CS=0;//片选
        OLED_DC=1;//数据指令线拉高,表示往DR写入数据
        SPI2_WriteReadByte(byte);//传输一个字节数据
        OLED_CS=1;//取消片选
}

/*******************************************************
*函数名:OLED_SetPos
*功  能:OLED屏幕内容起点地址设置函数
*参  数:x -- 列地址(0-127)  y--页地址 (0- 7)
*返  回:无
*备  注:OLED屏幕大小 128*8*8
命令(0xB0-0xB7)设置目标显示位置大行起始地址
命令(0x00-0x0F)设置列起始地址低四位
命令(0x10-0x17)设置列起始地址高四位

指令和地址整合成一个字节
指令(0x00)+1111 =0000  1111  
指令(0x10)+0111 =0001  0111 
0x5F
********************************************************/
void OLED_SetPos(u16 x, u16 y)
{
        OLED_WriteCMD(0xB0+y);//发送行地址
        OLED_WriteCMD(0x00+x&0xf);//发送列地址低四位 0x64 &0xf  x%16
        OLED_WriteCMD(0x10+((x&0xf0)>>4));//发送列地址高四位 0x64 &0xf0==》0x60>>4   ===>0x6  x/16
}

/*******************************************************
*函数名:OLED_Clear
*功  能:清屏函数
*参  数:无
*返  回:无
*备  注:OLED屏幕大小 128*8*8
********************************************************/
void OLED_Clear(void)
{
        u8 i,j;
        for(j=0;j<8;j++)
        {
                OLED_SetPos(0,j);
                for(i=0;i<128;i++)
                {
                        OLED_WriteDATA(0);
                }
        }
}
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值