找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1182|回复: 6
收起左侧

看下程序哪里不对

[复制链接]
ID:213280 发表于 2018-10-5 17:26 | 显示全部楼层 |阅读模式
50黑币
从网上下载的程序,下载到板子试了,就一直这样显示不动,大佬帮忙看下程序问题出在哪
#include<reg52.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
uchar red=0,blue=0,green=0,flag=0,i=0,j=0;
uchar dat[5]={0,0,0,0,0};
uint counter=0;
sbit TCS_OE=P1^0;
sbit TCS_S0=P1^1;
sbit TCS_S1=P1^2;
sbit TCS_S2=P1^3;
sbit TCS_S3=P1^4;
sbit TCS_OUT=P3^2;
sbit LCD_RS=P2^4;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^6;
sbit LCD_PSB=P2^1;
sbit LCD_RST=P2^3;
sbit LCD_BK=P2^7;
uchar table0[]="颜色识别:";
uchar table1[]="红色:";
uchar table2[]="蓝色:";
uchar table3[]="绿色:";
void delay(uint m)  //延时程序
{
unsigned int i,j;
  for(i=0;i<m;i++)
     for(j=0;j<10;j++);
}
void LCD_Busy(void)// 测试液晶是否忙
{  
   P0=0xff;    // 数据口先送 0xff
   LCD_RS=0;     // 指令
   LCD_RW=1;     // 读出忙标志(BF)及地址记数器(AC)
   LCD_EN=1;     // 使能
   while(P0&0x80); // 最高位为1则忙,再读
   LCD_EN=0;
}
void LCD_cmd(char md,char dt)         //写指令或数据  md=0命令 md=1数据
{
   LCD_Busy();    // 测试液晶是否忙
if(md) LCD_RS=1;  // 判断是数据还是命令
   else LCD_RS=0;
   LCD_RW=0;    // 写
   P0=dt;   // 送数据或命令
   delay(20);
   LCD_EN=1;     // 使能
   delay(20);
   LCD_EN=0;
}
void LCD_init(void)//液晶显示器初始化
{  LCD_PSB=1;
   LCD_RST=0;
   delay(10);
   LCD_RST=1;
   LCD_cmd(0,0x34);  // 关闭图形显示 *
   delay(100);
   LCD_cmd(0,0x30);  // 基本指令动作   
   delay(100);
   LCD_cmd(0,0x06);    // 光标的移动方向
   delay(100);
   LCD_cmd(0,0x0c);    // 开显示,关光标
   delay(100);
   LCD_cmd(0,0x01);  // 清屏,地址指针指向00H
   delay(100);
}
void DisplayZF(uchar m,char *p)
{    LCD_cmd(0,m);
     while((*p)!='\0')
     {                                      //显示字符"         "
      LCD_cmd(1,*p++);
     }
}
void DisplayScreen()          
{   LCD_cmd(0,0x30);     // 基本指令动作
        //delay(100);
    LCD_cmd(0,0x0c);       // 开显示,关光标   
        //delay(100);
    DisplayZF(0x80,table0);
    //delay(100);
    DisplayZF(0x91,table1);
        //delay(100);
        DisplayZF(0x89,table2);
        //delay(100);
    DisplayZF(0x99,table3);
        //delay(100);
}
void INTER_init()
{   TCS_S0=1;
    TCS_S1=1;
        TCS_S2=0;
    TCS_S3=0;
        TCS_OE=1;
        TMOD=0x11;
        TH1=(65536-60000)/256;
        TL1=(65536-60000)%256;
        EA=1;//开总中断
        ET0=0; //关定时器0中断
        ET1=1; // 开定时器0中断
        TR0=0; //关定时器0
        TR1=1; //启动定时器1
        EX0=1;        //开外部中断0
        EX1=0;        // 关外部中断1
        IT0=1;         //外部中断0跳变沿触发
               
}
void timer0() interrupt 1
{
        counter++;       
}
void timer1() interrupt 3
{
        TH1=(65536-60000)/256;
        TL1=(65536-60000)%256;
    EA=0;//关总中断
        EX0=0;
        TR1=0;       
        flag++;//实现先检测红色,再检测蓝色,然后检测绿色,循环检测
        if(flag==1)
        {                    
                 red=counter;
                 dat[0]=counter/1000+0x30;                 
                 counter=counter%1000;
                 dat[1]=counter/100+0x30;
                 counter=counter%100;
                 dat[2]=counter/10+0x30;
                 counter=counter%10;
                 dat[3]=counter+0x30;
                    DisplayZF(0x94,dat);                        
             TCS_S2=0;//下次检测蓝色(S2,S3=0,1)
                 TCS_S3=1;               
        }
        else if(flag==2)
        {
                    blue=counter;
                 dat[0]=counter/1000+0x30;                 
                 counter=counter%1000;
                 dat[1]=counter/100+0x30;
                 counter=counter%100;
                 dat[2]=counter/10+0x30;
                 counter=counter%10;
                 dat[3]=counter+0x30;               
                    DisplayZF(0x8c,dat);                                         
                TCS_S2=1;//下次检测绿色(S2,S3=1,1)
                TCS_S3=1;
        }
    else if(flag==3)
        {
                    green=counter;
                 dat[0]=counter/1000+0x30;                 
                 counter=counter%1000;
                 dat[1]=counter/100+0x30;
                 counter=counter%100;
                 dat[2]=counter/10+0x30;
                 counter=counter%10;
                 dat[3]=counter+0x30;       
                    DisplayZF(0x9c,dat);                                                 
                TCS_S2=0;//下次检测红色(S2,S3=0,0)
                TCS_S3=0;
        }
        else if(flag==4)
        {      
             flag=0;                 
                 if((red+5)>(blue+green))                 
                     DisplayZF(0x85,"蓝色");
                 else if((blue+8>red)&&(blue+2>green))
                     DisplayZF(0x85,"红色");               
                 /*else if((green-3<red)&&(green-15>blue))
                     DisplayZF(0x85,"绿色");*/                 
                 else if((red>blue)&&(green>blue))
                      DisplayZF(0x85,"黄色");               
                 else
                     DisplayZF(0x85,"绿色");                 
        }
        counter = 0;//清零外中断计数标志               
    TR0=1;
        EX0=1;
        TR1=1;
        EA=1;
       
}       

void main(void)
{
    LCD_init();
        INTER_init();
        while(1)
        {       
        DisplayScreen();
    delay(100);
        }  
}

IMG_20181005_171931.jpg
回复

使用道具 举报

ID:405662 发表于 2018-10-5 19:43 | 显示全部楼层
是不是延迟太短,显示太快,看不见。增大延时试试
回复

使用道具 举报

ID:213280 发表于 2018-10-5 21:48 | 显示全部楼层
chen232001 发表于 2018-10-5 19:43
是不是延迟太短,显示太快,看不见。增大延时试试

不是,增大延时也不行
回复

使用道具 举报

ID:405708 发表于 2018-10-5 22:01 | 显示全部楼层
1. 你的程序很乱呀,要养成良好的风格
2. 主程序中有循环调用 DisplayZF,定时器3中断中也调用了 DisplayZF,会有冲突
    比如此时正在执行主程序中的 DisplayZF,然后中断来了,打破了原来的时序,所以你要
   先整理一下程序再找原因
回复

使用道具 举报

ID:330198 发表于 2018-10-6 09:49 | 显示全部楼层
上面的程序有问题,用不到外中断,以下程序仅供参考。
/*******************************************
* 文件名:TCS230.c
* 功能: 读取RGB值
* 说明:
* 时间:
/********************************************/
#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

/**引脚定义**/
//sbit oe=P1^0;   
//sbit s0=P1^2;
//sbit s1=P1^3;
sbit s2=P1^5;
sbit s3=P1^4;

//变量、常量定义

long int color,red,green,blue;
long int disp_tc;   
long int buf_cor;    //颜色值

uint rp=3,gp=6,bp=3;    //定义比例因子

uchar disp_p;    //颜色标志位(0:红 1:绿 2:蓝)


//数组

uchar disp_buf[3]={0xff,0xff,0xff};    //临时保存当前的色值

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x08,0x42,0x00};/*数码管花数*/
uchar code scan[4]={0x8f,0x4f,0x2f,0x0f};    /*数码管位选*/

/*******************************************
* 函数名称: t0_init()
* 函数功能: 定时器0初始化
* 入口参数: 无
* 出口参数: 无
/********************************************/
void t0_init()
{
     TMOD=0x51;        //T1计数 T0定时 工作方式1

     TH0=0x3C;        //定时50ms

     TL0=0xB0;
     TH1=0xFF;        //计数初值

     TL1=0x9C;
     EA=1;            //开中断

     ET0=1;        
     TR0=1;            //启动

     TR1=1;
}

