在没有PWM的情况下在AVR组件中生成方波

时间:2016-06-24 03:17:15

标签: algorithm assembly avr

我正在使用ATmega328。问题是我想生成给定频率和给定幅度的方波。不能使用PWM,因为我得到了一块已经焊接的电路板,因此必须将波放在连接到处理器B端口的R2R resistor ladder的输出端。因此,基本上,我的想法是我必须定期将端口B的引脚置于0和VOLUME(VOLUME是1到255之间的数字),给定频率和占空比为50%。请记住:无PWM 。频率应该能够每100毫秒改变一次,但是我无法完成这项工作所以我只是试图产生一个恒定的频率,看看最初会发生什么。

我以1MHz的频率运行时钟。我写了以下代码:

.DSEG
.ORG 0x100

.CSEG
.ORG 0x100

;Initializing stack pointer
LDI R16,HIGH(RAMEND)
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT SPL,R16

MAIN:
CALL GENERATE ;Calling the generating routine
RJMP MAIN ;Repeat this forever

;I will generate a 440Hz frequency. It has an approximate period of 2273 microseconds
;This means that half a period stands for approximately 1136 clocks
GENERATE:
LDI R17, 0x70
LDI R18, 0x04   ;Half the period in hexadecimal is 0x0470
LDI R19, 243    ;Volume = 243 (arbitrary, it could be any number)
LDI R21, 88 ;The amount of half-periods in 100 ms (arbitrary election, too)

LDI R25, 0xFF
OUT DDRB, R25       ;Port B is an output port

LDI R24, 0xFF       ;R25R24 = 0xFFFF
CLC         ;Clean the carry
SBC R24, R17
SBC R25, R18        ;R25R24 = 0xFFFF - Halfperiod
ADIW R25:R24, 1     ;R25R24 = 0xFFFF - Halfperiod +1
OUT PORTB, R18      ;The wave starts at 0

BEGIN:
CALL LOOP_1
EOR R19, R19        ;It varies between 0 and volume
OUT PORTB, R19      ;It puts the output to the actual value of R19 (0 or volume)
CLZ         ;Clean Z flag
DEC R21
BREQ END        ;When 100ms have passed, generation is over
JMP BEGIN       ;If not, generation continues

LOOP_1: STS TCNT1H, R25
STS TCNT1L, R24     ;Loading the amount of clocks the timer has to count
LDI R16, 0x00
STS TCCR1A, R16
LDI R16, 0x01
STS TCCR1B, R16     ;Timer operating in normal mode, no prescaler
LOOP_2: IN R16, TIFR1
SBRS R16, TOV1      ;If timer's over, skip the next jump
JMP LOOP_2
LDI R16, 0x00
STS TCCR1B, R16     ;Stopping the timer
LDI R16, 0x04
OUT TIFR1, R16      ;Clean TOV1
RET         ;Back to BEGIN

END:
RET         ;Back to MAIN

这是我第一次参加大会的方法之一,所以阅读起来可能非常难看。该代码目前无法正常工作。有什么想法吗?

编辑:

感谢Spektre向我指出这一点,我纠正了上面的一段代码。除了

之外,代码是相同的
GENERATE:
.
.
.
LDI R21, 44 ;The amount of PERIODS (not half-periods as before) in 100 ms
.
.
.
BEGIN:
OUT PORTB, R18      ;This was before the BEGIN tag, now it is after it
CALL LOOP_1     ;It counts a halfperiod with output=0
OUT PORTB, R19      ;Now output=volume
CALL LOOP_1     ;It counts a halfperiod with output=volume
CLZ         ;Clean Z Flag
DEC R21
BREQ END        ;When 100ms have passed, generation is over
JMP BEGIN       ;If not, generation continues

1 个答案:

答案 0 :(得分:2)

多年来我为这样的架构做了一些事情......我正在使用 UC3 (后继者)并且在 MCU 66 MHz时钟我可以实现2-5 MHz轮询频率。但是我担心你的目标平台会降低很多。因此,首先测量轮询频率以查看 HW 的限制。

1 MHz是输出时钟还是 MCU 时钟?你需要输出什么最大频率?

