矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
楼主: 往事已去

单片机学习路线求教

[复制链接]
     
 楼主| 发表于 2023-12-13 19:06:38 | 显示全部楼层
luosifu 发表于 2023-12-13 18:54
用万用表测单片机IO不适合,对于5V  TTL电平,1.2V不是高电平,1.8V也不是可靠的状态。这两个电压值,要么 ...

这么说程序没问题了?用示波器看看,不过模拟示波器干这个不好用,看上去是工作起来了。桌子上乱七八糟,怎么收拾呢? 屏不知道好的坏的?3-5V通用的屏。
回复 支持 反对

使用道具 举报

     
发表于 2023-12-13 19:57:02 | 显示全部楼层
程序没看,确定单片机能运行,各个IO都正常后,如果还不显示,再找程序问题
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-14 17:56:38 | 显示全部楼层
本帖最后由 往事已去 于 2023-12-14 18:29 编辑

P3.5 RST加电瞬间有个正跳变,说不来对不对,正常是延迟0.1秒变成正。
P3.0RS数据/指令加电瞬间有个正跳变,零点几秒后变成0,然后无信号,触发灯不亮。
P3.1RW读/写加电瞬间有个正跳变,然后无信号,触发灯不亮。
P3.2EN使能是方波
P1.7-1.2方波,前沿有个斜坡
P1.0-1锯齿波不正常,加10K上拉电阻变成圆角方波。还是白屏。
看来是程序有问题?
1.jpg
2.jpg
3.jpg
4.jpg
回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 10:47:44 | 显示全部楼层
建设楼主买一个逻辑分析仪,玩具级别的就行。可以分析输出数据串。
回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 11:55:56 | 显示全部楼层
程序运行了,但无法判断是卡在哪出不来了还是其他问题。
找一个无用引脚做标记,测试,假设P20没用,那就用P20观测,,在下面加入 P20 = ~P20;
然后用示波器看P20,如果P20是方波,说明程序没卡死。


