⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc_driver.s

📁 AVR单片机做的两轮自平衡机器人
💻 S
字号:
#define ENABLE_BIT_DEFINITIONS
#define	__SFR_OFFSET 0       	/* GCC 3.2 needs this for direct low I/O access */
#include <avrx-io.h>
#include <avrx-signal.h>
#include <avrx.inc>
/*
 interrupt driven ADC conversion drivers.

 Does continuous conversions of all 8 channels, starting with #7, then
 decrementing to 0 and rolling over to 7 again.

 53 cycles/interrupt.  At 8mhz it is roughly 432/900*8 or ~6% load.

 Uses a 1/64 clock.  On an 8mhz machine each conversion takes roughly
 100us for a total conversion time of ~.9ms or roughly 8% load.

 */
        _MODULE(adc_driver)
        _DATASECTION

        _STATIC(adc_channel, 1)  ; Internal: current channel number
        _STATIC(adc, 16)         ; Results


        _CODESECTION
        _FUNCTION(SIG_ADC)

SIG_ADC:
        push    R28
        in      R28, SREG
        push    R28
        push    R30
        push    R31

        ldi     R30, lo8(adc)
        ldi     R31, hi8(adc)
        lds     R28, adc_channel

        add     R28, R28
        add     R30, R28
        sbci    R31, lo8(-0)    ; Add channel # to index
        in      R28, ADCL
        std     Z+0, R28         ; store ADC results little endien for C
        in      R28, ADCH
        std     Z+1, R28

        lds     R28, adc_channel
        subi    R28, 1          ; If < 0, then wrap to 7
        brcc    continue
        ldi     R28, lo8(7)
continue:
        out     ADMUX, R28
        sts     adc_channel, R28
        sbi     ADCSRA, ADSC     ; Get next channel results
        pop     R31
        pop     R30
        pop     R28
        out     SREG, R28
        pop     R28
        reti
        _ENDFUNC

;
; void ADC_StartConversion(void)
;
; Initializes Channel to 7, then starts a conversion
; Enable the interrupt flag (never disabled afterwards)
;
        _FUNCTION(ADC_Init)

ADC_Init:
        ldi     tmp0, (1<<ADEN) | (1<<ADSC) | (1<<ADPS1) | (1<<ADPS2)
        out     ADCSRA, tmp0
adc0:
        sbic    ADCSRA, ADSC     ; Wait until dummy conversion done.
        rjmp    adc0

        ldi     tmp0, lo8(7)
        sts     adc_channel, tmp0
        out     ADMUX, tmp0
        sbi     ADCSRA, ADSC
        sbi     ADCSRA, ADIE
        ret
        _ENDFUNC
/*
 unsigned short ADC_Channel(unsigned char)

 Atomic read of a word from the ADC data array
*/
        _FUNCTION(GetADC)

GetADC:
        ldi     R30, lo8(adc)
        ldi     R31, hi8(adc)
        add     p1l, p1l
        add     R30, p1l
        sbci    R31, -(0)
        in      tmp0, SREG
        cli
        ldd     p1l, Z+0
        ldd     p1h, Z+1
        out     SREG, tmp0
        ret
        _ENDFUNC
        _END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -