C - AVR - 简单的PORTB,DDRB,PINB说明

 灭世师太 发布于 2023-02-05 11:21

我正在研究学校项目,需要使用AVR atmega控制器学习C语言的基础知识.

我不明白一切都是如何建立的.例如PORTB,PORTD,DDRB; DDRD,PINB,PIND等等.我不知道if语句,while循环等是如何工作的.

有人可以给我一个简短的解释吗?

我有一些代码行......

DDRB = 0b00000011; // I know that here DDRB is set to input/output

并且if语句:

if (PINB & (1 << PINB0)){
    A = true;
}

有人可以解释一下这个"if语句"是如何工作的吗?为什么PINB & (1<< PINB0))

谢谢

4 个回答
  • if (PINB & (1 << PINB0)){
            A = true;
        }
    

    此代码检查是否PIN 0 in PORTBHIGH or LOW.如果是高然后分配A = true; 在这里,PINB- >读取数据PORTB, (1<<PINB0)- >写第0位为1 AND的值都知道PIN 0无论PORTB是高还是不行.

    2023-02-05 11:23 回答
  • 你的意思是条件是什么PINB & (1<< PINB0))

    它检查PINB0 + 1数字位(来自rhs)是ON(1)in PINB还是OFF(0).

    例如.(a & (1 << 2))检查第3位是ON a还是OFF.在表达式中,两个运算符<<按位左移和&按位使用,下面我解释了一个字节的例子:

      10000 0001

      1 << 2 左移后给出 0000 0100

      a按位和同时0000 0100给出全零0000 00000000 0100

      3A.如果全为零,则条件为假(当第三位a为零时).
      3B.如果是按位的结果,0000 0100那么条件的计算结果为真(当第三位a为1时).

    2023-02-05 11:24 回答
  • 对于寄存器的含义,建议咨询

    您正在使用的设备的数据表

    您正在使用的C编译器附带的头文件.

    简而言之,最后一个字母(B,D)表示您正在访问的端口:GPIO引脚按8组合在一起,因此每个端口有8个引脚.

    DDRx 是一种设置每个端口引脚方向的方法.

    PORTxPINx用于输入和输出,但我习惯了使用PORTA.IN,PORTB.DDR,PORTD.OUT等,我不能由他们做什么的心脏告诉.

    对于该语言的基础知识,有书籍和教程可以让您学习这门语言.

    2023-02-05 11:24 回答
  • 微处理器使用存储器映射将其硬件功能与软件连接.

    基本上,内存中存在静态地址,硬件将使用这些地址来确定其功能.这些特定于制造商,零件,有时甚至是零件的配置方式.

    该部件的数据表将告诉您控制不同功能的确切内存位置.但是,这通常非常繁琐.因此,数据表也(几乎)总是给内存中描述其功能的特定位置命名.这些名称再次是制造商和部分特定的.

    为了使程序员更容易使用这个界面,人们(制造商或社区)通常会为这些内存位置创建宏.例如,你可以找到

    // Clock Prescalar Register for ATMega328p
    #define CLKPR *0x61
    

    在与该部件关联的头文件中(例如AVR libc).

    现在,通过写入OSCCAL = 0b10000000(或者我想写的任何其他可以通过数据表中的规范进行编写的内容),我可以直接访问和更改此部分的时钟预分频模块.

    但是,我们常常对单个位的值感兴趣,而不是整个字节的值.其结果是,我们使用位运算符(如&,|,~,<< >>),以"掩模"关,我们有兴趣操纵比特.

    这提供了同时的优势,允许我们只从感兴趣的位读取值,同时不会无意中改变我们不打算切换的任何位.

    宏也给出了许多位位置.例如,第7位OSCCAL被命名CLKPCE(再次,来自数据表).

    CLKPCE很可能是通过以下方式定义的(至少在AVR libc中 - 标准各不相同):

    #define CLKPCE 7
    

    因为它定义了到达内部所需位所需的位移OSCCAL.

    为了谈谈这里的一点,我可以做几件事.

    设置位

    要设置该位,我们希望将其设为1,而不影响任何其他位.为此,我们使用OR掩码,如下所示:

    OSCCAL = (OSCCAL | (1 << CLKPCE));
    

    我将留给你审查位操作符,看看它是如何工作的.

    清除一下

    在这里,我们希望将其设为0,而不影响其他位.它看起来像这样:

    OSCCAL = (OSCCAL & ~(1 << CLKPCE));
    

    查询一下

    在查询时,我们想要一个表达式,如果该位置位(1)则返回非零值,如果该位被清除则返回0(0).它看起来像这样:

    (OSCCAL & (1 << CLKPCE));
    

    外卖

    通过使用预定义宏的这些不同的按位运算,我们可以使用此静态存储器映射直接控制和查询硬件状态.

    但是,要了解所有这些宏,您需要查阅(并阅读,重新读取和重新读取)数据表.幸运的是,您可以在您的部分页面上免费搜索Atmel的可搜索PDF文件!

    2023-02-05 11:24 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有