STM32 基于SPI的OLED屏显示

  • 一、任务要求
  • 二、显示自己的学号和姓名
    • 1、例子程序的改写
      • (1)下载资料
      • (2)解压后找到文件,并用KEIL打开。
      • (3)改写程序
    • 2、连接硬件
    • 3、运行结果
  • 三、显示AHT20的温度和湿度
    • 1、例子程序改写
      • ①main.c的代码
      • ②i2c.c的代码
      • ③i2c.h的代码
      • ④usart.c的代码
      • ⑤usart.h的代码
    • 2、连接软件
    • 3、运行结果
  • 四、上下或左右的滑动显示长字符
    • 1、例子程序改写
    • 2、连接软件
    • 3、运行结果
  • 五、总结
  • 参考链接

一、任务要求

练习通过SPI总线实现OLED屏幕显示。
1、显示自己的学号和姓名。
2、显示AHT20的温度和湿度。
3、上下或左右的滑动显示长字符。

二、显示自己的学号和姓名

1、例子程序的改写

链接: 0.96inch SPI OLED Module资料
.

(1)下载资料

(2)解压后找到文件,并用KEIL打开。

注:看清楚名字,0.96inch_OLED_Demo_STM32F103ZET6_Hardware_4-wire_SPI

(3)改写程序

①打开PCtoLCD软件,生成字模的代码数组。

注:需要自行安装,该软件在野火资料包里的开发软件自带。

注:需要将其改成镜像,然后根据自己的想法进行旋转。这样才能在显示屏上显示出自己想要的方向

②找到oledfont.h文件,在里面添加个人需要显示的汉字子模。

const typFNT_GB16 cfont16[] =
{"向",0x02,0x00,0x04,0x00,0x08,0x00,0x7F,0xFC,0x40,0x04,0x40,0x04,0x47,0xC4,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x47,0xC4,
0x44,0x44,0x40,0x04,0x40,0x14,0x40,0x08,/*"向",0*/"洁",0x00,0x40,0x40,0x40,0x20,0x40,0x2F,0xFE,0x00,0x40,0x80,0x40,0x47,0xFC,0x50,0x00,0x10,0x00,0x23,0xF8,0xE2,0x08,0x22,0x08,
0x22,0x08,0x22,0x08,0x23,0xF8,0x02,0x08,/*"洁",1*/
};

③在test.c文件中,找到void TEST_MainPage(void)函数,将其修改。

void TEST_MainPage(void)
{   GUI_ShowString(28,0,"631807030xxx",16,1);GUI_ShowString(16,16,"xx",16,1);delay_ms(1500);
}

