预期实现功能:单片机通过两外部中断计数外部脉冲。两计数脉冲可在数码管上显示。脉冲数可由按键或指令flag发送至PC。出现问题为:不管单片机一何种方法向PC发送数据,只要有外部干扰,能自动向PC发送数据。数码管上显示的数值并不是按我想的15s变化一次。为什么?#include <reg52.h> #include <string.h>#define uchar unsigned char#define uint unsigned int
sbit M_RE= P2^5; //接收器低电平有效sbit M_DE= P2^6; //驱动器高电平有效sbit KEY1 = P3^2; //按键S19
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};sbit HC138A0 = P2^0; sbit HC138A1 = P2^1; sbit HC138A2 = P2^2; uchar led[8];
sbit D1=P1^0; sbit flag=P1^1; //单片机是否收到主机发过来的指令int Num1=0,Num2=0;m=0,D_all=0,X_all=0;/****************************/
//初始化设置 void coun() { EA=1; //开总中断EX0=1; //开外部中断0EX1=1; //开外部中断1IT0=1; //外部中断0的中断触发控制位:此为下降沿触发方式。IT1=1; //外部中断1的中断触发控制位:此为下降沿触发方式。 ET0=1; //开定时/计数器T0中断 TR0=1; //T0运行控制位,置1,开始工作。 TMOD=0x01; //T0定时,工作方式选择方式1。 TH0=(65536-50000)/256; //一个机器周期时间为1/11.0592*12=1.085us 50000机器周期时间为50000*1.085us=54.25msTL0=(65536-50000)%256; }
//初始化串口void init_serialcomm( void ){ SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr 串口模式1,允许接收(选择串口的工作方式和某些控制功能)TMOD = 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload 定时1,方式2,PCON = 0x80 ; //SMOD=1 波特率提高一倍 TH1 = 0xFa ; //Baud:9600 fosc=11.0592MHz // IE = 0x90 ; //Enable Serial Interrupt 允许串口中断TR1 = 1 ; // timer 1 run // TI=1; ES=1;EA=1; }
//延时函数void delay(int z) { unsigned char x,y; for(x=0;x<50;x++) for(y=z;y>0;y--) ;}
//1ms延时void Delay_1ms(uint i){uchar x,j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}
//向串口发送一个字符 void send_char_com( unsigned char ch){ SBUF=ch;while (TI== 0 ); TI= 0 ; }
//向串口发送一个数组,length为该数组长度 void send_array_com( unsigned char *str, unsigned int length){ uint k= 0 ;do{ send_char_com(*(str + k)); k++;} while (k<length);}
//显示函数 138译码器显示void display() { char i;// X_all=1234; // D_all=5678;led[0]=table[X_all/1000]; led[1]=table[X_all%1000/100]; led[2]=table[X_all%100/10]; led[3]=table[X_all%10];led[4]=table[D_all/1000]; led[5]=table[D_all%1000/100]; led[6]=table[D_all%100/10]; led[7]=table[D_all%10];
for( i=0; i<8; i++) //实现8位动态扫描循环 { P0 = led; //将字模送到P0口显示 switch(i) { case 0:HC138A0=0; HC138A1=0; HC138A2=0; break; case 1:HC138A0=1; HC138A1=0; HC138A2=0; break; case 2:HC138A0=0; HC138A1=1; HC138A2=0; break; case 3:HC138A0=1; HC138A1=1; HC138A2=0; break; case 4:HC138A0=0; HC138A1=0; HC138A2=1; break; case 5:HC138A0=1; HC138A1=0; HC138A2=1; break; case 6:HC138A0=0; HC138A1=1; HC138A2=1; break; case 7:HC138A0=1; HC138A1=1; HC138A2=1; break; } delay(10);}
}//条件发送(按键闭合或收到主机指令,单片机像主机发送指令)void send(){PS=1;if(KEY1 ==0) {Delay_1ms(30); //30ms软件防抖 while(!KEY1);
M_RE=1;M_DE=1; // 串口处于发送状态
send_array_com(led,8);M_RE=0;M_DE=0; //设置串口再次处于接收状态}
/* if(flag=1) //单片机接受到主机上的指令,想主机发送数据。{flag=0;M_RE=1;M_DE=1; // 串口处于发送状态
send_array_com(led,8);M_RE=0;M_DE=0; //设置串口再次处于接收状态} */ PS=0;
}
/*************主函数***************/
void main(){P0=table[0];display();D1=0; //对灯D1赋值,开始时为亮,当有外部中断,则灯灭。
delay(50); coun(); //初始化init_serialcomm(); //初始化串口 while(1) { if(m==300) // 1200采样时间1分钟,达到时间后停止采样 (300为15s) {EX0=0;EX1=0;m=0;
D_all=Num1;X_all=Num2; X_all-=D_all;Num1=0;Num2=0;EX0=1;EX1=1;
}send();display();
} }
/*************中断函数***************/void int0() interrupt 0 using 1{ EX0=0; Num1++; EX0=1; D1=1;}
void int1() interrupt 1 using 2{
TH0=(65536-50000)/256;TL0=(65536-50000)%256;m++;
}
void timer0() interrupt 2 using 3{ EX1=0; Num2++; EX1=1;}/*
//串口接收中断函数void serial () interrupt 4 using 0{ if (RI){ uchar temp; RI = 0 ;
temp=SBUF; flag=1;if(temp='a')flag=1;
} } */
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
init_serialcomm(); //初始化串口
一周热门 更多>