AlexBi (12.11.2008 16:17, просмотров: 5674)
Наткнулся на проблему в работе АЦП у PIC24HJ256GP206. Проблема проявляется при переходе из режима автосамплинга в режим без автосамплинга. При этом первое преобразование делается не для выбранного канала, а для автосамплированного. Вот такую программу я написал для обнаружения проблемы:
int main()
{
unsigned volatile i;
// настройка PLL
PLLFBD=30; // M=32
CLKDIVbits.PLLPOST=3; // N1=8
CLKDIVbits.PLLPRE=0; // N2=2
__builtin_write_OSCCONH(0b011); // initiate switch to new clk source
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.OSWEN) continue; // wait switch end
_ADON=0;
AD1CON1bits.ADDMABM=1; // 1 = DMA buffers are written in the order of conversion.
AD1CON1bits.AD12B=1; // 12-bit, 1-channel A/D operation
AD1CON3bits.ADCS=200/*ns*//100-1; // TAD = 200ns
AD1CON3bits.SAMC=6; // Auto Sample Time bits = 6 * TAD
// Настройка на работу без автосамплинга
AD1CON1bits.ASAM=0; // 1 = Sampling begins immediately after last conversion. SAMP bit is auto-set.
AD1CON1bits.SSRC=7; // 111 = Internal counter ends sampling and starts conversion (auto-convert)
_ADON=1;
// Включение АЦП в работу без автосамплинга перед переключением в автосамплинг
// важно, иначе проблема не проявляется
// Настройка на работу с автосамплингом и выбор канала AN12
_ADON=0;
AD1CON1bits.ASAM=1; // 1 = Sampling begins immediately after last conversion. SAMP bit is auto-set.
AD1CON1bits.SSRC=2; // 2 = GP timer (Timer3 for ADC1, Timer5 for ADC2) compare ends sampling and starts conversion
_CH0SA=12;
_ADON=1;
// Здесь можно использовать АЦП, а можно и просто подождать
// Наличие задержки важно, иначе проблема не проявляется
for(i=0; i<100; ++i) {}
// Настройка на работу в режим без автосамплинга
_ADON=0;
AD1CON1bits.ASAM=0; // 1 = Sampling begins immediately after last conversion. SAMP bit is auto-set.
AD1CON1bits.SSRC=7; // 111 = Internal counter ends sampling and starts conversion (auto-convert)
_ADON=1;
// Запуск измерения в канале AN15
_DONE=0;
_CH0SA=15;
_SAMP=1;
do { } while( _DONE==0 ); // Ожидание окончания преобразования
i=ADC1BUF0; // Полученный результат соответствует каналу из автоскана
__builtin_nop();
__builtin_nop();
__builtin_nop();
// Еще раз измеряется тот же канал AN15
_DONE=0;
_CH0SA=15;
_SAMP=1;
do { } while( _DONE==0 ); // Ожидание окончания преобразования
i=ADC1BUF0; // А теперь результат правильный
__builtin_nop();
__builtin_nop();
__builtin_nop();
while(1){};
}