AVR USART 编程

问题描述 投票:0回答:1

我目前正在开展一个项目,我们必须使用 AVR ATMEGA328 微控制器(特别是 USART 外设)来控制 8 个 LED。我们必须向微控制器发送命令,以不同的速率打开、关闭 LED 并使其闪烁。我已经用 C 编写了一个程序,我认为它可以完成这项工作,但我希望有人查看它并帮助我修复我可能遇到的任何错误。我们将非常感谢您的帮助!

*附注命令数组中的每个命令都与 LED 数组中相应的 LED 状态相关联。 LED 连接到微控制器的 PORTB。

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

/* Arrays that contain all input commands and LED states */
const char *commands[] = {"ON0","ON1","ON2","ON3","ON4","ON5","ON6","ON7","ON8","OFF0","OFF1","OFF2","OFF3","OFF4","OFF5","OFF6","OFF7","OFF8","BLINK0","BLINK1","BLINK2","BLINK3","BLINK4","BLINK5","BLINK6","BLINK7","BLINK8","STOP"\0}
int LEDs[28] = {0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80,0XFF,0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F,0,0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80,0XFF,0}

int i;
int j;

int Blinky(int j); // Function to execute blinking commands where j is the argument
{
    PORTB = LEDs[j];
    _delay_ms[250 + (j-18) * 50];  /* Calculates blinking delay times */
    PORTB = 0;
    _delay_ms[250 + (j-18) * 50];
}

int main(void)
{
    DDRB=0XFF; // PORTB is set to output
    DDRD=0X02; // Turns on the transmit pin for the USART in PORTD

    /* Setup USART for 9600,N,8,1 */
    USCR0B = 0X18;
    USCR0C = 0X06;
    UBRR0 = 51;

    sei(); // Enable Global Interrupts

    char input;

    if(UCSR0A & 0X80) /* Reads data from the USART and assigns the contents to the character input */
        input = UDR0;

    j=28;

    char cmd;
    cmd = *commands[i];

    for(i=0; i<28; i++)
    {
        if(input==cmd) /* If the contents of UDR0 are equal to one of the commands */
            j = i;
    }

    while(1)
    {
        if(j<18)
            PORTB=LEDs[j]; // Executes the "ON" and "OFF" commands

        else if(j<27)
            Blinky(j);  // Executes the blinking command by calling the Blinky function

        else if(j=27)
            PORTB=0;  // Executes the "STOP" command

        else
            PORTB=0; // Accounts for typing errors
    }
    return(0);
}
c microcontroller avr usart
1个回答
1
投票

这个程序有很多错误,一些明显的问题是:

  • _delay_ms() 函数需要使用编译时常量来调用。如果需要在运行时计算参数,则无法正常工作。

  • 如果您没有从 USART 读取任何字符,那么您仍然会执行循环的其余部分。

  • char cmd
    声明一个字符变量,然后为它分配一个指针。

  • i
    在设置为有意义的值之前使用。

  • input== cmd
    可能永远不会成立,因为一侧是字符,另一侧是指针。

© www.soinside.com 2019 - 2024. All rights reserved.