佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

楼主: gabrielloy

问问关于atmelAT89c51的program问题!

[复制链接]
 楼主| 发表于 14-3-2009 07:30 PM | 显示全部楼层
我現在用的manual reset沒什麽效果,所以我現在接power-on reset了。應該沒什麽分別的吧。
那麽我還想問問,就89c51,如果我有一個gas sensor,可是sensor的output是analog的,然後我的89c51的input是要digital的,那麽我是不是應該接一個ADC converter,先把sensor的output convert成digital的,然後才input 進去89c51。我買了一個ADC0804 chip。我應該怎麽接呢?
還有就是當我用了第133樓的program后,我在89c51的port0.0,0.1,和0.2分別接了1個buzzer和兩個led,可是當我on power后,lcd會display string但是led和buzzer去不會亮和不會響?爲什麽呢??
回复

使用道具 举报


ADVERTISEMENT

发表于 14-3-2009 08:00 PM | 显示全部楼层
看情况而定咯。。
output 是analogue, 如果output 高过某个threshold voltage 然后就trigger, 那么不需要adc. 用 comparator 就可以了。
port 0 你要sink current 进去。 或自己pull up. 8051 的port 0 好像是open drain.
如果你不要加pull up resistor 然后你用port 1, 2, 3 也应该ok 的。
回复

使用道具 举报

 楼主| 发表于 16-3-2009 12:58 AM | 显示全部楼层
对于ALAN1314大大的回复,我还是不是很清楚。“如果output 高过某个threshold voltage 然后就trigger“,是什么意思?如果我的OUTPUT是5V,然后代表什么?大大说的threshold volt是哪里的threshold volt?
回复

使用道具 举报

发表于 17-3-2009 08:13 AM | 显示全部楼层
原帖由 gabrielloy 于 13-3-2009 12:34 AM 发表
想再问问fritlizt大大,关于那个reset circuit,manual reset和power on reset有什么不同?如果我接的是manual reset,我的switch是normal open的,就是以下的接法,
http://i697.photobucket.com/albums/vv334/zico ...


你需要normally open的switch。
你的switch 1 和 2 是shorted. 3 和4也是。你要小心。 reset switch的两端要接1-3, 1-4, 2-3, 或者2-4.接1-2,还是3-4就错了。
回复

使用道具 举报

发表于 17-3-2009 08:27 AM | 显示全部楼层
原帖由 gabrielloy 于 14-3-2009 07:30 PM 发表
我現在用的manual reset沒什麽效果,所以我現在接power-on reset了。應該沒什麽分別的吧。
那麽我還想問問,就89c51,如果我有一個gas sensor,可是sensor的output是analog的,然後我的89c51的input是要digital的, ...


-〉我現在用的manual reset沒什麽效果,所以我現在接power-on reset了。應該沒什麽分別的吧。
也是没问题的。只是你不能manual reset而已。

-〉那麽我還想問問,就89c51,如果我有一個gassensor,可是sensor的output是analog的,然後我的89c51的input是要digital的,那麽我是不是應該接一個ADCconverter,先把sensor的output convert成digital的,然後才input進去89c51。我買了一個ADC0804 chip。我應該怎麽接呢?
如果只是要detect高过还是低过危险水平。用comparater就可以了。也就是chan大大奖的方法。

-〉還有就是當我用了第133樓的program后,我在89c51的port0.0,0.1,和0.2分別接了1個buzzer和兩個led,可是當我on power后,lcd會display string但是led和buzzer去不會亮和不會響?爲什麽呢??
port0是open collector output.也就是所。 1=open circuit. 0 = sinking.
你可以用active low来解决这个问题。 可以不用pull up resistor gang.
不过为了以后方便。先加上pull up resistor gang.10k.然后用active low.
回复

使用道具 举报

发表于 17-3-2009 08:34 AM | 显示全部楼层
原帖由 gabrielloy 于 16-3-2009 12:58 AM 发表
对于ALAN1314大大的回复,我还是不是很清楚。“如果output 高过某个threshold voltage 然后就trigger“,是什么意思?如果我的OUTPUT是5V,然后代表什么?大大说的threshold volt是哪里的threshold volt?


你的gas sensor是analog output.应该是voltage output把。
如果你只是要‘危险’还是‘安全’
就是1还是0而已 。可以用comprator
参考
http://en.wikipedia.org/wiki/Comparator
这个website不错。你先不考虑hysterysis.看简单的comparator怎样接。看comparator operation这个部分。
http://home.cogeco.ca/~rpaisley4/Comparators.html
回复

使用道具 举报

Follow Us
 楼主| 发表于 18-3-2009 12:41 AM | 显示全部楼层
fritlizt大大,我的program改成以下这样,为什么port0.0,port0.1,port0.2还是不会亮的?我把P0set成0xC0 else P0= 0xA0了。对于comparator的问题,我的sensor 的output voltage 是anolog的,直接用comparator然后在接到at89c51的port1.0上吗?
int main (void)
{
        system_init ();
        while (1){
        if (a == 1){
           P0 = 0xC0;
           lcd_print ("CO inside car in\n@danger level");
                   }
        else{
           P0 = 0xA0;
           lcd_print ("CO inside car in\n@safety level");
                   }
        delay_ms(10);
                }

                while (1);
        return 0;
}

void system_init (void)
{
        P0 = 0xFF;          //port initialization
        P1 = 0xFF;
        P2 = 0xFF;
        P3 = 0xFF;
        TMOD = 0x21;        // set timer 1 to 8bit auto reload mode.
        lcd_init();
}
回复

使用道具 举报

 楼主| 发表于 18-3-2009 07:23 PM | 显示全部楼层
各位大大,我现在很郁闷,之前的LCD display的part是已经完成了,但是现在当我加进我的sensor的时候,很多问题就出现了。例如,在我的program里,port0是open collector output。 1=open circuit. 0 = sinking,那我的program该怎么写呢?不要用port0?我要的只是当我的p1.0 input是5V的时候,也就是program里面的a == 1的时候,要有三个pins给我control,所以我用了port0.0,0.1,0.2来control我的buzzer和led,所以我该了program,可是我真的不知道为什么跑不了?
还有就是,我的sensor有点麻烦,以下是我的sensor的datasheet circuit.不好意思,有点小。可以save下来再放大来看。sensor的pin1,2,3,4的接法,我接了两个transistors了,可是关于那个pulse,我就有点混乱了,我又想过用555timer来generate pulse,又或者用at89c51来做pulse。可是我不是很明白,它的pulse到底是要怎样的?可是我又不会发pdf的文件,请问pdf的文件该怎样发上来?
还有就是就以下的电路图,我的sensor output是analog voltage output,该怎样接到我的at89c51的p1.0的pin呢?用comparator就可以了吗?
回复

使用道具 举报


ADVERTISEMENT

发表于 19-3-2009 11:19 PM | 显示全部楼层
原帖由 gabrielloy 于 18-3-2009 07:23 PM 发表
各位大大,我现在很郁闷,之前的LCD display的part是已经完成了,但是现在当我加进我的sensor的时候,很多问题就出现了。例如,在我的program里,port0是open collector output。 1=open circuit. 0 = sinking,那我的 ...


gas sensor接comparator 可以做到你要的东西。
port0.0, 0.1, 0.2不能拿来drive东西。加了10k resistor gang也不能。 5v/10k 的电流很小罢了。
你的方法
mcu io------( + led - )-----resistor-----ground
mcu io = 0, led当然不能亮。这个不用解释。
mcu io = 1, 由于mcu io 是open collector output, 根本不能supply current , led能亮,这个才神奇。所以led还是不能亮的。
加上resistor gang过后。 current还是太小了。 led还是不能亮。 buzzer依然没有响。

如果你要drive 东西就用sinking把。
mcu io-------( - led + )-----resistor-----5v
mcu io = 0, led 亮
mcu io = 1, led 暗。

有什么不同看到了吗?通常我driving用第二个方法。port 0,1,2,3都是。

把你的gas sensor part number post上来就可以了。
回复

使用道具 举报

 楼主| 发表于 22-3-2009 04:13 PM | 显示全部楼层
原帖由 fritlizt 于 19-3-2009 11:19 PM 发表


gas sensor接comparator 可以做到你要的东西。
port0.0, 0.1, 0.2不能拿来drive东西。加了10k resistor gang也不能。 5v/10k 的电流很小罢了。
你的方法
mcu io------( + led - )-----resistor-----ground
m ...

那如果我要用port1.0来控制我的port0.0,0.1,0.2的话,就要sinking current进去,好像大大所说的,mcu port0.0接buzzer再接一个resistor然后接到5V。然后在下面的program里面,我的b代表buzzer,然后c和d是两个led,那么当我的a = =1的时候也就是port1.0=1(5V)的时候,我的buzzer就会响,led就会一个亮一个不亮 ,对不对?
#include<at89x51.h>

#define CLR_DISP 0x01
#define DISP_ON 0x0C
#define DISP_OFF 0x08
#define CUR_HOME 0x02
#define CUR_OFF 0x0C
#define CUR_ON_UNDER 0x0E
#define CUR_ON_BLINK 0x0F
#define CUR_LEFT 0x10
#define CUR_RIGHT 0x14
#define CUR_UP 0x80
#define CUR_DOWN 0xC0
#define ENTER 0xC0
#define DD_RAM_ADDR 0x80
#define DD_RAM_ADDR2 0xC0

sbit D7 = P2^6;
sbit D6 = P2^5;
sbit D5 = P2^4;
sbit D4 = P2^3;
sbit EN = P2^2;
sbit RW = P2^1;
sbit RS = P2^0;
sbit a = P1^0;
sbit b = P0^0;
sbit c = P0^1;
sbit d = P0^2;

void system_init (void);
void delay_ms (unsigned int milisec);
void lcd_init (void);
void lcd_write_cmd (unsigned char cmd);
void lcd_write_data (unsigned char character);
void lcd_print (char *string);
void lcd_busy (void);

int main (void)
{
system_init ();
while (1){
if (a == 1){
b = 0;
c = 1;
d = 0;
lcd_print ("CO inside car in\n@danger level");
}
else{
b = 1;
c = 0;
d = 1;
lcd_print ("CO inside car in\n@safety level");
}
delay_ms(10);
}

while (1);
return 0;
}

void system_init (void)
{
P0 = 0xFF; //port initialization
P1 = 0xFF;
P2 = 0xFF;
P3 = 0xFF;
TMOD = 0x21; // set timer 1 to 8bit auto reload mode.
lcd_init();
}
还有我用的co sensor是figaro tgs 2442, http://www.figarosensor.com/products/2442pdf.pdf.大大可以帮帮我看看吗?如果我用555timer 来供给那两个transistors波,可以吗?我用了以下的连接,

我也算过了,从公式上如果我要得到1Hz(1秒)的波,我用了c=4.7uF,R1=300k,R2=3.9k.可是我接了上面的电路,但是得不到我要的datasheet里面的Vh的波。会可能是太快吗?我的电路里面的led一直亮着,而不是亮暗亮暗的。
而第二个波,我接了又接了以下的电路,

这次我用c=4.7uF,R2=300K,R1=1.5K,再加一个1N4148的二极管。
可是以上的接法我得不到我要的效果,也就是datasheet里面的Vc的波。
回复

使用道具 举报

 楼主| 发表于 22-3-2009 04:19 PM | 显示全部楼层
如果我想在mcu里面写一个program来给两个transistors波,可以吗?我写成interrupt吗?
回复

使用道具 举报

发表于 22-3-2009 05:27 PM | 显示全部楼层
那如果我要用port1.0来控制我的port0.0,0.1,0.2的话,就要sinking current进去,好像大大所说的,mcu port0.0接buzzer再接一个resistor然后接到5V。然后在下面的program里面,我的b代表buzzer,然后c和d是两个 led,那么当我的a = =1的时候也就是port1.0=1(5V)的时候,我的buzzer就会响,led就会一个亮一个不亮 ,对不对?


对。没错。
你的naming做好来。 比较容易。
abcd谁懂谁打谁。
回复

使用道具 举报

 楼主| 发表于 23-3-2009 02:19 AM | 显示全部楼层
那么关于555 timer的问题,还有就是interrupt program的问题?谁可以帮帮我?尤其是interrupt program,我想在我的display c program里加入一个interrupt,可是我不是很清楚怎么写,可不可以给点提示?
回复

使用道具 举报

发表于 23-3-2009 02:41 PM | 显示全部楼层
原帖由 gabrielloy 于 23-3-2009 02:19 AM 发表
还有就是interrupt program的问题?谁可以帮帮我?尤其是interrupt program,我想在我的display c program里加入一个interrupt,可是我不是很清楚怎么写,可不可以给点提示?


这里给个外部中断0 处理。

void External_INT0 (void) interrupt 0
{

        /*  这里写你的中断代码 */

}
回复

使用道具 举报

 楼主| 发表于 23-3-2009 08:46 PM | 显示全部楼层