/*********以下是主函数*********/
void main()
{
  uchar i;
  Delay_ms(100);                //上电等待
  lcd_init();
  while(1)
  {
    插入 P20 = ~p20;


回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 14:10:04 来自手机 | 显示全部楼层
本帖最后由 xiaocake1 于 2023-12-15 14:12 编辑

可以去看看相关论坛上别人的单片机小制作,觉得用得上就去仿制。
在这个过程中,熟悉别人的代码,有不懂的地方就查资料,这样就可以很快学会了。
回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 15:02:52 | 显示全部楼层
路线选好了没?

选路线就像选老婆
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-15 20:49:13 | 显示全部楼层
luosifu 发表于 2023-12-15 11:55
程序运行了,但无法判断是卡在哪出不来了还是其他问题。
找一个无用引脚做标记,测试,假设P20没用,那就 ...

“P3.0RS数据/指令加电瞬间有个正跳变,零点几秒后变成0”,从这个时间看写第一行数据中途(差不多一半)就不对了,但是怎么变成零的搞不懂。仿真还不太会操作,曾经怎么弄早就忘了,新百度的,但是仿真是能跑下去的。看主程序定义了个无符号单字节变量i,用于字符地址自增,但是驱动中延时程序中又定义无符号双字节i,会不会这里打架?对于这种情况不知道是造成混乱还是两个i分别对待(各是各的不会打架)?所以把主程序的i改成n,然后加个LED,每行写完后分别闪1次、2次、3次,最后一行灯长亮2秒,然后清屏循环。搭棚焊拆了,手头没这种座,原板子上的不好拆,把腿刀割断了 ,再把别的座的弹片拆过来安上。等焊完了试试怎么样。
#include <reg51.h>
#include <intrins.h>
#include <12864LCD Drive_Parallel.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED_XS = P3^4;            //点亮LED灯用来显示程序运行情况
uchar code line1_data[] ={"12864屏操练"};
uchar code line2_data[] ={"C语言不能用中文"};
uchar code line3_data[] ={"还得用英文,但是"};
uchar code line4_data[] ={"不需要会英语"};
/*********以下是设定显示位置函数*********/
void LCD_pos (uchar X,uchar Y)
{
  uchar pos;
  if (X==1){X=0x80;}
  else if (X==2){X=0x90;}
  else if (X==3){X=0x88;}
  else if (X==4){X=0x98;}
  pos = X+Y;
  lcd_wcmd(pos);
}
/*********以下是主函数*********/
void main()
{
  uchar n;
  Delay_ms(100);                //上电等待
  lcd_init();
  while(1)
  {
                 LED_XS =1;
     LCD_pos (1,0);           //设显示位置为第一行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪1次
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (2,0);           //设显示位置为第二行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line2_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪2次
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (3,0);           //设显示位置为第三行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line3_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪3次
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (4,0);           //设显示位置为第四行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line4_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                LED_XS =0;               // LED长亮2秒
                Delay_ms(2000);
                LED_XS =1;
                lcd_clr();
                Delay_ms(500);
   }
}
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-15 21:24:29 | 显示全部楼层
本帖最后由 往事已去 于 2023-12-15 21:31 编辑
iffi123 发表于 2023-12-15 15:02
路线选好了没?

选路线就像选老婆


这不第一次操练翻车了 ,接下来是把C语言方面再了解点,现在了解的不多也不深入,然后单片机方面I2C等再了解,主要是年龄越大脑子越来越差,看完之后是走马观花式的效果,了解个大概,细节记不住,真不如青少年时候,差远了,特别是灵气方面。然后各种玩,玩来玩去逐渐就提高了,那些东西玩的过程中逐渐就掌握了。现在C语言算入门了,虽然还是不咋地,然后逐渐巩固,然后就是算法的问题了,这是另外一个问题了,不知道这个又怎么个弄法?难道抄别人的代码?
回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 22:55:45 | 显示全部楼层
往事已去 发表于 2023-12-15 21:24
这不第一次操练翻车了 ,接下来是把C语言方面再了解点,现在了解的不多也不深入,然后单片机方面I2 ...

如果真想学深入,自己写代码,我最开始的I2C就是对照时序图,写出来运行成功
回复 支持 反对

使用道具 举报

     
发表于 2023-12-15 23:44:18 | 显示全部楼层
两个i并不冲突,子函数的i只在子函数中有效,临时分配地址,子函数运行结束后这个i的地址被释放。下次运行子函数时,再重新分配个地址给i,虽然主函数也有i,但这俩不冲突。不过尽量避免这么写,虽然编译器能分清这俩i,写代码的人容易混。
程序中有一段液晶忙的死等操作,这种情况软仿真不适合因为软仿真不知道真实的液晶忙信息。2051好像不能在线单步调试(Debug)
8位数据线,如果单片机引脚是漏极开路门输出。也要加上拉电阻,不然数据也是类似锯齿波形状,液晶不容易识别到正确的数据。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-16 09:31:59 | 显示全部楼层
luosifu 发表于 2023-12-15 23:44
两个i并不冲突,子函数的i只在子函数中有效,临时分配地址,子函数运行结束后这个i的地址被释放。下次运行 ...

那就i改成n还是不行。写中文字符的时候先写入高字节再写入低字节,这里加了个100mS延迟,会不会这里造成问题?前5个是数字,0.5秒这个时间差不多。
     for(n=0;n<16;n++)
       {
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-16 11:31:59 | 显示全部楼层
百度一下果然是两个字节连续写入的,中间加个延迟可能会导致问题,即忙,然后就反复地检测忙,RS就是这么变成0的。那就改成连续写两次,数字加个空格凑成双位。不过这只是想象,实际试下来看怎么样。
1.jpg
#include <reg51.h>
#include <intrins.h>
#include <12864LCD Drive_Parallel.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED_XS = P3^4;            //点亮LED灯用来显示程序运行情况
uchar code line1_data[] ={" 12864屏操练"};
uchar code line2_data[] ={" C语言不能用中文"};
uchar code line3_data[] ={"还得用英文,但是"};
uchar code line4_data[] ={"不需要会英语"};
/*********以下是设定显示位置函数*********/
void LCD_pos (uchar X,uchar Y)
{
  uchar pos;
  if (X==1){X=0x80;}
  else if (X==2){X=0x90;}
  else if (X==3){X=0x88;}
  else if (X==4){X=0x98;}
  pos = X+Y;
  lcd_wcmd(pos);
}
/*********以下是主函数*********/
void main()
{
  uchar n;
  Delay_ms(100);                //上电等待
  lcd_init();
  while(1)
  {
     LED_XS =1;
     LCD_pos (1,0);           //设显示位置为第一行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line1_data[n]);
        n++;
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪1次
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (2,0);           //设显示位置为第二行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line2_data[n]);
        n++;
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪2次
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (3,0);           //设显示位置为第三行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line3_data[n]);
        n++;
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪3次
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
                 Delay_ms(300);
                 LED_XS =0;
                 Delay_ms(300);
                 LED_XS =1;
     LCD_pos (4,0);           //设显示位置为第四行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line4_data[n]);
        n++;
        lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                LED_XS =0;               // LED长亮2秒
                Delay_ms(2000);
                LED_XS =1;
                lcd_clr();
                Delay_ms(500);
   }
}
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2023-12-16 17:22:28 | 显示全部楼层
还是不行,RS高电平时间好像更短了,其它几个引脚还是那,数据口除P1.7是1.8V外其它都是0,灯不亮。这个时间像是把数字写完再写中文的时候不行了,所以改成仅显示第一行的数字中国字删除,其它行取消,然而还是不行,还是那表现。于是再改,把驱动的测忙改成延时5mS,这回行了,灯闪起来了,屏幕上有淡淡的字,调电位器对比度增强了,但是效果不好,正面不清楚,侧面清楚,但有鬼影。看来问题出在测忙程序上。显示效果不好需要外接电位器?已经调到头了,往回调一点可以消除鬼影,但是显示淡。
1.jpg
2.jpg
3.jpg
#include <reg51.h>
#include <intrins.h>
#include <12864LCD Drive_Parallel.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED_XS = P3^4;            //点亮LED灯用来显示程序运行情况
uchar code line1_data[] ={" 12864"};
//uchar code line2_data[] ={" C语言不能用中文"};
//uchar code line3_data[] ={"还得用英文,但是"};
//uchar code line4_data[] ={"不需要会英语"};
/*********以下是设定显示位置函数*********/
void LCD_pos (uchar X,uchar Y)
{
  uchar pos;
  if (X==1){X=0x80;}
  else if (X==2){X=0x90;}
  else if (X==3){X=0x88;}
  else if (X==4){X=0x98;}
  pos = X+Y;
  lcd_wcmd(pos);
}
/*********以下是主函数*********/
void main()
{
  uchar n;
  Delay_ms(100);                //上电等待
  lcd_init();
  while(1)
  {
                 LED_XS =1;
     LCD_pos (1,0);           //设显示位置为第一行第一位
     for(n=0;n<16;n++)
       {
        lcd_wdat(line1_data[n]);
                                //n++;
                                //lcd_wdat(line1_data[n]);
        Delay_ms(100);             //每个字符停留时间100mS
       }
                 LED_XS =0;               //LED闪1次
                 Delay_ms(300);
                 LED_XS =1;
                         Delay_ms(300);
                 //}                         
    //                 LCD_pos (2,0);           //设显示位置为第二行第一位
    // for(n=0;n<16;n++)
      // {
       // lcd_wdat(line2_data[n]);
                                //n++;
                                //lcd_wdat(line1_data[n]);
        //Delay_ms(100);             //每个字符停留时间100mS
      // }
                // LED_XS =0;               //LED闪2次
                // Delay_ms(300);
                // LED_XS =1;
                 //Delay_ms(300);
                // LED_XS =0;
                // Delay_ms(300);
                // LED_XS =1;
   //  LCD_pos (3,0);           //设显示位置为第三行第一位
    // for(n=0;n<16;n++)
      // {
       // lcd_wdat(line3_data[n]);
                                //n++;
                                //lcd_wdat(line1_data[n]);
        //Delay_ms(100);             //每个字符停留时间100mS
      // }
                // LED_XS =0;               //LED闪3次
                // Delay_ms(300);
                // LED_XS =1;
                // Delay_ms(300);
                // LED_XS =0;
                // Delay_ms(300);
                // LED_XS =1;
                // Delay_ms(300);
                // LED_XS =0;
                // Delay_ms(300);
                // LED_XS =1;
    // LCD_pos (4,0);           //设显示位置为第四行第一位
    // for(n=0;n<16;n++)
      // {
       // lcd_wdat(line4_data[n]);
                        //        n++;
                        //        lcd_wdat(line1_data[n]);
       // Delay_ms(100);             //每个字符停留时间100mS
       //}
                LED_XS =0;               // LED长亮2秒
                Delay_ms(2000);
                LED_XS =1;
                lcd_clr();
                Delay_ms(500);
   }
}

补充内容 (2023-12-17 08:48):
更正:数据口除P1.7是1.8V外其它都是1
回复 支持 反对

使用道具 举报

     
发表于 2023-12-16 21:28:38 | 显示全部楼层
视角的问题和对比度引脚,就是接电位器的那个脚有关的可能性比较大。
这段程序是反复刷屏同一内容,所以如果怀疑是刷新问题,可以在程序最后加一个while(1);来试一下。
用于让程序只刷新一次屏幕然后进去while(1)不出来,这样就不会反复刷新了。这只是测试方法,看看会不会是刷屏反复刷新问题导致。
近十年没用过这屏了,所以不敢确定,后面有一个清屏的指令,并且这种硬写出来的延时函数不准,何况晶振频率与代码所用的频率也可能不同。


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-5-7 14:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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