PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 08, 2004 3:26 pm |
|
|
I have posted the ADC #define statements for the 16F676, and
some sample compiled code, with the .LST file below. You can
use this to write your own functions for the ADC. Compare the
ASM code from your functions to the ASM code below, to make
sure that your functions are written corrrectly. (This code was
generated by PCM vs. 3.184, so hopefully it is correct).
You will have to look up the correct addresses for the registers,
(such as ADRESH, etc.) from the data sheet and use #byte
statements to define their addresses.
Code: | // ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used in SETUP_ADC_PORTS() are:
// or together any combination
// of the sANx constants with one
// of the others.
#define sAN0 1 //| A0
#define sAN1 2 //| A1
#define sAN2 4 //| A2
#define sAN3 8 //| A4
#define sAN4 16 //| C0
#define sAN5 32 //| C1
#define sAN6 64 //| C2
#define sAN7 128 //| C3
#define NO_ANALOGS 0 // None
// The following may be OR'ed in with the above using |
#define VSS_VDD 0x8000 // Range 0-Vdd
#define VREF_VREF 0x9000 // Range VrefL-VrefH
#define VRL_VRH 0xA000 // Range Vrl-Vrh
#define VSS_VREF 0xB000 // Range 0-VrefH
#define VSS_VRH 0xC000 // Range 0-Vrl
#define VREF_VDD 0xD000 // Range VrefL-Vdd
#define VRL_VDD 0xE000 // Range Vrl-Vdd
#define VSS_VRL 0xF000 // Range 0-Vrl
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 1
#define ADC_CLOCK_DIV_4 0x41
#define ADC_CLOCK_DIV_8 0x11
#define ADC_CLOCK_DIV_32 0x21
#define ADC_CLOCK_DIV_16 0x51
#define ADC_CLOCK_DIV_64 0x61
#define ADC_CLOCK_INTERNAL 0x31 // Internal 2-6us
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6
|
Code: | .................... void main()
.................... {
0004: CLRF FSR
0005: MOVLW 1F
0006: ANDWF STATUS,F
0007: BSF STATUS.5
0008: CLRF ANSEL
0009: MOVLW 07
000A: BCF STATUS.5
000B: MOVWF ADCON0
....................
.................... int16 result;
....................
.................... setup_comparator(NC_NC_NC_NC);
000C: MOVLW 07
000D: MOVWF TXREG
000E: BSF STATUS.5
000F: MOVF TRISA,W
0010: MOVLW 03
0011: BCF STATUS.5
0012: MOVWF @57
0013: DECFSZ @57,F
0014: GOTO 013
0015: MOVF TXREG,W
0016: BCF PIR1.3
....................
.................... setup_adc_ports(sAN0 | VSS_VDD);
0017: MOVLW 01
0018: BSF STATUS.5
0019: MOVWF ANSEL
.................... setup_adc(ADC_CLOCK_INTERNAL);
001A: BCF STATUS.5
001B: BSF ADCON0.0
001C: BCF ADCON0.7
001D: BSF STATUS.5
001E: MOVF ADCON1,W
001F: ANDLW 8F
0020: IORLW 30
0021: MOVWF ADCON1
.................... set_adc_channel(0);
0022: MOVLW 00
0023: BCF STATUS.5
0024: MOVWF @58
0025: MOVF ADCON0,W
0026: ANDLW C3
0027: IORWF @58,W
0028: MOVWF ADCON0
.................... result = read_adc();
0029: BSF ADCON0.1
002A: BTFSC ADCON0.1
002B: GOTO 02A
002C: MOVF ADRESH,W
002D: CLRF result+1
002E: MOVWF result
....................
.................... while(1);
002F: GOTO 02F
.................... } |
Edited: The compiler was wrongly putting in the symbol name SSPCON2
when it should have used ANSEL. I changed it to use the correct symbol.
I also added the setup_comparator() function. |
|