rothmans大大,如果我要写一个c program 用来连续一直产生pulse波的话,个人觉得用interrupt好像不是很恰当,个人认为interrupt是当我的program跑到一半的时候,突然加入的一个program,然后必须跑完interrupt才会回到我原来跑到一半的program.,在继续。可是我现在产生要的是一个如 http://www.figarosensor.com/products/2442pdf.pdf里面的pulse波,还是可以用interrupt吗?
现在我想用多一个atmel at89c51来写一个program来产生datasheet里面的两个pulse波给我的sensor 电路里面的两个三极管(datasheet第二面的那个电路) 。会不会比较好呢?
如果是的话,那我就先写写看,然后再发上来给各位大大看看
回复

使用道具 举报

 楼主| 发表于 24-3-2009 01:05 AM | 显示全部楼层
还有就是我的buzzer可以响了,但是当我的buzzer响的时候,我的lcd display的字就会变蒙蒙的,没响的时候反而正常,是不是我的power不够呢?
回复

使用道具 举报


ADVERTISEMENT

发表于 24-3-2009 08:28 AM | 显示全部楼层
interrupt 的code 有几短就几短。 之后再main 在做你的东西。 你可以set 一个flag 之类, 或者做固定时间interrupt 等。
回复

使用道具 举报

发表于 24-3-2009 09:08 AM | 显示全部楼层
原帖由 gabrielloy 于 23-3-2009 08:46 PM 发表
rothmans大大,如果我要写一个c program 用来连续一直产生pulse波的话,个人觉得用interrupt好像不是很恰当,个人认为interrupt是当我的program跑到一半的时候,突然加入的一个program,然后必须跑完interrupt才会回 ...


不必担心,使用中断将不会有明显的影响。你只要遵循或符合中断的规则要求即可,就如 chan1314 提的一样。你多加一颗 MCU 简直就是浪费资源,而且你也太小看这颗单片机的能力了。(题外话 :呵!呵!有时候我在想,是单片机的能力差还是程序设计员的功力不够)。单片机的执行速度是以微妙计算的,非常快,根本感觉不到。除非你的程序有很多个回路循环来当延迟。

还有就是我的buzzer可以响了,但是当我的buzzer响的时候,我的lcd display的字就会变蒙蒙的,没响的时候反而正常,是不是我的power不够呢? ...


依赖心不要这样强,这纯粹是很简单的问题,当蜂鸣器响时,你可以用电表测量电压的。。。

