找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1250|回复: 2
收起左侧

OLED12864 IIC画竖线花屏问题,附单片机程序

[复制链接]
ID:884042 发表于 2021-3-12 21:36 | 显示全部楼层 |阅读模式
我想用OLED来画出竖横斜线。
现在画点函数已经做好了,画横竖线就容易了。
单片机源程序如下:
  1. sbit SCL=P1^4; //串行时钟
  2. sbit SDA=P1^3; //串行数据

  3. #define high 1
  4. #define low 0

  5. #define        Brightness        0xCF
  6. #define X_WIDTH         128
  7. #define Y_WIDTH         64
  8. /*********************OLED驱动程序用的延时程序************************************/
  9. void delay(unsigned int z)
  10. {
  11.         unsigned int x,y;
  12.         for(x=z;x>0;x--)
  13.                 for(y=110;y>0;y--);
  14. }

  15. /**********************************************
  16. //IIC Start
  17. **********************************************/
  18. void IIC_Start()
  19. {
  20.    SCL = high;               
  21.    SDA = high;
  22.    SDA = low;
  23.    SCL = low;
  24. }

  25. /**********************************************
  26. //IIC Stop
  27. **********************************************/
  28. void IIC_Stop()
  29. {
  30.    SCL = low;
  31.    SDA = low;
  32.    SCL = high;
  33.    SDA = high;
  34. }

  35. /**********************************************
  36. // 通过I2C总线写一个字节
  37. **********************************************/
  38. void Write_IIC_Byte(unsigned char IIC_Byte)
  39. {
  40.         unsigned char i;
  41.         for(i=0;i<8;i++)
  42.         {
  43.                 if(IIC_Byte & 0x80)
  44.                         SDA=high;
  45.                 else
  46.                         SDA=low;
  47.                 SCL=high;
  48.                 SCL=low;
  49.                 IIC_Byte<<=1;
  50.         }
  51.         SDA=1;
  52.         SCL=1;
  53.         SCL=0;
  54. }

  55. /*********************OLED写数据************************************/
  56. void OLED_WrDat(unsigned char IIC_Data)
  57. {
  58.         IIC_Start();
  59.         Write_IIC_Byte(0x78);
  60.         Write_IIC_Byte(0x40);                        //write data
  61.         Write_IIC_Byte(IIC_Data);
  62.         IIC_Stop();
  63. }
  64. /*********************OLED写命令************************************/
  65. void OLED_WrCmd(unsigned char IIC_Command)
  66. {
  67.         IIC_Start();
  68.         Write_IIC_Byte(0x78);            //Slave address,SA0=0
  69.         Write_IIC_Byte(0x00);                        //write command
  70.         Write_IIC_Byte(IIC_Command);
  71.         IIC_Stop();
  72. }
  73. /*********************OLED 设置坐标************************************/
  74. void OLED_Set_Pos(unsigned char x, unsigned char y)
  75. {
  76.         OLED_WrCmd(0xb0+y);
  77.         OLED_WrCmd(((x&0xf0)>>4)|0x10);
  78.         OLED_WrCmd((x&0x0f)|0x01);
  79. }
  80. /*********************OLED全屏************************************/
  81. void OLED_Fill(unsigned char bmp_dat)
  82. {
  83.         unsigned char y,x;
  84.         for(y=0;y<8;y++)
  85.         {
  86.                 OLED_WrCmd(0xb0+y);
  87.                 OLED_WrCmd(0x01);
  88.                 OLED_WrCmd(0x10);
  89.                 for(x=0;x<X_WIDTH;x++)
  90.                 OLED_WrDat(bmp_dat);
  91.         }
  92. }
  93. /*********************OLED复位************************************/
  94. void OLED_CLS(void)
  95. {
  96.         unsigned char y,x;
  97.         for(y=0;y<8;y++)
  98.         {
  99.                 OLED_WrCmd(0xb0+y);
  100.                 OLED_WrCmd(0x01);
  101.                 OLED_WrCmd(0x10);
  102.                 for(x=0;x<X_WIDTH;x++)
  103.                 OLED_WrDat(0);
  104.         }
  105. }
  106. /*********************OLED初始化************************************/
  107. void OLED_Init(void)
  108. {
  109.         delay(500);//初始化之前的延时很重要!
  110.         OLED_WrCmd(0xae);//--turn off oled panel
  111.         OLED_WrCmd(0x00);//---set low column address
  112.         OLED_WrCmd(0x10);//---set high column address
  113.         OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  114.         OLED_WrCmd(0x81);//--set contrast control register
  115.         OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
  116.         OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
  117.         OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  118.         OLED_WrCmd(0xa6);//--set normal display
  119.         OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
  120.         OLED_WrCmd(0x3f);//--1/64 duty
  121.         OLED_WrCmd(0xd3);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
  122.         OLED_WrCmd(0x00);//-not offset
  123.         OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
  124.         OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
  125.         OLED_WrCmd(0xd9);//--set pre-charge period
  126.         OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  127.         OLED_WrCmd(0xda);//--set com pins hardware configuration
  128.         OLED_WrCmd(0x12);
  129.         OLED_WrCmd(0xdb);//--set vcomh
  130.         OLED_WrCmd(0x40);//Set VCOM Deselect Level
  131.         OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
  132.         OLED_WrCmd(0x02);//
  133.         OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
  134.         OLED_WrCmd(0x14);//--set(0x10) disable
  135.         OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
  136.         OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
  137.         OLED_WrCmd(0xaf);//--turn on oled panel
  138.         OLED_Fill(0x00); //初始清屏
  139.         OLED_Set_Pos(0,0);
  140. }
  141. /***************功能描述:显示6*8一组标准ASCII字符串        显示的坐标(x,y),y为页范围0~7****************/
  142. void OLED_P6x8Str(unsigned char x, y,unsigned char ch[])
  143. {
  144.         unsigned char c=0,i=0,j=0;
  145.         while (ch[j]!='\0')
  146.         {
  147.                 c =ch[j]-32;
  148.                 if(x>126){x=0;y++;}
  149.                 OLED_Set_Pos(x,y);
  150.                 for(i=0;i<6;i++)
  151.                 OLED_WrDat(F6x8[c][i]);
  152.                 x+=6;
  153.                 j++;
  154.         }
  155. }
  156. /*******************功能描述:显示8*16一组标准ASCII字符串         显示的坐标(x,y),y为页范围0~7****************/
  157. void OLED_P8x16Str(unsigned char x, y,unsigned char ch[])
  158. {
  159.         unsigned char c=0,i=0,j=0;
  160.         while (ch[j]!='\0')
  161.         {
  162.                 c =ch[j]-32;
  163.                 if(x>120){x=0;y++;}
  164.                 OLED_Set_Pos(x,y);
  165.                 for(i=0;i<8;i++)
  166.                 OLED_WrDat(F8X16[c*16+i]);
  167.                 OLED_Set_Pos(x,y+1);
  168.                 for(i=0;i<8;i++)
  169.                 OLED_WrDat(F8X16[c*16+i+8]);
  170.                 x+=8;
  171.                 j++;
  172.         }
  173. }
  174. /*****************功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
  175. void OLED_P16x16Ch(unsigned char x, y, N)
  176. {
  177.         unsigned char wm=0;
  178.         unsigned int adder=32*N;
  179.         OLED_Set_Pos(x , y);
  180.         for(wm = 0;wm < 16;wm++)
  181.         {
  182.                 OLED_WrDat(F16x16[adder]);
  183.                 adder += 1;
  184.         }
  185.         OLED_Set_Pos(x,y + 1);
  186.         for(wm = 0;wm < 16;wm++)
  187.         {
  188.                 OLED_WrDat(F16x16[adder]);
  189.                 adder += 1;
  190.         }                  
  191. }
  192. /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
  193. void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[])
  194. {
  195.         unsigned int j=0;
  196.         unsigned char x,y;

  197.   if(y1%8==0) y=y1/8;      
  198.   else y=y1/8+1;
  199.         for(y=y0;y<y1;y++)
  200.         {
  201.                 OLED_Set_Pos(x0,y);
  202.     for(x=x0;x<x1;x++)
  203.             {      
  204.                     OLED_WrDat(BMP[j++]);
  205.             }
  206.         }
  207. }
  208. void OLED_Point(unsigned char x, y)
  209. {        
  210.         switch(y)
  211.         {
  212.                 case(0):OLED_Set_Pos(x,0);OLED_WrDat(0x01);break;
  213.                 case(1):OLED_Set_Pos(x,0);OLED_WrDat(0x02);break;
  214.                 case(2):OLED_Set_Pos(x,0);OLED_WrDat(0x04);break;
  215.                 case(3):OLED_Set_Pos(x,0);OLED_WrDat(0x08);break;
  216.                 case(4):OLED_Set_Pos(x,0);OLED_WrDat(0x10);break;
  217.                 case(5):OLED_Set_Pos(x,0);OLED_WrDat(0x20);break;
  218.                 case(6):OLED_Set_Pos(x,0);OLED_WrDat(0x40);break;
  219.                 case(7):OLED_Set_Pos(x,0);OLED_WrDat(0x80);break;
  220.                 case(8):OLED_Set_Pos(x,1);OLED_WrDat(0x01);break;
  221.                 case(9):OLED_Set_Pos(x,1);OLED_WrDat(0x02);break;
  222.                 case(10):OLED_Set_Pos(x,1);OLED_WrDat(0x04);break;
  223.                 case(11):OLED_Set_Pos(x,1);OLED_WrDat(0x08);break;
  224.                 case(12):OLED_Set_Pos(x,1);OLED_WrDat(0x10);break;
  225.                 case(13):OLED_Set_Pos(x,1);OLED_WrDat(0x20);break;
  226.                 case(14):OLED_Set_Pos(x,1);OLED_WrDat(0x40);break;
  227.                 case(15):OLED_Set_Pos(x,1);OLED_WrDat(0x80);break;
  228.                 case(16):OLED_Set_Pos(x,2);OLED_WrDat(0x01);break;
  229.                 case(17):OLED_Set_Pos(x,2);OLED_WrDat(0x02);break;
  230.                 case(18):OLED_Set_Pos(x,2);OLED_WrDat(0x04);break;
  231.                 case(19):OLED_Set_Pos(x,2);OLED_WrDat(0x08);break;
  232.                 case(20):OLED_Set_Pos(x,2);OLED_WrDat(0x10);break;
  233.                 case(21):OLED_Set_Pos(x,2);OLED_WrDat(0x20);break;
  234.                 case(22):OLED_Set_Pos(x,2);OLED_WrDat(0x40);break;
  235.                 case(23):OLED_Set_Pos(x,2);OLED_WrDat(0x80);break;
  236.                 case(24):OLED_Set_Pos(x,3);OLED_WrDat(0x01);break;
  237.                 case(25):OLED_Set_Pos(x,3);OLED_WrDat(0x02);break;
  238.                 case(26):OLED_Set_Pos(x,3);OLED_WrDat(0x04);break;
  239.                 case(27):OLED_Set_Pos(x,3);OLED_WrDat(0x08);break;
  240.                 case(28):OLED_Set_Pos(x,3);OLED_WrDat(0x10);break;
  241.                 case(29):OLED_Set_Pos(x,3);OLED_WrDat(0x20);break;
  242.                 case(30):OLED_Set_Pos(x,3);OLED_WrDat(0x40);break;
  243.                 case(31):OLED_Set_Pos(x,3);OLED_WrDat(0x80);break;
  244.                 case(32):OLED_Set_Pos(x,4);OLED_WrDat(0x01);break;
  245.                 case(33):OLED_Set_Pos(x,4);OLED_WrDat(0x02);break;
  246.                 case(34):OLED_Set_Pos(x,4);OLED_WrDat(0x04);break;
  247.                 case(35):OLED_Set_Pos(x,4);OLED_WrDat(0x08);break;
  248.                 case(36):OLED_Set_Pos(x,4);OLED_WrDat(0x10);break;
  249.                 case(37):OLED_Set_Pos(x,4);OLED_WrDat(0x20);break;
  250.                 case(38):OLED_Set_Pos(x,4);OLED_WrDat(0x40);break;
  251.                 case(39):OLED_Set_Pos(x,4);OLED_WrDat(0x80);break;
  252.                 case(40):OLED_Set_Pos(x,5);OLED_WrDat(0x01);break;
  253.                 case(41):OLED_Set_Pos(x,5);OLED_WrDat(0x02);break;
  254.                 case(42):OLED_Set_Pos(x,5);OLED_WrDat(0x04);break;
  255.                 case(43):OLED_Set_Pos(x,5);OLED_WrDat(0x08);break;
  256.                 case(44):OLED_Set_Pos(x,5);OLED_WrDat(0x10);break;
  257.                 case(45):OLED_Set_Pos(x,5);OLED_WrDat(0x20);break;
  258.                 case(46):OLED_Set_Pos(x,5);OLED_WrDat(0x40);break;
  259.                 case(47):OLED_Set_Pos(x,5);OLED_WrDat(0x80);break;
  260.                 case(48):OLED_Set_Pos(x,6);OLED_WrDat(0x01);break;
  261.                 case(49):OLED_Set_Pos(x,6);OLED_WrDat(0x02);break;
  262.                 case(50):OLED_Set_Pos(x,6);OLED_WrDat(0x04);break;
  263.                 case(51):OLED_Set_Pos(x,6);OLED_WrDat(0x08);break;
  264.                 case(52):OLED_Set_Pos(x,6);OLED_WrDat(0x10);break;
  265.                 case(53):OLED_Set_Pos(x,6);OLED_WrDat(0x20);break;
  266.                 case(54):OLED_Set_Pos(x,6);OLED_WrDat(0x40);break;
  267.                 case(55):OLED_Set_Pos(x,6);OLED_WrDat(0x80);break;
  268.                 case(56):OLED_Set_Pos(x,7);OLED_WrDat(0x01);break;
  269.                 case(57):OLED_Set_Pos(x,7);OLED_WrDat(0x02);break;
  270.                 case(58):OLED_Set_Pos(x,7);OLED_WrDat(0x04);break;
  271.                 case(59):OLED_Set_Pos(x,7);OLED_WrDat(0x08);break;
  272.                 case(60):OLED_Set_Pos(x,7);OLED_WrDat(0x10);break;
  273.                 case(61):OLED_Set_Pos(x,7);OLED_WrDat(0x20);break;
  274.                 case(62):OLED_Set_Pos(x,7);OLED_WrDat(0x40);break;
  275.                 case(63):OLED_Set_Pos(x,7);OLED_WrDat(0x80);break;
  276.         }                  
  277. }
  278. void OLED_XLine(unsigned char x0, y0,x1)
  279. {        
  280.     unsigned char z;        
  281.         if(x0<=x1)
  282.         {
  283.                 OLED_Point(x0, y0);
  284.                 for(z=x0;z<x1;z++)
  285.             {
  286.                     OLED_Point(z, y0);
  287.             }
  288.         }
  289.         if(x0>=x1)
  290.         {
  291.                 OLED_Point(x0, y0);
  292.                 for(z=x0;z<=x1;z--)          //z=16 z=0 z--
  293.             {
  294.                     OLED_Point(z, y0);
  295.             }
  296.         }                          
  297. }
复制代码
但不知道为什么,画点函数有些地方就不能一起显示(表达能力有限,可以自己试下)!
例如:
  1. OLED_Point(0, 0);
  2. OLED_Point(1, 1);
复制代码
大家可以在自己的屏幕上试试看。
还有,画竖线函数我编好后下载到屏幕上却花屏。
源码:
  1. void OLED_YLine(unsigned char y0, x0,y1)
  2. {        
  3.     unsigned char z;        
  4.         if(y0<=y1)
  5.         {
  6.                 OLED_Point(x0, y0);
  7.                 for(z=y0;z<y1;z++)
  8.             {
  9.                     OLED_Point(x0, z);
  10.             }
  11.         }
  12.         if(y0>=y1)
  13.         {
  14.                 OLED_Point(x0, y0);
  15.                 for(z=y0;z<=y1;z--)          //z=16 z=0 z--
  16.             {
  17.                     OLED_Point(x0, z);
  18.             }
  19.         }                          
  20. }
复制代码
现在求助各位大神,给我解释以下这怎么回事!
回复

使用道具 举报

ID:884042 发表于 2021-3-20 18:18 | 显示全部楼层
怎么这么久了还没人回?
回复

使用道具 举报

ID:884042 发表于 2021-3-21 15:06 | 显示全部楼层
画点函数的方法很笨,但没办法,因为OLED是一个字节一个字节显示的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表