切换到宽版
  • 4490阅读
  • 21回复

[C51]STC15硬件SPI驱动96*96 OLED屏 [复制链接]

上一主题 下一主题
离线961259337
 

发帖
436
M币
280
专家
3
粉丝
30
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2017-12-26
— 本帖被 發騷友 执行加亮操作(2018-02-12) —
看群里玩白光的OLED屏很漂亮,心里痒痒啊,淘宝买个oled屏一查都不便宜,,,
千挑万选的找到一家还算便宜的,他家还有其他彩色TFT屏,也是spi驱动的,价格比较合适了啊
(免费给他们打广告了),,,

由于初次接触oled屏,对着全英文的datasheet研究了好几天终于写出来驱动了。不敢独享,发出来
让坛友们有需要的可以参考下,卖家给的是stm32的例程。

这个oled屏幕起始是16级灰度的屏,很少见这种有灰度的oled屏吧,哈哈,这么重要的卖点卖家都
没写到宝贝详情里去。。。。

卖家宣传照片


我驱动以后的

选了四级灰度展示一下








下面是程序,新手,能用,写的不好大神们改改~

  1. #include <stc15.h>                                //本例程为SSD1329驱动芯片的96x96OLED屏
  2. sbit RSDC=P1^0;          //即D/C  0是command  1是data
  3. sbit CS=P1^1;          //片选        低有效
  4. struct hanzi                                 // 汉字字模数据结构
  5. {
  6.         unsigned char index[2];         // 汉字内码索引
  7.         unsigned char msk[32];         // 点阵码数据
  8. };
  9. struct hanzi code hz[]=
  10. {
  11. "床", 0x01,0x00,0x00,0x84,0x3F,0xFE,0x20,0x80,
  12.       0x20,0x80,0x20,0x88,0x3F,0xFC,0x20,0x80,
  13.       0x21,0xC0,0x21,0xA0,0x22,0x90,0x24,0x88,
  14.       0x48,0x8E,0x50,0x84,0x80,0x80,0x00,0x80,
  15. "前", 0x10,0x10,0x0C,0x30,0x04,0x44,0xFF,0xFE,
  16.       0x00,0x00,0x3E,0x08,0x22,0x48,0x22,0x48,
  17.       0x3E,0x48,0x22,0x48,0x22,0x48,0x3E,0x48,
  18.       0x22,0x08,0x22,0x08,0x2A,0x28,0x24,0x10,
  19. "明", 0x00,0x04,0x04,0xFE,0x7E,0x84,0x44,0x84,
  20.       0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,
  21.       0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,
  22.       0x01,0x04,0x01,0x04,0x02,0x14,0x04,0x08,
  23. "月", 0x00,0x10,0x0F,0xF8,0x08,0x10,0x08,0x10,
  24.       0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,
  25.       0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,
  26.       0x10,0x10,0x10,0x10,0x20,0x50,0x40,0x20,
  27. "光", 0x01,0x00,0x21,0x08,0x11,0x0C,0x09,0x10,
  28.       0x09,0x20,0x01,0x04,0xFF,0xFE,0x04,0x40,
  29.       0x04,0x40,0x04,0x40,0x04,0x40,0x08,0x40,
  30.       0x08,0x42,0x10,0x42,0x20,0x3E,0x40,0x00,
  31. "疑", 0x20,0x00,0x26,0xFC,0x38,0x08,0x22,0x50,
  32.       0x1E,0x20,0x21,0xFE,0x3E,0x22,0x48,0x24,
  33.       0x08,0xA0,0xFE,0xB8,0x08,0xA0,0x08,0xA0,
  34.       0x14,0xE0,0x22,0xA0,0x41,0x1E,0x02,0x04,
  35. "是", 0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,
  36.       0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x04,
  37.       0xFF,0xFE,0x01,0x00,0x09,0x20,0x09,0xF0,
  38.       0x09,0x00,0x15,0x00,0x23,0x06,0x40,0xFC,
  39. "地", 0x00,0x40,0x20,0x40,0x22,0x40,0x22,0x40,
  40.       0x22,0x48,0x22,0x7C,0xFB,0xC8,0x26,0x48,
  41.       0x22,0x48,0x22,0x48,0x22,0x68,0x22,0x50,
  42.       0x3A,0x42,0xE2,0x02,0x41,0xFE,0x00,0x00,
  43. "上", 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
  44.       0x01,0x10,0x01,0xF8,0x01,0x00,0x01,0x00,
  45.       0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
  46.       0x01,0x00,0x01,0x04,0xFF,0xFE,0x00,0x00,
  47. "霜", 0x1F,0xF0,0x01,0x00,0x7F,0xFE,0x41,0x02,
  48.       0x9D,0x74,0x01,0x00,0x1D,0x70,0x08,0x04,
  49.       0x08,0xFE,0x7E,0x84,0x08,0xFC,0x1C,0x84,
  50.       0x2A,0xFC,0x48,0x84,0x08,0xFC,0x08,0x84,
  51. "举", 0x22,0x08,0x19,0x18,0x09,0x20,0x00,0x44,
  52.       0xFF,0xFE,0x04,0x40,0x09,0x20,0x11,0x10,
  53.       0x2F,0xEE,0xC1,0x04,0x01,0x10,0x3F,0xF8,
  54.       0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
  55. "头", 0x00,0x80,0x00,0x80,0x08,0x80,0x06,0x80,
  56.       0x22,0x80,0x18,0x80,0x08,0x80,0x00,0x84,
  57.       0xFF,0xFE,0x00,0x80,0x01,0x00,0x01,0x60,
  58.       0x02,0x10,0x04,0x08,0x18,0x0C,0x60,0x04,
  59. "望", 0x10,0x04,0x0A,0x7E,0xFF,0x44,0x20,0x7C,
  60.       0x20,0x44,0x26,0x7C,0x38,0x44,0x20,0x8C,
  61.       0x00,0x00,0x3F,0xF8,0x01,0x00,0x1F,0xF0,
  62.       0x01,0x00,0x01,0x04,0xFF,0xFE,0x00,0x00,
  63. "低", 0x10,0x08,0x10,0x3C,0x17,0xC0,0x24,0x40,
  64.       0x24,0x40,0x64,0x40,0xA4,0x44,0x27,0xFE,
  65.       0x24,0x20,0x24,0x20,0x24,0x20,0x24,0x90,
  66.       0x25,0x12,0x26,0x4A,0x24,0x2A,0x20,0x04,
  67. "思", 0x00,0x08,0x3F,0xFC,0x21,0x08,0x21,0x08,
  68.       0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,
  69.       0x21,0x08,0x3F,0xF8,0x20,0x08,0x02,0x00,
  70.       0x51,0x88,0x50,0x96,0x90,0x12,0x0F,0xF0,
  71. "故", 0x10,0x40,0x10,0x40,0x10,0x40,0x14,0x44,
  72.       0xFE,0xFE,0x11,0x08,0x12,0x88,0x10,0x88,
  73.       0x7C,0x88,0x44,0x88,0x44,0x50,0x44,0x20,
  74.       0x44,0x20,0x7C,0x50,0x44,0x8E,0x03,0x04,
  75. "乡", 0x02,0x00,0x02,0x00,0x04,0x20,0x08,0x20,
  76.       0x10,0x40,0x3F,0x80,0x01,0x00,0x02,0x08,
  77.       0x04,0x08,0x3F,0xF0,0x00,0x20,0x00,0x40,
  78.       0x00,0x80,0x03,0x00,0x0C,0x00,0x70,0x00,
  79. "静", 0x08,0x40,0x08,0x40,0x7E,0xF8,0x09,0x10,
  80.       0x3E,0x24,0x08,0xFE,0xFF,0x24,0x00,0x24,
  81.       0x3F,0xFE,0x22,0x24,0x3E,0x24,0x22,0xFC,
  82.       0x3E,0x24,0x22,0x20,0x22,0xA0,0x26,0x40,
  83. "夜", 0x02,0x00,0x01,0x04,0xFF,0xFE,0x08,0x80,
  84.       0x08,0x80,0x10,0xF8,0x11,0x08,0x32,0x88,
  85.       0x56,0x50,0x99,0x10,0x10,0xA0,0x10,0x40,
  86.       0x10,0xA0,0x11,0x10,0x12,0x0E,0x1C,0x04,
  87. "唐", 0x01,0x00,0x00,0x88,0x3F,0xFC,0x20,0x80,
  88.       0x2F,0xF8,0x20,0x88,0x3F,0xFE,0x20,0x88,
  89.       0x2F,0xF8,0x20,0x80,0x2F,0xF8,0x28,0x08,
  90.       0x48,0x08,0x48,0x08,0x8F,0xF8,0x08,0x08,
  91. "李", 0x01,0x00,0x01,0x08,0x7F,0xFC,0x01,0x00,
  92.       0x05,0x40,0x09,0x30,0x31,0x0E,0xC1,0x04,
  93.       0x0F,0xE0,0x00,0x40,0x01,0x88,0x7F,0xFC,
  94.       0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,
  95. "白", 0x02,0x00,0x04,0x00,0x08,0x08,0x3F,0xFC,
  96.       0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,
  97.       0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,
  98.       0x20,0x08,0x3F,0xF8,0x20,0x08,0x00,0x00,
  99. "。", 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  100.       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  101.       0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,
  102.       0x66,0x00,0x66,0x00,0x3C,0x00,0x00,0x00,
  103. ",", 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  104.       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  105.       0x0C,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,
  106.       0x04,0x00,0x08,0x00,0x10,0x00,0x00,0x00
  107. };
  108. void init_oled();                                                  //屏初始化,各种datasheet的设置,官方参考数据
  109. void WriteComm(unsigned char com);                  //单片机写命令
  110. void WriteData(unsigned char dat);                  //单片机写数据
  111. void init_SPI();                                                  //单片机SPI初始化
  112. void Delayms(unsigned int t);
  113. void sawhz(unsigned char x,unsigned char y,unsigned char c[2]);                  //设置起止坐标并写汉字数据
  114. void clear();                                                          //清屏
  115. void write(unsigned dat);                                  //最终写data函数,最高亮度,由4bit变1bit
  116.                                                                                   //因为本驱动是一个Byte的其中4位控制一个led像素点,共16种灰度模式,1111为亮  0000为熄灭
  117.                                                                                   //比如一个字节的低四位是D0像素,高四位是D1像素,依次类推
  118. //void writehz(unsigned char c[2]);
  119. unsigned char m;
  120. unsigned int i;
  121. void main()
  122. {
  123.     P0M0 = 0x00;
  124.     P0M1 = 0x00;
  125.     P1M0 = 0x00;
  126.     P1M1 = 0x00;
  127.     P2M0 = 0x00;
  128.     P2M1 = 0x00;
  129.     P3M0 = 0x00;
  130.     P3M1 = 0x00;
  131.     P4M0 = 0x00;
  132.     P4M1 = 0x00;
  133.     P5M0 = 0x00;
  134.     P5M1 = 0x00;
  135.     P6M0 = 0x00;
  136.     P6M1 = 0x00;
  137.     P7M0 = 0x00;
  138.     P7M1 = 0x00;                                //全设置为准双向口
  139.         init_SPI();
  140.         init_oled();
  141.         clear();
  142.         sawhz(12,0,"静");
  143.         sawhz(20,0,"夜");
  144.         sawhz(28,0,"思");
  145.         sawhz(8,16,"唐");
  146.         sawhz(20,16,"李");
  147.         sawhz(28,16,"白");
  148.         sawhz(0,32,"床");
  149.         sawhz(8,32,"前");
  150.         sawhz(16,32,"明");
  151.         sawhz(24,32,"月");
  152.         sawhz(32,32,"光");
  153.         sawhz(40,32,",");
  154.         sawhz(0,48,"疑");
  155.         sawhz(8,48,"是");
  156.         sawhz(16,48,"地");
  157.         sawhz(24,48,"上");
  158.         sawhz(32,48,"霜");
  159.         sawhz(40,48,"。");
  160.         sawhz(0,64,"举");
  161.         sawhz(8,64,"头");
  162.         sawhz(16,64,"望");
  163.         sawhz(24,64,"明");
  164.         sawhz(32,64,"月");
  165.         sawhz(40,64,",");
  166.         sawhz(0,80,"低");
  167.         sawhz(8,80,"头");
  168.         sawhz(16,80,"思");
  169.         sawhz(24,80,"故");
  170.         sawhz(32,80,"乡");
  171.         sawhz(40,80,"。");
  172.         while(1);
  173. }
  174. void clear()                //清屏
  175. {
  176.         for(i=4608;i>0;i--)
  177.                 WriteData(0x00);
  178. }
  179. /*
  180. void writehz(unsigned char c[2])
  181. {
  182.         unsigned char i,k;
  183.         for(k=0;k<23;k++)                           //23 代表字库中的个数  轮询方式查询
  184.         {
  185.                 if((hz[k].index[0]==c[0])&&(hz[k].index[1]==c[1]))                         //数据结构查询
  186.                 {
  187.                         for(i=0;i<32;i++)
  188.                                 write(hz[k].msk);
  189.                 }
  190.         }
  191. }
  192. */
  193. void sawhz(unsigned char x,unsigned char y,unsigned char c[2])                         //setxy and writehz  头字母saw  设置起止坐标并写汉字
  194. {
  195.         unsigned char i,k;
  196.         WriteComm(0x15);//SET COLUMN ADDR
  197.         WriteComm(0x10+x);//第 16+x 列开始                 即本屏幕的第一列
  198.         WriteComm(0x10+x+7);  //第16+x+3列结束  
  199.         WriteComm(0x75);//SET ROW ADDR
  200.         WriteComm(0x00+y);//第 0+y 行开始
  201.         WriteComm(0x00+y+15);//第0+y+15行结束   共16行
  202.         for(k=0;k<25;k++)
  203.         {
  204.                 if((hz[k].index[0]==c[0])&&(hz[k].index[1]==c[1]))
  205.                 {
  206.                         for(i=0;i<32;i++)
  207.                                 write(hz[k].msk);
  208.                 }
  209.         }        
  210. }
  211. void Delayms(unsigned int t)         //stc15@11.0592   1ms延时
  212. {
  213.         unsigned int a,b;
  214.         for(a=t;a>0;a--)
  215.                 for(b=850;b>0;b--);
  216. }
  217. void WriteComm(unsigned char com)                   //单片机写命令SPI函数
  218. {
  219.         RSDC=0;
  220.         SPSTAT=0xc0;                //SPIstat clear        
  221.         SPDAT=com;                        //upper eight bits
  222.         while((SPSTAT&0x80)==0);          //wait for transfer finished
  223.         SPSTAT=0xc0;                //SPIstat clear
  224.         RSDC=1;        
  225. }
  226. void WriteData(unsigned char dat)                   //单片机写data,SPI函数
  227. {
  228.         RSDC=1;
  229.         SPSTAT=0xc0;                //SPIstat clear        
  230.         SPDAT=dat;                        //upper eight bits
  231.         while((SPSTAT&0x80)==0);         //wait for transfer finished        
  232.         SPSTAT=0xc0;                //SPIstat clear
  233.         RSDC=0;
  234. }
  235. void write(unsigned dat)                         //最终写data函数,最高亮度,由4bit变1bit
  236. {
  237.         unsigned char n;
  238.         for(n=0;n<4;n++)
  239.         {        
  240.                 if((dat&0xc0)==0xc0)           //与1100 0000与,留高两位
  241.                         WriteData(0xff);
  242.                 else if((dat&0xc0)==0x80)
  243.                         WriteData(0xf0);
  244.                 else if((dat&0xc0)==0x40)
  245.                         WriteData(0x0f);
  246.                 else
  247.                         WriteData(0x00);
  248.                 dat<<=2;
  249.         }
  250. }
  251. void init_SPI()
  252. {
  253.         SPDAT=0;        
  254.         SPSTAT=0xc0;                //SPIstat clear
  255.         SPCTL=0xdc;                    //master         dc高到低   f8低到高                        
  256. }
  257. void init_oled()
  258. {
  259.         CS=0;
  260.         Delayms(25);
  261.         WriteComm(0x15);//SET COLUMN ADDR
  262.         WriteComm(0x10);//第16列开始
  263.         WriteComm(0x3f);  //第63列结束  共(63-16+1)*2=96列
  264.         WriteComm(0x75);//SET ROW ADDR
  265.         WriteComm(0x00);//第0行开始
  266.         WriteComm(0x5f);//第95行结束   共96行  
  267.         WriteComm(0xA0);//SET RE-MAP
  268.         WriteComm(0x51);
  269.         WriteComm(0xA1);//SET DISPLAY START LINE
  270.         WriteComm(0x00);
  271.         WriteComm(0xA2);//SET DISPLAY OFFSET
  272.         WriteComm(0x60);
  273.         WriteComm(0xA4);//SET DISPLAY MODE
  274.         WriteComm(0xA8);//SET MUX RADIO
  275.         WriteComm(0x5F);
  276.         WriteComm(0xB2);//SET FRAME FREQUENCY
  277.         WriteComm(0x23);
  278.         WriteComm(0xB3);//SET FRONT CLOCK DIVIDER & OSCILLATOR FREQUENCY
  279.         WriteComm(0xF0);
  280.         WriteComm(0x81);//SET CONTRAST CURRENT
  281.         WriteComm(0x7F);//
  282.         WriteComm(0xBC);    //first pre_charge voltage
  283.         WriteComm(0x1F);
  284.         Delayms(10);
  285.         WriteComm(0x82);   //second pre_charge speed
  286.         WriteComm(0xFE);
  287.         Delayms(10);
  288.         WriteComm(0xB1);   //first pre_charge phase length
  289.         WriteComm(0x21);
  290.         WriteComm(0xBB);//SET SECONDE PRE_CHARGE PERIOD
  291.         WriteComm(0x0F);
  292.         WriteComm(0xbe);//SET VCOMH
  293.         WriteComm(0x1F);
  294.         WriteComm(0xB8);        //SET GS
  295.         WriteComm(0x04); //GS1
  296.         WriteComm(0x06); //GS2
  297.         WriteComm(0x08); //GS3        
  298.         WriteComm(0x0A); //GS4
  299.         WriteComm(0x0C); //GS5  
  300.         WriteComm(0x0E); //GS6      
  301.         WriteComm(0x10); //GS7
  302.         WriteComm(0x12); //GS8
  303.         WriteComm(0x14); //GS9  
  304.         WriteComm(0x16); //GS10
  305.         WriteComm(0x18); //GS11
  306.         WriteComm(0x1A); //GS12
  307.         WriteComm(0x1C); //GS13
  308.         WriteComm(0x1E); //GS14
  309.         WriteComm(0x20); //GS15
  310.         Delayms(10);
  311.         WriteComm(0xAF);         //DSPLAY ON
  312. }