[ 本帖最后由 rothmans 于 24-3-2009 10:02 AM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 24-3-2009 11:33 PM | 显示全部楼层
如果我写了以下的program来产生脉冲,不知道对不对?
#include<at89x51.h>
sbit a = P1^0;
sbit b = P1^1;

void delay_ms (unsigned int milisec);

int main (void)
{
        while (1){
                b = 1;
                a = 1;
                delay_ms(5);
                b = 0;
                delay_ms(9);
                a = 0;
                   delay_ms(986);
                }
               
                return 0;
}

void delay_ms (unsigned int milisec)
{  
        unsigned int i;

        for (i = 1; i <= milisec; i++){
                TH0 = 0xFC;
                TL0 = 0x18;
                TR0 = 1;
               
                while (!TF0);
                TF0 = 0;
                TR0 = 0;
        }
}
回复

使用道具 举报

 楼主| 发表于 26-3-2009 10:53 AM | 显示全部楼层
那么我又写了以下的program,加了interrupt,不知写得对不对?哪位大大可以帮帮忙改正或给点意见吗?
#include<at89x51.h>

#define     CLR_DISP        0x01      
#define     DISP_ON         0x0C      
#define     DISP_OFF        0x08      
#define     CUR_HOME        0x02
#define     CUR_OFF         0x0C
#define     CUR_ON_UNDER    0x0E
#define     CUR_ON_BLINK    0x0F
#define     CUR_LEFT        0x10
#define     CUR_RIGHT       0x14
#define     CUR_UP          0x80      
#define     CUR_DOWN        0xC0
#define     ENTER           0xC0
#define     DD_RAM_ADDR     0x80      
#define     DD_RAM_ADDR2    0xC0

sbit D7 = P2^6;
sbit D6 = P2^5;
sbit D5 = P2^4;
sbit D4 = P2^3;
sbit EN = P2^2;
sbit RW = P2^1;
sbit RS = P2^0;
sbit input = P1^0;
sbit b = P0^0;
sbit air_con = P0^1;
sbit wdw= P0^2;
sbit pulse1 = p1^1;
sbit pulse2 = p1^2;

void system_init (void);
void delay_ms (unsigned int milisec);
void lcd_init (void);
void lcd_write_cmd (unsigned char cmd);
void lcd_write_data (unsigned char character);
void lcd_print (char *string);
void lcd_busy (void);
void External_INT0 (void) interrupt 0

int main (void)
{
        system_init ();
        void External_INT0 (void) interrupt 0()
        while (1){
                if (input == 1){
                        b = 0;
                        air_con = 1;   
                        wdw = 0;
                        lcd_print ("CO inside car in\n unhealthy level");
                        delay_ms(10000);
                        b = 1;
                        delay_ms(3000);          
                }
                else{
                        b = 1;
                        air_con = 0;
                        wdw = 1;
                        lcd_print ("CO inside car in\n safety level");
                }
        delay_ms(10);
        }

                while (1);
        return 0;
}

void system_init (void)
{
        P0 = 0xFF;          //port initialization
        P1 = 0xFF;
        P2 = 0xFF;
        P3 = 0xFF;
        TMOD = 0x21;        // set timer 1 to 8bit auto reload mode.
        lcd_init();
}

void delay_ms (unsigned int milisec)
{  
        unsigned int i;

        for (i = 1; i <= milisec; i++){
                TH0 = 0xFC;
                TL0 = 0x18;
                TR0 = 1;
               
                while (!TF0);
                TF0 = 0;
                TR0 = 0;
        }
}

void lcd_init (void)
{
        unsigned char i;
        delay_ms (15);
        RS = 0;
        RW = 0;
      
        for (i = 0; i < 3; i++){
                EN = 1;
                D7 = 0;
                D6 = 0;
                D5 = 1;
                D4 = 1;
                EN = 0;
                delay_ms (5);
        }
      
        EN = 1;
        D7 = 0;
        D6 = 0;
        D5 = 1;
        D4 = 0;
        EN = 0;
        delay_ms (5);
      
        lcd_write_cmd (0x28);                                   //4 bit mode
        lcd_write_cmd (CUR_ON_BLINK);                //display on, curser on, curcor blink on
        lcd_write_cmd (CLR_DISP);                         //Clear Display
        lcd_write_cmd (0x06);                                //increment cursor position
}

void lcd_write_cmd (unsigned char cmd)
{
        lcd_busy();
        RW = 0;
        RS = 0;         
        EN = 1;
      
        D7 = cmd & 0x80;
        D6 = cmd & 0x40;
        D5 = cmd & 0x20;
        D4 = cmd & 0x10;
        EN = 0;
      
        EN = 1;         
        D7 = cmd & 0x08;
        D6 = cmd & 0x04;
        D5 = cmd & 0x02;
        D4 = cmd & 0x01;
        EN = 0;
}

void lcd_write_data (unsigned char character)
{
        lcd_busy();
        RW = 0;
        RS = 1;
        EN = 1;
      
        D7 = character & 0x80;
        D6 = character & 0x40;
        D5 = character & 0x20;
        D4 = character & 0x10;
        EN = 0;
      
        EN = 1;                 
        D7 = character & 0x08;
        D6 = character & 0x04;
        D5 = character & 0x02;
        D4 = character & 0x01;
        EN = 0;
}

void lcd_print (char *string)
{
        unsigned char temp, i = 1;
        lcd_write_cmd (CLR_DISP);
        for (temp = 0; string[temp]!= 0; temp++){
                if (string[temp] == '\n'){
                        i++;
                        if(i > 2)
                                i = 1;
                        switch (i){
                                case 1:
                                        lcd_write_cmd (CUR_UP);
                                        break;
                                case 2:
                                        lcd_write_cmd (CUR_DOWN);
                                        break;      
                                default:
                                        break;
                        }
                }
                else
                        lcd_write_data (string[temp]);
        }
}

void lcd_busy (void)
{
        bit busy = 1;
        RS = 0;
        RW = 1;
        D7 = 1;
        D6 = 1;
        D5 = 1;
        D4 = 1;
        while (busy){
                EN = 0;
                EN = 1;
                EN = 1;
                busy = D7;
                EN = 0;
                EN = 1;
        }
        EN = 0;
}

void External_INT0 (void) interrupt 0
{
       
        pulse2 = 1;
        pulse1 = 1;
        delay_ms(5);
        pulse2 = 0;
        delay_ms(9);
        pulse1 = 0;
        delay_ms(986);
               
               
        return 0;
}
回复

使用道具 举报

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

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 23-1-2025 10:13 AM , Processed in 0.128663 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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