单片机程序求助,请帮我看看,哪里有问题

2019-03-24 18:02发布

//***************************************
// 使用单片机STC89C51
// 晶振:11.0592M
// 显示:LCD1602
// 编译环境 Keil uVision3
// 参考宏晶网站24c04通信程序
// 时间:2011年4月20日
//****************************************
#include  <REG52.H>       
#include  <math.h>    //Keil library  
#include  <stdio.h>   //Keil library       
#include  <INTRINS.H>
#define   uchar unsigned char
#define   uint unsigned int       
#define   DataPort P0         //LCD1602数据端口
sbit          SCL=P1^0;      //IIC时钟引脚定义
sbit            SDA=P1^1;      //IIC数据引脚定义
sbit      LCM_RS=P2^0;   //LCD1602命令端口               
sbit      LCM_RW=P2^1;   //LCD1602命令端口               
sbit      LCM_EN=P2^2;   //LCD1602命令端口
sbit rxd=P3^1;    //HC-05接入端口
sbit txd=P3^0;
sbit s0=P3^3;     //定义按键
sbit s1=P3^6;
sbit s2=P3^7;
sbit s3=P3^2;     //定义按键
sbit IN1=P1^0;    //定义L298N
sbit IN2=P1^1;
sbit ENA=P1^2;

           
uchar   ge,shi,bai,qian,wan;            //显示变量
uchar num,slnum,num0;
uchar light1;
uchar light2;
uchar L1,L2,L3,L4;
int     dis_data;                       //变量

void delay_nms(unsigned int k);
void Uart_Init();
void Recv(void) ;

void InitLcd();
void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
void conversion(uint temp_data);

void light(uchar date);
void KeyRead();

void init_Timer0(void);
void Timer0(void) interrupt 1 using 1;
/**************************串口初使化函数***********************/
void Uart_Init()                                                                    
{
        TMOD = 0x20;  //T1方式2,用于产生波特率
        TH1  = 0xFD;  //装初值
        TL1  = 0xFD;
        SCON = 0X50;  //UART方式1;8位UART
        PCON = 0x00;  //SMOD=0;波特率不加倍
        TR1  = 1;     //启动定时器1
        EA   = 1;     //打开全局中断控制
        ES   = 1;     //串行口中断
}
/************************命令数据接收函数**********************/
void Recv(void)    //串口中断                         
{  
        int temp;
        if(RI == 1)   //是否有数据传过来
        {       
         temp= SBUF;
                RI = 0;
        }
   
      light1= temp;
}
void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
{  
    wan=temp_data/10000+0x30 ;
    temp_data=temp_data%10000;   //取余运算
    qian=temp_data/1000+0x30 ;
    temp_data=temp_data%1000;    //取余运算
    bai=temp_data/100+0x30   ;
    temp_data=temp_data%100;     //取余运算
    shi=temp_data/10+0x30    ;
    temp_data=temp_data%10;      //取余运算
    ge=temp_data+0x30;        
}
//毫秒延时**************************
void delay_nms(unsigned int k)       
{                                               
unsigned int i,j;                               
for(i=0;i<k;i++)
{                       
for(j=0;j<121;j++)                       
{;}}                                               
}

