找回密码
 立即注册

QQ登录

只需一步,快速开始

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

急求答案啊!!!!拜托了!!!

[复制链接]
跳转到指定楼层
楼主
ID:67905 发表于 2014-10-26 19:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5黑币
小车上方有宽窄不同的障碍物,要求小车数出宽的障碍物个数并显示。怎样让每次发生低电平时计数器计数,而恢复高点平时不计数呢?我的程序可以让它在第一次低电平时开始计数,但是当电平恢复高电平时还在计数停不下来。
#include<stc12c5a60s2.h>
#define uint unsigned int
#define uchar unsigned char
sbit  chuanganqi=P3^3;
sbit RS=P2^5;
sbit RW=P2^6;
sbit EP=P2^7;
unsigned int geshu,kuan,num;
void delay(int z)
{
   int i,j;
   for(i=z;i>0;i--)
     for(j=1000;j>0;j--);
}
void zhongduan1() interrupt 2   //外部中断1
{
TR1=0;
Timer1_int();
   TR1=1;
}
void zhongduan2() interrupt 3        //定时器中断1
{
     num++;
   TL1 = 0x9C;  //设置定时初值
TH1 = 0xFF;  //设置定时初值 //定时100us=0.1ms
}
void Timer1_int()  //定时器1初始化
{
/* TMOD|=0x10;
TH1=(65536-65436)/256;
TL1=(65536-65436)%256;   //定时100us=0.1ms
EA=1;
TR1=1;
ET1=1; */
AUXR &= 0xBF;  //定时器时钟12T模式
TMOD &= 0x0F;  //设置定时器模式
TMOD |= 0x10;  //设置定时器模式
TL1 = 0x9C;  //设置定时初值
TH1 = 0xFF;  //设置定时初值
TF1 = 0;  //清除TF1标志  
// TR1 = 1;  //定时器1开始计时
ET1=1;
}
void write_com(char com) //输入命令函数
{
RS=0;
RW=0;
EP=0;
P0=com;
delay(5);
EP=1;
delay(5);
EP=0;
}
void write_date(char date)//输入数据函数
{
RS=1;
RW=0;
EP=0;
P0=date;
delay(5);
EP=1;
delay(5);
EP=0;
}
void write_init()//初始化函数
{
   write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
void display()
{
write_com(0x80+0x00);
write_date(geshu/1000+0x30);
write_com(0x80+0x01);
write_date(geshu%1000/100+0x30);
write_com(0x80+0x02);
write_date(geshu%1000%100/10+0x30);
write_com(0x80+0x03);
write_date(geshu%10+0x30);
}
void main()
{
IT1=1;  //低电平触发中断
EX1=1;
write_init();
while(1)
{ EA=1;
Timer1_int();  
   if (num>=1000)
   {  
     kuan++;   // kuan/2是托盘个数
  num=0;
      TR1=0;
geshu=kuan/2;
}
     display();
// delay(5);
}
}

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

使用道具 举报

沙发
ID:66032 发表于 2014-10-27 17:54 | 只看该作者
一定要用这个stc12c5a60s2吗? 用PIC的话, 我可以帮你写一个,外部中断做不准, 最好是用CCP模块的捕获方法,因为进入中断程序会消耗时钟周期。
回复

使用道具 举报

板凳
ID:67992 发表于 2014-10-28 11:22 | 只看该作者
我初学一月,说不对别怪。楼主程序目的想检测低电平持续时间,用外中断不好处理。如用低电平触发,低电平不退出则程序死在外中断服务程序里,其它任务做不了,包括定时中断服务也不做。如用下降触发,则触发后定时器计时,到设定时间(1S吧?)才停止计时,成了触发式一秒定时器,当然也可以改两秒三秒。检测低电平持续时间,应该在电平持续时间内定时器计时,高电平关闭,再算时间,对吧?
回复

使用道具 举报

地板
ID:67992 发表于 2014-10-28 11:28 | 只看该作者
#include "stc.h"
#define uint unsigned int
#define uchar unsigned char
sbit  chuanganqi=P3^3;
sbit  RS=P2^5;
sbit  RW=P2^6;
sbit  EP=P2^7;
unsigned int geshu,kuan,num;
void Timer1_int();
void delay(int z)
{
   int i,j;
   for(i=z;i>0;i--)
     for(j=1000;j>0;j--);
}
void zhongduan2() interrupt 3        //定时器中断1
{
     num++;
     TL1 = 0x9C;  //设置定时初值
     TH1 = 0xFF;  //设置定时初值 //定时100us=0.1ms
}
void Timer1_int()  //定时器1初始化
{
        AUXR &= 0xBF;  //定时器时钟12T模式
        TMOD &= 0x0F;  //设置定时器模式
        TMOD |= 0x10;  //设置定时器模式
        TL1 = 0x9C;  //设置定时初值
        TH1 = 0xFF;  //设置定时初值
        ET1=1;
        EA=1;
}
void write_com(char com) //输入命令函数
{
                RS=0;
                RW=0;
                EP=0;
                P0=com;
                delay(5);
                EP=1;
                delay(5);
                EP=0;
}
void write_date(char date)//输入数据函数
{
        RS=1;
        RW=0;
        EP=0;
        P0=date;
        delay(5);
        EP=1;
        delay(5);
        EP=0;
}
void write_init()//初始化函数
{
    write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
}
void display()
{
                write_com(0x80+0x00);
                write_date(geshu/1000+0x30);
                write_com(0x80+0x01);
                write_date(geshu%1000/100+0x30);
                write_com(0x80+0x02);
                write_date(geshu%1000%100/10+0x30);
                write_com(0x80+0x03);
                write_date(geshu%10+0x30);
}
void main()
{         
    Timer1_int();
   write_init();
        while(1)
        {          while(chuanganqi==0)
                {
                         TR1=1;
                }
             TR1=0;
           if (num>=1000)
           {  
              kuan++;   // kuan是托盘个数
              num=0;
              TR1=0;
              geshu=kuan;
            }
              display();
        }
}
回复

使用道具 举报

5#
ID:66032 发表于 2014-10-28 11:53 | 只看该作者
老实说我从未用过这个stc12c5a60s2; 你说的对,用捕获的方法 要么检测低电平持续时间, 或者检测高电平持续时间, 然后运用算法计算这样的时间有多少个即可。
如果用外部中断+定时器应该也可以,但是比较粗略:
用一个外部中断做触发,一定要用电平触发, 不可以用上升沿和下降沿,因为物体开始时如果是上升沿, 那么结束时是下降沿, 反之依然。 一旦触发就打开定时器timer(定时器先要关)开始计时, 当下一个电平改变后停止计时器,当接下来的电平再次改变时,定时器又打开,反复 计算出这段时间, 用算法计算这样有多少个即可。
回复

使用道具 举报

6#
ID:67992 发表于 2014-10-28 15:53 | 只看该作者
不好意思,上面给的程序有问题,重新改过如下:
#include "stc.h"
//#include "uart.h"
#define uint unsigned int
#define uchar unsigned char
sbit  chuanganqi=P3^3;
sbit  RS=P2^6;
sbit  RW=P2^5;
sbit  EP=P2^7;
unsigned int geshu,kuan,num;
void Timer1_int();
void delay(int z)
{
   int i,j;
   for(i=z;i>0;i--)
     for(j=1000;j>0;j--);
}
void zhongduan2() interrupt 3        //定时器中断1
{
     num++;
//         printexp1("num",num);
     TL1 = 0x9C;  //设置定时初值
     TH1 = 0xFF;  //设置定时初值 //定时100us=0.1ms
}
void Timer1_int()  //定时器1初始化
{
        AUXR &= 0xBF;  //定时器时钟12T模式
        TMOD &= 0x0F;  //设置定时器模式
        TMOD |= 0x10;  //设置定时器模式
        TL1 = 0x9C;  //设置定时初值
        TH1 = 0xFF;  //设置定时初值
        ET1=1;
        EA=1;
}
void write_com(char com) //输入命令函数
{
                RS=0;
                RW=0;
                EP=0;
                P0=com;
                delay(5);
                EP=1;
                delay(5);
                EP=0;
}
void write_date(char date)//输入数据函数
{
        RS=1;
        RW=0;
        EP=0;
        P0=date;
        delay(5);
        EP=1;
        delay(5);
        EP=0;
}
void write_init()//初始化函数
{
    write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
}
void display()
{
                write_com(0x80+0x00);
                write_date(geshu/1000+0x30);
                write_com(0x80+0x01);
                write_date(geshu%1000/100+0x30);
                write_com(0x80+0x02);
                write_date(geshu%1000%100/10+0x30);
                write_com(0x80+0x03);
                write_date(geshu%10+0x30);
}
void main()
{         
        uart_ini();
    Timer1_int();
   write_init();
        while(1)
        {          while(chuanganqi==0)
                {
                         TR1=1;
                }
             TR1=0;
           if (num>=1000)
           {  
              kuan++;
//                 printexp1("kuan",kuan);   // kuan是托盘个数
              num=0;
              TR1=0;
              geshu=kuan;
            }
                else
                {
                  num=0;
              TR1=0;
                }

              display();
        }
}
回复

使用道具 举报

7#
ID:67905 发表于 2014-10-29 14:08 | 只看该作者
dgahz 发表于 2014-10-28 11:22
我初学一月,说不对别怪。楼主程序目的想检测低电平持续时间,用外中断不好处理。如用低电平触发,低电平不 ...

对,就是这意思
回复

使用道具 举报

8#
ID:67905 发表于 2014-10-29 14:12 | 只看该作者
dgahz 发表于 2014-10-28 15:53
不好意思,上面给的程序有问题,重新改过如下:
#include "stc.h"
//#include "uart.h"

可是烧到板上,LCD什么都不显示啊
回复

使用道具 举报

9#
ID:67905 发表于 2014-10-29 14:30 | 只看该作者
mqwu 发表于 2014-10-27 17:54
一定要用这个stc12c5a60s2吗? 用PIC的话, 我可以帮你写一个,外部中断做不准, 最好是用CCP模块的捕获方 ...

是啊,因为其他模块要用PCA,所以必须得用它,实际上我们用的是stc12c5a16s2
回复

使用道具 举报

10#
ID:67992 发表于 2014-10-29 16:10 | 只看该作者
#include "stc.h"
//#include "uart.h"
这些是我调试用的,和你的程序没关系,凡是打//的可删掉。
回复

使用道具 举报

11#
ID:67992 发表于 2014-10-29 16:13 | 只看该作者
有东西挡住传感器时间长点,会加1,短时间不会。
回复

使用道具 举报

12#
ID:67992 发表于 2014-10-29 16:16 | 只看该作者
前提你的传感器被挡住能输出低电平。
回复

使用道具 举报

13#
ID:67992 发表于 2014-10-29 16:37 | 只看该作者
把main里的 uart_ini();删掉,复制时我忘在前面打//了。
回复

使用道具 举报

14#
ID:67905 发表于 2014-10-30 20:55 | 只看该作者
我就是删掉了之后,发现还是不显示。找不到其他的问题了。
回复

使用道具 举报

15#
ID:67992 发表于 2014-10-30 21:31 | 只看该作者
编译通过没有?有没有和其它模块组合一起用?如果单用它是没问题的。我下载试过,正常显示,你改用你的头文件,不要用我的试试。
回复

使用道具 举报

16#
ID:67992 发表于 2014-10-30 21:49 | 只看该作者
#include<stc12c5a60s2.h>
#define uint unsigned int
#define uchar unsigned char
sbit  chuanganqi=P3^3;
sbit  RS=P2^6;
sbit  RW=P2^5;
sbit  EP=P2^7;
unsigned int geshu,kuan,num;
void Timer1_int();
void delay(int z)
{
   int i,j;
   for(i=z;i>0;i--)
     for(j=1000;j>0;j--);
}
void zhongduan2() interrupt 3        //定时器中断1
{
     num++;
     TL1 = 0x9C;  //设置定时初值
     TH1 = 0xFF;  //设置定时初值 //定时100us=0.1ms
}
void Timer1_int()  //定时器1初始化
{
        AUXR &= 0xBF;  //定时器时钟12T模式
        TMOD &= 0x0F;  //设置定时器模式
        TMOD |= 0x10;  //设置定时器模式
        TL1 = 0x9C;  //设置定时初值
        TH1 = 0xFF;  //设置定时初值
        ET1=1;
        EA=1;
}
void write_com(char com) //输入命令函数
{
                RS=0;
                RW=0;
                EP=0;
                P0=com;
                delay(5);
                EP=1;
                delay(5);
                EP=0;
}
void write_date(char date)//输入数据函数
{
        RS=1;
        RW=0;
        EP=0;
        P0=date;
        delay(5);
        EP=1;
        delay(5);
        EP=0;
}
void write_init()//初始化函数
{
    write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
}
void display()
{
                write_com(0x80+0x00);
                write_date(geshu/1000+0x30);
                write_com(0x80+0x01);
                write_date(geshu%1000/100+0x30);
                write_com(0x80+0x02);
                write_date(geshu%1000%100/10+0x30);
                write_com(0x80+0x03);
                write_date(geshu%10+0x30);
}
void main()
{         
        uart_ini();
    Timer1_int();
   write_init();
        while(1)
        {          while(chuanganqi==0)
                {
                         TR1=1;
                }
             TR1=0;
           if (num>=1000)
           {  
              kuan++;
              num=0;
              TR1=0;
              geshu=kuan;
            }
                else
                {
                  num=0;
              TR1=0;
                }
              display();
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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