C 和 AVR pow 函数点亮 LED

标签 c arduino avr pow

我正在编写代码,使一组五个 LED 看起来像“霹雳游侠”风格来回“弹跳”。写入 PORTB 寄存器时,我注意到插入 LED 的方式不同,分别为 1、2、4、8、16。这些会点亮相应的 LED。所以我想通过使用 pow 函数循环将寄存器的值 2 提高到 LED 编号 (0, 1, 2, 3, 4)。虽然它不能正常工作。

#include <avr/io.h>
#include <inttypes.h>
#include <math.h>

void delay(uint16_t x);
//void buttons(int b1, int b2);

int led = 0;
int inc = 1;
unsigned int ledpow = 0;

int main(void)
{
    DDRB |= (1<<PORTB0); //Set PORTB0 (pin 8) as an output
    DDRB |= (1<<PORTB1); //Set PORTB1 (pin 9) as an output
    DDRB |= (1<<PORTB2); //Set PORTB2 (pin 10) as an output
    DDRB |= (1<<PORTB3); //Set PORTB3 (pin 11) as an output
    DDRB |= (1<<PORTB4); //Set PORTB4 (pin 12) as an output
    DDRD &= ~(1<<PORTD3); //Set PORTD3 (pin 3) as an input
    DDRD &= ~(1<<PORTD4); //Set PORTD4 (pin 4) as an input
    PORTB = 0; //Disable Pull-up resistors for PORTB
    PORTD = 0; //Disable Pull-up resistors for PORTD

    while(1)
    {
        while((PIND & (1<<PORTD3)) != 0) {
            //Do nothing, just pause the program
        }

        ledpow = pow(2,led);
        PORTB = ledpow;

        led = led + inc;

        if ((led == 4) || (led==0)) {
            inc = -inc;
        }

        if((PIND & (1<<PORTD4)) != 0) {
            delay(50);
        }
        else {
            delay(100);
        }
    }
}

void delay(uint16_t x)
{
    uint16_t i,j;

    for(i=0;i<x;i++)
        for(j=0;j<1000;j++)
            ;
    return;
}

为什么这不起作用?我让它与 switch/case 语句一起工作。我通过执行 PORTB = pow(2,0); 测试了 pow 函数的工作原理以及变量“led”的其他幂。一切正常。

最佳答案

因为 pow 函数返回一个 float ,它不是它应该表示的值的精确表示(而且,数学函数使用近似值工作)。所以也许pow(2, 3)不返回 8,而是返回 7.99856 或 8.0000261 等。在前一种情况下,你搞砸了,因为当你将它分配给端口时,它会被截断为一个整数(端口保存整数,对吧?)并丢失它的小数部分,形成 7 以点亮所有前 3 个 LED。

对于整数运算,pow函数也是过时了,白费力气了。我想知道你为什么不使用 PORTB = 1 << led;而您确实使用它来设置其他端口状态...

此外,您的延迟循环非常不可移植。深入研究 AVR-libc 的文档,有两个延迟循环函数提供几乎精确的时间延迟。您可以在我的 AVR 实用程序库中查看如何使用它们:http://github.com/H2CO3/libavrutil

关于C 和 AVR pow 函数点亮 LED,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12328010/

相关文章:

c - bsearch() 在 C 中的字符串数组上

c - SSL_CTX_use_certificate_file 因 EXC_BAD_ACCESS 而失败

c++ - C/C++。输入行数字

c - AVR 编程,在 7 段上显示错误值。引领

c - 如何允许 C 库使用调用者的日志记录?

arduino - avrdude : stk500_getsync(): not in sync: resp=0x00

c - 距离传感器测距误差估计

c++ - 如何将获取的字符串数据转换为字符数组?

c - 旋转由字节数组表示的位图

c - C 无法识别 AVR USART 文件