④在main.c文件中,找到while语句,修改。

 while(1) {  TEST_MainPage();         //ÏÔʾÐÕÃûѧºÅOLED_Clear(0); }

⑤修改成功后,编译下载,生成hex文件。

注:由于是直接用usb串口下载,所以需要修改下列的参数。

2、连接硬件

SPI引脚:
MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据;
MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据;
SCK:串口时钟,作为主设备的输入,从设备的输入;
NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

注:连线根据mian.c文件。

3、运行结果

三、显示AHT20的温度和湿度

1、例子程序改写

(1)依然使用同一个代码。
(2)打开工程,在user目录下加入i2c.c,usart.c文件。

(3)在HARDWARE的目录下添加

(4)将main.c的内容修改。

代码如下

①main.c的代码

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
#include "i2c.h"
#include "usart.h"
int main(void)
{   int *H,*T;int H1=0,T1=0;int a,b,c,d;H=&H1;T=&T1;delay_init();                  //延时函数初始化      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级   OLED_Init();                     //初始化OLED  OLED_Clear(0);             //清屏(全黑)while(1) { read_AHT20_once(T,H);GUI_ShowCHinese(16,10,16,"温度:",1);a=*T/10;b=*T%10;GUI_ShowNum(60,10,a,2,16,1);GUI_ShowString(80,10,".",16,1);GUI_ShowNum(82,10,b,2,16,1);GUI_ShowCHinese(16,30,16,"湿度:",1);c=*H/10;d=*H%10;GUI_ShowNum(60,30,c,2,16,1);GUI_ShowString(80,30,".",16,1);GUI_ShowNum(82,30,d,2,16,1);}
}

②i2c.c的代码

#include "i2c.h"
#include "delay.h"uint8_t   ack_status=0;
uint8_t   readByte[6];
uint8_t   AHT20_status=0;uint32_t  H1=0;  //Humility
uint32_t  T1=0;  //Temperatureuint8_t  AHT20_OutData[4];
uint8_t  AHT20sendOutData[10] = {0xFA, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF};void IIC_Init(void)
{                        GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);IIC_SCL=1;IIC_SDA=1;}
//产生IIC起始信号
void IIC_Start(void)
{SDA_OUT();     //sda线输出IIC_SDA=1;       IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDA设置为输入  IIC_SDA=1;delay_us(1);    IIC_SCL=1;delay_us(1);   while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0       return 0;
}
//产生ACK应答
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{                        u8 t;   SDA_OUT();         IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){              IIC_SDA=(txd&0x80)>>7;txd<<=1;      delay_us(2);   //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0;    delay_us(2);}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++;   delay_us(1); }                   if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK   return receive;
}void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr)
{IIC_Start();  if(device_addr==0xA0) //eeprom地址大于1字节IIC_Send_Byte(0xA0 + ((addr/256)<<1));//发送高地址elseIIC_Send_Byte(device_addr);       //发器件地址IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF);   //发送低地址IIC_Wait_Ack(); IIC_Send_Byte(data);     //发送字节                              IIC_Wait_Ack();                     IIC_Stop();//产生一个停止条件 if(device_addr==0xA0) //delay_ms(10);elsedelay_us(2);
}uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead)  //读寄存器或读数据
{   uint16_t data;IIC_Start();  if(device_addr==0xA0)IIC_Send_Byte(0xA0 + ((addr/256)<<1));elseIIC_Send_Byte(device_addr); IIC_Wait_Ack();IIC_Send_Byte(addr&0xFF);   //发送低地址IIC_Wait_Ack(); IIC_Start();      IIC_Send_Byte(device_addr+1);      //发器件地址IIC_Wait_Ack();if(ByteNumToRead == 1)//LM75温度数据为11bit{data=IIC_Read_Byte(0);}else{data=IIC_Read_Byte(1);data=(data<<8)+IIC_Read_Byte(0);}IIC_Stop();//产生一个停止条件       return data;
}/**********
*上面部分为IO口模块I2C配置
*
*从这以下开始为AHT20的配置I2C
*函数名有IIC和I2C的区别,请注意!!!!!
*
*2020/2/23最后修改日期
*
***********/
void  read_AHT20_once(int *T,int *H)
{delay_ms(10);reset_AHT20();delay_ms(10);init_AHT20();delay_ms(10);startMeasure_AHT20();delay_ms(80);read_AHT20(T,H);delay_ms(5);
}void  reset_AHT20(void)
{I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("1");else printf("1-n-");I2C_WriteByte(0xBA);ack_status = Receive_ACK();if(ack_status) printf("2");else printf("2-n-");I2C_Stop();/*AHT20_OutData[0] = 0;AHT20_OutData[1] = 0;AHT20_OutData[2] = 0;AHT20_OutData[3] = 0;*/
}void  init_AHT20(void)
{I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("3");else printf("3-n-");    I2C_WriteByte(0xE1);ack_status = Receive_ACK();if(ack_status) printf("4");else printf("4-n-");I2C_WriteByte(0x08);ack_status = Receive_ACK();if(ack_status) printf("5");else printf("5-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("6");else printf("6-n-");I2C_Stop();
}void startMeasure_AHT20(void)
{//------------I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("7");else printf("7-n-");I2C_WriteByte(0xAC);ack_status = Receive_ACK();if(ack_status) printf("8");else printf("8-n-");I2C_WriteByte(0x33);ack_status = Receive_ACK();if(ack_status) printf("9");else printf("9-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("10");else printf("10-n-");I2C_Stop();
}void read_AHT20(int *T,int *H)
{uint8_t   i;for(i=0; i<6; i++){readByte[i]=0;}//-------------I2C_Start();I2C_WriteByte(0x71);ack_status = Receive_ACK();readByte[0]= I2C_ReadByte();Send_ACK();readByte[1]= I2C_ReadByte();Send_ACK();readByte[2]= I2C_ReadByte();Send_ACK();readByte[3]= I2C_ReadByte();Send_ACK();readByte[4]= I2C_ReadByte();Send_ACK();readByte[5]= I2C_ReadByte();SendNot_Ack();//Send_ACK();I2C_Stop();//--------------if( (readByte[0] & 0x68) == 0x08 ){H1 = readByte[1];H1 = (H1<<8) | readByte[2];H1 = (H1<<8) | readByte[3];H1 = H1>>4;H1 = (H1*1000)/1024/1024;T1 = readByte[3];T1 = T1 & 0x0000000F;T1 = (T1<<8) | readByte[4];T1 = (T1<<8) | readByte[5];T1 = (T1*2000)/1024/1024 - 500;AHT20_OutData[0] = (H1>>8) & 0x000000FF;AHT20_OutData[1] = H1 & 0x000000FF;AHT20_OutData[2] = (T1>>8) & 0x000000FF;AHT20_OutData[3] = T1 & 0x000000FF;}else{AHT20_OutData[0] = 0xFF;AHT20_OutData[1] = 0xFF;AHT20_OutData[2] = 0xFF;AHT20_OutData[3] = 0xFF;printf("失败了");}printf("\r\n");printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);printf("\r\n");*T=T1;*H=H1;
}uint8_t  Receive_ACK(void)
{uint8_t result=0;uint8_t cnt=0;IIC_SCL = 0;SDA_IN(); delay_us(4);IIC_SCL = 1;delay_us(4);while(READ_SDA && (cnt<100)){cnt++;}IIC_SCL = 0;delay_us(4);if(cnt<100){result=1;}return result;
}void  Send_ACK(void)
{SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);SDA_IN();
}void  SendNot_Ack(void)
{SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 1;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4);
}void I2C_WriteByte(uint8_t  input)
{uint8_t  i;SDA_OUT();for(i=0; i<8; i++){IIC_SCL = 0;delay_ms(5);if(input & 0x80){IIC_SDA = 1;//delaymm(10);}else{IIC_SDA = 0;//delaymm(10);}IIC_SCL = 1;delay_ms(5);input = (input<<1);}IIC_SCL = 0;delay_us(4);SDA_IN();delay_us(4);
}   uint8_t I2C_ReadByte(void)
{uint8_t  resultByte=0;uint8_t  i=0, a=0;IIC_SCL = 0;SDA_IN();delay_ms(4);for(i=0; i<8; i++){IIC_SCL = 1;delay_ms(3);a=0;if(READ_SDA){a=1;}else{a=0;}//resultByte = resultByte | a;resultByte = (resultByte << 1) | a;IIC_SCL = 0;delay_ms(3);}SDA_IN();delay_ms(10);return   resultByte;
}void  set_AHT20sendOutData(void)
{/* --------------------------* 0xFA 0x06 0x0A temperature(2 Bytes) humility(2Bytes) short Address(2 Bytes)* And Check (1 byte)* -------------------------*/AHT20sendOutData[3] = AHT20_OutData[0];AHT20sendOutData[4] = AHT20_OutData[1];AHT20sendOutData[5] = AHT20_OutData[2];AHT20sendOutData[6] = AHT20_OutData[3];//  AHT20sendOutData[7] = (drf1609.shortAddress >> 8) & 0x00FF;
//  AHT20sendOutData[8] = drf1609.shortAddress  & 0x00FF;//    AHT20sendOutData[9] = getXY(AHT20sendOutData,10);
}void  I2C_Start(void)
{SDA_OUT();IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4);IIC_SDA = 0;delay_ms(4);IIC_SCL = 0;delay_ms(4);
}void  I2C_Stop(void)
{SDA_OUT();IIC_SDA = 0;delay_ms(4);IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4);
}

③i2c.h的代码

#ifndef __BSP_I2C_H
#define __BSP_I2C_H#include "sys.h"
#include "delay.h"
#include "usart.h"
//使用IIC1 挂载M24C02,OLED,LM75AD,HT1382    PB6,PB7#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}//IO操作函数
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA
#define READ_SDA   PBin(7)  //输入SDA //IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口
void IIC_Start(void);               //发送IIC开始信号
void IIC_Stop(void);                //发送IIC停止信号
void IIC_Send_Byte(u8 txd);         //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void);              //IIC等待ACK信号
void IIC_Ack(void);                 //IIC发送ACK信号
void IIC_NAck(void);                //IIC不发送ACK信号void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr);
uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead);//寄存器地址,器件地址,要读的字节数  void  read_AHT20_once(int *T,int *H);
void  reset_AHT20(void);
void  init_AHT20(void);
void  startMeasure_AHT20(void);
void  read_AHT20(int *T,int *H);
uint8_t  Receive_ACK(void);
void  Send_ACK(void);
void  SendNot_Ack(void);
void I2C_WriteByte(uint8_t  input);
uint8_t I2C_ReadByte(void);
void  set_AHT20sendOutData(void);
void  I2C_Start(void);
void  I2C_Stop(void);
#endif

