attiny13 плохой МК.
1- Мало выводов (светодиоды 8 шт. не подключишь).
2- Данные АЦП можно передавать на компьютер (программа терминал) по UART. Но в attiny13 нет UART. Там вообще ничего нет))
Все МК AVR имеют АЦП 10-бит (
1111111111):
Вложение:
Screenshot_1.jpg [112.77 KiB]
Скачиваний: 129
В одном регистре 8 бит.
Чтоб запихнуть 10 бит сделали два регистра:
ADCH // 000000
11 - старший регистр АЦП - сюда записываются 2 старших бит АЦП.
ADCL //
11111111 - младший регистр АЦП - сюда записываются 8 младших бит АЦП.
В сумме два эти регистра (ADCH + ADCL) содержат 10 бит:
11 (2 бита) +
1111 1111 (8 бит) =
1111111111 (10 бит).
в объединенном регистре ADCW =
1111111111 (10 бит).
Какие светодиоды зажгутся? Зажгутся Младшего регистра:
PORTD=ADCW; // ADCL =
11111111 - младший регистр АЦП - сюда записываются 8 младших бит АЦП.
Добавлено after 28 minutes 46 seconds:Чтоб зажечь все 10-бит (1111111111) надо припаять ещё 2 светодиода на другой порт.
Например в ATmega128 есть свободный порт А.
Код будет такой:
ISR(ADC_vect) //Прерывание по АЦП
{
// Крутим резистор
// Выводим ADCL в порт D
PORTD=ADCL;
// Выводим ADCH в порт A
PORTA=ADCH;
}
//Зажгли все 10-бит (1111111111) АЦП. ))
Или можно так:
ISR(ADC_vect) //Прерывание по АЦП
{
// Крутим резистор
// Выводим ADCW в младшие 8 бит в порт D
PORTD=ADCW;
// Выводим ADCW в старшие 2 бит в порт A
PORTA=ADCW >> 8;
}
//Зажгли все 10-бит (1111111111) АЦП. ))
P.S.
Если читать два регистра (ADCH + ADCL) по отдельности, то при чтении всегда надо первым читать младший регистр (ADCL).
Об этом написано в даташите подробно. Там хитрая система чтения регистров (эти два регистра связаны между собой внутри МК).
Поэтому проще читать "бъединенный регистр ADCW".
На самом деле это никакой не "бъединенный регистр ADCW", это два отдельных регистра, просто компилятор думает что это один регистр "бъединенный регистр ADCW". ))
Добавлено after 26 minutes 52 seconds:Но сначала надо правильно настроить АЦП.
Вот полный список всех битов настройки и флагов АЦП (всего два регистра настройки):
----------
ADMUX=0b01100001; // настройка АЦП
----------
//ADMUX
//1... .... REFS1 - опорное напряжение - 0
//.1.. .... REFS0 - опорное напряжение - 1 - AVCC
//..1. .... ADLAR - Выравнивание результата
//...1 .... -
//.... 1... MUX3 - номер канала
//.... .1.. MUX2 - номер канала
//.... ..1. MUX1 - номер канала
//.... ...1 MUX0 - номер канала - ADC0...ADC7 (0000=ADC0)
----------
//REFS1=0 REFS0=0 - ИОН=AREF
//REFS1=0 REFS0=1 - ИОН=AVCC
//REFS1=1 REFS0=0 - не используется (зарезервировано)
//REFS1=1 REFS0=1 - ИОН=2.56V (встроенный ИОН 2.56V)
----------
//ADLAR=1
// Выравнивание результата в левую сторону < (8-бит):
// ADCH // 1111 1111 - читать вторым (или первым, тогда последии 2 бит потеряем)
// ADCL // 0000 0011 - читать первым
//ADLAR=0
// Выравнивание результата в правую сторону > (10-бит):
// ADCH // 0000 0011 - читать вторым
// ADCL // 1111 1111 - читать первым
----------
// MUX3...MUX0 - номер канала:
// 0000 - ADC0
// 0001 - ADC1
// .................
// 0111 - ADC7
// 1110 - ИОН (1,23V) !
----------
ADCSRA|=0b01000000; // Старт АЦП.
----------
//ADCSRA
//1... .... ADEN - 1- вкл ADC. (0-ADC не потребляет мощности)
//.1.. .... ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
//..1. .... ADFR - 1- режим Непрерывного Преобразования.
//...1 .... ADIF - 1- флаг завершения преобразования
-сброс программно.
-для прерывания очищается аппаратно.
//.... 1... ADIE - 1- Разрешение прерывания
//.... .1.. ADPS2 - предделитель
//.... ..1. ADPS1 - предделитель
//.... ...1 ADPS0 - предделитель
предделитель ADC:
ADPS2 -ADPS1 -ADPS0
----------
// 000: 1 МГц/2=500.000 Hz
// 001: 1 МГц/2=500.000 Hz
// 010: 1 МГц/4=250.000 Hz
// 011: 1 МГц/8=125.000 Hz
// 100: 1 МГц/16=62.500 Hz
// 101: 1 МГц/32=31.250 Hz
// 110: 1 МГц/64=15.625 Hz
// 111: 1 МГц/128=7.812,5 Hz
----------
Выбираем режим работы АЦП...
Частоту преобразования...
Выравнивание результата...
Источник опорного напряжения...
Канал (мультиплексор)...
После пишем программу))
Добавлено after 23 minutes 22 seconds:Вот сама программа (для mega8):
Прерывание я не использую.
----------
#include <mega8.h>
#include <delay.h>
unsigned int u; // переменная для АЦП
// функция АЦП: -время одного преобразования АЦП = 0,000.070c
void adc(unsigned char adc_input)
{
ADMUX = 0b01000000 | adc_input; // Опорное напряжение АЦП = AVCC // канал АЦП = ADC0...ADC7
delay_us(10); // Стабилизация входа...
ADCSRA|=0b01000000; // Старт преобразования АЦП...
while (ADCSRA & 0b01000000); // Ждём окончания преобразования АЦП...
//При завершении преобразования этот бит сбрасывается аппаратно.
}
// главная функция
void main(void)
{
// Настройка PORTD:
DDRD = 0xFF; // PORTD
PORTD = 0x00; // PORTD
// Настройка АЦП:
ADCSRA=0x84; // вкл. АЦП // Режим одиночного преобразования // Частота преобразования = 4 МГц/16=250.000 Hz
while (1)
{
// запускаем одиночное преобразование АЦП (канал 5):
adc(5); a=ADCW;
// выводим значение АЦП в PORTD
PORTD = a;
// ждём 1 секунду...
delay_ms(1000);
};
}
----------
Светодиоды показывают напряжение на входе АЦП (ножка PC5). Обновление каждую секунду.
Всё))