搜索
bottom↓
回复: 18

为何89c52程序移植到12c5a上无法运行

[复制链接]

出0入0汤圆

发表于 2013-11-15 03:43:01 | 显示全部楼层 |阅读模式
本帖最后由 cityfuture 于 2013-11-15 15:13 编辑

为何89c52程序移植到12c5a上无法运行,晶振频率越低正常,接了一个18B20,一个1602,keil vusion 4建的工程是89c51,无定时器配置,无中断,这个应该在哪修正程序呢
1602的程序在下面,为何
LCD_Data = WCLCD;
        LCD_RS = 0;
        LCD_RW = 0;
        LCD_E = 0;
        LCD_E = 0;
        LCD_E = 1;
}
LCD_RS = 0; 这个要放在数据后面?
LCD_E = 0;
        LCD_E = 0;
        LCD_E = 1;
不是应该 高向低电平跳变吗,为何是低向高跳变,为何在stc89c52中还可以正常运行?
在12C5a中无法运行,将rs位移到lcd data前,en位改为1->0 跳变,后可以运行,但出现了9楼描述的情况

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-11-15 05:47:48 | 显示全部楼层
一个是12T的,一个是1T的。你可以在烧写芯片的时候修改配置。或者是修改程序,增加延时12倍

出0入0汤圆

发表于 2013-11-15 08:43:46 | 显示全部楼层
你是否有delay类似的延时???

出0入0汤圆

发表于 2013-11-15 09:12:59 | 显示全部楼层
同意二楼,主要是1602指令不能太快。

出0入0汤圆

发表于 2013-11-15 10:21:13 | 显示全部楼层
18B20的时序太严格,你在C51上能用,在stc能用的几率很渺小。主要是处理速度的问题。有示波器的话看一下波形你就知道了。

出0入0汤圆

发表于 2013-11-15 11:43:47 | 显示全部楼层
本帖最后由 qllaoda1 于 2013-11-15 11:50 编辑

18B20是1-wire总线,时序要求很严。89C51是标准51,指令执行时间是固定的,而STC的使用了流水线,指令真实的消耗时间有一定的不确定性。建议你在做18B20的操作的时候,关掉全部中断,代码里不要有任何的跳转和分支语句还有if之类的条件判断语句和循环语句,以确保流水线不被打乱,指令按固定时间严格执行。

出0入0汤圆

发表于 2013-11-15 13:56:33 来自手机 | 显示全部楼层
去官网下stc15系列的程序下载器,里面有计算他自家芯片延时函数的功能,直接替换你程序里的延时就行了

出0入0汤圆

 楼主| 发表于 2013-11-15 14:00:25 | 显示全部楼层
本帖最后由 cityfuture 于 2013-11-15 14:16 编辑
STM32_Study 发表于 2013-11-15 05:47
一个是12T的,一个是1T的。你可以在烧写芯片的时候修改配置。或者是修改程序,增加延时12倍 ...


请问改了程序后,为何出现了,显示["55"]后再显示["1"] 后边那个5不消失变成 15,显示["-10"],再显示["1“]变成110 为何,如果在前加一句DisplayListChar[1,2"     "]会出现闪烁,但不会出现拖位现象
void WriteDataLCD(unsigned char WDLCD)
{
        ReadStatusLCD(); //检测忙
         LCD_RS = 1;
        LCD_Data = WDLCD;
        //delay();
       
        LCD_RW = 0;
        LCD_E = 1;                 //若晶振速度太高可以在这后加小的延时
        LCD_E = 1;                 //延时

        // delay();
        LCD_E = 0;                 //89c52中写法不同,89c52请使用原液晶写法
}

/***********写指令********************************************************/       
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测
{
        if (BuysC) ReadStatusLCD(); //根据需要检测忙
        LCD_RS = 0;
        LCD_Data = WCLCD;
       
        LCD_RW = 0;
        LCD_E = 1;
        LCD_E = 1;
        //delay();
        LCD_E = 0;
}

/***********读数据********************************************************/       
unsigned char ReadDataLCD(void)
{
        LCD_RS = 1;
        LCD_RW = 1;
        LCD_E = 1;
        LCD_E = 1;

        LCD_E = 0;
        return(LCD_Data);
}

/***********读状态*******************************************************/       
unsigned char ReadStatusLCD(void)
{
        LCD_Data = 0xFF;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_E = 0;
        LCD_E = 0;
        LCD_E = 1;
        while (LCD_Data & Busy); //检测忙信号
        return(LCD_Data);
}

/***********初始化********************************************************/       
void LCDInit(void)
{
        LCD_Data = 0;
        WriteCommandLCD(0x38,0);         //三次模式设置,不检测忙信号
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,1);         //显示模式设置,开始要求每次检测忙信号
        WriteCommandLCD(0x08,1);         //关闭显示
        WriteCommandLCD(0x01,1);         //显示清屏
        WriteCommandLCD(0x06,1);         //显示光标移动设置
        WriteCommandLCD(0x0C,1);         //显示开及光标设置
}
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40;                 //当要显示第二行时地址码+0x40;
        X |= 0x80;                         //算出指令码
        WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
        Delay5Ms();
        WriteDataLCD(DData);
}
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
        unsigned char ListLength;

        ListLength = 0;
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>=0x20){ //若到达字串尾则退出
                   if (X <= 0xF){                 //X坐标应小于0xF
                     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                     ListLength++;
                     X++;
            }
          }
}


/***********短延时********************************************************/       
void Delay5Ms(void)
{
        unsigned int TempCyc = 5552;
        while(TempCyc--);
}

/***********长延时********************************************************/       
void Delay400Ms(void)
{
        unsigned char TempCycA = 5;
        unsigned int TempCycB;
        while(TempCycA--){
                  TempCycB=7269;
                  while(TempCycB--);
        }
}

出0入0汤圆

 楼主| 发表于 2013-11-15 14:16:48 | 显示全部楼层
jswd0810 发表于 2013-11-15 09:42
+1,应该有配置可以修改

请问改了程序后,为何出现了,显示["55"]后再显示["1"] 后边那个5不消失变成 15,显示["-10"],再显示["1“]变成110 为何,如果在前加一句DisplayListChar[1,2"     "]会出现闪烁,但不会出现拖位现象
void WriteDataLCD(unsigned char WDLCD)
{
        ReadStatusLCD(); //检测忙
         LCD_RS = 1;
        LCD_Data = WDLCD;
        //delay();
        
        LCD_RW = 0;
        LCD_E = 1;                 //若晶振速度太高可以在这后加小的延时
        LCD_E = 1;                 //延时

        // delay();
        LCD_E = 0;                 //89c52中写法不同,89c52请使用原液晶写法
}

/***********写指令********************************************************/        
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测
{
        if (BuysC) ReadStatusLCD(); //根据需要检测忙
        LCD_RS = 0;
        LCD_Data = WCLCD;
        
        LCD_RW = 0;
        LCD_E = 1;
        LCD_E = 1;
        //delay();
        LCD_E = 0;
}

/***********读数据********************************************************/        
unsigned char ReadDataLCD(void)
{
        LCD_RS = 1;
        LCD_RW = 1;
        LCD_E = 1;
        LCD_E = 1;

        LCD_E = 0;
        return(LCD_Data);
}

/***********读状态*******************************************************/        
unsigned char ReadStatusLCD(void)
{
        LCD_Data = 0xFF;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_E = 0;
        LCD_E = 0;
        LCD_E = 1;
        while (LCD_Data & Busy); //检测忙信号
        return(LCD_Data);
}

/***********初始化********************************************************/        
void LCDInit(void)
{
        LCD_Data = 0;
        WriteCommandLCD(0x38,0);         //三次模式设置,不检测忙信号
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,1);         //显示模式设置,开始要求每次检测忙信号
        WriteCommandLCD(0x08,1);         //关闭显示
        WriteCommandLCD(0x01,1);         //显示清屏
        WriteCommandLCD(0x06,1);         //显示光标移动设置
        WriteCommandLCD(0x0C,1);         //显示开及光标设置
}
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40;                 //当要显示第二行时地址码+0x40;
        X |= 0x80;                         //算出指令码
        WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
        Delay5Ms();
        WriteDataLCD(DData);
}
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
        unsigned char ListLength;

        ListLength = 0;
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>=0x20){ //若到达字串尾则退出
                   if (X <= 0xF){                 //X坐标应小于0xF
                     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                     ListLength++;
                     X++;
            }
          }
}


/***********短延时********************************************************/        
void Delay5Ms(void)
{
        unsigned int TempCyc = 5552;
        while(TempCyc--);
}

/***********长延时********************************************************/        
void Delay400Ms(void)
{
        unsigned char TempCycA = 5;
        unsigned int TempCycB;
        while(TempCycA--){
                  TempCycB=7269;
                  while(TempCycB--);
        }
}

出0入0汤圆

 楼主| 发表于 2013-11-15 14:17:10 | 显示全部楼层
zbn2010 发表于 2013-11-15 09:12
同意二楼,主要是1602指令不能太快。

