看门狗和电压控制不工作微控制器[AVR128DB48 Curiosity Nano]

如何解决看门狗和电压控制不工作微控制器[AVR128DB48 Curiosity Nano]

嗨,我正在使用看门狗来控制 LED 灯。微控制器通过电缆连接到笔记本电脑。微控制器的输入为 5V。现在在引脚上有一个引脚 PB2,它是直接连接到输入的 5V。如果我从 LED 关闭 PB2 移除那根 5V 母对公线,我想这样做。当我用 PB2 再次插入时,指示灯亮起,然后看门狗每 4 秒调用一次并关闭红灯

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#define WDTO_4S 8


void fun_red(){
        PORTB.IN=0x04; // PB2 as input
        PORTB.DIR=0x09; // PB0 and PB3 output
        
    
    PORTB.OUTCLR=0x00; // Green
    PORTB.OUTSET=0x01;
        
        
        wdt_enable(WDTO_4S);
        do 
        {
            if (PORTB.IN)
            {
                PORTB.OUTCLR=0x00; // red
            }
            else{
                PORTB.OUTSET=0x08;
            }
            

        
        } while(1);
        wdt_reset();

}

int main(void)
{
    fun_red();
}

解决方法

好的,所以在编辑中,您似乎希望使用 PB2 作为输入来控制 PB3 上的 LED - 对吗?

您不应该考虑电压,这些是数字 I/O,它们具有高状态和低状态以及两者之间的阈值。您的输入将在高于 0.8 伏时变高。但是,如果您启用了内部上拉,那么通过断开电线来移除输入电压将没有任何效果,如果您没有启用,它将浮动并且可能不会触发逻辑 0(零)。

您要么需要一个外部下拉电阻,要么启用内部上拉并反转逻辑 - 即当输入低时 LED 亮,输入高时 LED 关闭。然后,不是将 PB2 连接到 5V,而是将其连接到 GND。由于内部上拉,去掉 GND 连接将导致逻辑​​状态变为 1。此外,这更安全,因为它避免了对输入施加过高电压和损坏处理器的任何风险。

鉴于您明显缺乏电子知识,我还想问一下您是如何连接 LED 的。您应该有一个限流串联电阻,并以正确的方式连接 LED。

目前尚不清楚看门狗的目的是什么。它没有任何作用,但如果您启用它,您必须维护它以防止处理器重置。看门狗的目的是在软件停止正常运行时通过在正常的软件执行路径中定期复位处理器来复位处理器,因此如果正常路径停止执行则系统重新启动。

首先阅读这篇入门应用笔记:Getting Started with GPIO

首先,你误解了GPIO寄存器的功能。 PORTB.IN 读取配置为输入的 PORTB 引脚的输入状态。它是只读,所以:

PORTB.IN=0x04; // PB2 as input

没有效果,当然不会将引脚配置为输入。这是由 DDR 完成的,所以:

PORTB.DIR=0x09; // PB0 and PB3 output

将 PB0 和 PB3 设置为输出,任何不是输出的都是输入 - 因此 PB2 凭借这条线成为输入。

现在,如果您按照我的建议进行操作并使用 PB2 的内部上拉,您必须在 PIN2CTRL 寄存器中启用它:

PORTB.PIN2CTRL = 0x08 ; // PULLUPEN

顺便说一句,所有这些位都定义了符号,因此您应该能够编写:

PORTB.PIN2CTRL = PORT_PULLUPEN_bm ;

这也使得注释变得不必要。

寄存器 OUTSETOUTCLR 分别设置(逻辑 1/高)和清除(逻辑 0/低)。要设置/清除的引脚由传入的位掩码决定。因此:

PORTB.OUTCLR=0x00; // Green

什么都不做,它将无引脚设置为低电平状态。将红色 LED(我假设为 PB3)关闭并打开绿色 LED (PB0):

PORTB.OUTCLR = PIN3_bm ;
PORTB.OUTSET = PIN0_bm ;

现在,您对 PORTB.IN 的测试就好像它是布尔值一样在这种情况下会起作用,因为您只有一个输入。但是如果你有多个输入,它就不会区分 then,无论如何使用整数表达式就像是布尔值一样是一个坏习惯。您应该明确测试 PB2 的状态:

    // If PB2 is low (GND wire connected)
    if( (PORTB.IN & PIN2_bm) == 0 )
    {
        PORTB.OUTSET = PIN3_bm ; // red on
    }
    else
    {
        PORTB.OUTCLR = PIN3_bm ; // red off
    }

看门狗定时器的目的是在软件无法正常运行时重置处理器。您设置了超时,然后您需要在代码中定期重置它以防止重置。这不是您用于延迟的通用目的。为此,您将使用硬件计时器。不幸的是,它变得有点复杂;对于运行在 24MHz 的电路板,16 位 TIMER1 的最大定时器周期约为 2.8 秒。为了获得更大的灵活性,您通常会实现一个定时器中断来计算多个较小周期并计算定时器重新加载的次数。例如:

volatile unsigned tick = 0 ;
ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
    tick++ ;
}

void tickStart()
{
    
    TCCR1B = (1<<CS11) // Prescaler 24MHz / 8
    TCNT1 = 3000 ;   // 1 ms at 24MHz/8 
    TCCR1A = 0x00;
    TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)
    sei();        // Enable global interrupts
}

unsigned getTick()
{
    unsigned t = 0 ;
    do
    {
        t = tick ;
    } while( tick != t ) ;

    return t ;
}

然后在监视 P2 的同时延迟 4 秒,您可能会这样做:

// Wait 4 seconds or until PB2 disconnected
unsigned start = getTick() ;
while( getTick() - start < 4000 && 
       (PORTB.IN & PIN2_bm) != 0 ) 
{
    // waiting
} 

最后评论你的代码。它将让您了解您正在尝试做什么,并且当您发布问题时,它会告诉其他人您正在尝试做什么,并且通过将解释与代码一致,它会使您的问题变得更简单,因此它是不仅要清楚你想让代码做什么,还要清楚你认为它是如何做的。

综合起来,以下更合理:

void fun_red( void )
{ 
    // Initialise I/O 
    PORTB.PIN2CTRL = PORT_PULLUPEN_bm ;
    PORTB.DIR = PIN0_bm | PIN3_bm ;
    
    PORTB.OUTSET = PIN0_bm ; // Green on

    for(;;) 
    {
        // Red off
        PORTB.OUTCLR = PIN3_bm ;
        
        // Wait for PB2 to be connected (to GND)
        while( (PORTB.IN & PIN2_bm) == 0 )
        {
            // waiting
        }
        
        // Red on
        PORTB.OUTSET = PIN3_bm ;
        
        // Wait 4 seconds or until PB2 disconnected
        unsigned start = getTick() ;
        while( getTick() - start < 4000 && 
               (PORTB.IN & PIN2_bm) != 0 ) 
        {
            // waiting
        } 
        
        // Wait for PB2 to be reconnected
        while( (PORTB.IN & PIN2_bm) != 0)
        {
            // waiting
        }
    }
}

int main( void )
{
    tickStart() ;
    fun_red() ;
}

请记住,您将 PB2 连接到 GND(0 伏)而不是 5V/Vcc。问题中的要求并不完全清楚,但这会做什么(未经测试 - 我没有硬件)是:

  • 当 PB2 断开连接时,LED 将熄灭,
  • 连接 PB2 时,LED 将亮起 4 秒或直到 PB2 重新连接。

虽然这不是它的预期目的,也不是真正用于通用目的,因为这个要求非常简单,我们可以通过看门狗定时器实现所需的行为,如下所示:

void fun_red()
{ 
    // Initialise I/O 
    PORTB.PIN2CTRL = PORT_PULLUPEN_bm ;
    PORTB.DIR = PIN0_bm | PIN3_bm ;
    
    // Green on
    PORTB.OUTSET = PIN0_bm ;
    
    // Red off
    PORTB.OUTCLR = PIN3_bm ;
     
    // Enable watchdog
    wdt_enable(WDTO_4S);
    
    for(;;)
    {
        // Maintain watchdog while waiting for 
        // PB2 to be connected (to GND)
        while( (PORTB.IN & PIN2_bm) == 0 )
        {
            wdt_reset() ;
        }
        
        // Red on
        PORTB.OUTSET = PIN3_bm ;
        
        // Maintain watchdog while waiting for 
        // PB2 to be disconnected (from GND)
        while( (PORTB.IN & PIN2_bm) != 0)
        {
            wdt_reset() ;
        }

        // Red off
        PORTB.OUTCLR = PIN3_bm ;

        // Wait for PB2 to be reconnected (to GND)
        // without maintaining watchdog.  Will reset after 4 seconds
        // if not reconnected.
        while( (PORTB.IN & PIN2_bm) != 0)
        {
            // do nothing
        }
    }
}

这里在 PB2 断开后,看门狗不保持,因此 4 秒后将发生复位并重新启动程序并等待 PB2 连接。我想我应该把这样的代码归类为“肮脏的把戏”,而不是被认为是正常或特别有用的东西。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res