2019-03-25 17:02发布
谢谢你!我正是用IO口来控制它的通断的,不然我都把MCU给烧掉了!我需要用PNP管来驱动继电器!我自己弄了一个制作,用它来控制高压但是用NPN管子出了点问题。把它改一下。大侠!能否抽出你宝贵的时间帮我看看下面的程序!为什么在我上电的时候,继电器会吸合一下,然后释放呢?该芯片复位时P3口复位值都为1,跟这个有关系吗? /*************************************************************实验效果:用定时器定时来控制继电器的工作,初始时定时为150分钟、继电器吸合、同时所定的时间在三位数码管上显示出来。开始时定时器工作,按下S1确认定时键,每过1分钟时间减1,当所定的150分钟减为0时继电器释放、定时器0不工作、数码管不显示单片机进入掉电模式。按下S1、S2、S3均可唤醒单片机。S1的作用是按下该键时确认开始定时键,S2的作用是按下该键时数码管显示或者不显示之间进行切换,S3的作用是设置需要定时的时间,每按该键定时时间减10分钟。同时每个按键按下时都会发出滴的一声。晶振采用12MHZ.****************************************************************/#include"STC15F204EA.h"#include<intrins.h>#define GPIO_DIG P1#define Fosc 12000000sbit DS1=P3^7;sbit DS2=P0^0;/*我所使用的单片机是A版本P0.0。B版本为P5.4*/sbit DS3=P0^1;/*我所使用的单片机是A版本,所以这里用P0.1。B版本为P5.5*/ sbit S3=P3^0;sbit S2=P3^2;sbit S1=P3^3;sbit BZ=P3^4;sbit RELAY=P3^5;bit flag;signed int Num=160;unsigned char bit100,bit10,bit1,Time; unsigned char code DIG[10]={0x7e,0x0c,0xb6,0x9e,0xcc,0xda,0xfa,0x0e,0xfe,0xde};void Delay3ms(); //@12.000MHzvoid Delay10ms(); //@12.000MHzmain(){ unsigned char a,temp; BZ=0; RELAY=0;/*关闭继电器*/ /*喂狗*/ WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/ P5M0=0x30; P3M0=0xB0; P1M0=0XFF; IT1=1;/*外部中断1为下降沿触发方式*/ IT0=1;/*外部中断0为下降沿触发方式*/ INT_CLKO=0x40;/*允许外部中断4中断*/ EX1=1;/*允许外部中断1中断*/ EX0=1;/*允许外部中断0中断*/ TMOD=0x00;/*设定定时器0、1工作模式为0*/ AUXR=0x00;/*设定定时器0、1工作在12T模式*/ TH0=(65536-Fosc/12/20)>>8;/*给定时器0赋初值,定时50ms*/ TL0=(65536-Fosc/12/20); TH1=(65536-4*Fosc/12000)>>8;/*给定时器0赋初值,定时3ms*/ TL1=(65536-4*Fosc/12000); ET0=1;/*开定时器0中断允许*/ ET1=1;/*开中断允许*/ PT1=1;/*设置定时器1为高优先级*/ TR0=0;/*关闭定时器0*/ TR1=1;/*开启定时器1*/ EA=1;/*打开总中断*/ while(1) { WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/ /*喂狗*/ a=Num; bit100=a/100;/*提取百位*/ a=a%100; bit10=a/10;/*提取十位*/ bit1=a%10;/*提取个位*/ if(Time==10)/*500毫秒到了吗?*/ { Time=0; temp++; if(temp==120)/*1秒到了吗?*/ { Num--; temp=0; } if((Num==1)&&(temp==119)) BZ=1; if(Num==0) { BZ=0; Num=180; RELAY=0;/*关闭继电器*/ TR0=0;/*关闭定时器0*/ TR1=0;/*关闭定时器1*/ GPIO_DIG=0;/*关闭数码管*/ PCON=0x02;/*掉电模式,单片机睡觉*/ } } if(TR1==0)/*关闭数码管显示*/ { //DS1=1;DS2=1;DS3=1; GPIO_DIG=0; } } }void Timr0() interrupt 1{ Time++; }void Int0() interrupt 0{ Delay10ms(); if(S2==0) { TR1=~TR1;/*数码管显示位取反*/ flag=1; } }void Int1() interrupt 2{ Delay10ms(); if(S1==0) { flag=1; TR0=1;/*定时器0启动确认定时*/ TR1=1;/*启动定时计数器1扫描显示数码管*/ Num--; }}void Int4() interrupt 16{ Delay10ms(); if(S3==0) { RELAY=1;/*打开继电器*/ TR0=0;/*关闭定时计数器0进行调时间*/ flag=1; if(TR1==1)/*数码管显示时才可以进行调节时间*/ { Num=Num-10; if(Num<=0) Num=180; } TR1=1;/*启动定时计数器1扫描显示数码管*/ } }void Timr1() interrupt 3{ unsigned char n,cnt; if(flag==1)/*有按键按下时蜂鸣器响一下(除按下S2键数码管不显示时不响外)*/ { BZ=1; cnt++; if(cnt==12) { cnt=0; BZ=0; flag=0; } } if(Num>=100) { switch(n) { case(0):DS1=1;/*关闭第3位数码管显示*/ GPIO_DIG=DIG[bit100];/*送出数字段码*/ DS3=0; /*打开第一个数码的位选*/ break; case(1):DS3=1;/*关闭第1位数码管显示*/ GPIO_DIG=DIG[bit10];/*送出数字段码*/ DS2=0;/*打开第二个数码的位选*/ break; case(2):DS2=1;/*关闭第2位数码管显示*/ GPIO_DIG=DIG[bit1];/*送出数字段码*/ DS1=0;/*打开第三个数码的位选*/ break; } } else if((Num>=10)&&(Num<100)) { switch(n) { case(0): DS1=1;/*关闭第3位数码管显示*/ break; case(1): DS3=1;/*关闭第1位数码管显示*/ GPIO_DIG=DIG[bit10];/*送出数字段码*/ DS2=0;/*打开第二个数码的位选*/ break; case(2): DS2=1;/*关闭第2位数码管显示*/ GPIO_DIG=DIG[bit1];/*送出数字段码*/ DS1=0;/*打开第三个数码的位选*/ break; } } else { switch(n) { case(0): DS1=1;/*关闭第3位数码管显示*/ DS3=1;/*关闭第1位数码管显示*/ break; case(1): DS2=1;/*关闭第2位数码管显示*/ break; case(2): GPIO_DIG=DIG[bit1];/*送出数字段码*/ DS1=0;/*打开第三个数码的位选*/ break; } } n++; if(n>2) n=0;} void Delay3ms() //@12.000MHz{ unsigned char i, j; _nop_(); _nop_(); i = 36; j = 1; do { while (--j); } while (--i);}void Delay10ms() //@12.000MHz{ unsigned char i, j; _nop_(); _nop_(); i = 117; j = 183; do { while (--j); } while (--i);}
不然我都把MCU给烧掉了!
我需要用PNP管来驱动继电器!
我自己弄了一个制作,用它来控制高压
但是用NPN管子出了点问题。把它改一下。大侠!能否抽出你宝贵的时间帮我看看下面的程序!为什么在我上电的时候,继电器会吸合一下,然后释放呢?该芯片复位时P3口复位值都为1,跟这个有关系吗?
/*************************************************************
实验效果:用定时器定时来控制继电器的工作,初始时定时为150分钟、
继电器吸合、同时所定的时间在三位数码管上显示出来。开始时定时器
工作,按下S1确认定时键,每过1分钟时间减1,当所定的150分钟减为0时
继电器释放、定时器0不工作、数码管不显示单片机进入掉电模式。按下S1、
S2、S3均可唤醒单片机。S1的作用是按下该键时确认开始定时键,S2的作用
是按下该键时数码管显示或者不显示之间进行切换,S3的作用是设置需要定
时的时间,每按该键定时时间减10分钟。同时每个按键按下时都会发出滴的
一声。晶振采用12MHZ.
****************************************************************/
#include"STC15F204EA.h"
#include<intrins.h>
#define GPIO_DIG P1
#define Fosc 12000000
sbit DS1=P3^7;
sbit DS2=P0^0;/*我所使用的单片机是A版本P0.0。B版本为P5.4*/
sbit DS3=P0^1;/*我所使用的单片机是A版本,所以这里用P0.1。B版本为P5.5*/
sbit S3=P3^0;
sbit S2=P3^2;
sbit S1=P3^3;
sbit BZ=P3^4;
sbit RELAY=P3^5;
bit flag;
signed int Num=160;
unsigned char bit100,bit10,bit1,Time;
unsigned char code DIG[10]={0x7e,0x0c,0xb6,0x9e,0xcc,0xda,0xfa,0x0e,0xfe,0xde};
void Delay3ms(); //@12.000MHz
void Delay10ms(); //@12.000MHz
main()
{
unsigned char a,temp;
BZ=0;
RELAY=0;/*关闭继电器*/
/*喂狗*/
WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/
P5M0=0x30;
P3M0=0xB0;
P1M0=0XFF;
IT1=1;/*外部中断1为下降沿触发方式*/
IT0=1;/*外部中断0为下降沿触发方式*/
INT_CLKO=0x40;/*允许外部中断4中断*/
EX1=1;/*允许外部中断1中断*/
EX0=1;/*允许外部中断0中断*/
TMOD=0x00;/*设定定时器0、1工作模式为0*/
AUXR=0x00;/*设定定时器0、1工作在12T模式*/
TH0=(65536-Fosc/12/20)>>8;/*给定时器0赋初值,定时50ms*/
TL0=(65536-Fosc/12/20);
TH1=(65536-4*Fosc/12000)>>8;/*给定时器0赋初值,定时3ms*/
TL1=(65536-4*Fosc/12000);
ET0=1;/*开定时器0中断允许*/
ET1=1;/*开中断允许*/
PT1=1;/*设置定时器1为高优先级*/
TR0=0;/*关闭定时器0*/
TR1=1;/*开启定时器1*/
EA=1;/*打开总中断*/
while(1)
a=Num;
bit100=a/100;/*提取百位*/
a=a%100;
bit10=a/10;/*提取十位*/
bit1=a%10;/*提取个位*/
if(Time==10)/*500毫秒到了吗?*/
Time=0;
temp++;
if(temp==120)/*1秒到了吗?*/
Num--;
temp=0;
}
if((Num==1)&&(temp==119))
BZ=1;
if(Num==0)
Num=180;
TR1=0;/*关闭定时器1*/
GPIO_DIG=0;/*关闭数码管*/
PCON=0x02;/*掉电模式,单片机睡觉*/
if(TR1==0)/*关闭数码管显示*/
//DS1=1;DS2=1;DS3=1;
GPIO_DIG=0;
void Timr0() interrupt 1
Time++;
void Int0() interrupt 0
Delay10ms();
if(S2==0)
TR1=~TR1;/*数码管显示位取反*/
flag=1;
void Int1() interrupt 2
if(S1==0)
TR0=1;/*定时器0启动确认定时*/
TR1=1;/*启动定时计数器1扫描显示数码管*/
void Int4() interrupt 16
if(S3==0)
RELAY=1;/*打开继电器*/
TR0=0;/*关闭定时计数器0进行调时间*/
if(TR1==1)/*数码管显示时才可以进行调节时间*/
Num=Num-10;
if(Num<=0)
void Timr1() interrupt 3
unsigned char n,cnt;
if(flag==1)/*有按键按下时蜂鸣器响一下(除按下S2键数码管不显示时不响外)*/
cnt++;
if(cnt==12)
cnt=0;
flag=0;
if(Num>=100)
switch(n)
case(0):DS1=1;/*关闭第3位数码管显示*/
GPIO_DIG=DIG[bit100];/*送出数字段码*/
DS3=0; /*打开第一个数码的位选*/
break;
case(1):DS3=1;/*关闭第1位数码管显示*/
GPIO_DIG=DIG[bit10];/*送出数字段码*/
DS2=0;/*打开第二个数码的位选*/
case(2):DS2=1;/*关闭第2位数码管显示*/
GPIO_DIG=DIG[bit1];/*送出数字段码*/
DS1=0;/*打开第三个数码的位选*/
else if((Num>=10)&&(Num<100))
case(0): DS1=1;/*关闭第3位数码管显示*/
case(1): DS3=1;/*关闭第1位数码管显示*/
case(2): DS2=1;/*关闭第2位数码管显示*/
else
DS3=1;/*关闭第1位数码管显示*/
case(1): DS2=1;/*关闭第2位数码管显示*/
case(2): GPIO_DIG=DIG[bit1];/*送出数字段码*/
n++;
if(n>2)
n=0;
void Delay3ms() //@12.000MHz
unsigned char i, j;
_nop_();
i = 36;
j = 1;
do
while (--j);
} while (--i);
void Delay10ms() //@12.000MHz
i = 117;
j = 183;
大侠!能否给我说个明白呢?我是真的不太懂,希望大侠能够给我讲解详细点呢?万分感谢
我是真的不太懂,希望大侠能够给我讲解详细点呢?
chunyang 发表于 2015-2-8 22:34 建议楼主还是找出教材重新学习晶体管基本电路。
werjufour 发表于 2015-2-8 23:01
最多设置5个标签!
基本概念不清的话,只知道结果没什么好处。而基本原理不是几句话能说清的,最基本的东西务必去看书。
一周热门 更多>