Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Timer 带arduino的attiny85位bang uart_Timer_Arduino_Uart_Attiny - Fatal编程技术网

Timer 带arduino的attiny85位bang uart

Timer 带arduino的attiny85位bang uart,timer,arduino,uart,attiny,Timer,Arduino,Uart,Attiny,我曾尝试为ATTiny85实现仅发送uart,并使用arduino micro接收位。(没有帮助,因为这与我的情况完全不同) 我的目的是能够通过attiny85->arduino->控制台打印,这样我就可以调试attiny85,因为我没有示波器可用 attiny85保险丝为:“efuse:w:0xff:m-U hfuse:w:0xdf:m-U lfuse:w:0xf1:m”。16MHz F_CPU arduino似乎也有16MHz的F_CPU 与上述问题类似,attiny85通过定时器0 ISR

我曾尝试为ATTiny85实现仅发送uart,并使用arduino micro接收位。(没有帮助,因为这与我的情况完全不同)

我的目的是能够通过attiny85->arduino->控制台打印,这样我就可以调试attiny85,因为我没有示波器可用

attiny85保险丝为:“efuse:w:0xff:m-U hfuse:w:0xdf:m-U lfuse:w:0xf1:m”。16MHz F_CPU arduino似乎也有16MHz的F_CPU

与上述问题类似,attiny85通过定时器0 ISR一次发送一位:

#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define TX_PIN  PB0

volatile uint16_t tx_shift_reg = 0;

ISR(TIMER0_COMPA_vect) {
   uint16_t local_tx_shift_reg = tx_shift_reg;
   if( local_tx_shift_reg & 0x01 ) {
      PORTB |= _BV(TX_PIN);
   } else {
      PORTB &= ~_BV(TX_PIN);
   }
   local_tx_shift_reg >>= 1;
   if(!local_tx_shift_reg) {
      // Stop timer0.
      GTCCR |= (1<<TSM) | (1<<PSR0);
   }
   tx_shift_reg = local_tx_shift_reg;
}

void UART_tx(char byte) {
   uint16_t local_tx_shift_reg = tx_shift_reg;
   local_tx_shift_reg = (0b1<<9) | ((uint16_t)byte<<1);
   tx_shift_reg = local_tx_shift_reg;
   TCNT0 = 0;
   TCCR0B |= (1<<CS02)|(1<<CS00); // 1024 prescaler
   GTCCR &= ~(1<<TSM);
}

void UART_tx_char(char c) {
   UART_tx( c );
   // wait until transmission is finished
   while(tx_shift_reg);
}

void UART_init() {
   cli()
   // set TX pins as output
   DDRB |= (1<<TX_PIN);
   PORTB |= (1<<TX_PIN);
   // set timer0 to CTC mode, keep it halted.
   TCCR0A |= (1<<WGM01);
   TCCR0B = 0;
   // enable interrupt
   TIMSK |= (1<<OCIE0A);
   OCR0A = 128;
   OCR0B = 128;
   TCNT0 = 0;
   GTCCR |= (1<<TSM);
   sei();
}

void main(void)
{
   UART_init();
   while(1) {
      for(char c = 1; c < 128; ++c) {
         UART_tx_char(c);
         _delay_ms(100);
      }
   }
}
\ifndef F\u CPU
#定义F_CPU 1600000UL//16 MHz
#恩迪夫
#包括
#包括
#包括
#定义TX_引脚PB0
易失性uint16\u t tx\u shift\u reg=0;
行业特殊报告员(计时器公司){
uint16\u t local\u tx\u shift\u reg=tx\u shift\u reg;
if(本地发送移位寄存器&0x01){
端口B |=_BV(TX|U引脚);
}否则{
端口B&=~\u BV(TX\u引脚);
}
本地_-tx_-shift_-reg>>=1;
如果(!本地发送移位寄存器){
//停止计时器0。

GTCCR |=(1我最近遇到了另一端串行通信作为垃圾输出的问题。在我的例子中,ATtiny85使用USB-to-TTL UART转换器向我的笔记本电脑发送位,该转换器在其他情况下工作得很好,但我只是在Arduino IDE串行监视器中收到垃圾

我发现了一个关于校准
OSCCAL
的方法

在我的相关课程中,我有点喜欢,但我测试了我应该使用以下代码校准
OSCCAL
的理论:

#include <SoftwareSerial.h>

SoftwareSerial comm(-1, 0);

static const int anchor = 128;

void
print_osccal(int v) {
  comm.println(F("********************************"));
  comm.print(F("OSCCAL = "));
  comm.println(v);
  comm.println(F("********************************"));
}

void
setup() {
  delay(5000);
  comm.begin(300);
  OSCCAL = anchor;
  print_osccal(anchor);
  delay(5000);
}

void
loop() {
  int x;
  for (int i = 1; i < 128; ++i) {
    x = anchor + i;
    OSCCAL = x;
    print_osccal(x);
    delay(1000);
    x = anchor - i;
    OSCCAL = x;
    print_osccal(x);
    delay(1000);
  }
}
#包括
软件串行通信(-1,0);
静态常数int-anchor=128;
无效的
打印光盘(int v){
comm.println(F)(“*************************************”);
通讯打印(F(“OSCCAL=”);
通讯打印(v);
comm.println(F)(“*************************************”);
}
无效的
设置(){
延迟(5000);
通信开始(300);
OSCCAL=锚;
打印光盘(锚);
延迟(5000);
}
无效的
循环(){
int x;
对于(int i=1;i<128;++i){
x=锚+i;
OSCCAL=x;
打印光盘(x);
延迟(1000);
x=锚-i;
OSCCAL=x;
打印光盘(x);
延迟(1000);
}
}
这是一个启示,在串行监视器中看到垃圾突然转变为格式良好的消息(当然,返回垃圾,因为搜索是一个无限循环)

现在,ATtiny85的内部振荡器只能支持1MHz和8MHz。据我所知,
OSCCAL
的存在是因为该内部振荡器1)不太准确,2)对温度非常敏感

如果ATtiny85设置为16MHz运行,它需要一个可靠的外部振荡器,不需要再摆弄
OSCCAL
可能会有帮助。但是,在我的情况下,它确实允许我发现使
SoftwareSerial
在8MHz下运行的值,以及从
300
38400
的波特率范围


这使我能够为位触发UART获得正确的值,以与
SoftwareSerial

不支持的1MHz时钟一起工作,非常有趣的是,16MHz时钟的ATtiny85可能不可靠。这可能解释了为什么在较高的串行速度下时钟会很快地去同步。谢谢!
#include <SoftwareSerial.h>

SoftwareSerial comm(-1, 0);

static const int anchor = 128;

void
print_osccal(int v) {
  comm.println(F("********************************"));
  comm.print(F("OSCCAL = "));
  comm.println(v);
  comm.println(F("********************************"));
}

void
setup() {
  delay(5000);
  comm.begin(300);
  OSCCAL = anchor;
  print_osccal(anchor);
  delay(5000);
}

void
loop() {
  int x;
  for (int i = 1; i < 128; ++i) {
    x = anchor + i;
    OSCCAL = x;
    print_osccal(x);
    delay(1000);
    x = anchor - i;
    OSCCAL = x;
    print_osccal(x);
    delay(1000);
  }
}