打印

关于51单片机的中断函数调用问题

[复制链接]
9226|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
logokfu|  楼主 | 2012-3-15 22:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
ayb_ice| | 2012-3-16 08:33 | 只看该作者
应该是非重入函数的原因

使用特权

评论回复
板凳
logokfu|  楼主 | 2012-3-16 08:52 | 只看该作者
能详细说下吗。我调用的那个子函数内容很简单。
void turn_off()
{
    P2=0xfe;
}

我把P2=0xfe;直接写到外部中断1函数中就可以运行。这个和重入有关系吗。

使用特权

评论回复
地板
原野之狼| | 2012-3-16 09:01 | 只看该作者
1  中断是否会嵌套,如果会,则需要考虑重入的问题。
2  你所说的函数是否会被前台与后台访问,如果会则需要考虑线程安全问题。不过你这里给出的例子不需要考虑这个。

使用特权

评论回复
5
ayb_ice| | 2012-3-16 09:07 | 只看该作者
具体的这个函数没有问题
把全部代码帖上来

使用特权

评论回复
6
mycomputerliu| | 2012-3-16 15:31 | 只看该作者
完全看不明白是什么东东。

使用特权

评论回复
7
gool| | 2012-3-16 17:08 | 只看该作者
不懂啊

使用特权

评论回复
8
logokfu|  楼主 | 2012-3-16 22:13 | 只看该作者
本帖最后由 **kfu 于 2012-3-16 22:21 编辑
具体的这个函数没有问题
把全部代码帖上来
ayb_ice 发表于 2012-3-16 09:07


我的这个是个用串口发指令,控制小车的程序,出问题的就在红色字体的部分,首先说明下,下面的程序是没有问题的,可为正常运行,我的问题就是 当我把红色部分的代码换成对应的函数时候就不管用了。对应的函数就是左转,右转,后退那几个函数。

#include<at89x51.h>
#include<stdio.h>
#define uchar unsigned char

/***************************************************************************
* DIR1 和 PWM1控制左边电机
* DIR2 和 PWM2控制右边电机
* DIR为方向控制(控制正反转),PWM为使能信号(1为运转,0为停止)
* 下面为左边电机的状态表(右边电机也是如此):
—————————————————————————
     DIR1 PWM1  状态   
—————————————————————————
      0    1  正转  
—————————————————————————
      0    0   停  
—————————————————————————
      1    1  反转
—————————————————————————   
      1    0   停  
—————————————————————————
****************************************************************************/
#define DIR1 P2_0
#define PWM1 P2_1
#define DIR2 P2_2
#define PWM2 P2_3
void delayMS(uchar t);//延时
void go_forward(); //前走
void go_back();//后退
void turn_left();//左转
void turn_right();//右转
void stop(); //停