/*******************************/
void WaitForEnable(void)       
{                                       
DataPort=0xff;               
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);       
LCM_EN=0;                               
}                                       
/*******************************/
void WriteCommandLCM(uchar CMD,uchar Attribc)
{                                       
if(Attribc)WaitForEnable();       
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();       
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}                                       
/*******************************/
void WriteDataLCM(uchar dataW)
{                                       
WaitForEnable();               
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();       
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}               
/***********************************/
void InitLcd()                               
{
    DataPort=0;       
    WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号
    WriteCommandLCM(0x38,0);
    WriteCommandLCM(0x38,0);       
   WriteCommandLCM(0x38,1);  /*显示模式设置*/       
   WriteCommandLCM(0x08,1); /*显示关闭*/        
   WriteCommandLCM(0x01,1); /*显示清屏*/        
   WriteCommandLCM(0x06,1);/*显示光标移动设置*/       
   WriteCommandLCM(0x0c,1);/*显示开及光标设置*/
}                       
/***********************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{                                               
Y&=1;        // 限制X不能大于15,Y不能大于1                                       
X&=15;                                               
if(Y)X|=0x40;         // 当要显示第二行时地址码:0xc0                               
X|=0x80;        // 第一行的地址码:0x80               
WriteCommandLCM(X,Y);// 这里不检测忙信号,发送地址码               
WriteDataLCM(DData);               
}
/***********设置按键处理程序************/
/****************************************
* 函数名  :KeyRead
* 描述    :按键扫描函数
* 输入    :无
* 输出    :无
* 返回    :无
* 调用    :外部调用
***************************************/                       
void KeyRead()
{
        if(s0==0)
        {        delayms(5);
                if(s0==0)
                {        slnum++;
                        while(!s0);
                        if(slnum==1)
                        {         WriteCommandLCM(0x80+0x0e);
                                 WriteCommandLCM(0x0f);
                        }
                        if(slnum==2)
                        {         WriteCommandLCM(0x80+0x0d);
                        }
                        if(slnum==3)
                        {
                            WriteCommandLCM(0x80+0x0c);
                        }
                        if(slnum==4)
                        {         WriteCommandLCM(0x80+0x0b);
                        }
                        if(slnum==5)
                        {        slnum=0;
                                 WriteCommandLCM(0x0c);
                        }
                        if(slnum==0)
                        {       
                        }
                }
        }
        if(slnum!=0)
        {       
                if(s1==0)
                {        delayms(5);
                        if(s1==0)
                        {        while(!s1);
                                if(slnum==1)
                                {        L1++;
                                        if(L1==10)
                                                L1=0;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(11,1,L1+0x30);Delay_nms(10);
                               
                                }
                                if(slnum==2)
                                {        L2++;
                                        if(L2==10)
                                                L2=0;
                                         WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(10,1,L1+0x30);Delay_nms(10);
                               
                                }
                                if(slnum==3)
                                {        L3++;
                                        if(L3==10)
                                                L3=0;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(9,1,L1+0x30);Delay_nms(10);
                               
                                }
                                if(slnum==4)
                                {        L4++;
                                        if(L4==10)
                                                L4=0;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(8,1,L1+0x30);Delay_nms(10);
                                       
                                }
                        }
                }
                if(s2==0)
                {        delayms(5);
                        if(s2==0)
                        {        while(!s2);
                                if(slnum==1)
                                {        L1--;
                                        if(L1==-1)
                                                L1=9;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(11,1,L1+0x30);Delay_nms(10);
                               
                                }
                                if(slnum==2)
                                {        L2--;
                                        if(L2==-1)
                                                L2=9;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(10,1,L1+0x30);Delay_nms(10);
                                       
                                }
                                if(slnum==3)
                                {        L3--;
                                        if(L3==-1)
                                                L3=9;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(9,1,L1+0x30);Delay_nms(10);
                                       
                                }
                                if(slnum==4)
                                {        L4--;
                                        if(L4==-1)
                                                L4=9;
                                        WriteCommandLCM(0x0c,1);
                                        DisplayOneChar(8,1,L1+0x30);Delay_nms(10);
                                       
                                }
                        }
                }       
        }
        light1=L1+L2*10+L3*100+L4*1000;
}                       
// **********PWM产生**********//
/*******************************
* 函数名  :init_Timer0
* 描述    :初始化定时器0
* 输入    :无
* 输出    :无
* 返回    :无
* 调用    :外部调用
******************************/
void init_Timer0(void)   //定时器中断初始化
{
        TH0 = 0;
        TL0 = 0;
        TMOD=0x01;                                   //设置定时器0为工作方式1
        TH0 = (65536 - 100) / 256;      /*右端表达式编译后为0xFF*/
      TL0 = (65536 - 100) % 256;      /*同上*/
        TR0=1;                   //开定时器T0
        ET0 = 1;                 // //开定时器T0中断
        EA = 1;                         //定时器0中断允许
}                                            
/************LED驱动使能*********************************/
void LEDGo()
{
EN1=1;
EN2=0;
}


