【问题标题】:Could not call the sub-routine correctly Microcontroller PIC18F无法正确调用子程序 单片机 PIC18F
【发布时间】:2012-05-22 10:44:22
【问题描述】:

我有一个对微控制器 PIC18F 进行编程的项目,我必须将一个开关电路连接到微控制器板上,这个开关电路有一个电子锁和一个要连接的蜂鸣器。

锁最初是通电的。假设当我发送'1'时,蜂鸣器将以方波供电,锁将断电。当它收到“0”时,蜂鸣器将关闭,不再为锁供电。当它收到'2'时,锁应该通电,但如果蜂鸣器之前没有通电,则不应再次通电。

我的困惑在最后一部分。当我通过超级终端发送“2”,在它之前发送“0”时,蜂鸣器再次通电。

这是代码,

void buzzertest();
char uart_rd;
int buzzer;
void main() {
TRISB=0X00;
PORTB=0x00;
RB5_bit = 0xFF;                  //lock  open
UART1_Init(9600);               // Initialize UART module at 9600 bps
while (1) {                     // Endless loop
 if (UART1_Data_Ready())       // If data is received,
 {
    buzzer=1;
    uart_rd = UART1_Read();     // read the received data,
    if(uart_rd =='1') {
       RB5_bit = 0x00;  //lock closed
       buzzertest();
     }
     if(uart_rd =='0' ){   //disable buzzer
        RB1_bit = 0x00;   //buzzer
        buzzer=0;
       }//end if
      buzzer=0;

      if(uart_rd =='2'){   //disable lock
        RB5_bit=0xFF;
        if(buzzer!=1){
            buzzertest();
         }
       }//end if
     } //end outer if
    } //end while
}//end main
void buzzertest(){
 while(1){
  RB1_bit = 0xFF;  //buzzer
  Delay_ms(1000);
  RB1_bit = 0x00; //buzzer
  Delay_ms(1000);
  if (UART1_Data_Ready())
  break;
 }//end while loop
}

谁能帮我解决这个问题?

【问题讨论】:

  • 您不必要地测试 uart_rd 三次,而它的值不能改变 - 请改用 switch( uart_rd )

标签: c embedded microcontroller microchip mikroc


【解决方案1】:

您在if(uart_rd='0') 块之外将buzzer 设置为0。因此,当您来到 if(uart_rd='2') 块时,buzzer 始终为 0,因此始终调用 if(buzzer!=1) 块。

您是否尝试过使用调试器单步执行此操作?它会很容易地出现这种事情。您还可以将这些 if 块更改为 switch 语句或一系列 if / else if 语句以避免此类问题。

【讨论】:

  • 抱歉 if(buzzer!=1) 打错字了,是 if(buzzer==1)
  • 好的,如果您希望我们调试您的代码,您需要发布您正在使用的实际代码。您是否按照我的建议尝试过调试器?
  • Vicky 是正确的。你需要清理你的逻辑。您有两个输出(蜂鸣器和锁定)、一个输入(UART)和一个状态变量(蜂鸣器激活)。用这些术语来思考它。
  • @Sahar:如果您发布的代码与您正在运行的代码不同(即复制和粘贴),我们就是在浪费时间查看它!现在错误已经指出了为什么不纠正它!?无论哪种方式,无条件的buzzer=0 行都会通过始终启用蜂鸣器或从不启用它来阻止它工作 - 取决于您真正运行的代码。
  • 感谢您的所有回复,它现在正在工作。我会在几分钟内发布运行代码
【解决方案2】:

这是运行代码:

void buzzertest();
char uart_rd;
int buzzer;
void main() {
TRISB=0X00;
PORTB=0x00;
RB5_bit = 0xFF;                  //lock  open
UART1_Init(9600);               // Initialize UART module at 9600 bps
while (1) {                     // Endless loop
if (UART1_Data_Ready())       // If data is received,
 {
  uart_rd = UART1_Read();     // read the received data,
  if(uart_rd =='1') {
    RB5_bit = 0x00;  //lock closed
    buzzertest();
    buzzer=1  ;
   }
  else if(uart_rd =='0' ){   //disable buzzer
    RB1_bit = 0x00;   //buzzer
    buzzer=0;
   }//end else if

   else if(uart_rd =='2'){   //disable lock
     RB5_bit=0xFF;
     if(buzzer==1){
       buzzertest();
      }
    }//end else if
   } //end outer if
 } //end while
}//end main
void buzzertest(){
 while(1){
  RB1_bit = 0xFF;  //buzzer
  Delay_ms(1000);
  RB1_bit = 0x00; //buzzer
  Delay_ms(1000);
  if (UART1_Data_Ready())
   break;
 }//end while loop
}

【讨论】:

  • 您是将其发布为“解决方案”还是仍然是不起作用的代码?由于您的 cmets 对您在问题中发布的代码是否“真实”存在一些不确定性,因此现在不清楚这是否是对此的回应,在这种情况下,它应该是对问题的编辑,或者它是否是您最终更正的代码,在这种情况下是不必要的。 if..else if..else 结构更好,但switch 更合适 - 这需要 1 到 3 次测试,而交换机只有一个。
  • @Clifford .. 实际上这是解决方案,第二个发布的代码是正确的,我将在 switch 中重写它而不是 if 条件,我认为是的它会更好,谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
相关资源
最近更新 更多