有很多方法可以实现这一点,显而易见的是:

  1. <强>定时器/计数器

    您可以设置示例1 us的定时器并进行定时和切换。或者您可以使用它来设置新频率。但要注意任何中断都会导致输出信号中的时序问题,如抖动......如果有足够的时间可以避免这些问题,但通常会限制最大输出频率。

  2. 主要线程轮询

    看起来这就是你正在做的事情。但是你忘了所有的指令都有自己的时机。条件可以有不同的时间,所以你应该补偿。

  3. 利用界面(如果存在)

    查看数据表,看看是否有 HW 连接到该端口。 MCU 通常在引脚上复用更多功能,有时可以利用它们。例如,我曾经利用串行接口,DMA + ABI / SD卡接口制作了 VGA 图像生成器。每种方法都能正确生成16色VGA信号,但在同一芯片和引脚上具有完全不同的代码和硬件架构......要与 ATMega168 上的平台进行比较20 MHz时钟(这是与 ATMega328相同的核心)我能够为 LCD 生成1位 LCD 640x480信号(比用于需要的信号低很多倍)彩色 VGA 信号)。有时您甚至可以在运行期间更改引脚的含义...例如,要实现100 000 rpm BLDC 控制器,我可以将内部电路改变几次,电机的电动周期就能够产生如此高的速度(否则无法通过直接手段实现。

  4. 您需要尝试哪种方法快速/准确/适合您。从第一次看你的代码我偶然发现:

    EOR R19, R19        ;It varies between 0 and volume
    OUT PORTB, R19      ;It puts the output to the actual value of R19 (0 or volume)
    

    如果我看对了,你 XOR ing R19R19 ...首次通过后销毁R19的内容。因此,您始终将0输出到B端口:

    XOR Volume,Volume -> Volume = 0
    XOR 0,0  -> 0
    

    相反,我会:

    1. 输出端口量
    2. 等半段
    3. 输出端口零
    4. 等半段
    5. 如果100ms达到更改频率
    6. 转到#1
    7. 您应该尽可能少地使用端口访问权限。不确定 ATMega 的情况是否也是如此,但在较新的架构上,端口可通过 HW 接口/ API 进行访问,而且对于高端来说真的很慢如果不明智地使用速度切换。

      <强> PS。

      希望您的 R2R 梯形图在输入电阻之前有二极管,或者至少 PORTB 具有开路集电极输出,否则它将无法工作,因为相邻引脚之间的电流如果两者都设置不同的价值。

      [Edit1]一些澄清

      1. 要更清楚R2R当前的问题

        R2R

        二极管应具有相同的 PN 阻隔电压!!!

      2. 1MHz时钟

        你写了I'm running the clock at 1MHz但没有说明它是 MCU / CPU 时钟,定时器时钟还是输出方波信号频率。现在很清楚您的输出信号是<130,523> Hz,这应该可以在您的平台上轻松实现。我之前不确定......我已经在MCU上产生了甚至大约30 MHz的信号,因此有可能达到1 MHz。

      3. <强>时序

        大多数平台上的BREQ END等条件指令在条件为真时具有不同的时间,而在为假时则为假,因此为了保持同步,您应该考虑到这一点...有时候放置良好的nop可以解决问题...如果是这样的话,Yu shoudl检查文档中的指令时间。

        您声明您使用的是计数器/计时器我在您的代码中没有看到它。为了正确使用,你应该

        1. 为您想要的模式和频率配置硬件
        2. 注册中断子程序
        3. 启用中断和/或触发定时器计数器事件...
        4. 内部中断事件处理程序

          如果需要,重置计数器值并清除中断标志,以便发生另一个事件。如果您接近芯片功能的边缘,有时甚至需要校正计数器值才能正确计时。

        5. 我看到的是计时器/计数器的某些配置不确定是否正确完成,因为我长时间不使用该平台。我在任何地方都看不到中断处理程序子程序...可能你正在查询计数器寄存器但又不确定它是否是正确的方法(并非所有硬件寄存器都可读)你应该面对文档。但无论如何,它正在进行轮询,因此教学时间很重要......

          如果有助于我挖掘一个古老的发电机(在PortC上产生方波)asm代码为ATMega168:

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;; generator ver: 0.00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          /*
          CPU:    ATMega168 8MHz internal RC
          
          OUT:    PC
          */
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;; ATMega168 startup: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ; fuses:BOOTRST=1 disabled
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  .equ stack  =0x04FF
                  .equ cpuclk =8000000
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  .device ATmega168   ; device selection
                  .equ PINB  =0x03    ; IO reg adresses definition in/out
                  .equ DDRB  =0x04
                  .equ PORTB =0x05
                  .equ PINC  =0x06
                  .equ DDRC  =0x07
                  .equ PORTC =0x08
                  .equ PIND  =0x09
                  .equ DDRD  =0x0A
                  .equ PORTD =0x0B
                  .equ TIFR0 =0x15
                  .equ TIFR1 =0x16
                  .equ TIFR2 =0x17
                  .equ PCIFR =0x1B
                  .equ EIFR  =0x1C
                  .equ EIMSK =0x1D
                  .equ GPIOR0=0x1E
                  .equ EECR  =0x1F
                  .equ EEDR  =0x20
                  .equ EEARL =0x21
                  .equ EEARH =0x22
                  .equ GTCCR =0x23
                  .equ TCCROA=0x24
                  .equ TCCROB=0x25
                  .equ TCNT0 =0x26
                  .equ OCROA =0x27
                  .equ OCROB =0x28
                  .equ GPIOR1=0x2A
                  .equ GPIOR2=0x2B
                  .equ SPCR  =0x2C
                  .equ SPSR  =0x2D
                  .equ SPDR  =0x2E
                  .equ ACSR  =0x30
                  .equ SMCR  =0x33
                  .equ MCUSR =0x34
                  .equ MCUCR =0x35    
                  .equ SPMCSR=0x37
                  .equ SPL   =0x3D
                  .equ SPH   =0x3E
                  .equ SREG  =0x3F
          
                  .equ WDTCSR=0x60    ; sts,lds
                  .equ CLKPR =0x61
                  .equ PRR   =0x64
                  .equ OSCCAL=0x66
                  .equ PCICR =0x68
                  .equ EICRA =0x69
                  .equ PCMSK0=0x6B
                  .equ PCMSK1=0x6C
                  .equ PCMSK2=0x6D
                  .equ TIMSK0=0x6E
                  .equ TIMSK1=0x6F
                  .equ TIMSK2=0x70
                  .equ ADCL  =0x78
                  .equ ADCH  =0x79
                  .equ ADCSRA=0x7A
                  .equ ADCSRB=0x7B
                  .equ ADMUX =0x7C
                  .equ DIDR0 =0x7E
                  .equ DIDR1 =0x7F
                  .equ TCCR1A=0x80
                  .equ TCCR1B=0x81
                  .equ TCCR1C=0x82
                  .equ TCNT1L=0x84
                  .equ TCNT1H=0x85
                  .equ ICR1L =0x86
                  .equ ICR1H =0x87
                  .equ OCR1AL=0x88
                  .equ OCR1AH=0x89
                  .equ OCR1BL=0x8A
                  .equ OCR1BH=0x8B
                  .equ TCCR2A=0xB0
                  .equ TCCR2B=0xB1
                  .equ TCNT2 =0xB2
                  .equ OCR2A =0xB3
                  .equ ASSR  =0xB6
                  .equ TWBR  =0xB8
                  .equ TWSR  =0xB9
                  .equ TWAR  =0xBA
                  .equ TWDR  =0xBB
                  .equ TWCR  =0xBC
                  .equ TWAMR =0xBD
                  .equ UCSR0A=0xC0
                  .equ UCSR0B=0xC1
                  .equ UCSR0C=0xC2
                  .equ UBRR0L=0xC4
                  .equ UBRR0H=0xC5
                  .equ UDR0  =0xC6
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
                  .cseg           ; Start of code segment
                  .org 0x0000     ; interrupts, highest priority first
                  jmp RESET       ; 3 Reset Handler
                  jmp EXT_INT0    ; 3 IRQ0 Handler
                  jmp EXT_INT1    ; 3 IRQ1 Handler
                  jmp PCINT0      ; 3 PCINT0 Handler
                  jmp PCINT1      ; 3 PCINT1 Handler
                  jmp PCINT2      ; 3 PCINT2 Handler
                  jmp WDT         ; 3 Watchdog Timer Handler
                  jmp TIM2_COMPA  ; 3 Timer2 Compare A Handler
                  jmp TIM2_COMPB  ; 3 Timer2 Compare B Handler
                  jmp TIM2_OVF    ; 3 Timer2 Overflow Handler
                  jmp TIM1_CAPT   ; 3 Timer1 Capture Handler
                  jmp TIM1_COMPA  ; 3 Timer1 Compare A Handler
                  jmp TIM1_COMPB  ; 3 Timer1 Compare B Handler
                  jmp TIM1_OVF    ; 3 Timer1 Overflow Handler
                  jmp TIM0_COMPA  ; 3 Timer0 Compare A Handler
                  jmp TIM0_COMPB  ; 3 Timer0 Compare B Handler
                  jmp TIM0_OVF    ; 3 Timer0 Overflow Handler
                  jmp SPI_STC     ; 3 SPI Transfer Complete Handler
                  jmp USART_RXC   ; 3 USART, RX Complete Handler
                  jmp USART_UDRE  ; 3 USART, UDR Empty Handler
                  jmp USART_TXC   ; 3 USART, TX Complete Handler
                  jmp ADC_DONE    ; 3 ADC Conversion Complete Handler
                  jmp EE_RDY      ; 3 EEPROM Ready Handler
                  jmp ANA_COMP    ; 3 Analog Comparator Handler
                  jmp TWI         ; 3 2-wire Serial Interface Handler
                  jmp SPM_RDY     ; 3 Store Program Memory Ready Handler
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          RESET:  cli             ; Reset Handler
                  ldi  r16,high(stack)
                  out  SPH,r16
                  ldi  r16,low(stack)
                  out  SPL,r16
          
                  ldi  r16, 0xFF  ; DDRB 1 - output, 0 - input direction
                  out  DDRB, r16
                  ldi  r16, 0xFF  ; DDRC 1 - output, 0 - input direction
                  out  DDRC, r16
                  ldi  r16, 0xFF  ; DDRD 1 - output, 0 - input direction
                  out  DDRD, r16
          
                  ldi  r16, 0xFF  ; all outputs high,and all inputs Pull Up to Ucc
                  out  PORTB,r16
                  out  PORTC,r16
                  out  PORTD,r16
                  jmp  main
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          EXT_INT0:               ; IRQ0 Handler
                  reti
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          EXT_INT1:               ; IRQ1 Handler
                  reti
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          PCINT0:                 ; PCINT0 Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          PCINT1:                 ; PCINT1 Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          PCINT2:                 ; PCINT2 Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          WDT:                    ; Watchdog Timer Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM2_COMPA:             ; Timer2 Compare A Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM2_COMPB:             ; Timer2 Compare B Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM2_OVF:               ; Timer2 Overflow Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM1_CAPT:              ; Timer1 Capture Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM1_COMPA:             ; Timer1 Compare A Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM1_COMPB:             ; Timer1 Compare B Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM1_OVF:               ; Timer1 Overflow Handler 
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM0_COMPA:             ; Timer0 Compare A Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM0_COMPB:             ; Timer0 Compare B Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TIM0_OVF:               ; Timer0 Overflow Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          SPI_STC:                ; SPI Transfer Complete Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          USART_RXC:              ; USART, RX Complete Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          USART_UDRE:             ; USART, UDR Empty Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          USART_TXC:              ; USART, TX Complete Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ADC_DONE:               ; ADC Conversion Complete Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          EE_RDY:                 ; EEPROM Ready Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ANA_COMP:               ; Analog Comparator Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          TWI:                    ; 2-wire Serial Interface Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          SPM_RDY:                ; Store Program Memory Ready Handler
                  reti            ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          main:   ldi  r16,0
          
          main0:  out  PORTC,r16  ; 1 8T / 8MHz = 1MHz PC0, 0.5MHz PC1, ...
                  inc  r16        ; 1
                  nop             ; 1
                  nop             ; 1
                  nop             ; 1
                  nop             ; 1
                  rjmp main0      ; 2
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
          waitms: push r31        ; 2 wait cca r31 [ms] +(15+r31*4)T
                  push r30        ; 2
                  push r29        ; 2
          waitms2:ldi  r30,cpuclk/200000;1 1ms
          waitms1:ldi  r29,49     ; 1     200T
          waitms0:nop             ; 1
                  dec  r29        ; 1
                  brne waitms0    ; 2/1
                  dec  r30        ; 1
                  brne waitms1    ; 2/1
                  dec  r31        ; 1
                  brne waitms2    ; 2/1
                  pop  r29        ; 2
                  pop  r30        ; 2
                  pop  r31        ; 2
                  ret             ; 4
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;; ID: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;; end. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          

          这是我当时用于这些设备的标准模板...看看它等待尽可能接近waitms的{​​{1}}子程序。存在指令的时序,并且条件指令在该芯片上具有不同的时序。由于ATMega328具有相同的内核,因此您的芯片也是如此。

          用C ++中的Oscilloscope He我的ATMega模拟器仍适用于Win7 ...(写于w9x或w2k现在还不确定)(与我公布的源代码编译的十六进制一起使用)。

          emulator