Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SPI
SPI
使用RT-Thread studio开启SPI框架驱动OLED
发布于 2021-09-08 10:46:14 浏览:1551
订阅该版
想学习使用SPI框架驱动OLED,就准备把中景园的程序移植到RTT上,参考了网上的步骤,在settings里开启spi,在board.c里复制HAL_SPI_MspInit,在board.h和stm32xxxx_hal_config.h里开启了spi,然后代码如下: ```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-09-07 Administrator the first version */ #include "OLED.h" #define SPI_BUS_NAME "spi1" #define SPI_SSD1306_DEVICE_NAME "spi10" #define RES_PIN 11 #define DC_PIN 12 #define CS_PIN 15 uint8_t OLED_GRAM[128][8]; static struct rt_spi_device* spi_dev_ssd1306; /* SPI设备ssd1306对象 */ int oled_spi_device_init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); //设备挂载到SPI总线,抽象为 spi10 设备,同时使用时还需进行 rt_spi_configure rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_15); return RT_EOK; } INIT_DEVICE_EXPORT(oled_spi_device_init);//自动初始化 int my_oled_init(void) { rt_pin_mode(RES_PIN, PIN_MODE_OUTPUT ); rt_pin_mode(DC_PIN, PIN_MODE_OUTPUT ); rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT ); spi_dev_ssd1306 = (struct rt_spi_device *)rt_device_find("spi10"); if (!spi_dev_ssd1306) { rt_kprintf("spi sample run failed! can't find %s device!\n", "spi10"); } else { // owner必须配置,因为默认为空,为空时无法进行初始化操作 spi_dev_ssd1306->bus->owner = spi_dev_ssd1306; // 必须!!! // 配置spi struct rt_spi_configuration cfg; cfg.data_width = 8; cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB; // 主机,模式0,高位在前 cfg.max_hz = 20 * 1000 * 1000; // SPI 接口时钟频率 rt_spi_configure(spi_dev_ssd1306, &cfg); // 此时才进行MspInit相关的时钟及IO口初始化 } OLED_Init(); return RT_EOK; } //OLED写一个字节 void OLED_WR_Byte(uint8_t dat, uint8_t cmd) { if(cmd) { OLED_DC_Set(); }else{ OLED_DC_Clr(); } rt_spi_send(spi_dev_ssd1306, &dat, 1); OLED_DC_Set(); } //开启OLED显示 void OLED_DisPlay_On(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵 OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕 } //关闭OLED显示 void OLED_DisPlay_Off(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵 OLED_WR_Byte(0xAF,OLED_CMD);//关闭屏幕 } //更新显存到OLED void OLED_Refresh(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址 OLED_WR_Byte(0x00,OLED_CMD); //设置低列起始地址 OLED_WR_Byte(0x10,OLED_CMD); //设置高列起始地址 for(n=0;n<128;n++) OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } //清屏函数 void OLED_Clear(void) { uint8_t i,n; for(i=0;i<8;i++) { for(n=0;n<128;n++) { OLED_GRAM[n][i]=0;//清除所有数据 } } OLED_Refresh();//更新显示 } //画点 //x:0~127 //y:0~63 void OLED_DrawPoint(uint8_t x,uint8_t y) { uint8_t i,m,n; i=y/8; m=y%8; n=1<
= r * r) { OLED_DrawPoint(x + a, y - b); OLED_DrawPoint(x - a, y - b); OLED_DrawPoint(x - a, y + b); OLED_DrawPoint(x + a, y + b); OLED_DrawPoint(x + b, y + a); OLED_DrawPoint(x + b, y - a); OLED_DrawPoint(x - b, y - a); OLED_DrawPoint(x - b, y + a); a++; num = (a * a + b * b) - r*r;//计算画的点离圆心的距离 if(num > 0) { b--; a--; } } } //OLED的初始化 void OLED_Init(void) { OLED_RES_Clr(); rt_thread_delay(200); OLED_RES_Set(); OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//-not offset OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WR_Byte(0x02,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5) OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD); OLED_Clear(); OLED_DrawCircle(50, 50, 20); OLED_Refresh(); } ``` 在OLED_Init最后想画个点测试是否成功,但是屏幕没有点亮,msh里输入list_device可以看见spi1和spi10是正常开启的,请问是哪个步骤做错了吗
查看更多
1
个回答
默认排序
按发布时间排序
jiao96
2021-09-08
这家伙很懒,什么也没写!
拿着个试试 ```c /* * Copyright (c) 2014-2019, Winning_technology * * SPDX-License-Identifier: None * * Change Logs: * Date Author Notes * 2019-07-19 Jiao newly-built */ /* * 程序清单:OLED屏幕底层驱动 */ #include
#include "oled_drv.h" #include "stdlib.h" #include
#include
#include "drv_spi.h" #define OLED_DC_PIN 4 /* 数据控制脚 */ #define Max_Column 128 #define Max_Row 64 #define X_WIDTH 128 #define Y_WIDTH 64 //OLED控制用函数 struct rt_spi_device *spi_device = RT_NULL; rt_uint8_t video_mem[8][128]; //显存,1K RAM空间 //屏幕命令 static void OLED_CMD(unsigned dat) { struct rt_spi_message spi_msg; rt_pin_write(OLED_DC_PIN,PIN_LOW); rt_memset(&spi_msg, 0x00, sizeof(spi_msg)); spi_msg.send_buf = &dat; spi_msg.length = 1; rt_spi_transfer_message(spi_device, &spi_msg); rt_pin_write(OLED_DC_PIN,PIN_LOW); } //开启OLED显示 void OLED_Display_On(void) { OLED_CMD(0X8D); //SET DCDC命令 OLED_CMD(0X14); //DCDC ON OLED_CMD(0XAF); //DISPLAY ON } //关闭OLED显示 void OLED_Display_Off(void) { OLED_CMD(0X8D); //SET DCDC命令 OLED_CMD(0X10); //DCDC OFF OLED_CMD(0XAE); //DISPLAY OFF } //刷屏,不刷不显示 void OLED_refresh(void) { struct rt_spi_message spi_msg; rt_uint8_t i; rt_memset(&spi_msg, 0x00, sizeof(spi_msg)); for(i=0;i<8;i++) { OLED_CMD(0xB0+i); OLED_CMD(0x02); OLED_CMD(0x10); rt_pin_write(OLED_DC_PIN,PIN_HIGH); spi_msg.send_buf = video_mem[i]; spi_msg.length = 128; rt_spi_transfer_message(spi_device, &spi_msg); rt_pin_write(OLED_DC_PIN,PIN_LOW); } } //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! void OLED_Clear(void) { rt_uint8_t i,n; for(i=0;i<8;i++)for(n=0;n<128;n++)video_mem[i][n]=0X00; // OLED_refresh();//更新显示 } //画点 //x:0~127 //y:0~63 //t:1 填充 0,清空 void OLED_DrawPoint(rt_uint8_t x,rt_uint8_t y,rt_uint8_t t) { rt_uint8_t pos,bx,temp=0; if(x>127||y>63)return;//超出范围了. pos=7-(y>>3); bx=y%8; temp=1<<(7-bx); if(t)video_mem[pos][x]|=temp; else video_mem[pos][x]&=~temp; } //x1,y1,x2,y2 填充区域的对角坐标 //确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63 //dot:0,清空;1,填充 void OLED_Fill(rt_uint8_t x1,rt_uint8_t y1,rt_uint8_t x2,rt_uint8_t y2,rt_uint8_t dot) { rt_uint8_t x,y; for(x=x1;x<=x2;x++) { for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot); } OLED_refresh();//更新显示 } /*OLED spi驱动初始化*/ rt_err_t oled_drv_init(void) { char *spi_dev_name="spi10"; /* 输入模式 */ rt_pin_mode(OLED_DC_PIN, PIN_MODE_OUTPUT); //OLED_DC rt_pin_write(OLED_DC_PIN,PIN_LOW); rt_hw_spi_device_attach("spi1",spi_dev_name,GPIOA,GPIO_PIN_12); if (spi_device != RT_NULL) { return 0; } spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); if (spi_device == RT_NULL) { rt_kprintf("SPI device %s not found!", spi_dev_name); return -RT_ENOSYS; } /* check SPI device type */ RT_ASSERT(spi_device->parent.type == RT_Device_Class_SPIDevice); /* configure SPI device*/ { struct rt_spi_configuration cfg; cfg.data_width = 8; cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ cfg.max_hz = 8 * 1000 * 1000; /* SPI Interface with Clock Speeds Up to 8 MHz */ rt_spi_configure(spi_device, &cfg); } if (rt_device_open((rt_device_t) spi_device, RT_DEVICE_OFLAG_WRONLY) != RT_EOK) { rt_kprintf("open SPI device %s error.", spi_dev_name); return -RT_ERROR; } return RT_EOK; } //显示初始化 void Display_Init(void) { oled_drv_init(); rt_thread_mdelay(300); OLED_CMD(0xAE); //关闭显示 OLED_CMD(0xD5); //设置时钟分频因子,震荡频率 OLED_CMD(80); //[3:0],分频因子;[7:4],震荡频率 OLED_CMD(0xA8); //设置驱动路数 OLED_CMD(0X3F); //默认0X3F(1/64) OLED_CMD(0xD3); //设置显示偏移 OLED_CMD(0X00); //默认为0 OLED_CMD(0x40); //设置显示开始行 [5:0],行数. OLED_CMD(0x8D); //电荷泵设置 OLED_CMD(0x14); //bit2,开启/关闭 OLED_CMD(0x20); //设置内存地址模式 OLED_CMD(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; OLED_CMD(0xA1); //段重定义设置,bit0:0,0->0;1,0->127; OLED_CMD(0xC0); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 OLED_CMD(0xDA); //设置COM硬件引脚配置 OLED_CMD(0x12); //[5:4]配置 OLED_CMD(0x81); //对比度设置 OLED_CMD(0xEF); //1~255;默认0X7F (亮度设置,越大越亮) OLED_CMD(0xD9); //设置预充电周期 OLED_CMD(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2; OLED_CMD(0xDB); //设置VCOMH 电压倍率 OLED_CMD(0x30); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; OLED_CMD(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) OLED_CMD(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示 OLED_CMD(0xAF); //开启显示 OLED_Clear(); OLED_refresh(); // rt_thread_mdelay(2000); } ```
撰写答案
登录
注册新账号
关注者
0
被浏览
1.6k
关于作者
Yuanq
这家伙很懒,什么也没写!
提问
11
回答
0
被采纳
0
关注TA
发私信
相关问题
1
BBB的SPI驱动
2
求个SPI上挂两个或多个设备的使用例子
3
SPI设备有个bug
4
spi flash 的fatfs使用一段时间后读写文件出现故障
5
SPI驱动
6
请教rt_spi_configure函数理解
7
SPI FLASH挂载的问题
8
SPI-FLASH 文件系统 SPIFFS
9
求助一个完整的 spi flash 驱动
10
关于同时使用文件系统与SPI FLASH的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
profinet从站主线error open adapt
2
2024 RT-Thread睿赛德开发者大会共探商业共赢的开源生态
3
rt-thread 小内存算法源码分析
4
env中添加lvgl软件包后,keil编译包--c99错误
5
【NXP-MCXA153】 定时器驱动移植
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
Debug
中断
编译报错
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
20
个答案
3
次被采纳
红枫
8
个答案
2
次被采纳
踩姑娘的小蘑菇
7
个答案
2
次被采纳
三世执戟
7
个答案
1
次被采纳
张世争
6
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
12
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部