实验 STM32 基于SPI的OLED屏显示
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屏显示相关推荐
- 【嵌入式】STM32基于SPI通信协议OLED屏显示
STM32基于SPI通信协议OLED屏显示 一.SPI协议和OLED介绍 1.SPI协议介绍 物理层 协议层 2.OLED显示屏介绍 二.显示个人学号姓名实验 1.题目要求 2.代码部分 1.完整代码 ...
- esp32 spi 驱动 oled 屏显示来自 PC 的画面
esp32 spi 驱动 oled 屏显示来自 PC 的画面 实验代码 gayhub 实验源码 设备及运行环境 装有python的电脑 Python 3.8.2 (tags/v3.8.2:7b3ab5 ...
- 基于SPI的OLED温湿度显示
本文首先会简单介绍SPI通信协议,然后后面的实验分为两个板块,一个是OLED屏的使用,另一个是在此基础上,结合上次实验(结尾会附上链接),用OLED屏显示温湿度信息. 实验器材:STM32F103C8 ...
- 基于STM32F4 的OLED屏显示噪点、花屏问题
现象 在实现OLED屏显示 内容时,屏幕会出现噪点:多点亮一些点位,使要显示的内容不能辨识. 原因 1.可能是因为当前io配置频率过高 2.延时时间太短 解决方法 方法1.更换io管脚为可高频io 例 ...
- 嵌入式作业使用STM32的SPI实现OLED屏显
目录 一.什么是SPI接口 二.使用OLED显示屏显示数据 三.自行修改程序实现显示学号和姓名 1.姓名学号的点阵 2. 实现显示代码 3.输入点阵代码 4.主函数设置 5.烧录 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 ...
- 用STM32F103达成基于I2C协议的AHT20温湿度传感器和OLED屏显示汉字
目录 一 I2C协议简介 硬件I2C与软件I2C 二 代码和ATH20芯片实现温湿度的串口显示 三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度 1 先用文字字模生成器 ...
- STM32硬件SPI驱动OLED
文章目录 一.OLED相关 1.OLED简介 2.0.96寸的OLED模块概述 3.模块引脚说明 4.汉字点阵编码原理 二.硬件SPI 1.SPI简介 2.SPI的引脚映射关系 三.SPI驱动的OLE ...
- 嵌入式开发-STM32硬件SPI驱动TFT屏
嵌入式开发-STM32硬件SPI驱动TFT屏 这次用到的TFT屏 CubeMX设置 代码编写 增加的内容 需要注意问题 代码下载 这次用到的TFT屏 现在的TFT屏幕已经很便宜了,65536色屏幕,2 ...
最新文章
- @ResponseBody 乱码
- 原生Js_简易图片轮播模板
- 《Java核心技术卷一》p60~p70 学长教我学Java(7)
- /hbase/WALs/desktop,xxxxxxxx-splitting is non empty: Directory is not empty
- 电脑微信不用手机确认_不用安装第三方软件,手机投屏到电脑就这么简单
- tomcat GET 编码疑惑
- 矩阵键盘简易计算机设计报告,矩阵键盘显设计报告..doc
- mysql的jar包文件在哪找_java连接mysql要导入的jar包在哪。
- 用java编写数组最小公倍数_[求助]Java编的求最小公倍数的程序,老是不对。。。调试了无数次了,请达人指教。。...
- csdn博客搬家:及其方便的博客迁移、搬家工具,支持主流博客平台----CsdnSyncHexo。
- 微信浏览器自动关闭页面
- windows 安装SNMP MIB Browser
- python自己制作节奏大师游戏_十分钟利用Python制作属于你自己的个性logo
- 3种方法解决word文档无法编辑
- 快速加速计算机的方法,电脑慢的快速解决办法 四种方法电脑速度变快10倍
- 曾国藩家书-修身篇 致诸弟·明师益友虚心请教
- 手把手教你最近很火的 微信公众号测试号推送消息
- 企业研究:赢在起跑线,首个10年便建起壁垒的新国都
- 互联网医院软件|互联网医院系统开发|在线问诊提高医疗效率
- Win10、Win7定时开关机
热门文章
- 传奇霸业维护服务器,37传奇霸业9月29日部分区服维护计划
- C语言实现字符的归一化,(5条消息)归一化方法总结
- 读书:习惯的力量-([美]杰克•霍吉)
- Context都没弄明白凭什么拿高薪?附小技巧
- 【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化)
- 优化方法与实践-第一次课程
- HTML5是什么与什么合作推出的语言,H5和Html5是一回事吗?-- -H5和Html5问答
- 联想小新进入BIOS
- Android中应用到的设计模式
- html是超文本标记语言而不是编程语