本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共4条打赏M币+117专家+1
离线961259337

发帖
436
M币
280
专家
3
粉丝
30
只看该作者 1楼 发表于: 2017-12-26
离线youimisss

发帖
185
M币
370
专家
0
粉丝
1
只看该作者 2楼 发表于: 2017-12-26
价格不错 字数字数
离线lxa0

发帖
1128
M币
352
专家
10
粉丝
44
只看该作者 3楼 发表于: 2017-12-26
请教楼主
这个种显示屏和12864之间有啥不同?
离线961259337

发帖
436
M币
280
专家
3
粉丝
30
只看该作者 4楼 发表于: 2017-12-26
回 lxa0 的帖子
lxa0:请教楼主
这个种显示屏和12864之间有啥不同? (2017-12-26 18:56) 回 lxa0 的帖子

12864  就是横向 128个点,纵向64个点,这个是横向纵向都96个点
离线66ok66

发帖
1256
M币
997
专家
7
粉丝
18
只看该作者 5楼 发表于: 2017-12-26
没有信价比了  , 0.96的12864也才 13一片了,差不多了
离线lxa0

发帖
1128
M币
352
专家
10
粉丝
44
只看该作者 6楼 发表于: 2017-12-26
继续请教:
那在驱动方面与12864有啥不同?
离线sadate

发帖
213
M币
2142
专家
2
粉丝
33
只看该作者 7楼 发表于: 2017-12-26
完全无性价比可言

内容来自Android手机客户端

离线961259337

发帖
436
M币
280
专家
3
粉丝
30
只看该作者 8楼 发表于: 2017-12-26
lxa0继续请教:<br>那在驱动方面与12864有啥不同?
      
即使都是12864驱动不一样程序也不一样,其实都差不多的,一个玩通了其他都一样的原理
离线961259337

发帖
436
M币
280
专家
3
粉丝
30
只看该作者 9楼 发表于: 2017-12-26
66ok66没有信价比了  , 0.96的12864也才 13一片了,差不多了
      
还行呀,12864纵向少点,横向多点。