你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 SPI驱动OLED12864原理图和源代码分享

[复制链接]
STMCU小助手 发布时间:2022-4-21 21:00
一、原理图

20210220174119409.jpg

芯片引脚连接
20210220174119357.jpg

二、驱动程序

spi.c

  1. #include "spi.h"

  2. void SPI1_Init(void)
  3. {
  4.          GPIO_InitTypeDef GPIO_InitStructure;
  5.     SPI_InitTypeDef  SPI_InitStructure;

  6.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOA, ENABLE );//PORTA时钟使能
  7.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_SPI1,  ENABLE );//SPI1时钟使能         

  8.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  10.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA

  12.          GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);  //PB13/14/15上拉

  13.         SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  14.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
  15.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
  16.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
  17.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
  18.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  19.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
  20.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  21.         SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
  22.         SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

  23.         SPI_Cmd(SPI1, ENABLE); //使能SPI外设
  24.         
  25.         SPI1_ReadWriteByte(0xff);//启动传输                 


  26. }   
  27. //SPI 速度设置函数
  28. //SpeedSet:
  29. //SPI_BaudRatePrescaler_2   2分频   
  30. //SPI_BaudRatePrescaler_8   8分频   
  31. //SPI_BaudRatePrescaler_16  16分频  
  32. //SPI_BaudRatePrescaler_256 256分频

  33. void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
  34. {
  35.   assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
  36.         SPI1->CR1&=0XFFC7;
  37.         SPI1->CR1|=SPI_BaudRatePrescaler;        //设置SPI1速度
  38.         SPI_Cmd(SPI1,ENABLE);

  39. }

  40. //SPIx 读写一个字节
  41. //TxData:要写入的字节
  42. //返回值:读取到的字节
  43. u8 SPI1_ReadWriteByte(u8 TxData)
  44. {               
  45.         u8 retry=0;                                         
  46.         while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
  47.                 {
  48.                 retry++;
  49.                 if(retry>200)return 0;
  50.                 }                          
  51.         SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
  52.         retry=0;

  53.         while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
  54.                 {
  55.                 retry++;
  56.                 if(retry>200)return 0;
  57.                 }                                                              
  58.         return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据                                            
  59. }
复制代码

oled.c

  1. #include "oled.h"
  2. #include "stdlib.h"
  3. #include "oledfont.h"           
  4. #include "delay.h"
  5. #include "stdio.h"
  6. #include "spi.h"
  7. //OLED的显存
  8. //存放格式如下.
  9. //[0]0 1 2 3 ... 127        
  10. //[1]0 1 2 3 ... 127        
  11. //[2]0 1 2 3 ... 127        
  12. //[3]0 1 2 3 ... 127        
  13. //[4]0 1 2 3 ... 127        
  14. //[5]0 1 2 3 ... 127        
  15. //[6]0 1 2 3 ... 127        
  16. //[7]0 1 2 3 ... 127                           

  17. //向SSD1106写入一个字节。
  18. //dat:要写入的数据/命令
  19. //cmd:数据/命令标志 0,表示命令;1,表示数据;
  20. void OLED_WR_Byte(u8 dat,u8 cmd)
  21. {                          
  22.         if(cmd)
  23.           OLED_DC_Set();
  24.         else
  25.           OLED_DC_Clr();                  
  26.         OLED_CS_Clr();
  27.         SPI1_ReadWriteByte(dat);                                       
  28.         OLED_CS_Set();
  29.         OLED_DC_Set();            
  30. }

  31. void OLED_Set_Pos(unsigned char x, unsigned char y)
  32. {
  33.         OLED_WR_Byte(0xb0+y,OLED_CMD);
  34.         OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  35.         OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);
  36. }            
  37. //开启OLED显示   
  38. void OLED_Display_On(void)
  39. {
  40.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  41.         OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  42.         OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  43. }
  44. //关闭OLED显示     
  45. void OLED_Display_Off(void)
  46. {
  47.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  48.         OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
  49.         OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  50. }                                            
  51. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!         
  52. void OLED_Clear(void)  
  53. {  
  54.         u8 i,n;                    
  55.         for(i=0;i<8;i++)  
  56.         {  
  57.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  58.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  59.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  60.                 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  61.         } //更新显示
  62. }


  63. //在指定位置显示一个字符,包括部分字符
  64. //x:0~127
  65. //y:0~63
  66. //mode:0,反白显示;1,正常显示                                 
  67. //size:选择字体 16/12
  68. void OLED_ShowChar(u8 x,u8 y,u8 chr)
  69. {              
  70.         unsigned char c=0,i=0;        
  71.         c=chr-' ';//得到偏移后的值                        
  72.         if(x>Max_Column-1){x=0;y=y+2;}
  73.         if(SIZE ==16)
  74.         {
  75.                 OLED_Set_Pos(x,y);        
  76.                 for(i=0;i<8;i++)
  77.                 OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
  78.                 OLED_Set_Pos(x,y+1);
  79.                 for(i=0;i<8;i++)
  80.                 OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
  81.         }
  82. }
  83. //m^n函数
  84. u32 oled_pow(u8 m,u8 n)
  85. {
  86.         u32 result=1;         
  87.         while(n--)result*=m;   
  88.         return result;
  89. }                                 
  90. //显示2个数字
  91. //x,y :起点坐标         
  92. //len :数字的位数
  93. //size:字体大小
  94. //mode:模式        0,填充模式;1,叠加模式
  95. //num:数值(0~4294967295);                           
  96. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
  97. {                 
  98.         u8 t,temp;
  99.         u8 enshow=0;                                                   
  100.         for(t=0;t<len;t++)
  101.         {
  102.                 temp=(num/oled_pow(10,len-t-1))%10;
  103.                 if(enshow==0&&t<(len-1))
  104.                 {
  105.                         if(temp==0)
  106.                         {
  107.                                 OLED_ShowChar(x+(size/2)*t,y,' ');
  108.                                 continue;
  109.                         }else enshow=1;
  110.                           
  111.                 }
  112.                  OLED_ShowChar(x+(size/2)*t,y,temp+'0');
  113.         }
  114. }
  115. //显示一个字符号串
  116. void OLED_ShowString(u8 x,u8 y,u8 *chr)
  117. {
  118.         unsigned char j=0;
  119.         while (chr[j]!='\0')
  120.         {               
  121.                 OLED_ShowChar(x,y,chr[j]);
  122.                 x+=8;
  123.                 if(x>120)
  124.                 {
  125.                         x=0;
  126.                         y+=2;
  127.                 }
  128.                 j++;
  129.         }
  130. }
  131. /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
  132. void oled_draw_picture(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
  133. {
  134.         unsigned int j=0;
  135.         unsigned char x,y;

  136.         if(y1%8==0) y=y1/8;      
  137.         else y=y1/8+1;
  138.         for(y=y0;y<y1;y++)
  139.         {
  140.                 OLED_Set_Pos(x0,y);
  141.                 for(x=x0;x<x1;x++)
  142.                 {      
  143.                         OLED_WR_Byte(BMP[j++],OLED_DATA);
  144.                 }
  145.         }
  146. }
  147. void oled_gpio_init()
  148. {
  149.         GPIO_InitTypeDef  GPIO_InitStructure;

  150.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);

  151.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  152.         
  153.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8;                                 
  154.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
  155.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
  156.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                       
  157.         GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_8);

  158.         
  159. }



  160. //初始化SSD1306                                            
  161. void oled_init(void)
  162. {         
  163.         oled_gpio_init();
  164.         SPI1_Init();

  165. //        OLED_RST_Set();//复位使用系统复位,所有此处不需要再复位
  166. //        delay_ms(5);
  167. //        OLED_RST_Clr();
  168. //        delay_ms(5);
  169. //        OLED_RST_Set();
  170.                                           
  171.         OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  172.         OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  173.         OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  174.         OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  175.         OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  176.         OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
  177.         OLED_WR_Byte(0xA0,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
  178.         OLED_WR_Byte(0xC0,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  179.         OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  180.         OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  181.         OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  182.         OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
  183.         OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  184.         OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  185.         OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  186.         OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  187.         OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  188.         OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  189.         OLED_WR_Byte(0x12,OLED_CMD);
  190.         OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  191.         OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  192.         OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  193.         OLED_WR_Byte(0x02,OLED_CMD);//
  194.         OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  195.         OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  196.         OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  197.         OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  198.         OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
  199.         
  200.         OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
  201.         OLED_Clear();
  202.         OLED_Set_Pos(0,0);         
  203.         SPI1_SetSpeed(SPI_BaudRatePrescaler_2);
  204. }  
复制代码

main.c

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "oled.h"
  5. #include "tm1804.h"
  6. int main(void)
  7. {        
  8.         delay_init();            //延时函数初始化         
  9.         oled_init();
  10.         tm1804_init();
  11.         OLED_ShowString(0,0,"xupengxisxveryx1");
  12.         OLED_ShowString(0,2,"xupeng is very");
  13.         OLED_ShowString(0,4,"xupeng is very");
  14.         OLED_ShowString(0,6,"xupeng is very");
  15.         
  16.         while(1)
  17.         {
  18.                 set_tm1804_data(0xcc,0x00);
  19.                 delay_ms(1000);
  20.                 set_tm1804_data(0x00,0x00);
  21.                 delay_ms(1000);
  22.         }
  23. }
复制代码




收藏 评论0 发布时间:2022-4-21 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版