④usart.c的代码

#include "sys.h"
#include "usart.h"//STM32F103核心板例程
//库函数版本例程
/********** mcudev.taobao.com 出品  ********///
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h"                 //ucos 使用
#endif
//
//STM32开发板
//串口1初始化           //     //
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{ int handle; }; FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{ x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   USART1->DR = (u8) ch;      return ch;
}
#endif /*使用microLib的方法*//*
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}  return ch;
}
int GetKey (void)  { while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));
}
*/#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0,   接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记   void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX   PA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//USART1_RX     PA.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);  //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断USART_Cmd(USART1, ENABLE);                    //使能串口 }void USART1_IRQHandler(void)                   //串口1中断服务程序{u8 Res;
#ifdef OS_TICKS_PER_SEC     //如果时钟节拍数定义了,说明要使用ucosII了.OSIntEnter();
#endifif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);//(USART1->DR);   //读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始else USART_RX_STA|=0x8000;  //接收完成了 }else //还没收到0X0D{   if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收   }      }}          }
#ifdef OS_TICKS_PER_SEC     //如果时钟节拍数定义了,说明要使用ucosII了.OSIntExit();
#endif
}
#endif

⑤usart.h的代码

#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h" //STM32F103核心板例程
//库函数版本例程
/********** mcudev.taobao.com 出品  ********///
//STM32开发板
//串口1初始化           #define USART_REC_LEN            200     //定义最大接收字节数 200
#define EN_USART1_RX            1           //使能(1)/禁止(0)串口1接收extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA;                //接收状态标记
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
#endif

