打印

大家帮我看一下这个程序,着急啊,很奇怪,没有道理的啊

[复制链接]
1606|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
happywxg|  楼主 | 2009-3-28 22:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序要实现的目的:就是用串口发送数据,下面单片机驱动1602,显示接收到的数据。
主函数:
#include "reg52.h"
#include "string.h"
#include"lcd1602.h"

//#include "mscom.h"
sbit recom=P1^0;
sbit ticom=P1^1;


#define uint unsigned int
#define uchar unsigned char

uchar code  LCD1[]={"StepMotorContorl"};
uchar code  LCD2[]={"Speed:"};
unsigned int  LCD3[];    
unsigned int  re_dat[3];

unsigned int count;
unsigned char temp0,temp1,temp2;
unsigned int speed;
 
//*****************************************
//      电机初始化  
//*****************************************
/*
void init()
{
    RE=0;
    HA=1;  // 整部 
    CW=1;  // 正传 
    EN=1;  // 电机使能 
    CON=0; // 电机绕组限流控制 
    CL=1;
    RE=1;
}
*/
//*****************************************
//      串口初始化  
//*****************************************
void init_serialcomm()        
{
    SCON  = 0x50;       //确定串口控制:方式1(10位异步收发,波特率由定时器1控制),允许串口接收
    TMOD  = TMOD|0x20;  //确定定时器1的工作方式:方式2(常数自动装如的8位T/C,TH寄存8位初值,TL进行8位计数)
    PCON  = 0x80;       //串口波特率加倍位SMOD=1 
    TH1   = 0xf3;       //计算装入初始值使波特率=4800(fosc=12MHz )       
    TL1   = 0xf3;
    TR1   = 1;          //启动定时器1                                    
    IE    = 0x9A;       //串口在中断方式工作时,开CPU和源中断            

}

//*****************************************
//        LCD1602初始化                                                             
//*****************************************
void LCD_Init(void)
{
    
    WriteOrder(0X01);        // clear display 
    WriteOrder(0x38);       //两行显示     
    WriteOrder(0x0C);        // open display 
    WriteOrder(0x06);       //set the way of input :AC++ 

    
}

//*****************************************
//        串口中断                                                      
//*****************************************

void serial () interrupt 4
{
    if(RI) 
      {
        re_dat[count]=SBUF;
        RI=0;
        TI=0;
        SBUF=re_dat[count];
        while(TI==0);
        count++;
       }


}

//*****************************************
//        主程序 
//*****************************************

void main()
{
    delayms(10);
    //init_serialcomm();
    delayms(10);
    LCD_Init();    
    delayms(10);
    WriteData(0,0,LCD1);
    delayms(10);
    WriteData(1,0,LCD2);
    delayms(10);
    WriteData(1,6,"0");
    delayms(10);
    WriteData(1,10,"r/min");
    delayms(10);
    while(1)
    {    
        P1=0xff;
        count=0;
        while(RI==0);
        if(count==2)
           {
               count=0;
        }
        if(re_dat[2]==49)
        {
        
            recom=0;
            delayms(100);
             WriteDat(8,49);
        }

        //comm_re();
        
        

      }
}
下面是1602的程序:
#include"reg52.h"
#include "string.h"
#include"lcd1602.h"
#define uint unsigned int
#define uchar unsigned char

//*************************************
//        延时程序          
//*************************************
void delayms(uint t)
{
    uint i;
    while(t--)
    {
        for(i=0;i<100;i++);
    }
}
//*************************************
//       LCD1602 判忙函数
//*************************************
Is_busy()
{
    uchar busy;
    LCD_Data=0xff;
    rs=0;
    rw=1;
    en=0;
    delayms(1);
    en=1;
    delayms(1);
    busy= P2&0x80;
    while(busy);
    en=0;

}
//************************************
//        写命令           
//************************************
void WriteOrder(uchar Order)
{
    Is_busy();
    rs=0;
    rw=0;
    en=0;
    delayms(5);
    en=1;
    LCD_Data=Order;
    delayms(5);
    en=0;
}
//************************************
//        写字符串 
//************************************
void WriteData(uchar y,uchar x,unsigned char LcdData[])
{
    uchar j,len;
    len= strlen (LcdData);
    if(0==y) 
    {
        WriteOrder(x+0x80);
    }
    else
    { 
        WriteOrder(x+0xC0);    
    }
    Is_busy();
    
    for(j=0;j<len;j++)
    {
        Is_busy();
        rs=1;
        rw=0;
        en=0;
           delayms(5);
        en=1;
        LCD_Data=LcdData[j];
        delayms(5);
          en=1;
          delayms(5);
          en=0;
    }
        
}    

//**************************************
//        写数字 
//**************************************
void WriteDat(unsigned char x,unsigned char dat)
{
      //LCD_Data=0x00;
      WriteOrder(x+0xC0);
       Is_busy();
      rs=1;
      rw=0;
      en=0;
      delayms(5);
      en=1;
      LCD_Data=dat;
      delayms(5);
      en=1;
      delayms(5);
      en=0;


}

程序编的不是很严谨,但是现在存在的问题是:只要是把串口的初始化加上的话,1602就不能显示,但是要是把串口的初始化去掉或是把串口的中断函数去掉的话,1602就是正常的,还有就是把串口初始化放在液晶屏的显示程序后面,就OK,也就是说只要是串口在工作的话,液晶屏就不会正常工作。
个人分析:好像串口一直在中断,根本就不会去驱动液晶屏,调了好长时间了,还是不明白,请各位高手帮我看一下啊。我的C语言不是很好。
先谢谢各位大侠了。。。

相关帖子

沙发
xwj| | 2009-3-28 22:43 | 只看该作者

开了中断,还到处用while(RI==0);???

还在中断服务程序里用while(TI==0);

使用特权

评论回复
板凳
happywxg|  楼主 | 2009-3-29 21:51 | 只看该作者

关于数组问题

从串口发过来的数据放在一个变量里面,然后直接显示的话就没有问题,但是我要书放在一个数组里面的话,显示就会使乱码,为什么呢??

使用特权

评论回复
地板
hotpower| | 2009-3-29 22:08 | 只看该作者

队列问题

使用特权

评论回复
5
yes24| | 2009-3-30 10:58 | 只看该作者

程序的实质都是存储空间,指针,ram够吗?

使用特权

评论回复
6
songbangyan| | 2009-3-30 11:56 | 只看该作者

解决数组问题

在C语言中一般都认为数组是通过首地址的指针传递的,但是实际使用的时候会发现一些问题。最好的解决办法就是直接使用数组来作为形参。
如果你需要某个子函数修改你数组的赋值可以如下定义:
char a[];
……
char funtion(char a[])
{……
一些实际操作
return 1;}

这样在funtion中就完成了对数组a的赋值。不要尝试使用return来完成数组传递。

使用特权

评论回复
7
happywxg|  楼主 | 2009-3-30 21:46 | 只看该作者

感谢

感谢楼上大侠们的解答,现在明白点了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

136

帖子

0

粉丝