搜索
bottom↓
回复: 8

12864两线串行控制,怎样画点和线

[复制链接]

出0入0汤圆

发表于 2020-4-16 12:05:21 | 显示全部楼层 |阅读模式
12864两线串行控制,怎样画点和线,有没有做过的高手,请教一下

出0入10汤圆

发表于 2020-4-16 14:29:52 | 显示全部楼层
不能读数据的话,只能在MCU里面划分一段1K RAM,对应屏幕上的点,更新RAM后全屏刷新

出0入55汤圆

发表于 2020-4-16 15:37:10 | 显示全部楼层

  1. #include "Globals.h"

  2. #define LCD_RST_1                GPIO_SetBits(GPIOA,GPIO_Pin_11)
  3. #define LCD_RST_0                GPIO_ResetBits(GPIOA,GPIO_Pin_11)

  4. #define LCD_CS_1                GPIO_SetBits(GPIOC,GPIO_Pin_8)
  5. #define LCD_CS_0                GPIO_ResetBits(GPIOC,GPIO_Pin_8)

  6. #define LCD_CLK_1                GPIO_SetBits(GPIOA,GPIO_Pin_8)
  7. #define LCD_CLK_0                GPIO_ResetBits(GPIOA,GPIO_Pin_8)

  8. #define LCD_SID_1                GPIO_SetBits(GPIOC,GPIO_Pin_9)
  9. #define LCD_SID_0                GPIO_ResetBits(GPIOC,GPIO_Pin_9)

  10. void Mmemcpy(unsigned char *Out,const char *In, unsigned char L)
  11. {        unsigned char i;for(i=0;i<L;i++)Out[i]=In[i];       
  12. }

  13. unsigned char LCDdat[64];//此处不能用 idata 显示缓存

  14. void write(char cmd, unsigned char dat) //写指令或数据
  15. {        unsigned char i,j,Temp;
  16.        
  17.         LCD_CS_1;
  18.         LCD_CLK_0;
  19.        
  20.         for(j=0;j<3;j++)   
  21.         {             
  22.                          if (j==0){ Temp =( cmd? 0xfa:0xf8);} //数据cmd=1:0xfa 命令cmd=0:0xf8
  23.                 else if (j==1){ Temp =((dat<<0) & 0xf0);}
  24.                 else if (j==2){ Temp =((dat<<4) & 0xf0);}
  25.                
  26.                 for(i=0;i<8;i++)
  27.                 {  
  28.                         (Temp&0x80)?(LCD_SID_1):(LCD_SID_0);  Temp<<=1; delay_us(1); //左移
  29.                         LCD_CLK_1; delay_us(1);   //_nop_();_nop_();//移入  
  30.                         LCD_CLK_0; delay_us(1);   //_nop_();_nop_();_nop_(); //读出
  31.                 }                      //_nop_();_nop_();_nop_();_nop_(); //延时
  32.         }   
  33.         LCD_CS_0;
  34. }       

  35. void LCD_setWhite2(unsigned char x,unsigned char y,unsigned char left,unsigned char right)
  36. {
  37.         unsigned char i;
  38.         if(y>1)
  39.         {
  40.                 y-=2;
  41.                 x+=8;
  42.         }
  43.         write(0,0x34);
  44.         write(0,0x36);
  45.         for(i=0;i<16;i++)
  46.         {
  47.                 write(0,0x80+i+y*16);
  48.                 write(0,0x80+x);
  49.                 write(1,left);
  50.                 write(1,right);
  51.         }
  52. //        write(0,0x36);
  53.         write(0,0x30);
  54. }

  55. void LCD_ClearGM(void)
  56. {
  57.         unsigned char i,j;
  58.         write(0,0x34);
  59.         write(0,0x36);
  60.         for(j=0;j<32;j++)
  61.         {
  62.                 write(0,0x80+j);
  63.                 write(0,0x80);
  64.                 for(i=0;i<16;i++)
  65.                 {
  66.                         write(1,0x00);
  67.                 }
  68.         }
  69.         for(j=0;j<32;j++)
  70.         {
  71.                 write(0,0x80+j);
  72.                 write(0,0x88);
  73.                 for(i=0;i<16;i++)
  74.                 {
  75.                         write(1,0x00);
  76.                 }
  77.         }
  78.         write(0,0x30);
  79. }


  80. void LCD_RefreshALL(void) //模拟刷屏12864
  81. {       
  82.         unsigned char X,Y,Addr;
  83.        
  84.         for(X=0;X<4;X++) //送四行汉字
  85.         {        switch(X)   //一次送一个汉字
  86.                 {        case 0: Addr=0x80;break;
  87.                         case 1: Addr=0x90;break;
  88.                         case 2: Addr=0x88;break;
  89.                         case 3: Addr=0x98;break;        
  90.                         default:Addr=0x80;break;
  91.                 }   write(0,Addr); //先送地址后送16个字符
  92.                 for(Y=0;Y<16;Y++){write(1,LCDdat[(X*16)+Y]);}
  93.         }
  94. }


  95. //测试
  96. void LCD_Test(void)
  97. {
  98.         const char Tab[][16]={
  99.                 {"                "},
  100.                 {"                "},
  101.                 {"                "},
  102.                 {"                "},
  103.                 };

  104.          
  105.         Mmemcpy(LCDdat+0, Tab[0],16); //送出
  106.         Mmemcpy(LCDdat+16,Tab[1],16); //送出
  107.         Mmemcpy(LCDdat+32,Tab[2],16); //送出
  108.         Mmemcpy(LCDdat+48,Tab[3],16); //送出
  109.        
  110.         LCD_RefreshALL(); //更新显示
  111.        
  112. }

  113. void LCD_Clear(void)
  114. {
  115.         const char Tab[][16]={
  116.                 {"                "},
  117.                 {"                "},
  118.                 {"                "},
  119.                 {"                "},
  120.                 };

  121.          
  122.         Mmemcpy(LCDdat+0, Tab[0],16); //送出
  123.         Mmemcpy(LCDdat+16,Tab[1],16); //送出
  124.         Mmemcpy(LCDdat+32,Tab[2],16); //送出
  125.         Mmemcpy(LCDdat+48,Tab[3],16); //送出
  126.        
  127.         LCD_RefreshALL(); //更新显示
  128.         LCD_ClearGM();
  129. }

  130. //显示一行
  131. void LCD_ShowLine(unsigned char y,char *pStr)
  132. {
  133.         Mmemcpy(LCDdat+16*y, pStr,16); //送出
  134. //        printf("==%s \r\n",pStr);

  135.         LCD_RefreshALL(); //更新显示
  136. }

  137. //此函数有个缺陷,就是无法知道二维字符串的一维的长度,会把后面的字符串也显示出来
  138. void LCD_ShowString(unsigned char x,unsigned char y,const char *pStr)
  139. {
  140.         unsigned char i;
  141.         unsigned int strLen;
  142. //        unsigned char strBuff[16];        //一行字符缓存
  143.         strLen = strlen(pStr);        //字符串长度用 strlen(); 类型长度 sizeof();
  144. //        if(strLen>16) strLen = 16;
  145. //        strLen = (sizeof(pStr)/sizeof(pStr[0]));
  146. //        printf("Str Len=%d \r\n",strLen);
  147.         if(strLen>16) strLen = 16;        //一行总长度最多显示16个字符,多余的不显示
  148.         else if(strLen==0) return;        //空
  149.        
  150. //        memset(strBuff,' ',sizeof(strBuff));
  151.         for(i=0;i<strLen;i++)
  152.         {
  153.                 LCDdat[16*y+x+i] = pStr[i];
  154.         }
  155.         LCD_RefreshALL(); //更新显示
  156. }

  157. void LCD_ShowStringLen(unsigned char x,unsigned char y,const char *pStr,unsigned char len)
  158. {
  159.         unsigned char i;
  160.         unsigned int strLen;
  161. //        unsigned char strBuff[16];        //一行字符缓存
  162.         strLen = len;        //字符串长度用 strlen(); 类型长度 sizeof();
  163. //        if(strLen>16) strLen = 16;
  164. //        strLen = (sizeof(pStr)/sizeof(pStr[0]));
  165. //        printf("Str Len=%d \r\n",strLen);
  166.         if(strLen>16) strLen = 16;        //一行总长度最多显示16个字符,多余的不显示
  167.         else if(strLen==0) return;        //空
  168.        
  169. //        memset(strBuff,' ',sizeof(strBuff));
  170.         for(i=0;i<strLen;i++)
  171.         {
  172.                 LCDdat[16*y+x+i] = pStr[i];
  173.         }
  174.         LCD_RefreshALL(); //更新显示
  175. }

  176. void LCD_ShowNumber(unsigned char x,unsigned char y,long num,unsigned char disLen,unsigned char align)
  177. {
  178.         unsigned char i;
  179.         char strBuff[16];        //一行字符缓存
  180.         char disBuff[16];        //一行字符缓存用于显示
  181.         unsigned int strLen;        //字符串长度用 strlen(); 类型长度 sizeof();
  182.        
  183.         if(disLen>16 || disLen==0) return;
  184.        
  185.         memset(strBuff,0,sizeof(strBuff));
  186.         memset(disBuff,0,sizeof(disBuff));
  187.         sprintf(strBuff,"%ld",num);
  188.         strLen = strlen(strBuff);
  189. //        printf("%s : ",strBuff);
  190. //        printf("%d \r\n",strLen);
  191.        
  192.         if(align==0)        //左对齐
  193.         {
  194.                 if(strLen>=disLen)        //当数字位数大于要显示的长度时,显示高位
  195.                 {
  196.                         for(i=0;i<disLen;i++)
  197.                         {
  198.                                 disBuff[i] = strBuff[i];
  199.                         }
  200.                 }
  201.                 else
  202.                 {
  203.                         for(i=0;i<disLen;i++)
  204.                         {
  205.                                 if(i<strLen)
  206.                                         disBuff[i] = strBuff[i];
  207.                                 else
  208.                                         disBuff[i] = ' ';        //后面补空格
  209.                         }
  210.                 }
  211.         }
  212.         else        //右对齐
  213.         {
  214.                 if(strLen>=disLen)        //当数字位数大于要显示的长度时,显示高位
  215.                 {
  216.                         for(i=0;i<disLen;i++)
  217.                         {
  218.                                 disBuff[i] = strBuff[i];
  219.                         }
  220.                 }
  221.                 else
  222.                 {
  223.                         unsigned char dx = disLen-strLen;
  224.                         for(i=0;i<disLen;i++)
  225.                         {
  226.                                 if(i<dx)
  227.                                         disBuff[i] = ' ';        //前面补空格
  228.                                 else
  229.                                         disBuff[i] = strBuff[i-dx];
  230.                         }
  231.                 }
  232.         }
  233.        
  234.         LCD_ShowString(x,y,disBuff);
  235.        
  236.        
  237.         LCD_RefreshALL(); //更新显示
  238. }

  239. /**********************************
  240.           LCD初始化
  241. **********************************/

  242. void LCD_Config(void)
  243. {
  244.         GPIO_InitTypeDef GPIO_InitStructure;
  245.        
  246. //        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
  247.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
  248.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  249.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  250.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  251.        
  252.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11;
  253.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  254.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  255.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  256.        
  257.         LCD_RST_0;         delay_ms(500);
  258.         LCD_RST_1;         delay_ms(500);//复位
  259.         write(0,0x30);  //8 位介面,基本指令集
  260.         write(0,0x0c);  //显示打开,光标关,反白关
  261.         write(0,0x01);  //清屏,将DDRAM的地址计数器归零

  262.         delay_ms(500);
  263.         LCD_Clear();
  264.         LCD_Test();
  265.        
  266. }


复制代码

出0入0汤圆

发表于 2020-4-16 15:47:09 | 显示全部楼层
2线的优势就是  省io  ,但是耗时(+耗ram+耗flash)

出30入25汤圆

发表于 2020-4-16 15:47:43 | 显示全部楼层
Bresenham算法是点阵屏上画直线的基础方法,可以找找看。

出0入0汤圆

 楼主| 发表于 2020-4-17 11:09:46 | 显示全部楼层

谢谢提供代码

出0入0汤圆

发表于 2020-4-17 11:23:53 | 显示全部楼层
测试有成功吗,回复一下

出0入362汤圆

发表于 2020-4-17 11:34:29 | 显示全部楼层
12864开缓存也就是128*64/8=1k,对stm32来说不算多
写像素类似这样就行
  1. void pset(unsigned short x, unsigned short y, unsigned long c)
  2. {
  3.     if(x >= 128 || y >= 64) {
  4.         return;
  5.     }
  6.     unsigned char y1 = y >> 3;
  7.     unsigned char yt = y & 0x7;
  8.     if(c)
  9.         g.disp_buf[y1 * 128 + x] |= (1<<yt);
  10.     else
  11.         g.disp_buf[y1 * 128 + x] &= ~(1<<yt);
  12. }
复制代码

刷屏用dma,很快的。

如果需要透明写,else后面这句不要就行。

出0入362汤圆

发表于 2020-4-17 11:36:36 | 显示全部楼层
画点画线之类,随便找本计算机图形学,第一章第一节就是画线,第二节画圆,第三节椭圆,第四节多边形和填充,第五节字符。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 04:55

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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