//*********************************************************
//主程序********
//*********************************************************
void main()
{  
   float temp;
   delay_nms(200);            //延时200ms       
   Uart_Init();       // 串口初使化函数
   KeyRead();
   InitLcd();           //初始化LCD
   init_Timer0(void);    //定时器中断初始化
   LEDGo();
  while(1)              //循环
  {
   
         EN1=1;
     EN2=0;
         if(s0==0)
                {        num0=1;}
                while(num0)
                {        keyscan();
                        if(slnum==0)
                        {        num0=0;}
                }
    CYCLE = 100;// 时间可以调整 这个是10调整 8位PWM就是256步                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
        while(light1=light2)   /*渐亮,每一次变化亮度增加1*/
        {
          
           if(light1 >= light2)   /*若预设值和接受值相等时,pwm不再增加*/
           {         
              delay(200); //延时时间,从一个亮度到下一个亮度的间隔时间,速度快就能看到连续效果
              PWM_ON++;     //这个使用较长延时,以便能看清楚变化过程  
                            //这个里可以添加其他程序 如到最亮时候控制设备
           }
        
         
    }
       
        while(light1=light2)     //渐暗,每一次变化亮度减少1 //
        {
          
           if(light1 <= light2)   /*若预设值和接受值相等时。pwm不再增加*/
           {
              delay(200);  /*延时*/
              PWM_ON--;    /*高电平脉宽缩短,即亮度降低*/
          
           }
            
      
        }
  
    conversion(temp);         //计算数据和显示
        DisplayOneChar(0,0,'L');
        DisplayOneChar(1,0,'i');
        DisplayOneChar(2,0,'g');
        DisplayOneChar(3,0,'h');
        DisplayOneChar(4,0,'t');
        DisplayOneChar(5,0,':');
    conversion(data);  
        DisplayOneChar(1,1,'S');
        DisplayOneChar(2,1,'e');
        DisplayOneChar(3,1,'t');
        DisplayOneChar(5,1,':');

    DisplayOneChar(7,0,wan); //显示光照采集数据
    DisplayOneChar(8,0,qian);//显示光照采集数据  
    DisplayOneChar(9,0,bai); //显示光照采集数据
    DisplayOneChar(10,0,shi);//显示光照采集数据
    DisplayOneChar(11,0,ge); //显示光照采集数据

    DisplayOneChar(8,1,L1+0x30);//显示按键设定数据
    DisplayOneChar(9,1,L2+0x30); //显示按键设定数据
    DisplayOneChar(10,1,L3+0x30);//显示按键设定数据
    DisplayOneChar(11,1,L4+0x30); //显示按键设定数据


        DisplayOneChar(13,0,'L'); //显示光照采集数单位
        DisplayOneChar(14,0,'u');
        DisplayOneChar(15,0,'x');  
        DisplayOneChar(13,1,'L'); //显示按键设置数单位
        DisplayOneChar(14,1,'u');
        DisplayOneChar(15,1,'x');      
  }
}
/**********************************************************
* 函数名  :Timer0(void) interrupt 1
* 描述    :定时器0中断服务函数,设置pwm输出引脚高低电平,实现pwm输出
* 输入    :无
* 输出    :无
* 返回    :无
* 调用    :无
*********************************************************/
void Timer0(void) interrupt 1 using 1
{
        static uchar count;
        TH0=(65536-100)/256;
        TL0=(65536-100)%256;//定时0.1mS
        if(count == PWM_ON)      /*若中断次数达到亮度设定值*/
      {
        ENA=0;       /*则熄灯*/
      }
       count++;        /*每次中断记录+1*/
      if(count == CYCLE)      /*若中断次数达到PWM周期长度*/
      {
       count = 0;       /*则清零中断记录*/
          if(PWM_ON != 0)  /*若此时亮度值非零*/
          {
            ENA=1;       /*则点灯*/
           }
         }
}
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。