OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6030|回复: 3

求一个STC8做oled水平滚动显示的程序(用指令写的)

[复制链接]

1

主题

1

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2019-7-7
在线时间
10 小时
发表于 2020-2-1 23:26:50 | 显示全部楼层 |阅读模式
10金钱
如标题所示,在家无聊,但是怎么也实现不了。 QQ截图20200201231235.png

就如我写的这样,非常糟糕。我主要不懂的几点:
1、关闭命令0x2e前给RAM写数据还是之后写。
2、写数据时,总是写什么就直接显示,而不是滚动,怎么解决。

  1. #include <intrins.h>
  2. #include <STC8.H>

  3. sbit lcd_sclk=P5^0;  /*接口定义:lcd_sclk就是CLK*/
  4. sbit lcd_sid=P5^1;   /*接口定义:lcd_sid就是MOSI*/
  5. sbit lcd_rs=P5^2;    /*接口定义:lcd_rs就是DC*/
  6. sbit lcd_cs1=P5^3;   /*接口定义:lcd_cs1就是OLED的片选CS1*/
  7. sbit Rom_OUT=P5^4;   /*字库IC接口定义:Rom_OUT就是FSO*/
  8. sbit Rom_CS=P5^5;    /*字库IC接口定义Rom_CS就是字库IC的CS2*/



  9. #define uchar unsigned char
  10. #define uint unsigned int
  11. #define ulong unsigned long

  12. uchar code bmp1[];



  13. /*写指令到LCD模块*/
  14. void transfer_command_lcd(int data1)   
  15. {
  16.         char i;
  17.         lcd_rs=0;
  18.         lcd_sclk=0;
  19.         for(i=0;i<8;i++)
  20.    {
  21.                
  22.                 if(data1&0x80) lcd_sid=1;
  23.                 else lcd_sid=0;
  24.                 lcd_sclk=1;
  25.                 _nop_();
  26.                 lcd_sclk=0;
  27.                  data1<<=1;
  28.    }
  29. }

  30. /*写数据到LCD模块*/
  31. void transfer_data_lcd(int data1)
  32. {
  33.         char i;
  34.         lcd_rs=1;
  35.         lcd_sclk=0;
  36.         for(i=0;i<8;i++)
  37.    {
  38.                
  39.                 if(data1&0x80) lcd_sid=1;
  40.                 else lcd_sid=0;
  41.                 lcd_sclk=1;
  42.                 _nop_();
  43.                 lcd_sclk=0;
  44.                  data1<<=1;
  45.    }
  46. }

  47. /*延时*/
  48. void delay(int n_ms)               
  49. {
  50. int j,k;
  51. for(j=0;j<n_ms;j++)
  52. for(k=0;k<110;k++);
  53. }


  54. /*等待一个按键,我的主板是用P2.0与GND之间接一个按键*/
  55. //void waitkey()
  56. //{
  57. // repeat:
  58. //          if (P2&0x01) goto repeat;
  59. //        else delay(6);
  60. //        if (P2&0x01) goto repeat;
  61. //        else
  62. //        delay(40);;
  63. //}


  64. /*LCD模块初始化*/
  65. void initial_lcd()
  66. {
  67.         lcd_cs1=0;
  68.         Rom_CS = 1;
  69. //        lcd_reset=0;        /*低电平复位*/
  70.         delay(20);
  71.         //lcd_reset=1;                    /*复位完毕*/
  72.         delay(20);        
  73.         transfer_command_lcd(0xAE);   //显示关
  74.         transfer_command_lcd(0x20);        //内存地址模式设置       
  75.         transfer_command_lcd(0x10);        //00,水平寻址模式;01,垂直寻址模式;10,页地址模式 (RESET);11,无效
  76.         transfer_command_lcd(0xb0);        //设置页开始地址0作为页地址模式,0-7
  77.         transfer_command_lcd(0xc8);        //设置COM输出扫描方向
  78.         transfer_command_lcd(0x00);//设置列开始地址0作为页地址模式
  79.         transfer_command_lcd(0x10);//设置列地址0作为页的开始地址
  80.         transfer_command_lcd(0x40);//设置显示开始行0
  81.         transfer_command_lcd(0x81);//设置对比度
  82.         transfer_command_lcd(0x7f);//
  83.         transfer_command_lcd(0xa1);//--设置 segment 重映射 0 to 127
  84.         transfer_command_lcd(0xa6);//正常显示
  85.         transfer_command_lcd(0xa8);//--set multiplex ratio(1 to 64)设置复用率
  86.         transfer_command_lcd(0x3F);//
  87.         transfer_command_lcd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
  88.         transfer_command_lcd(0xd3);//设置行显示偏移
  89.         transfer_command_lcd(0x00);//无偏移
  90.         transfer_command_lcd(0xd5);//设置显示时钟分频率、振荡器频率
  91.         transfer_command_lcd(0xf0);//11110000高四位为振荡器频率、低四位为显示时钟分频率
  92.         transfer_command_lcd(0xd9);//设置重充电周期
  93.         transfer_command_lcd(0x22); //
  94.         transfer_command_lcd(0xda);//设置COM引脚硬件配置
  95.         transfer_command_lcd(0x12);
  96.         transfer_command_lcd(0xdb);//--设置vcomh
  97.         transfer_command_lcd(0x20);//0x20,0.77xVcc
  98.         transfer_command_lcd(0x8d);//--set DC-DC enable
  99.         transfer_command_lcd(0x14);//
  100.         transfer_command_lcd(0xaf);//显示开
  101.         lcd_cs1=1;
  102. }

  103. /*
  104. 页开始地址column:0~7;
  105. 列开始地址page:0~127;
  106. */
  107. void lcd_address(uchar page,uchar column)
  108. {

  109.         transfer_command_lcd(0xb0 + column);   /*设置页地址*/
  110.         transfer_command_lcd(((page & 0xf0) >> 4) | 0x10);        /*设置列地址的高4位*/
  111.         transfer_command_lcd((page & 0x0f) | 0x00);        /*设置列地址的低4位*/       
  112. }

  113. /*全屏清屏*/
  114. void clear_screen()
  115. {
  116.         unsigned char i,j;
  117.         lcd_cs1=0;
  118.         Rom_CS = 1;       
  119.         for(i=0;i<8;i++)
  120.         {
  121.                 transfer_command_lcd(0xb0+i);
  122.                 transfer_command_lcd(0x00);
  123.                 transfer_command_lcd(0x10);
  124.                 for(j=0;j<128;j++)
  125.                 {
  126.                           transfer_data_lcd(0x00);
  127.                 }
  128.         }
  129.         lcd_cs1=1;
  130. }

  131. /*显示128x64点阵图像*/
  132. //void display_128x64(uchar *dp)
  133. //{
  134. //        uint i,j;
  135. //        lcd_cs1=0;
  136. //        for(j=0;j<8;j++)
  137. //        {
  138. //                lcd_address(0,j);
  139. //                for (i=0;i<128;i++)
  140. //                {       
  141. //                        transfer_data_lcd(*dp);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
  142. //                        dp++;
  143. //                }
  144. //        }
  145. //        lcd_cs1=1;
  146. //}



  147. /*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
  148. void display_graphic_16x16(uint page,uint column,uchar *dp)
  149. {
  150.         uint i,j;
  151.         lcd_cs1=0;
  152.         Rom_CS = 1;        
  153.         for(j=2;j>0;j--)
  154.         {
  155.                 lcd_address(column,page);
  156.                 for (i=0;i<16;i++)
  157.                 {       
  158.                         transfer_data_lcd(*dp);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
  159.                         dp++;
  160.                 }
  161.                 page++;
  162.         }
  163.         lcd_cs1=1;
  164. }


  165. /*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/
  166. void display_graphic_8x16(uint page,uchar column,uchar *dp)
  167. {
  168.         uint i,j;
  169.         lcd_cs1=0;       
  170.         for(j=2;j>0;j--)
  171.         {
  172.                 lcd_address(column,page);
  173.                 for (i=0;i<8;i++)
  174.                 {       
  175.                         transfer_data_lcd(*dp);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
  176.                         dp++;
  177.                 }
  178.                 page++;
  179.         }
  180.         lcd_cs1=1;
  181. }

  182. /*
  183. i:向右0向左1
  184. a:滚屏开始行0-7
  185. b:滚屏时间间隔
  186. c:多少行滚屏1-8(a+c<8)
  187. dat:显示的内容
  188. off_on:开关1开0关
  189. */
  190. void display_GB2312_string(uchar y,uchar x,uchar *text);

  191. void gundong(uchar *dp)
  192. {
  193.         uint i;
  194.         lcd_cs1=0;
  195.         Rom_CS = 1;
  196. //        display_graphic_16x16(0,32,dat);       
  197.         for (i=0;i<128;i++)
  198.         {       
  199.                 transfer_data_lcd(*dp);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
  200.                 dp++;
  201.         }
  202.        
  203.         transfer_command_lcd(0x2e);
  204. //        display_graphic_16x16(0,32,dat);
  205.         for (i=0;i<128;i++)
  206.         {       
  207.                 transfer_data_lcd(*dp);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
  208.                 dp++;
  209.         }
  210.         transfer_command_lcd(0x26);
  211.         transfer_command_lcd(0x00);
  212.         transfer_command_lcd(0x00);
  213.         transfer_command_lcd(0x07);
  214.         transfer_command_lcd(0x07);
  215.         transfer_command_lcd(0x00);
  216.         transfer_command_lcd(0xff);
  217.         transfer_command_lcd(0x2f);
  218.         lcd_cs1=1;
  219. }



  220. /*显示5*7点阵图像、ASCII, 或5x7点阵的自造字符、其他图标*/
  221. //void display_graphic_5x7(uint page,uchar column,uchar *dp)
  222. //{
  223. //        uint col_cnt;
  224. //        uchar page_address;
  225. //        uchar column_address_L,column_address_H;
  226. //        page_address = 0xb0+page-1;
  227. //       
  228. //        lcd_cs1=0;       
  229. //       
  230. //        column_address_L =(column&0x0f)-1;
  231. //        column_address_H =((column>>4)&0x0f)+0x10;
  232. //       
  233. //        transfer_command_lcd(page_address);                 /*Set Page Address*/
  234. //        transfer_command_lcd(column_address_H);        /*Set MSB of column Address*/
  235. //        transfer_command_lcd(column_address_L);        /*Set LSB of column Address*/
  236. //       
  237. //        for (col_cnt=0;col_cnt<6;col_cnt++)
  238. //        {       
  239. //                transfer_data_lcd(*dp);
  240. //                dp++;
  241. //        }
  242. //        lcd_cs1=1;
  243. //}

  244. /****送指令到亿阳字库IC***/
  245. void send_command_to_ROM( uchar datu )
  246. {
  247.         uchar i;
  248.         for(i=0;i<8;i++ )
  249.         {
  250.                 if(datu&0x80)
  251.                         lcd_sid = 1;
  252.                 else
  253.                         lcd_sid = 0;
  254.                         datu = datu<<1;
  255.                         lcd_sclk=0;
  256.                         lcd_sclk=1;
  257.         }
  258. }

  259. /****从亿阳字库IC中取汉字或字符数据(1个字节)***/
  260. static uchar get_data_from_ROM( )
  261. {
  262.        
  263.         uchar i;
  264.         uchar ret_data=0;
  265.         lcd_sclk=1;
  266.         for(i=0;i<8;i++)
  267.         {
  268.                 Rom_OUT=1;
  269.                 lcd_sclk=0;
  270.                 ret_data=ret_data<<1;
  271.                 if( Rom_OUT )
  272.                         ret_data=ret_data+1;
  273.                 else
  274.                         ret_data=ret_data+0;
  275.                 lcd_sclk=1;
  276.         }
  277.         return(ret_data);
  278. }



  279. /*从相关地址(addrHigh:地址高字节,addrMid:地址中字节,addrLow:地址低字节)中连续读出DataLen个字节的数据到 pBuff的地址*/
  280. /*连续读取*/
  281. void get_n_bytes_data_from_ROM(uchar addrHigh,uchar addrMid,uchar addrLow,uchar *pBuff,uchar DataLen )
  282. {
  283.         uchar i;
  284.         Rom_CS = 0;
  285.         lcd_cs1=1;       
  286.         lcd_sclk=0;
  287.         send_command_to_ROM(0x03);
  288.         send_command_to_ROM(addrHigh);
  289.         send_command_to_ROM(addrMid);
  290.         send_command_to_ROM(addrLow);
  291.         for(i = 0; i < DataLen; i++ )
  292.              *(pBuff+i) =get_data_from_ROM();
  293.         Rom_CS = 1;
  294. }


  295. /*显示坐标*/

  296. ulong  fontaddr=0;
  297. void display_GB2312_string(uchar y,uchar x,uchar *text)//y为行地址 x为点阵像素汉字为16,ASCII码符号为8
  298. {
  299.         uchar i= 0;
  300.         uchar addrHigh,addrMid,addrLow ;
  301.         uchar fontbuf[32];                       
  302.         while((text[i]>0x00))
  303.         {
  304.                 if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1))
  305.                 {                                               
  306.                         /*国标简体(GB2312)汉字在亿阳字库IC中的地址由以下公式来计算:*/
  307.                         /*Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0*/
  308.                         /*由于担心8位单片机有乘法溢出问题,所以分三部取地址*/
  309.                         fontaddr = (text[i]- 0xb0)*94;
  310.                         fontaddr += (text[i+1]-0xa1)+846;
  311.                         fontaddr = (ulong)(fontaddr*32);
  312.                        
  313.                         addrHigh = (fontaddr&0xff0000)>>16;  /*地址的高8位,共24位*/
  314.                         addrMid = (fontaddr&0xff00)>>8;      /*地址的中8位,共24位*/
  315.                         addrLow = fontaddr&0xff;             /*地址的低8位,共24位*/
  316.                         get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32 );/*取32个字节的数据,存到"fontbuf[32]"*/
  317.                         display_graphic_16x16(y,x,fontbuf);/*显示汉字到LCD上,y为页地址,x为列地址,fontbuf[]为数据*/
  318.                         i+=2;
  319.                         x+=16;
  320.                 }
  321.                 else if(((text[i]>=0xa1) &&(text[i]<=0xa3))&&(text[i+1]>=0xa1))
  322.                 {                                               
  323.                         /*国标简体(GB2312)15x16点的字符在亿阳字库IC中的地址由以下公式来计算:*/
  324.                         /*Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0*/
  325.                         /*由于担心8位单片机有乘法溢出问题,所以分三部取地址*/
  326.                         fontaddr = (text[i]- 0xa1)*94;
  327.                         fontaddr += (text[i+1]-0xa1);
  328.                         fontaddr = (ulong)(fontaddr*32);
  329.                        
  330.                         addrHigh = (fontaddr&0xff0000)>>16;  /*地址的高8位,共24位*/
  331.                         addrMid = (fontaddr&0xff00)>>8;      /*地址的中8位,共24位*/
  332.                         addrLow = fontaddr&0xff;             /*地址的低8位,共24位*/
  333.                         get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32 );/*取32个字节的数据,存到"fontbuf[32]"*/
  334.                         display_graphic_16x16(y,x,fontbuf);/*显示汉字到LCD上,y为页地址,x为列地址,fontbuf[]为数据*/
  335.                         i+=2;
  336.                         x+=16;
  337.                 }
  338.                 else if((text[i]>=0x20) &&(text[i]<=0x7e))       
  339.                 {                                               
  340.                         unsigned char fontbuf[16];                       
  341.                         fontaddr = (text[i]- 0x20);
  342.                         fontaddr = (unsigned long)(fontaddr*16);
  343.                         fontaddr = (unsigned long)(fontaddr+0x3cf80);                       
  344.                         addrHigh = (fontaddr&0xff0000)>>16;
  345.                         addrMid = (fontaddr&0xff00)>>8;
  346.                         addrLow = fontaddr&0xff;

  347.                         get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,16 );/*取16个字节的数据,存到"fontbuf[32]"*/
  348.                        
  349.                         display_graphic_8x16(y,x,fontbuf);/*显示8x16的ASCII字到LCD上,y为页地址,x为列地址,fontbuf[]为数据*/
  350.                         i+=1;
  351.                         x+=8;
  352.                 }
  353.                 else
  354.                         i++;       
  355.         }
  356.        
  357. }

  358. //void display_string_5x7(uchar y,uchar x,uchar *text)
  359. //{
  360. //        unsigned char i= 0;
  361. //        unsigned char addrHigh,addrMid,addrLow ;
  362. //        while((text[i]>0x00))
  363. //        {
  364. //               
  365. //                if((text[i]>=0x20) &&(text[i]<=0x7e))       
  366. //                {                                               
  367. //                        unsigned char fontbuf[8];                       
  368. //                        fontaddr = (text[i]- 0x20);
  369. //                        fontaddr = (unsigned long)(fontaddr*8);
  370. //                        fontaddr = (unsigned long)(fontaddr+0x3bfc0);                       
  371. //                        addrHigh = (fontaddr&0xff0000)>>16;
  372. //                        addrMid = (fontaddr&0xff00)>>8;
  373. //                        addrLow = fontaddr&0xff;

  374. //                        get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,8);/*取8个字节的数据,存到"fontbuf[32]"*/
  375. //                       
  376. //                        display_graphic_5x7(y,x,fontbuf);/*显示5x7的ASCII字到LCD上,y为页地址,x为列地址,fontbuf[]为数据*/
  377. //                        i+=1;
  378. //                        x+=6;
  379. //                }
  380. //                else
  381. //                i++;       
  382. //        }
  383. //       
  384. //}



复制代码


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5562

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10541
金钱
10541
注册时间
2017-2-18
在线时间
1908 小时
发表于 2020-2-3 10:57:35 | 显示全部楼层
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2020-3-10
在线时间
2 小时
发表于 2020-4-8 14:13:53 | 显示全部楼层
棒。。。。。。。。。。。。。。。。
回复

使用道具 举报

4

主题

77

帖子

0

精华

高级会员

Rank: 4

积分
637
金钱
637
注册时间
2019-1-12
在线时间
67 小时
发表于 2020-5-5 12:04:26 | 显示全部楼层
帮顶,我也想知道
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 08:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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