我正在尝试编写 ATtiny416 代码以使用以下输入执行以下功能;
目的: 每 X 个时钟周期从外部时钟源的输入发送一个字节消息“0x01”,并将该字节的输出同步到外部输入时钟信号的上升沿。
输入:
有人对如何做到这一点有任何建议吗?目前,我刚刚实现了通过使用
deöay
函数每 488.281us 传输该字节消息。
任何有关通过计算外部输入时钟周期并将输出同步到外部输入时钟信号的上升沿来执行此延迟的提示将不胜感激。
#define F_CPU 20000000UL
#define DELAY_US 488.281 //488.281us +1us
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <until/atomic.h>
int main(void)
{
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc; // Use 20 MHz internal clock as source
CPU_CCP = CCP_IOREG_gc; // Unlock the IO config registers for writing
CLKCTRL.MCLKCTRLB = 0; // Disable the prescaler
while (1)
{
//Setup USART and Transmit 0x01 Byte
USART0.BAUD = F_CPU*4/921600; // Setup BAUD Rate
USART0.CTRLB = 0x40; // TXEN
PORTB.DIRSET = PIN2_bm; // PB2/TX - output
while( (USART0.STATUS & 0x20) == 0 ){} // DREIF
USART0.STATUS = 0x40; // clear TXCIF
USART0.TXDATAL = 0x01; // Transmit 0x01
while( (USART0.STATUS & 0x40) == 0 ){} // TXCIF
_delay_us(DELAY_US);
}
}
一种简单的方法是在 IO 引脚上使用中断来传输 ISR 中的字节。计算中断被调用的次数来决定何时发送。一种变体是使用
<util/atomic.h>
仅在 ISR 中进行计数,并使用原子块检查计数并在 main
中进行传输。
软件仅进行硬件和中断初始化,然后空闲。中断具有可预测的时序,并将生成可预测且一致的输出。
我假设 PORTB 引脚 2 被复用以用作 USART0 Tx?
如果您可以更改硬件设计以使用 PA1 -> TXD 和 PA3 <- XCK. Then you can use the Real Time Counter(RTC) to generate an interrupt every 512 clocks. This is the ideal solution with the least delay and most accuracy depending only on the external clock source.