Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Xmega ADC

Сообщений 1 страница 8 из 8

1

Это точно требует отдельной темы, в Xmega с ADC не всё так просто.
Первое, что оказалось проблемой - максимум опорное напряжение 1,6в., даже если использовать AREF и подать на него 3,3в., всё равно ничего не получится.
Чистого нуля по АЦП тоже нет.
Аналог инициализации Atmega в Xmega будет примерно такой:

Код:
Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 512 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B0_0000_000


Для получения данных:
W = Getadc(adca , 0 , &B0_0000_000 )

Где:
adca - входы порта А, входы порта B - типа того
0 - Номер используемого канала
&B0_0000_000 - а это понимать вот так:

0000 Pin0 ADC0
0001 Pin1
0010 Pin2
0011 Pin3
0100 Pin4
0101 Pin5
0110 Pin6
0111 Pin7
1000 Pin8
1001 Pin9
1010 Pin10
1011 Pin11
1100 Pin12
1101 Pin13
1110 Pin14
1111 Pin15 ADC15

Для получения данных с АЦП можно и так:
ADC0 = Getadc(adca , 0 , &B0_0000_000 )
ADC1 = Getadc(adca , 0 , &B0_0001_000 )
ADC2 = Getadc(adca , 0 , &B0_0010_000 )

Но вот не задача, начальное значение 9-11.
Тут то и беда, к Xmega чего-то замутили с DAC и какой-то калибровкой чего-то.
Есть у кого информация, как можно просто оцифровать аналоговый сигнал?

Отредактировано Ev3658 (2017-12-24 15:06:37)

0

2

Есть ещё один не понятный случай.
У меня срабатывает прерывание по INT0 порта С по смене значения любого ADC, не могу понять причину, условие прерывания не выполняется точно, а вот само прерывание срабатывает.

Код:
$regfile = "xm256a3def.dat"
$crystal = 33177600
$hwstack = 225
$swstack = 225
$framesize = 225

$lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014


Config Osc = Enabled , Extosc = Enabled , Pllosc = Enabled , _
Range = 2mhz_9mhz , Startup = Xtal_1kclk , Pllsource = Extclock , Pllmul = 9 , Plldiv2 = Disabled , 32khzosc = Disabled       ', 32khzpowermode = Normal
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1
Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled

'============== АЦП
Config Adca = Single , Convmode = Unsigned , Resolution = 8bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 512 , _
Ch0_gain = 4 , Ch0_inp = Single_ended , Mux0 = &B0_0011_000
Config Pina.3 = Input
Config Pina.4 = Input
Config Pina.5 = Input

'Порт матрицы клавиатуры (перебор)
Portkn Alias Portd
Config Portkn = Output
Config Xpin = Portd , Slewrate = Enabled , Outpull = Pulldown      ' (по порядку: , ограничение скорости порта, порт подтянуть к минусу)

'Порт проверка срабатывания кнопок матрицы
Pinkn Alias Pinc
Config Portc = Input 
Config Xpin = Pinc , Outpull = Pulldown , Slewrate = Enabled , Sense = Rising '(по порядку: Подтянуть к минусу, ограничить скорость порта, вызывать событие по подъёму фронта)
Portc_int0mask = &B0111_1111 'Маска прерывания порта C (7 бит это выход)

'Порт свечения светодиодов, чтоб ноги лишние не тратить, светодиоды сидят на матрице клавиатуры.

Ledkn Alias Portc.7
Config Ledkn = Output
Config Xpin = Portc.7 , Invertio = Enabled 'Аппаратная инверсия пина

'==========Переменные
Dim Knl As Byte
Dim Knh As Byte
Dim Led As Byte
Dim Ledtm As Byte

Dim Spr As Byte
Dim Fpr As Byte
Dim Rfpr As Byte

Portkn = 1 'для сдвига бита

'====== Прерывания 
Config Tcf0 = Normal , Prescale = 256 'Запуская таймер
Tcf0_per = 300 'Ограничиваю счёт

On Tcf0_ovf Knopkitm  'Прерывание по переполнению таймера
Enable Tcf0_ovf
 
On Portc_int0 Knopki 'Прерывание по маске INT0 порта С
Enable Portc_int0 , Lo   'Включаю прерывание с приоритетом выше.

Enable Interrupts


Do
!Nop
Loop

Knopki:
     Knl = Pinkn And &B0111_1111
     Knh = Portkn
     Portc_intflags.0 = 1 'Убираем флаг прерывания, который мог остаться от дребезга
Return

Knopkitm:
        Rotate Portkn , Left   'Сдвигаем бит матрицы клавиатуры
        Ledkn = Led.ledtm 'Зажигаем светодиод если он совпадает с битами матрицы
        If Ledtm < 7 Then 'Ограничиваем счёт битов и одновременно 1 раз за 8 циклов опрашиваем АЦП
          Incr Ledtm
          Else
          Ledtm = 0
          Spr = Getadc(adca , 0 , &B0_0011_000 )
          Fpr = Getadc(adca , 0 , &B0_0100_000 )
          Rfpr = Getadc(adca , 0 , &B0_0101_000 )
        End If
Return


Так вот, прерывание INT0 срабатывает не по условию, так как Knl = Pinkn And &B0111_1111 - равно нулю в момент ложного прерывания.

Либо каким-то образом АЦП влияет на маску прерывания порта, либо чего-то не то.

Отредактировано Ev3658 (2017-12-24 15:06:00)

0

3

Буду рад любой информации по ADC Xmega, мне до лета надо провести ряд удачных экспериментов и создать кисть руки, которая будет сжиматься от импульсов нервных окончаний, а тут без АЦП и производительности Xmega вообще никак.

0

4

Вечером постараюсь не забыть глянуть код, но я другим занимался, пытался в реалтайме звук обрабатывать. На счет встроенного АЦП не помню, возился или нет, но ЦАП точно пробовал, играл неплохо, там правда есть тоже ряд настроек, сильно влияющих на конечный результат.

0

5

Это точно, не пойму вот одно, есть процесс калибровки АЦП или ЦАП - он обязателен или нет, ведь в контроллере записано изготовителем какое-то эталонное значение и типа его надо загружать куда-то.

0

6

Насколько я помню, вроде бы надо прочитать эту таблицу и от туда, записать значения в АЦП/ЦАП.

https://www.mcselec.com/index2.php?opti … +calibrate

0

7

И точно, оказывается калибровочное значение не только в Xmega но и в Mega328p! Не знал даже.

Код:
var = READSIG(offset)

Но это не дало эталонный нуль:

Код:
Adca_call = Readsig(&H20 )
Adca_calh = Readsig(&H21 )

Отредактировано Ev3658 (2017-12-25 18:45:27)

0

8

Ну, тогда надо читать про калибровку, а вообще проверь питание на предмет помехов и входящий сигнал.

0