2、连接软件

3、运行结果

四、上下或左右的滑动显示长字符

1、例子程序改写

(1)依然是同一个例子程序
(2)在HARDWAR目录下的oled.c文件中添加一个roll函数。

注:这个函数是表示显示字符的时候的滚动依据。

void roll(void)
{![在这里插入图片描述](https://img-blog.csdnimg.cn/20210105230051954.gif)OLED_WR_Byte(0x2e,OLED_CMD); //关滚动      OLED_WR_Byte(0x29,OLED_CMD); //29向右     OLED_WR_Byte(0x00,OLED_CMD); //A:空字节OLED_WR_Byte(0x00,OLED_CMD); // B:水平起始页      OLED_WR_Byte(0x07,OLED_CMD); //C:水平滚动速度       OLED_WR_Byte(0x07,OLED_CMD); //D:水平结束页       OLED_WR_Byte(0x01,OLED_CMD); //E:每次垂直滚动位移      OLED_WR_Byte(0x2F,OLED_CMD); //开滚动
}

(3)将main.c文件修改如下:

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{   delay_init();                  //延时函数初始化      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级   OLED_Init();                     //初始化OLED  OLED_Clear(0);             //清屏(全黑)while(1) { TEST_MainPage();    delay_ms(50);roll();}
}

(4)在test.c文件里面修改函数

void TEST_MainPage(void)
{   GUI_ShowString(28,0,"hello",16,1);GUI_ShowString(16,16,"Welcome to the training room 205",16,1);delay_ms(1500);
}

2、连接软件

3、运行结果

五、总结

本次stm32实验主要是在OLED屏幕上显示自己的学号和名字,显示温湿度和长字符,后续还需深入学习。

参考链接

链接: STM32 SPI协议接口下的OLED屏显示.
链接: 基于SPI接口的OLED数据显示.

实验 STM32 基于SPI的OLED屏显示相关推荐

  1. 【嵌入式】STM32基于SPI通信协议OLED屏显示

    STM32基于SPI通信协议OLED屏显示 一.SPI协议和OLED介绍 1.SPI协议介绍 物理层 协议层 2.OLED显示屏介绍 二.显示个人学号姓名实验 1.题目要求 2.代码部分 1.完整代码 ...

  2. esp32 spi 驱动 oled 屏显示来自 PC 的画面

    esp32 spi 驱动 oled 屏显示来自 PC 的画面 实验代码 gayhub 实验源码 设备及运行环境 装有python的电脑 Python 3.8.2 (tags/v3.8.2:7b3ab5 ...

  3. 基于SPI的OLED温湿度显示

    本文首先会简单介绍SPI通信协议,然后后面的实验分为两个板块,一个是OLED屏的使用,另一个是在此基础上,结合上次实验(结尾会附上链接),用OLED屏显示温湿度信息. 实验器材:STM32F103C8 ...

  4. 基于STM32F4 的OLED屏显示噪点、花屏问题

    现象 在实现OLED屏显示 内容时,屏幕会出现噪点:多点亮一些点位,使要显示的内容不能辨识. 原因 1.可能是因为当前io配置频率过高 2.延时时间太短 解决方法 方法1.更换io管脚为可高频io 例 ...

  5. 嵌入式作业使用STM32的SPI实现OLED屏显

    目录 一.什么是SPI接口 二.使用OLED显示屏显示数据 三.自行修改程序实现显示学号和姓名 1.姓名学号的点阵 2. 实现显示代码 3.输入点阵代码 4.主函数设置 5.烧录 6.结果 四.自行修 ...

  6. 基于SPI协议OLED屏显实例

    目录 一.SPI协议 1.1 SPI简介 1.2 SPI四线 1.3 SPI四种工作模式 1.4 SPI时序图 二.项目实现 2.1 实验准备 2.2 字模提取 2.3 程序代码 2.4 硬件连接 2 ...

  7. 用STM32F103达成基于I2C协议的AHT20温湿度传感器和OLED屏显示汉字

    目录 一 I2C协议简介 硬件I2C与软件I2C 二 代码和ATH20芯片实现温湿度的串口显示 三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度 1 先用文字字模生成器 ...

  8. STM32硬件SPI驱动OLED

    文章目录 一.OLED相关 1.OLED简介 2.0.96寸的OLED模块概述 3.模块引脚说明 4.汉字点阵编码原理 二.硬件SPI 1.SPI简介 2.SPI的引脚映射关系 三.SPI驱动的OLE ...

  9. 嵌入式开发-STM32硬件SPI驱动TFT屏

    嵌入式开发-STM32硬件SPI驱动TFT屏 这次用到的TFT屏 CubeMX设置 代码编写 增加的内容 需要注意问题 代码下载 这次用到的TFT屏 现在的TFT屏幕已经很便宜了,65536色屏幕,2 ...

最新文章

  1. @ResponseBody 乱码
  2. 原生Js_简易图片轮播模板
  3. 《Java核心技术卷一》p60~p70 学长教我学Java(7)
  4. /hbase/WALs/desktop,xxxxxxxx-splitting is non empty: Directory is not empty
  5. 电脑微信不用手机确认_不用安装第三方软件,手机投屏到电脑就这么简单
  6. tomcat GET 编码疑惑
  7. 矩阵键盘简易计算机设计报告,矩阵键盘显设计报告..doc
  8. mysql的jar包文件在哪找_java连接mysql要导入的jar包在哪。
  9. 用java编写数组最小公倍数_[求助]Java编的求最小公倍数的程序,老是不对。。。调试了无数次了,请达人指教。。...
  10. csdn博客搬家:及其方便的博客迁移、搬家工具,支持主流博客平台----CsdnSyncHexo。
  11. 微信浏览器自动关闭页面
  12. windows 安装SNMP MIB Browser
  13. python自己制作节奏大师游戏_十分钟利用Python制作属于你自己的个性logo
  14. 3种方法解决word文档无法编辑
  15. 快速加速计算机的方法,电脑慢的快速解决办法 四种方法电脑速度变快10倍
  16. 曾国藩家书-修身篇 致诸弟·明师益友虚心请教
  17. 手把手教你最近很火的 微信公众号测试号推送消息
  18. 企业研究:赢在起跑线,首个10年便建起壁垒的新国都
  19. 互联网医院软件|互联网医院系统开发|在线问诊提高医疗效率
  20. Win10、Win7定时开关机

热门文章

  1. 传奇霸业维护服务器,37传奇霸业9月29日部分区服维护计划
  2. C语言实现字符的归一化,(5条消息)归一化方法总结
  3. 读书:习惯的力量-([美]杰克•霍吉)
  4. Context都没弄明白凭什么拿高薪?附小技巧
  5. 【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化)
  6. 优化方法与实践-第一次课程
  7. HTML5是什么与什么合作推出的语言,H5和Html5是一回事吗?-- -H5和Html5问答
  8. 联想小新进入BIOS
  9. Android中应用到的设计模式
  10. html是超文本标记语言而不是编程语