void main(void)
{
uchar xdata rcvdata[1];
    EA=1;   //开启总中断

SCON = 0x50; //串口方式1,允许接收
TMOD=0X21;
TH1 = 0xFD; //11.0592MHZ 9600 波特率
TL1 = 0xFD;
TR1 = 1; //启动定时器1
EX0=1;    //开启外部中断 0,即P32引脚
IT0=0;         //设置成 低电平触发方式,IT0=1为下降沿触发
   
    PWM1=0;//防止小车上电就开始跑
    PWM2=0;
while(1)
{
  rcvdata[0]=0;
  if(RI)
  {
   rcvdata[0]=SBUF;//把接收到的数据保存
   RI=0;
   SBUF=rcvdata[0];
   if(SBUF=='1')
    go_forward();
   if(SBUF=='2')
    go_back();
   if(SBUF=='3')
    turn_left();
   if(SBUF=='4')
    turn_right();
   if(SBUF=='5')
    stop();
   //把收到的数据通过串口发送出去
   while(!TI);
   TI=0;
  }
}
}
/***************************************************************************
*外部中断 0  C51中断号1    0的优先级最高,关键字"interrupt" , 这是C语言的中断函数表示法
*本中断的响应是P32引脚有低电平触发
****************************************************************************/
void int_0() interrupt 0
{
   // 后退防止碰住障碍物
DIR1=1;
  PWM1=1;
  DIR2=1;
  PWM2=1;

delayMS(1000);
//左转        
  DIR1=1;
  PWM1=1;
  DIR2=0;
  PWM2=1;

delayMS(1000);
//继续向前走
DIR1=0;
  PWM1=1;
  DIR2=0;
  PWM2=1;
delayMS(1000);
   
  
}
void go_forward() //前走
{
DIR1=0;
PWM1=1;
DIR2=0;
PWM2=1;
printf("go_forward");
}
void go_back()//后退
{
DIR1=1;
  PWM1=1;
  DIR2=1;
  PWM2=1;
printf("go_back");
}
void turn_left()//左转
{
  DIR1=1;
  PWM1=1;
  DIR2=0;
  PWM2=1;
  printf("turn_left");
}
void turn_right()//右转
{
  DIR1=0;
  PWM1=1;
  DIR2=1;
  PWM2=1;
  printf("turn_right");
}
void stop()//停
{  
  DIR1=0;
  PWM1=0;
  DIR2=0;
  PWM2=0;
printf("stop");   
}
void delayMS(uchar t)//延时
{
uchar i;
while(t--)
for(i=0;i<120;i++);
}

使用特权

评论回复
9
ayb_ice| | 2012-3-17 08:25 | 只看该作者
哪里一样嘛
不要用printf

使用特权

评论回复
10
logokfu|  楼主 | 2012-3-18 00:40 | 只看该作者
9# ayb_ice

1)我试过了,就是你说的原因。
2)我想知道为什么在中断函数里面不能调用带printf的函数呢

使用特权

评论回复
11
Cortex-M0| | 2012-3-18 04:50 | 只看该作者
9# ayb_ice  

1)我试过了,就是你说的原因。
2)我想知道为什么在中断函数里面不能调用带printf的函数呢
**kfu 发表于 2012-3-18 00:40



printf是非重入函数,不能在中断中嵌套使用。

使用特权

评论回复
12
logokfu|  楼主 | 2012-3-18 20:47 | 只看该作者
12# taishandadi

什么意思,怎么搞

使用特权

评论回复
13
ayb_ice| | 2012-3-19 08:33 | 只看该作者
printf函数不是重入函数
即使是重入函数,在中断中使用也是不明智的
因为这个函数很大,执行时间长。。。

使用特权

评论回复
14
qqfishboy| | 2012-3-19 11:14 | 只看该作者
printf没用~我的程序 多一个printf 就不行  有时候少一个也不行 最后干脆都不用了~直接用
void Uart0_SendString(unsigned char *ptr)
{
        while(*ptr)
        {
                Uart0_SendChar(*ptr++);  // ·¢ËÍÊý¾Ý
        }
}

void Uart0_Send232(int S)
{   
        Uart0_SendChar('0'+S/1000);
        Uart0_SendChar('0'+(S/100)%10);
        Uart0_SendChar('0'+(S/10)%10);
        Uart0_SendChar('0'+S%10);
}

使用特权

评论回复
15
xlsbz| | 2012-4-28 09:10 | 只看该作者
我目前知道的有

(1)我认为我水平一般  所以不敢用  那个reentrant
(2)某个中断里面调用的某个函数 只让这个中断调用 不要在别的地方调用。否则 即便我疏忽了 ,我用的keil会给提示

(3)printf 这个函数 我还不太会用,也不想用,因为printf 这个函数参数个数不一定,我不喜欢用参数个数不一定的函数。  我一般自己写自己的print打印 。

(4)甚至memcpy 和 memcmp我都自己写   可以上网查查 这类函数没有检测覆盖   微软自己都承认这点


希望我说的有帮助  也可能答非所问了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

76

主题

2646

帖子

7

粉丝