我试图编写一个ATTINY416来执行以下函数,输入如下:
- 目的:从外部时钟源的输入端,每隔X个时钟周期发送一个字节消息“0x01”,并将该字节的输出与外部输入时钟信号的上升沿同步。
- 输入:
1.外部时钟源的频率为1.048756MHz,并在PORTA引脚7上输入。
1.输出的字节消息将在PORTB引脚2上传输。
1.字节消息需要每488.281us(2048Hz)或(每512个时钟周期)出现一次。
有没有人对如何做到这一点有任何建议?目前,我已经实现了通过使用DELAY函数每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);
}
}
1条答案
按热度按时间eoxn13cs1#
一种简单的方法是在IO引脚上使用中断来传输ISR中的字节。计算调用中断的次数,以决定何时发送。一种变体是使用
<util/atomic.h>
仅在ISR中计数,并使用原子块在main
中检查计数和传输。软件只做硬件和中断初始化,然后闲置。中断具有可预测的定时,并且将生成可预测的和一致的输出。
我假设PORTB引脚2被多路复用用作USART 0 Tx?
如果您可以更改硬件设计,使用PA 1-> TXD和PA 3 <- XCK。然后,您可以使用真实的计数器(RTC)每512个时钟产生一个中断。这是一种理想的解决方案,延迟最小,精度最高,仅取决于外部时钟源。