标题: 以前没做过单片机写了个简单中断出问题了,求助啊! [打印本页]
作者: dabaojiu 时间: 2017-4-27 21:32
标题: 以前没做过单片机写了个简单中断出问题了,求助啊!
本帖最后由 dabaojiu 于 2017-5-4 10:09 编辑
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar Flag0;
uchar Flag1;
//--------------------------------------------------------------------------------------------------------------------------
void DelayMs(uint t)//定义延时函数
{
uchar j;
while(t--)
{
for(j=0;j<113;j++);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void TurnLeft (void) //定义LED灯做左循环
{
unsigned char i; //定义一个无符号字符型局部变量 i 取值范围 0~255
DelayMs(500);
P1=0xfe; //赋初始值
while (1) //主循环
{
for(i=0;i<8;i++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(500);
P1<<=1;
P1=P1|0x01; //左移后,最右端自动赋值0,所以需要该语句赋值1
}
P1=0xfe; //重新赋初始值
//主循环中添加其他需要一直工作的程序
}
}
//--------------------------------------------------------------------------------------------------------------------------
void TurnRight (void)
{
unsigned char k; //定义一个无符号字符型局部变量 k 取值范围 0~255
DelayMs(500);
P1=0x7f; //赋初始值
while (1) //主循环
{
for(k=0;k<8;k++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(500);
P1>>=1;
P1=P1|0x80; //右移后,最左端自动赋值0,所以需要该语句赋值1
}
P1=0x7f; //重新赋初始值
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FastTurnLeft (void) //定义LED灯做快速的左循环
{
unsigned char l; //定义一个无符号字符型局部变量 l 取值范围 0~255
DelayMs(500);
P1=0xfe; //赋初始值
while (1) //主循环
{
for(l=0;l<8;l++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(50); //做快速左循环时调整了延时函数
P1<<=1;
P1=P1|0x01; //左移后,最右端自动赋值0,所以需要该语句赋值1
}
P1=0xfe; //重新赋初始值
//主循环中添加其他需要一直工作的程序
}
}
//--------------------------------------------------------------------------------------------------------------------------
void main(void) //定义主函数
{
IE=0x85; //开放式中断
TCON=0x05; //边沿方式,自清中断标志
while(1)
{
TurnLeft(); //调用数码管左移
if(Flag0 == 1)
{
TurnRight();//调用数码管右移
}
if(Flag1 == 1)
{
FastTurnLeft();//调用数码管快速右移
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
//两个中断程序控制Flag1,Flag0两个状态标识。
void Ex0Isr()interrupt 0
{
if (Flag0 == 0)Flag0 = 1;
Flag1 = 0;
}
void Ex1Isr()interrupt 2
{
if (Flag1 == 0)Flag1 = 1;
Flag0 = 0;
}
作者: bbg3659 时间: 2017-4-27 21:32
刚没发出去?#include "reg51.h"
sbit K1=P3^1;
sbit K2=P3^0;
unsigned char led1[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char led2[9]={0x7f,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0xfe};
unsigned char i,j;
void delay(unsigned int x)
{
unsigned char a,b;
while(x--);
for(a=0;a<100;a++)
{
for(b=0;b<100;b++)
{}
}
}
void mint()
{
unsigned char a,b;
if(i==1&&j==0)
{
switch(a)
{
case 0:P2=led1[0];a++;delay(20000);break;
case 1:P2=led1[1];a++;delay(20000);break;
case 2:P2=led1[2];a++;delay(20000);break;
case 3:P2=led1[3];a++;delay(20000);break;
case 4:P2=led1[4];a++;delay(20000);break;
case 5:P2=led1[5];a++;delay(20000);break;
case 6:P2=led1[6];a++;delay(20000);break;
case 7:P2=led1[7];a=0;delay(20000);break;
default: break;
}
}
if(j==1&&i==0)
{
switch(b)
{
case 0:P2=led2[0];b++; delay(20000);break;
case 1:P2=led2[1];b++; delay(20000);break;
case 2:P2=led2[2];b++; delay(20000);break;
case 3:P2=led2[3];b++; delay(20000);break;
case 4:P2=led2[4];b++; delay(20000);break;
case 5:P2=led2[5];b++; delay(20000);break;
case 6:P2=led2[6];b++; delay(20000);break;
case 7:P2=led2[7];b++; delay(20000);break;
case 8:P2=led2[8];b=0; delay(20000);break;
default: break;
}
}
}
void main()
{
while(1)
{
mint();
if(K1==0)
{
delay(10);
if(K1==0)
{
i=1;
j=0;
}
while(!K1);
}
if(K2==0)
{
delay(10);
if(K2==0)
{
j=1;
i=0;
}
while(!K2);
}
}
}
试了效果可以.你改下脚或者数组试试....
作者: dabaojiu 时间: 2017-4-27 21:36
请大家来指导指导谢谢
作者: 你像风儿来了 时间: 2017-4-28 13:19
TurnLeft(); //调用数码管左移
这个函数里面有个while(1)大循环,程序根本不会执行后面的两个if判断,所以你中断里标志改变了也没有用,因为程序一直执行TurnLeft(); //调用数码管左移
程序我帮你修改了
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar Flag0=0;
uchar Flag1=0;
//--------------------------------------------------------------------------------------------------------------------------
void DelayMs(uint t)//定义延时函数
{
uchar j;
while(t--)
{
for(j=0;j<113;j++);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void TurnLeft (void) //定义LED灯做左循环
{
unsigned char i; //定义一个无符号字符型局部变量 i 取值范围 0~255
DelayMs(500);
P1=0xfe; //赋初始值
//while (1) //主循环
{
for(i=0;i<8;i++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(500);
P1<<=1;
P1=P1|0x01; //左移后,最右端自动赋值0,所以需要该语句赋值1
}
P1=0xfe; //重新赋初始值
//主循环中添加其他需要一直工作的程序
}
}
//--------------------------------------------------------------------------------------------------------------------------
void TurnRight (void)
{
unsigned char k; //定义一个无符号字符型局部变量 k 取值范围 0~255
DelayMs(500);
P1=0x7f; //赋初始值
//while (1) //主循环
{
for(k=0;k<8;k++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(500);
P1>>=1;
P1=P1|0x80; //右移后,最左端自动赋值0,所以需要该语句赋值1
}
P1=0x7f; //重新赋初始值
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FastTurnLeft (void) //定义LED灯做快速的左循环
{
unsigned char l; //定义一个无符号字符型局部变量 l 取值范围 0~255
DelayMs(500);
P1=0xfe; //赋初始值
//while (1) //主循环
{
for(l=0;l<8;l++) //加入 for循环,表明for循环大括号中的程序循环执行8次
{
DelayMs(50); //做快速左循环时调整了延时函数
P1<<=1;
P1=P1|0x01; //左移后,最右端自动赋值0,所以需要该语句赋值1
}
P1=0xfe; //重新赋初始值
//主循环中添加其他需要一直工作的程序
}
}
//--------------------------------------------------------------------------------------------------------------------------
void main(void) //定义主函数
{
IE=0x85; //开放式中断
TCON=0x05; //边沿方式,自清中断标志
while(1)
{
if((Flag0==0)&&(Flag1 == 0))
{
TurnLeft(); //调用数码管左移
}
if(Flag0 == 1)
{
TurnRight ();
}
if(Flag1 == 1)
{
FastTurnLeft();//调用数码管快速右移
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
//两个中断程序控制Flag1,Flag0两个状态标识。
void Ex0Isr()interrupt 0
{
if (Flag0 == 0)Flag0 = 1;
Flag1 = 0;
}
void Ex1Isr()interrupt 2
{
if (Flag1 == 0)Flag1 = 1;
Flag0 = 0;
}
作者: bbg3659 时间: 2017-4-28 14:23
这样在跑for()的时候,你跳不出吧.必须要它跑完.
我写了一个,试了一下可以跑两个流水,中间也可以跳出来.你改下脚或者数组试试...我也在学习中
#include "reg51.h"
sbit K1=P3^1;
sbit K2=P3^0;
unsigned char led1[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char led2[9]={0x7f,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0xfe};
unsigned char i,j;
void delay(unsigned int x)
{
unsigned char a,b;
while(x--);
for(a=0;a<100;a++)
{
for(b=0;b<100;b++)
{}
}
}
void mint()
{
unsigned char a,b;
if(i==1&&j==0)
{
switch(a)
{
case 0:P2=led1[0];a++;delay(20000);break;
case 1:P2=led1[1];a++;delay(20000);break;
case 2:P2=led1[2];a++;delay(20000);break;
case 3:P2=led1[3];a++;delay(20000);break;
case 4:P2=led1[4];a++;delay(20000);break;
case 5:P2=led1[5];a++;delay(20000);break;
case 6:P2=led1[6];a++;delay(20000);break;
case 7:P2=led1[7];a=0;delay(20000);break;
default: break;
}
}
if(j==1&&i==0)
{
switch(b)
{
case 0:P2=led2[0];b++; delay(20000);break;
case 1:P2=led2[1];b++; delay(20000);break;
case 2:P2=led2[2];b++; delay(20000);break;
case 3:P2=led2[3];b++; delay(20000);break;
case 4:P2=led2[4];b++; delay(20000);break;
case 5:P2=led2[5];b++; delay(20000);break;
case 6:P2=led2[6];b++; delay(20000);break;
case 7:P2=led2[7];b++; delay(20000);break;
case 8:P2=led2[8];b=0; delay(20000);break;
default: break;
}
}
}
void main()
{
while(1)
{
mint();
if(K1==0)
{
delay(10);
if(K1==0)
{
i=1;
j=0;
}
while(!K1);
}
if(K2==0)
{
delay(10);
if(K2==0)
{
j=1;
i=0;
}
while(!K2);
}
}
}
作者: dabaojiu 时间: 2017-4-30 20:15
刚刚看到,前几天出去几天,多谢多谢
作者: dabaojiu 时间: 2017-4-30 20:16
多谢多谢 看到问题了
作者: zl2168 时间: 2017-5-1 08:14
本帖最后由 zl2168 于 2017-5-1 17:28 编辑
键控流水循环灯。
① 8个发光二极管从上到下(K0断开)依次循环点亮,每次点亮时间约为0.5秒。
② 按下K0,流水方向从下至上滚动点亮。
③ 按下K1(K2断开),每循环一次后间隔时间缩短0.1秒,直至最短间隔0.1秒后保持不变。
④ 按下K2(K1断开),每循环一次后间隔时间增加0.1秒,直至最长间隔1秒后保持不变。
⑤ K1、K2同时断开或同时闭合,保持原滚动间隔时间不变。
先Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机Proteus仿真设计实例教程》清华大学出版社ISBN 978-7-302-41682-1仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。
作者: dabaojiu 时间: 2017-5-1 20:24
好的好的,我看看,谢谢了。
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |