找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1455|回复: 4
打印 上一主题 下一主题
收起左侧

单片机LCD12864程序烧到实物上后出现乱码 运行不正常 仿真没问题

[复制链接]
跳转到指定楼层
楼主
本人最近做一个基于avr单片机简易的交通灯系统,原定的功能是在交通灯正常运行时12864显示屏显示“交通灯正常运行”,代码写出来之后仿真也未出现问题,把程序烧进实物之后发现12864显示虽然亮了,但屏上未显示内容,而重复多次复位操作后发现有时会显示几个正确字符,但存在乱码。经百度后判断是时序问题,我修改了多次延时之后都没能让12864正常显示,现问下各位大佬怎么调整时序,以让12864正常运行?


单片机源程序如下:
  1. #define F_CPU 8000000UL
  2. #include <avr/io.h>
  3. #include <util/delay.h>
  4. #include <string.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #define RS (1<<5)
  8. #define RW (1<<6)
  9. #define EN (1<<7)
  10. #define delay_ms(x) _delay_ms(x)
  11. #define RED_1 (1<<0)
  12. #define RED_2 (1<<3)
  13. #define YEL_1 (1<<1)
  14. #define YEL_2 (1<<4)
  15. #define GREEN_1 (1<<2)
  16. #define GREEN_2 (1<<5)
  17. //此处定义字符串
  18. char text_1[]={"交通灯正常运行中"};
  19. char text_2[]={"    紧急模式"};
  20. char text_3[]={"调整间断模式"};
  21. char text_4[]={"红灯"};
  22. char text_5[]={"黄灯"};
  23. char red_time[]={"05s"};
  24. char YEL_time[]={"07ms"};
  25. int emer = 0;
  26. int adju = 0;
  27. int key = 0;
  28. int staus = 0;
  29. int n=9,Yel_time=7;
  30. void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
  31. {
  32.         /* 等待上一次写操作结束 */
  33.         while(EECR & (1<<EEWE))
  34.         ;
  35.         /* 设置地址和数据寄存器 */
  36.         EEAR = uiAddress;
  37.         EEDR = ucData;
  38.         /* 置位 EEMWE */
  39.         EECR |= (1<<EEMWE);
  40.         /* 置位 EEWE 以启动写操作 E */
  41.         EECR |= (1<<EEWE);
  42. }
  43. unsigned char EEPROM_read(unsigned int uiAddress)
  44. {
  45.         /* 等待上一次写操作结束 */
  46.         while(EECR & (1<<EEWE))
  47.         ;
  48.         /* 设置地址寄存器 */
  49.         EEAR = uiAddress;
  50.         /* 设置 EERE 以启动读操作 */
  51.         EECR |= (1<<EERE);
  52.         /* 自数据寄存器返回数据 */
  53.         return EEDR;
  54. }
  55. int key_board(void) {
  56.         unsigned char i,j; //键码记录
  57.         unsigned char key_num=0; //按键表示的数字
  58.         i=PIND&0xF3;
  59.         if (i == 0xF3) return key_num; //无按键按下,退出
  60.         delay_ms(10); //去按键颤抖
  61.         j = PIND&0xF3;
  62.         if(i == j) { //二次对比确定按键操作
  63.                 switch (i) { //将按键码转换成键值
  64.                         case 0xF2: key_num=1;break;
  65.                         case 0xF1: key_num=2;break;
  66.                         case 0xE3: key_num=3;break;
  67.                         case 0xD3: key_num=4;break;
  68.                         case 0xB3: key_num=5;break;
  69.                         case 0x73: key_num=6;break;
  70.                         default: key_num=0;break;
  71.                 }
  72.         }
  73.         while(PIND!=0xF3); //等待按键松开
  74.         return key_num;
  75. }
  76. void emer_mode(){
  77.         int a=1;
  78.         WriteCommandLCM(0x01);
  79.         PORTC=(RED_1)|(RED_2);
  80.         PORTA=(GREEN_1)|(GREEN_2);
  81.         DisplayList(0x80,text_2);
  82.         while(a){
  83.                 key=key_board();
  84.                 if (key)
  85.                 {
  86.                         a=0;
  87.                         key=1;
  88.                         WriteCommandLCM(0x01);
  89.                         s_ms(100);
  90.                         DisplayList(0x80,text_1);
  91.                 }
  92.         }
  93. }
  94. void adju_mode(){
  95.         staus = 1;
  96.         int real_time;
  97.         int sit = 0,sel=3;
  98.         unsigned char poab,pocb;
  99.         pocb=PORTC;
  100.         poab=PORTA;
  101.         real_time=n-4;
  102.         WriteCommandLCM(0x01);
  103.         DisplayList(0x80,text_3);
  104.         DisplayList(0x90,text_4);
  105.         DisplayList(0x95,text_5);
  106.         red_time[0]=(real_time/10)+48;
  107.         red_time[1]=(real_time%10)+48;
  108.         YEL_time[0]=(Yel_time/10)+48;
  109.         YEL_time[1]=(Yel_time%10)+48;
  110.         DisplayList(0x88,red_time);
  111.         DisplayList(0x8D,YEL_time);
  112.         PORTC=(RED_1)|(RED_2);
  113.         PORTA=(GREEN_1)|(GREEN_2);
  114.         while(staus){
  115.                 delay_ms(200);
  116.                 sit=key_board();
  117.                 if (sit==3)
  118.                 {
  119.                         sel=sit;
  120.                         PORTC=(RED_1)|(RED_2);
  121.                         PORTA=(GREEN_1)|(GREEN_2);
  122.                 }
  123.                 else if (sit==4)
  124.                 {
  125.                         sel=sit;
  126.                         PORTC=(YEL_1)|(YEL_2);
  127.                         PORTA=(YEL_1)|(YEL_2);
  128.                 }
  129.                 if (sel==3)
  130.                 {
  131.                         PORTC^=(RED_1)|(RED_2);
  132.                         PORTA^=(GREEN_1)|(GREEN_2);
  133.                 }
  134.                 else if (sel==4)
  135.                 {
  136.                         PORTC^=(YEL_1)|(YEL_2);
  137.                         PORTA^=(YEL_1)|(YEL_2);
  138.                 }
  139.                 if (sit==5&&sel==3)
  140.                 {
  141.                         n++;
  142.                         delay_ms(100);
  143.                         if (n-4>15)
  144.                         {
  145.                                 n=9;
  146.                         }
  147.                         EEPROM_write(0x00,n);
  148.                         real_time=n-4;
  149.                         red_time[0]=(real_time/10)+48;
  150.                         red_time[1]=(real_time%10)+48;
  151.                         DisplayList(0x88,red_time);
  152.                 }
  153.                 else if (sit==6&&sel==3)
  154.                 {
  155.                         n--;
  156.                         delay_ms(100);
  157.                         if (n-4<5)
  158.                         {
  159.                                 n=19;
  160.                         }
  161.                         EEPROM_write(0x00,n);
  162.                         real_time=n-4;
  163.                         red_time[0]=(real_time/10)+48;
  164.                         red_time[1]=(real_time%10)+48;
  165.                         DisplayList(0x88,red_time);
  166.                 }
  167.                 if (sit==5&&sel==4)
  168.                 {
  169.                         Yel_time++;
  170.                         delay_ms(100);
  171.                         if (Yel_time>20)
  172.                         {
  173.                                 Yel_time=5;
  174.                         }
  175.                         EEPROM_write(0x08,Yel_time);
  176.                         YEL_time[0]=(Yel_time/10)+48;
  177.                         YEL_time[1]=(Yel_time%10)+48;
  178.                         DisplayList(0x8D,YEL_time);
  179.                 }
  180.                 else if (sit==6&&sel==4)
  181.                 {
  182.                         Yel_time--;
  183.                         delay_ms(100);
  184.                         if (Yel_time<5)
  185.                         {
  186.                                 Yel_time=20;
  187.                         }
  188.                         EEPROM_write(0x08,Yel_time);
  189.                         YEL_time[0]=(Yel_time/10)+48;
  190.                         YEL_time[1]=(Yel_time%10)+48;
  191.                         DisplayList(0x8D,YEL_time);
  192.                 }
  193.                 if (sit==2)
  194.                 {
  195.                         WriteCommandLCM(0x01);
  196.                         s_ms(100);
  197.                         DisplayList(0x80,text_1);
  198.                         PORTA=poab;
  199.                         PORTC=pocb;
  200.                         staus=0;
  201.                 }
  202.         }
  203. }
  204. void get_key(){
  205.         int sel=0;
  206.         sel=key_board();
  207.         if (sel==1)
  208.         {
  209.                 emer_mode();
  210.         }
  211.         else if (sel==2)
  212.         {
  213.                 adju_mode();
  214.         }
  215. }
  216. //延时函数
  217. void s_ms(uint ms)
  218. {
  219.         int a;
  220.         for (a=0;a<1;a++)
  221.         {
  222.                 for(;ms>1;ms--);
  223.         }
  224. }

  225. //写数据
  226. void WriteDataLCM(unsigned char WDLCM)
  227. {
  228.         ReadStatusLCM(); //检测忙
  229.         s_ms(100);
  230.         PORTE|=RS;       //RS=1
  231.         s_ms(100);
  232.         PORTE&=~RW;      //RW=0
  233.         s_ms(100);
  234.         PORTE|=EN;       //EN=1
  235.         s_ms(100);
  236.         PORTB=WDLCM;     //输出数据
  237.         s_ms(100);
  238.         PORTE&=~EN;      //EN=0
  239.         s_ms(100);
  240. }

  241. //写指令
  242. void WriteCommandLCM(unsigned char WCLCM)
  243. {
  244.         ReadStatusLCM(); //根据需要检测忙
  245.         s_ms(100);
  246.         PORTE&=~RS;      //RS=0
  247.         s_ms(100);
  248.         PORTE&=~RW;      //RW=0
  249.         s_ms(100);
  250.         PORTE|=EN;       //EN=1
  251.         s_ms(100);
  252.         PORTB=WCLCM;     //输出指令
  253.         s_ms(100);
  254.         PORTE&=~EN;      //EN=0
  255.         s_ms(100);
  256. }

  257. //读状态:检测忙
  258. void ReadStatusLCM(void)
  259. {
  260.         uchar temp;
  261.         uchar flag = 1;
  262.         while(flag==1)
  263.         {
  264.                 DDRB=0x00;      //端口B改为输入
  265.                 PORTB=0xff;
  266.                 s_ms(100);
  267.                 PORTE&=~RS;     //RS=0
  268.                 s_ms(100);
  269.                 PORTE|=RW;      //RW=1
  270.                 s_ms(100);
  271.                 PORTE|=EN;      //EN=1
  272.                 s_ms(1000);
  273.                 temp = PINB;    //读端口B
  274.                 s_ms(1000);
  275.                 DDRB=0xff;      //端口B改为
  276.                 s_ms(100);
  277.                 PORTE&=~EN;     //EN=0
  278.                 s_ms(100);
  279.                 if(temp>>7==0)
  280.                 flag = 0;
  281.                 return;
  282.         }
  283. }
  284. //LCM初始化
  285. void LCMInit(void)
  286. {
  287.         WriteCommandLCM(0x38);    //三次显示模式设置,不检测忙信号
  288.         s_ms(1000);
  289.         WriteCommandLCM(0x38);
  290.         s_ms(1000);
  291.         WriteCommandLCM(0x38);
  292.         s_ms(1000);
  293.         WriteCommandLCM(0x38);    //显示模式设置,开始要求每次检测忙信号
  294.         WriteCommandLCM(0x08);    //关闭显示
  295.         WriteCommandLCM(0x01);    //显示清屏
  296.         WriteCommandLCM(0x06);    //显示光标移动设置
  297.         WriteCommandLCM(0x0C);    //显示开及光标设置
  298. }

  299. //按指定位置显示一串字符
  300. //液晶显示:汉字为16*16,字母及数字为8*16,此次显示的文本
  301. //          从第一行第一列开始,依次向左,如果想在不同的
  302. //          位置显示,只需修改相应的行值即可。液晶显示
  303. //          完毕后,转入语音文本发送。
  304. //DisplsyList(X,DData)函数:X为0x80在第一行显示;X为0x90在
  305. //                        第二行显示;X为0x88在第三行显示;X为0x98在
  306. //                        第四行显示;DData为显示数组。
  307. void DisplayList(unsigned char X,char *DData)
  308. {
  309.         unsigned char length;
  310.         unsigned char i=0;
  311.         char *p;
  312.         p = DData;
  313.         length = strlen(p);
  314.         WriteCommandLCM(0x08);
  315.         WriteCommandLCM(X);
  316.         WriteCommandLCM(0x06);
  317.         WriteCommandLCM(0x0C);
  318.         WriteCommandLCM(X);
  319.         for(i=0;i<length;i++)
  320.         {
  321.                 WriteDataLCM(DData[i]);
  322.                 i++;
  323.                 WriteDataLCM(DData[i]);
  324.         }
  325. }
  326. void Init(){
  327.         DDRA|=~((1<<6)|(1<<7));
  328.         DDRC|=~((1<<6)|(1<<7));
  329.         PORTC|=(RED_1)|(RED_2);
  330.         PORTA|=(GREEN_1)|(GREEN_2);
  331.         //端口初始化
  332.         DDRB=0xff;
  333.         PORTB=0xff;
  334.         DDRG=(1<<3)|(1<<4);
  335.         PORTG=(1<<3)|(1<<4);
  336.         DDRE|=RW|RS|EN;
  337.         PORTE|=RW|RS|EN;
  338.         DDRD|=(0<<0)|(0<<1)|(0<<4)|(0<<5)|(0<<6)|(0<<7);
  339.         PORTD|=(1<<0)|(1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7);
  340.         s_ms(200);
  341.         s_ms(200);
  342.         LCMInit(); //LCM初始化
  343. }
  344. int main(void)
  345. {
  346.         int a,b=0,c=0,time=10;
  347.         int im;
  348.         int chf=1;
  349.         Init();
  350.         ReadStatusLCM();
  351.         DisplayList(0x80,text_1);     //显示初始界面
  352.         s_ms(100);
  353.         im=EEPROM_read(0x10);
  354.         if (im)
  355.         {
  356.                 EEPROM_write(0x00,n);
  357.                 EEPROM_write(0x08,Yel_time);
  358.                 EEPROM_write(0x10,0);
  359.         }
  360.         n=EEPROM_read(0x00);
  361.         Yel_time=EEPROM_read(0x08);
  362.     while(1)
  363.     {
  364.                 while(chf==0)
  365.                 {
  366.                         for (a=0;a<n;a++)
  367.                         {
  368.                                 if (b==0)
  369.                                 {
  370.                                         PORTA=(GREEN_1)|(RED_2);
  371.                                         while(a>=n-5&&a<n){
  372.                                                 for (;a<n;a++)
  373.                                                 {
  374.                                                         get_key();
  375.                                                         PORTA^=(RED_2);
  376.                                                         delay_ms(200);
  377.                                                 }
  378.                                                 PORTA=(YEL_2)|(GREEN_1);
  379.                                                 for(c=0;c<Yel_time;c++)
  380.                                                 {
  381.                                                         get_key();
  382.                                                         delay_ms(100);
  383.                                                         }
  384.                                         }
  385.                                 }
  386.                                 else if (b==1)
  387.                                 {
  388.                                         PORTA=(RED_1)|(GREEN_2);
  389.                                         while(a>=n-5&&a<n){
  390.                                                 for (;a<n;a++)
  391.                                                 {
  392.                                                         get_key();
  393.                                                         PORTA^=(RED_1);
  394.                                                         delay_ms(200);
  395.                                                 }
  396.                                                 PORTA=(YEL_1)|(GREEN_2);
  397.                                                 for(c=0;c<Yel_time;c++)
  398.                                                 {
  399.                                                         get_key();
  400.                                                         delay_ms(100);
  401.                                                         }
  402.                                                 PORTA=(GREEN_1)|(GREEN_2);
  403.                                                 chf=1;
  404.                                                 PORTC=(GREEN_1)|(RED_2);
  405.                                         }
  406.                                 }
  407.                                 for(c=0;c<time;c++)
  408.                                 {
  409.                                         get_key();
  410.                                         delay_ms(100);
  411.                                         }
  412.                         }
  413.                         b=(++b)%2;
  414.                 }
  415.                 while(chf==1)
  416.                 {
  417.                         for (a=0;a<n;a++)
  418.                         {
  419.                                 if (b==0)
  420.                                 {
  421.                                         PORTC=(GREEN_1)|(RED_2);
  422.                                         while(a>=n-5&&a<n){
  423.                                                 for (;a<n;a++)
  424.                                                 {
  425.                                                         get_key();
  426.                                                         PORTC^=(GREEN_1);
  427.                                                         delay_ms(200);
  428.                                                 }
  429.                                                 PORTC=(YEL_1)|(RED_2);
  430.                                                 for(c=0;c<Yel_time;c++)
  431.                                                 {
  432.                                                         get_key();
  433.                                                         delay_ms(100);
  434.                                                         }
  435.                                         }
  436.                                 }
  437.                                 else if (b==1)
  438.                                 {
  439.                                         PORTC=(RED_1)|(GREEN_2);
  440.                                         while(a>=n-5&&a<n){
  441.                                                 for (;a<n;a++)
  442.                                                 {
  443.                                                         get_key();
  444.                                                         PORTC^=(GREEN_2);
  445.                                                         delay_ms(200);
  446.                                                 }
  447.                                                 PORTC=(YEL_2)|(RED_1);
  448.                                                 for(c=0;c<Yel_time;c++)
  449.                                                 {
  450.                                                         get_key();
  451.                                                         delay_ms(100);
  452.                                                         }
  453.                                                 PORTC=(RED_1)|(RED_2);
  454.                                                 chf=0;
  455.                                                 PORTA=(GREEN_1)|(RED_2);
  456.                                         }
  457.                                 }
  458.                                 for(c=0;c<time;c++)
  459.                                 {
  460.                                         get_key();
  461.                                         delay_ms(100);
  462.                                         }
  463.                         }
  464.                         b=(++b)%2;
  465.                 }
  466.         }
  467. }
复制代码

01.7z

22.3 KB, 下载次数: 6

程序及电路图

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2022-3-27 11:57 | 只看该作者
你买的硬件与仿真中的规格不符(包括偏差较大),或硬件连接错。
回复

使用道具 举报

板凳
ID:230742 发表于 2022-3-27 17:31 | 只看该作者
先检查12864是不是ST7920芯片驱动的,带中文字库的(看图好像是,如果不是会有CS1和CS2),
找一个别的和你的单片机差不多的例程看看12864的时序,对比一下。
或者直接烧进去看看显示的汉字是否正确。
以前用STC89C52用P0接12864要接上拉电阻。虽然仿真不用,但实物要用。
线路要仔细检查好,我就把上拉电阻排焊反过。检查2两天才发现。
再检查一下是不是用的STC的单片机仿真的,实物用的AVR?
回复

使用道具 举报

地板
ID:1013350 发表于 2022-3-28 15:57 | 只看该作者
man1234567 发表于 2022-3-27 11:57
你买的硬件与仿真中的规格不符(包括偏差较大),或硬件连接错。

感谢你的回答,经检测后发现是代码的读状态函数出了问题,把读状态函数注释掉,然后加足够的延时实物正常运行
回复

使用道具 举报

5#
ID:1013350 发表于 2022-3-28 15:57 | 只看该作者
啤酒瓶子老大 发表于 2022-3-27 17:31
先检查12864是不是ST7920芯片驱动的,带中文字库的(看图好像是,如果不是会有CS1和CS2),
找一个别的和你 ...

感谢你的回答,经检测后发现是代码的读状态函数出了问题,把读状态函数注释掉,然后加足够的延时实物正常运行
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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