请问改了程序后,为何出现了,显示["55"]后再显示["1"] 后边那个5不消失变成 15,显示["-10"],再显示["1“]变成110 为何,如果在前加一句DisplayListChar[1,2"     "]会出现闪烁,但不会出现拖位现象
void WriteDataLCD(unsigned char WDLCD)
{
        ReadStatusLCD(); //检测忙
         LCD_RS = 1;
        LCD_Data = WDLCD;
        //delay();
        
        LCD_RW = 0;
        LCD_E = 1;                 //若晶振速度太高可以在这后加小的延时
        LCD_E = 1;                 //延时

        // delay();
        LCD_E = 0;                 //89c52中写法不同,89c52请使用原液晶写法
}

/***********写指令********************************************************/        
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测
{
        if (BuysC) ReadStatusLCD(); //根据需要检测忙
        LCD_RS = 0;
        LCD_Data = WCLCD;
        
        LCD_RW = 0;
        LCD_E = 1;
        LCD_E = 1;
        //delay();
        LCD_E = 0;
}

/***********读数据********************************************************/        
unsigned char ReadDataLCD(void)
{
        LCD_RS = 1;
        LCD_RW = 1;
        LCD_E = 1;
        LCD_E = 1;

        LCD_E = 0;
        return(LCD_Data);
}

/***********读状态*******************************************************/        
unsigned char ReadStatusLCD(void)
{
        LCD_Data = 0xFF;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_E = 0;
        LCD_E = 0;
        LCD_E = 1;
        while (LCD_Data & Busy); //检测忙信号
        return(LCD_Data);
}

/***********初始化********************************************************/        
void LCDInit(void)
{
        LCD_Data = 0;
        WriteCommandLCD(0x38,0);         //三次模式设置,不检测忙信号
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,0);
        WriteCommandLCD(0x38,1);         //显示模式设置,开始要求每次检测忙信号
        WriteCommandLCD(0x08,1);         //关闭显示
        WriteCommandLCD(0x01,1);         //显示清屏
        WriteCommandLCD(0x06,1);         //显示光标移动设置
        WriteCommandLCD(0x0C,1);         //显示开及光标设置
}
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40;                 //当要显示第二行时地址码+0x40;
        X |= 0x80;                         //算出指令码
        WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
        Delay5Ms();
        WriteDataLCD(DData);
}
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
        unsigned char ListLength;

        ListLength = 0;
        Y &= 0x1;
        X &= 0xF;                                 //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>=0x20){ //若到达字串尾则退出
                   if (X <= 0xF){                 //X坐标应小于0xF
                     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                     ListLength++;
                     X++;
            }
          }
}


/***********短延时********************************************************/        
void Delay5Ms(void)
{
        unsigned int TempCyc = 5552;
        while(TempCyc--);
}

/***********长延时********************************************************/        
void Delay400Ms(void)
{
        unsigned char TempCycA = 5;
        unsigned int TempCycB;
        while(TempCycA--){
                  TempCycB=7269;
                  while(TempCycB--);
        }
}

出0入0汤圆

发表于 2013-11-15 17:59:58 | 显示全部楼层
12 与89 的时钟频率不一样呀

出0入0汤圆

发表于 2013-11-15 20:15:25 | 显示全部楼层
液晶具有锁存功能,因此你写了 【55】在写入1,只会在你写入1的那个地方做改变,其余显示的是不会改变的.
建议你用个3个字节数组,每次改变数组内的值后再将这3个字节一次写入液晶
如果数值没变,也省去写入的步骤

出0入0汤圆

发表于 2013-11-15 20:32:51 | 显示全部楼层
延时通过烧写软件就能设置

出0入0汤圆

发表于 2013-11-15 22:42:11 | 显示全部楼层
既然之前可以用,说明程序里的时序是没问题的。
既然调整一下语句顺序,可以出效果,说明硬件接口没问题。
根据经验,一般应该加延时。
单片机或晶振换了,指令周期也变了,对应的延时也会变。
在1602的手册里有一个表格对时序图作了,说明每个时序变化的延时范围。
而且,不同品牌的产品,参数不一定相同。

出0入0汤圆

发表于 2013-11-16 13:24:02 | 显示全部楼层
我也遇到过,我加延时后正常显示

出0入0汤圆

发表于 2013-11-16 13:30:46 | 显示全部楼层
延时问题

出0入54汤圆

发表于 2013-11-16 14:02:13 | 显示全部楼层
一般是延时问题 改长一些试下吧

出0入0汤圆

发表于 2013-11-17 13:13:33 | 显示全部楼层
在写多字节命令的时候会出现误取操作数的情况,可以在每一个双字节语句后加上适当空指令延时就可以解决
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-6-1 11:06

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

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