/*******************************************
* 函数名称: delay_1ms(uint w)
* 函数功能: 延时1mx
* 入口参数: 无符号整形W
* 出口参数: 无
/********************************************/
void delay_1ms(uint w)   
{
     uint y,z;
     for(z=w;z>0;z--)
        for(y=100;y>0;y--);
}

/*******************************************
* 函数名称: feed_buf()
* 函数功能: 根据颜色标志位disp_p,读取当前检测
            到的色值,并保存到disp_buf[]
* 入口参数: 无
* 出口参数: 无
/********************************************/
void feed_buf()
{
    //依次读取红、绿、蓝色值

     if(disp_p==0)
        {red=buf_cor/rp;color=red;}    //读取红色值         

     else if(disp_p==1)
        {green=buf_cor/gp;color=green;}
     else if(disp_p==2)
        {blue=buf_cor/bp;color=blue;}
            
     disp_buf[0]=color/100;
     disp_buf[1]=(color-100*disp_buf[0])/10;
     disp_buf[2]=color%10;
}

/*******************************************
* 函数名称: display()
* 函数功能: 数码管显示
* 入口参数: 无
* 出口参数: 无
/********************************************/
void display()
{
   uchar i;
   for(i=0;i<3;i++)
   {
        if(disp_p==0&&i==0)
            {P0=table[10];P2=scan[0];delay_1ms(2);P2=0xff;}
        else if(disp_p==1&&i==0)
            {P0=table[11];P2=scan[0];delay_1ms(2);P2=0xff;}
        else if(disp_p==2&&i==0)
            {P0=table[12];P2=scan[0];delay_1ms(2);P2=0xff;}
        else if(i<=3)
            {P0=table[disp_buf[i-1]];P2=scan[i];delay_1ms(2);P2=0xff;}
   }
}

/*******************************************
* 函数名称: main()
/********************************************/
void main()
{
     oe=0;        //使能TCS230

     s0=1; s1=1;    //选择输出比例因子100%

     t0_init();        //定时计数初使化

     while(1)
     {
        display();
     }
}

/*******************************************
* 函数名称: c10ms_out()
* 函数功能: 定时中断0服务程序
            修改颜色标志disp_tc(0:红 1:绿 2:蓝)
            设置S0 S1 S2 选择滤波器
            计算脉冲,读取色值
* 入口参数: 无
* 出口参数: 无
/********************************************/
void c10ms_out() interrupt 1
{
   TR0=0;    //关闭定时

   TR1=0;    //关闭计数


   disp_tc+=1;//实现先检测绿色,再检测蓝色,然后检测红色,循环检测

   
   if(disp_tc==100)
   {
        disp_tc=0;
        if(disp_p==0)
        {
            disp_p+=1;   
            s2=1;s3=1;    //选择滤波器为绿色            

        }
        else if(disp_p==1)
        {            
            disp_p+=1;
            s2=1;s3=0;    //选择滤波器为蓝色

        }
        else if(disp_p==2)
        {            
            disp_p=0;
            s2=0;s3=0;    //选择滤波器为红色

        }
    }
   
    if(disp_tc%10==0)
    {
        buf_cor=TH1*256+TL1;    //计算这段时间内 TCS230 的输出脉冲数

        feed_buf();
    }
   
    //重赋初值

     TH0=0xB0;
     TL0=0x3C;
     TL1=0x00;
     TH1=0x00;
     TR0=1;
     TR1=1;
}
回复

使用道具 举报

ID:213280 发表于 2018-10-6 10:33 | 显示全部楼层
psuxaog 发表于 2018-10-5 22:01
1. 你的程序很乱呀,要养成良好的风格
2. 主程序中有循环调用 DisplayZF,定时器3中断中也调用了 DisplayZ ...

好的,因为网上下载的,没整理到
回复

使用道具 举报

ID:213280 发表于 2018-10-6 14:45 | 显示全部楼层
zhanghyg 发表于 2018-10-6 09:49
上面的程序有问题,用不到外中断,以下程序仅供参考。
/*******************************************
*  ...

好的,谢谢哈
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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