📄 lab3_solution.c
字号:
#include <delays.h>#pragma romdata CONFIG_CONFIG_DECL (_OSC_HS_1H & _OSCS_OFF_1H, _PWRT_OFF_2L & _BOR_OFF_2L, _WDT_OFF_2H, _CONFIG3L_DEFAULT, _CCP2MUX_OFF_3H, _LVP_OFF_4L, _CONFIG5L_DEFAULT, _CONFIG5H_DEFAULT, _CONFIG6L_DEFAULT, _CONFIG6H_DEFAULT, 0xFF, _CONFIG7H_DEFAULT);#pragma romdatavoid tmr2 (void);void button (void);#pragma code high_vector_section=0x8voidhigh_vector (void){_asm GOTO button _endasm}#pragma code#pragma code low_vector_section=0x18voidlow_vector (void){_asm GOTO tmr2 _endasm}#pragma codevolatile unsigned s_cur_ad_val;int count = 0;volatile enum{ DIR_LEFT = 0, DIR_RIGHT } direction;#pragma interruptlow tmr2voidtmr2 (void){ /* clear the timer interrupt flag */ PIR1bits.TMR2IF = 0; /* if we've reached the repeat count, update the LEDs */ if (count++ < s_cur_ad_val) return; else count = 0; if (direction == DIR_LEFT) { _asm rlncf PORTD, 1, 0 _endasm } else { _asm rrncf PORTD, 1, 0 _endasm }}#pragma interrupt buttonvoidbutton (void){ direction = !direction; /* store the new direction in EEDATA. Note that since we're already in the high priority interrupt, we don't need to explicitly enable/disable interrupts around the write cycle */ EEADR = 0; EEDATA = direction; EECON2 = 0x55; EECON2 = 0xaa; EECON1bits.WR = 1; while (!PIR2bits.EEIF) ; PIR2bits.EEIF = 0; /* clear the interrupt flag */ INTCONbits.INT0IF = 0;}voidmain (void){ /* The first thing to do is to read read the start direction from data EEPROM. */ EEADR = 0; EECON1bits.EEPGD = 0; /* point to EEDATA */ EECON1bits.WREN = 1; /* enable EEDATA writes */ EECON1bits.RD = 1; direction = EEDATA; /* Make all bits on the Port D output bits for the LEDs */ TRISD = 0; /* Make PORTA RA0 input, for the A/D converter */ TRISAbits.TRISA0 = 1; /* PORTB RB0 input for the button */ TRISBbits.TRISB0 = 1; /* Reset Port D. Set just one bit to on. */ PORTD = 1; /* Enable interrupt priority */ RCONbits.IPEN = 1; /* clear the peripheral interrupt flags */ PIR1 = 0; /* enable the timer interrupt */ PIE1bits.TMR2IE = 1; IPR1bits.TMR2IP = 0; /* Set the button on RB0 to trigger an interrupt. it's always high priority */ INTCONbits.INT0IE = 1; /* configure the ADC, most of this is the default settings: Fosc/32 AN0 Analog, AN1-15 Digital Channel zero Interrupt disabled Internal voltage references An equivalent setup using the ADC library would be: OpenADC (ADC_FOSC_32 & ADC_LEFT_JUST & ADC_1ANA, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS ); */ /* FOSC/32 clock select */ ADCON2bits.ADCS0 = 1; ADCON2bits.ADCS1 = 1; ADCON2bits.ADCS2 = 1; ADCON2bits.ADCS2 = 1; /* AN0-15, VREF */ ADCON1 = 0b00001110; /* enable interrupts */ INTCONbits.GIEH = 1; INTCONbits.GIEL = 1; /* turn on the ADC */ ADCON0bits.ADON = 1; /* enable the timer */ T2CONbits.TMR2ON = 1; /* start the ADC conversion */ while (1) { /* Give the ADC time to get ready. */ Delay100TCYx (2); /* start the ADC conversion */ ADCON0bits.GO = 1; while (ADCON0bits.GO) ; s_cur_ad_val = ADRES; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -