Я пробую программировать ЦАП DAC8512F с помощью SPI порта контроллера ATMega168 (кварц 20 МГц).
ЦАП подключен к контроллеру следующим образом:
19 ножка МК (PB5/SCK) - 3 ножка ЦАПа CLK;
18 ножка МК (PB4/MISO) - 5 ножка ~LD;
17 ножка МК (PB3/MOSI) - 4 ножка SDI;
16 ножка МК (PB2/~SS) - 2 ножка ~CS;
15 ножка МК (PB1) - 6 ножка ~CLR;
8 ножка ЦАП +5В;
7 ножка ЦАП GND.
В итоге после выполнения программы (приведена ниже) на выходе ЦАПа устанавливается 0 В, а не требуемые 100 мВ. НО после того как я тестером в режиме измерения напряжения ткну в ножку ~LD ИЛИ ножку 18 МК, на выходе ЦАПа устанавливается требуемое значение. В чем может быть проблема? почему данные в регистр ЦАПа не поступают автоматически?? Спасибо за помощь! Проблема наверняка какая нибудь не сложная. Но к сожалению не могу в ней разобраться.
Программа:
CODE
#define DACDEFAULT 100
int main(void)
{
WDT_off(); // Отключаем сторожевой таймер
IO_conf(); // Конфигурируем порты
_delay_us(5); // Ждем 5 мкс
SPI_init(); // Инициализируем SPI
_delay_us(5); // Ждем 5 мкс
DAC_erase();
_delay_us(5); // Ждем 5 мкс
DAC_prog(DACDEFAULT); // Программируем ЦАП на 100 мВ
}
/* Часть программы SPI */
void SPI_init(void)
{
//Устанавливаем SPI в режиме мастера, SCL отрицательной полярности
//Скорость FCK/64, обработка сигнала по нарастающему фронту SCL
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1);
}
void SPI_Transmit(char cData) // Передача числа 8 бит
{
// Начать передачу
SPDR = cData;
// Ожидаем завершения передачи
while(!(SPSR & (1<<SPIF)));
}
/*Инициализация ножек МК*/
void IO_conf(void)
{
// Конфигурация порта B: Выводы 1-5 на выход xx11 1110
DDRB =(1<<DDB5)|(1<<DDB4)|(1<<DDB3)|(1<<DDB2)|(1<<DDB1);
// CS ЦАП PB2=1 (Не выбран),
//CLR ЦАП PB1=1 (Нет очистки),
PORTB |= (1<<PB4)|(1<<PB2)|(1<<PB1);
}
/* Программирование ЦАП */
void DAC_prog(unsigned int dacData)
{
DAClevelH = (unsigned char) dacData>>8;
DAClevelL = (unsigned char) dacData;
PORTB |= (1<<PB4);
_delay_us(5);
//Выбираем ЦАП с помощью CS - логический 0
PORTB &= ~(1<<PB2);
_delay_us(5);
//Записываем данные в ЦАП
SPI_Transmit(DAClevelH); // Ожидание завершения передачи прописано в функции
SPI_Transmit(DAClevelL); // Ожидание завершения передачи прописано в функции
//Возвращаем CS в состояние логической 1
_delay_us(5); // Ждем 5 мкс
PORTB |= (1<<PB2);
_delay_us(5); // Ждем 5 мкс
//Переносим данные из сдвигового регистра в регистр ЦАП - лог 0
PORTB &= ~(1<<PB4);
_delay_ms(1); // Ждем 5 мкс
PORTB |= (1<<PB4);
_delay_us(5); // Ждем 5 мкс
}
/* Стираем ЦАП */
void DAC_erase(void)
{
PORTB |= (1<<PB4);
_delay_us(5);
PORTB &= ~(1<<PB1);
_delay_ms(1); // Ждем 1 мс
//Возвращаем CLR в состояние - логическая 1
PORTB |= (1<<PB1);
_delay_us(30); // Ждем 30 мкс
}
int main(void)
{
WDT_off(); // Отключаем сторожевой таймер
IO_conf(); // Конфигурируем порты
_delay_us(5); // Ждем 5 мкс
SPI_init(); // Инициализируем SPI
_delay_us(5); // Ждем 5 мкс
DAC_erase();
_delay_us(5); // Ждем 5 мкс
DAC_prog(DACDEFAULT); // Программируем ЦАП на 100 мВ
}
/* Часть программы SPI */
void SPI_init(void)
{
//Устанавливаем SPI в режиме мастера, SCL отрицательной полярности
//Скорость FCK/64, обработка сигнала по нарастающему фронту SCL
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1);
}
void SPI_Transmit(char cData) // Передача числа 8 бит
{
// Начать передачу
SPDR = cData;
// Ожидаем завершения передачи
while(!(SPSR & (1<<SPIF)));
}
/*Инициализация ножек МК*/
void IO_conf(void)
{
// Конфигурация порта B: Выводы 1-5 на выход xx11 1110
DDRB =(1<<DDB5)|(1<<DDB4)|(1<<DDB3)|(1<<DDB2)|(1<<DDB1);
// CS ЦАП PB2=1 (Не выбран),
//CLR ЦАП PB1=1 (Нет очистки),
PORTB |= (1<<PB4)|(1<<PB2)|(1<<PB1);
}
/* Программирование ЦАП */
void DAC_prog(unsigned int dacData)
{
DAClevelH = (unsigned char) dacData>>8;
DAClevelL = (unsigned char) dacData;
PORTB |= (1<<PB4);
_delay_us(5);
//Выбираем ЦАП с помощью CS - логический 0
PORTB &= ~(1<<PB2);
_delay_us(5);
//Записываем данные в ЦАП
SPI_Transmit(DAClevelH); // Ожидание завершения передачи прописано в функции
SPI_Transmit(DAClevelL); // Ожидание завершения передачи прописано в функции
//Возвращаем CS в состояние логической 1
_delay_us(5); // Ждем 5 мкс
PORTB |= (1<<PB2);
_delay_us(5); // Ждем 5 мкс
//Переносим данные из сдвигового регистра в регистр ЦАП - лог 0
PORTB &= ~(1<<PB4);
_delay_ms(1); // Ждем 5 мкс
PORTB |= (1<<PB4);
_delay_us(5); // Ждем 5 мкс
}
/* Стираем ЦАП */
void DAC_erase(void)
{
PORTB |= (1<<PB4);
_delay_us(5);
PORTB &= ~(1<<PB1);
_delay_ms(1); // Ждем 1 мс
//Возвращаем CLR в состояние - логическая 1
PORTB |= (1<<PB1);
_delay_us(30); // Ждем 30 мкс
}