来自 ATMEGA8535 的 UART 信号如何比来自带有 ATMEGA328 的 Arduino 慢 200 倍?

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

所以我一直在尝试让 UART 在 ATMEGA8535 上工作,但遇到了一些问题。设置如下:当 ATMEGA 在自定义 pcb 上时,我需要 UART 工作。这不起作用,所以回到一个裸露的面包板,ATMEGA 只连接到 GND 和 5V。 TX 引脚连接到示波器以监控其输出。这是芯片上的代码:

#define F_CPU 1000000UL //CPU frequency

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

#define BAUD 19200 // baud
#define BRC ((F_CPU/16/BAUD) - 1)

int main(void) {
    
    /* Set baud rate */
    UBRRH = (BRC >> 8);
    UBRRL =  BRC;
    
    /* Enable receiver and transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Set frame format: 8data*/
    UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
    
    while(1){
        UDR = 'b';
        
        _delay_ms(2000);
    }
}

虽然示波器显示发送了正确的信号,但速度很慢:整个信号需要超过 200 毫秒。相比之下,对于设置为相同波特率的 Arduino,它需要不到 1 毫秒的时间。我检查了芯片是否有故障,但五个不同的 ATMEGA8535 给出了相同的输出。查看数据表时,我没有看到任何可能导致时钟生成出现如此大错误的情况。关于这个问题的起源和解决方案有什么想法吗?

avr uart atmega
1个回答
0
投票

您没有正确设置 UCSRC 注册。对于这种 MCU 类型,该寄存器的地址与 UBRRH 相同。如果要写入 UCSRC 寄存器,则必须将第八位设置为 1。因此,您的代码保存的不是 UCSRC,而是 UBRRH。这意味着 UBRRH 值被覆盖。

看看DS

Bit 7 – URSEL:寄存器选择 该位在访问 UCSRC 或 UBRRH 寄存器之间进行选择。它被读作 阅读 UCSRC 时的一个。写UCSRC时URSEL必须是一个。

数据表

UCSRC 的正确写法是:

/* Set frame format: 8data*/
UCSRC = (1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);

第 163 页讨论 UCSRC怎么写

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