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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Разное » Считывание ПЗС линейки


Считывание ПЗС линейки

Сообщений 31 страница 60 из 61

31

Забыл ещё сказать, что таймер настроен на 2МГц, но т.к. за 1 вызов прерывания происходит только смена состояния 1 или 0, то частота периода будет 1МГц. Что бы было именно 2МГц, нужно чтобы таймер срабатывал в 2 раза быстрее (каждые 4МГц).

0

32

Попробовал сосчитать данные с матрицы,что-то не получается... Считывается всегда значение ацп 4096,матрица подключена согласно даташиту. Помогите разобраться пожалуйста,сам пробовал - не получается. Код прилагаю.

Код:
$regfile = "xm256a3def.dat"
$crystal = 32000000                                         '32MHz
$hwstack = 64
$swstack = 64
$framesize = 64

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

'first enable the osc of your choice
Config Osc = Enabled , 32mhzosc = Enabled

'configure the systemclock
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1

Config Com4 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM4:" For Binary As #1

Dim Adcread As Integer
Dim Adccount As Integer
Dim Incom As String * 4


Config Portc.0 = Output                                     ' M íîæêà äëÿ äåðãàíèÿ

Config Portc.1 = Output
Config Portf.3 = Output

Config Porta.3 = Output
Config Porta.4 = Output

Led1 Alias Portc.1
Led2 Alias Portf.3
Sh Alias Porta.3
Icg Alias Porta.4

Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 4 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = 0

Config Tce0 = Normal , Prescale = 8 , Event_action = Restart , Resolution = 8
On Tce0_ovf Gnrtr
Tce0_per = 2                                                ' 32000000/8(scale) = 4000000/2 = 2MÃö = 500ns
Enable Tce0_ovf , Hi                                        ' âûñòàâëÿåì ïðèîðèòåò ïðåðûâàíèÿ è ðàçðåøàåì
Enable Interrupts

Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Print #1 , "I am run!"

'...
Do
Print #1 , ">_"
Input #1 , Incom , Noecho

 If Incom = "Get" Then                                      'read ccd
 Icg = 0
 Sh = 1
 Waitus 1
 Sh = 0
 Waitus 1
 Icg = 1
 Print #1 , "<"

For Adccount = 0 To 3694 Step 1
If Adccount = 3694 Then
Print #1 , ">"
Print #1 , "Job Done!"

Else
Adcread = Getadc(adca , 2 )
Print #1 , Adcread
End If
Next
 End If

Loop
End
'...

Gnrtr:
Toggle Portc.0
Return

0

33

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

Пайку проверял, схема правильно собрана?

0

34

Схема собрана правильно,все по даташиту. Напряжение питания 3,3В. Пайку в первую очередь проверил. Напряжение меняется на 1-10 значений. Инициализация линейки как по даташиту:

Icg = 0
Sh = 1
Waitus 1
Sh = 0
Waitus 1
Icg = 1
и считываем ацп 3694 раза

А как запустить ацп в режиме free в хмеге и будет ли ацп быстрее в free?

0

35

честно, пока с АЦП не работал, не знаю, но судя по обычным мегам, быстрее не будет, вот если через DMA, то возможно и имеет смысл
есть смысл даже целиком весь пакет 3694 запихнуть SRAM через DMA, вообще будет независимо принимать (аппаратно) и не будет сбивок и прочих переходных процессов

0

36

А просто массивом это все в SRAM можно записать?

0

37

там массив и так получится + если что, то оверлеем можно делать всё? что вздумается (перемешивать любые данные)
есть примеры в баскоме: http://www.mcselec.com/index2.php?optio … ight=xmega

0

38

Изначально и пробовал на базе этого примера все сделать,но что-то не получилось всегда 0 идут.

0

39

Может Вы сможете найти ошибку.

Код:
'----------------------------------------------------------------
'                 (c) 1995-2011, MCS Electronics
'                AD_Free_run_1_channel_DMA________.bas
' sample written by MAK3
'----------------------------------------------------------------

' You need BASCOM-AVR Version 2.0.6.0 to run this example

' We use DMA Channel 0 to transfer the ADC Result Values to SRAM (Array)

' ADC Prescaler = 16 --> 2MHz ADC Clock !

' 1500 Measurement Values (means 3000 Byte of SRAM)


' Configure the ADC of Port A to use 1 Channels with differential Input and with Gain (12-Bit Mode)
' Pina 0 (+) and Pina 4 (-) is used for Channel 0


$regfile = "xm256a3def.dat"
'$regfile = "xm32a4def.dat"
$crystal = 32000000                                         '32MHz
$hwstack = 64
$swstack = 40
$framesize = 40

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

Config Osc = Enabled , 32mhzosc = Enabled
Config Sysclock = 32mhz                                     '--> 32MHz

'Serial Interface to PC
Config Com4 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM4:" For Binary As #1

Config Dp = ","                                             'comma is used as a separator (for FUSING function)
'Config Dp = "."                                   'dot is used as a separator (for FUSING function). You also need to change this "###.#" in the fusing funtion


Print #1 , "--ADC A over DMA in 12-Bit Mode--"

Config Eeprom = Mapped                                      'when using EEPROM , add this config command

Const Mv_per_adc_step = 1.007                               'Vref = 3,3Volt/1,6 = 2,0625/2048 ADC Steps = 1.007

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Const Sample_count = 3694                                   'Number of 12-Bit Samples (Measurement Values)
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Dim Channel_0(sample_count) As Integer                      'Measurement Array for Channel 0
Dim Milli_volt As Single
Dim Dma_ready As Bit
Dim Dma_channel_0_error As Bit
Dim Channel_0_sample_count As Word
Dim X As Word

Dim Adcread As Integer
Dim Adccount As Integer
Dim Incom As String * 4


Config Portc.0 = Output                                     ' M íîæêà äëÿ äåðãàíèÿ

Config Portc.1 = Output
Config Portf.3 = Output

Config Porta.3 = Output
Config Porta.4 = Output

Led1 Alias Portc.1
Led2 Alias Portf.3
Sh Alias Porta.3
Icg Alias Porta.4


' DMA Interrupt
On Dma_ch0 Dma_ch0_int                                      'Interrupt will be enabled with  Tci = XX in Config DMAX
Config Dma = Enabled , Doublebuf = Disabled , Cpm = Ch01rr23       ' enable DMA, Double Buffer disabled

' DMA Channel 0 is used here
Config Dmach0 = Enabled , Burstlen = 2 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , _
 Sar = Burst , Sam = Inc , Dar = None , Dam = Inc , Trigger = &H10 , Btc = 3000 , Repeat = 1 , Sadr = Varptr(adca_ch0_res) , Dadr = Varptr(channel_0(1))


' We use DMA Channel 0
' Burstlen = 2 (We use here 12-Bit Mode so we need 2Bytes from Source Address = ADC A)
' Channelrepeat is enabled

' BTC = 2000 (must be 2X of Sample_count because of 2 Bytes per Measurement Value)

' TCI = Lo --> Low Level Transaction Complete Interrupt is enabled
' EIL = Lo --> Low Level Error Interrupt is enabled

' Sar = Source Address  reloaded after each burst
' Sam = incremented (Low Byte and High Byte of Measurement Value)

' Dar = No Destination address reload
' Dam = inc (Destination Address (the Array) will be incremented by one)

' Trigger (Trigger base value for ADC A = &H10   +    Trigger offset = &H00 for Channel 0 -->  &H10 )


'Configure ADC of Port A in FREE running mode
Config Adca = Free , Convmode = Signed , Resolution = 12bit , Dma = Ch01 , _
 Reference = Intvcc , Event_mode = None , Prescaler = 4 , Sweep = Ch0 , _
 Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B00000000


 ' With MuxX you can set the  MUX-Register
 ' ADCA_CH0_MUXCTRL   (for Channel 0)
 ' ADCA_CH1_MUXCTRL   (for Channel 1)

 ' Mux0 = &B00000000 means:
 ' MUXPOS Bits = 000 --> Pin 0 is positive Input for Channel 0
 ' MUXNEG Bits = 00  --> Pin 4 is negative Input for Channel 0   (Pin 4 because of Differential with gain)

 ' Mux1 = &B00001001 means:
 ' MUXPOS Bits = 001 --> Pin 1 is positive Input for Channel 1
 ' MUXNEG Bits = 01  --> Pin 5 is negative Input for Channel 1   (Pin 5 because of Differential with gain)


 ' Reference Voltage = 3,3 Volt/1.6 = 2.06Volt
 ' Prescaler = 16 --> 32MHz/16 = 2MHz


 ' RES = ((Measurement_Value - Vin Neg)/Reference Voltage )* GAIN * 2048 = z.B. (400mv-0mV)/2062mV)* 1 * 2048 = 397

 Config Tce0 = Normal , Prescale = 8 , Event_action = Restart , Resolution = 16
On Tce0_ovf Gnrtr
Tce0_per = 2                                                ' 32000000/8(scale) = 4000000/2 = 2MÃö = 500ns
Enable Tce0_ovf , Hi


Enable Interrupts
Config Priority = Static , Vector = Application , Lo = Enabled

'----------------------[Mainloop]-----------------------------------------------
 Do
 Print #1 , ">_"
 Input #1 , Incom , Noecho
 If Incom = "Get" Then                                      'read ccd



 End If
 Loop Until Dma_ready = 1
'-------------------------------------------------------------------------------

' Print #1 , Sample_count ; " Sample READY"
 'Disable Channel 0 Interrupt on comversion complete
 Adca_ch0_intctrl = &B0000_00_00                            'OFF Int on Conversion complete  (CH 0)

 'Disable Free Running mode
 Reset Adca_ctrlb.3
 'Disable ADC A
 Reset Adca_ctrla.0

 Icg = 0
 Sh = 1
 Waitus 1
 Sh = 0
 Waitus 1
 Icg = 1
 Print #1 , "|"

For Adccount = 0 To 3694 Step 1
If Adccount = 3694 Then
Print #1 , "|"
Print #1 , "Job Done!"
Else
'Adcread = Getadc(adca , 2 )
Print #1 , Channel_0(x)

End If
Next
 'Print Results to COM1
' For X = 1 To Sample_count
'  Milli_volt = Channel_0(x) * Mv_per_adc_step
'  Print #1 , Fusing(milli_volt , "###,#")
'  Waitms 1
'Next



End                                                         'end program


'----------------------[Interrupt Service Routines]-----------------------------

 ' Dma_ch0_int is for DMA Channel ERROR Interrupt A N D for TRANSACTION COMPLETE Interrupt
 ' Which Interrupt fired must be checked in Interrupt Service Routine
 Dma_ch0_int:

    If Dma_intflags.0 = 1 Then                              'Channel 0 Transaction Interrupt Flag
       Set Dma_intflags.0                                   'Clear the Channel 0 Transaction Complete flag
       Set Dma_ready
    End If

    If Dma_intflags.4 = 1 Then                              'Channel 0 ERROR Flag
       Set Dma_intflags.4                                   'Clear the flag
       Set Dma_channel_0_error                              'Channel 0 Error
    End If

 Return

 Adcrd:


Return

 Gnrtr:
Toggle Portc.0
Return

0

40

думаю для начало, нужно получить хоть какие-то данные с АЦП, а потом лезть в связку АЦП+ДМА
т.е. нужно точно знать, что аналоговая часть работает (нет ошибок)
на сколько я понял, даже одиночное, многоразовое измерение не даёт результата - нет смысла двигаться дальше (в сложное)

0

41

Можете инициализацию линейки проверить пожалуйста по даташиту. У меня смутные сомнения может я что-то не так делаю.

Icg = 0
Sh = 1
Waitus 1
Sh = 0
Waitus 1
Icg = 1
и считываем ацп 3694 раза

0

42

Страница №8, там как-то всё значительно сложнее.
Все периоды должны быть кратные "М" (задающей частоте), т.к. весь процесс должен проходить синхронно. Возможно проще всего процесс считывания запихнуть в тоже прерывание, что и генератор 2МГц.
Думаю правильнее сделать задержки не командами (иначе придется синхронизировать как-то это всё, ждать прихода высокого уровня генератора/прерывания), а просто считать кратность в генераторе (2МГц). А управлять общим запуском из основного тела программы.
SH надо дергать каждый раз на всём периоде чтения данных - период t3+t1 - в районе 2000ns (2us).

0

43

Проверьте пожалуйста,сделал вот так вроде что-то с матрицы получил.

Код:
Gnrtr:
Enable Interrupts
For Adccount = 0 To 3694 Step 1
If Adccount = 3694 Then
Disable Interrupts
Else

 Toggle Portc.0
 Incr N
 If N = 3 Then
 Toggle Porta.3
 Adcread = Getadc(adca , 2 , 16 )
 Print #1 , "<" ; Adcread ; ">"
 N = 0
 End If

End If
Next

Return

0

44

Зачем прерывания начинаются с "Enable Interrupts"? Раз сюда мы попали, они и так включены.
Так же и с "Disable Interrupts" - к чему бы это, не понимаю сути? Опять путаница будет с управлением.
Сейчас подпрограмма "Gnrtr" похожа больше не на обработчик прерываний, а на основное тело программы (кашу-молу).
Она же выполняется с частотой (как понимаю) 2МГц, почему внутри находится цикл "for"? Если организовывать, то счет надо, а не цикл, просто считаем количество "Adccount" переменной. Всё должно выполнятся быстро и за 1 проход (без всяких циклов).
Ещё не хватает инициализации/управления, ведь на самом деле не 3694, а вначале инициализация, а потом уже считаем 3694 (т.е. значений больше будет).
Потом цикл организован от 0 до 3694 - считать будет 3695 раз (а не 3694) - не верно.
Думаю стоит попробовать добавить бит запуска обработчика в прерывании, т.е. прерывание "генератора" всегда работает с частотой 2МГц, далее выставляем бит разрешающий выполняться содержимое прерывания (не самим прерыванием "Enable/Disable Interrupts"), в прерывании есть два этапа работы:

1. стартовый запуск сканирования линейки (подготовка);
2. (потом переключается на) само сканирование.

Ещё можно добавить бит окончания сканирования, пригодится тогда, когда параллельно с сканированием МК может заниматься и другими задачами, а не висеть и ждать...

Отредактировано RDW (2013-04-18 15:41:23)

0

45

Пробовал так, если цикла нет, то вообще данные не отправляются по юарту. Вот исправленный код. Проверьте пожалуйста.

Код:
$regfile = "xm256a3def.dat"
$crystal = 32000000                                         '32MHz
$hwstack = 64
$swstack = 64
$framesize = 64

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

'first enable the osc of your choice
Config Osc = Enabled , 32mhzosc = Enabled

'configure the systemclock
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1

'Íàñòðàèâàåì UART
Config Com4 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM4:" For Binary As #1

'Íåîáõîäèìûå ïåðåìåííûå äëÿ âû÷èñëåíèé
Dim Adcreadsave(3694) As Integer                            'Ìàññèâ çíà÷åíèé ÀÖÏ
Dim Adcread As Integer                                      'Òåêóùåå çíà÷åíèå ÀÖÏ
Dim Adccount As Integer                                     'Êîëè÷åñòâî èçìåðåíèé ÀÖÏ
Dim Incom As String * 4                                     'Ïðèåì ÷åðåç UART
Dim Getadcvalue As Bit                                      'Áèò ðàçðåøåíèÿ ïðåðûâàíèé
Dim N As Integer

'Êîíôèãóðàöèÿ ïîðòîâ
Config Portc.0 = Output                                     ' M íîæêà òàêòèðîâàíèÿ ÏÇÑ ëèíåéêè
Config Portc.1 = Output                                     'ñâåòîäèîä 1
Config Portf.3 = Output                                     'ñâåòîäèîä 2
Config Porta.3 = Output                                     ' Sh
Config Porta.4 = Output                                     'Icg

Led1 Alias Portc.1
Led2 Alias Portf.3
Sh Alias Porta.3
Icg Alias Porta.4

Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 32 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B000_00 _
 Ch1_gain = 1 , Ch1_inp = Single_ended , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 = &B10_000 , Ch3_gain = 1 , Ch3_inp = Single_ended , Mux3 = &B11_000


Config Tce0 = Normal , Prescale = 8 , Wgmode = Normal , Event_action = Restart , Resolution = 16
On Tce0_ovf Gnrtr
Tce0_per = 2                                                ' 32000000/8(scale) = 4000000/2 = 2MÃö = 500ns
Enable Tce0_ovf , Hi                                        ' âûñòàâëÿåì ïðèîðèòåò ïðåðûâàíèÿ è ðàçðåøàåì
Enable Interrupts

Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Print #1 , "CCD Tester based on ATXmega256A3 and TCD1304"

'...
Adccount = 1
Getadcvalue = 0

Do
 Input #1 , Incom , Noecho                                  'Ïðèåì êîìàíäû ÷åðåç UART
 If Incom = "Get" Then
 Getadcvalue = 1
 Icg = 1                                                    'èíèöèàëèçàöèÿ ÏÇÑ ëèíåéêè
 Sh = 0
 Waitus 1
 Sh = 1
 Waitus 1
 Icg = 0
 Gosub Gnrtr
 End If
Loop
End

'Ïðåðûâàíèå òàéìåðà
Gnrtr:
 If Getadcvalue = 1 Then
 Toggle Portc.0
 Incr N
 If N = 3 Then
 Toggle Porta.3
 Gosub Adcar
 N = 0
 End If
 End If
Return

'×òåíèå ÀÖÏ
Adcar:
Incr Adccount
If Adccount = 3694 Then
Gosub Send
Else
 Adcread = Getadc(adca , 2 , 16 )
 Adcreadsave(adccount) = Adcread
End If
Return

'Ïåðåäà÷à èçìåðåíèé ÷åðåç UART
Send:
For Adccount = 0 To 3694 Step 1
Adcread = Adcreadsave(adccount)
Print #1 , "<" ; Adcread ; ">"
Next
Return

0

46

1. Ножки порта правильно подпаяны относительно COM4?
2. Цикл отправки должен быть от 1 до 3694.
(ну и самое весёлое)
3. Dim Adcreadsave(3694) As Integer - это значит 3694 * 2 = 7388, у ХМеги нет столько SRAM (max 4KB)! :D Тут думаю выход простой, для начала следует организовать 8-битный массив, зачем 16 значений-то использовать? Надо на лету преобразовывать 2 байта в 1 и писать в массив. Ну или вешать внешнюю память...
У тебя тупо переполняется память и приводит к глюку (3-е состояние).

Отредактировано RDW (2013-04-19 17:47:03)

0

47

Ножки на СОМ4 припаял правильно 100%,тогда не буду сохранять в SRAM,а сразу  передавать по юарту.

Проверил. Без массива. Все равно данные не отправляются. Может есть замена For-Next и Incr?

Отредактировано Airat (2013-04-19 18:58:44)

0

48

сразу отправлять не получится, т.к. частота минимальная тактирования линейки 2МГц, а прерывание 4МГц происходит, скорость порта значительно меньше, если сразу отправлять, то скорость сразу упадет и линейка данные отдавать не будет

0

49

я бы наверное сделал вначале приём малого количества данных, а потом их отправку, чтобы проверить работает или нет всё

0

50

Меня пока волнует вопрос почему он без цикла for-next вообще ничего не отправляет? По поводу спада частоты, я думаю если все синхронно притормозится то ничего страшного,главное синхронно. Можно еще тактовую до 500кГц снизить. Я и так для проверки считываю только первые 200 пикселей.

А разве у ATXmega256A3 не 16KB SRAM?

Отредактировано Airat (2013-04-19 20:57:35)

0

51

Да, 16К (я всё забываю, что это не xmega32a4).

Каким образом получится снижать чтение данных из линейки, если по датащиту минимум 800кГц? А скорость порта значительно ниже! Линейка просто данные отдавать не будет и всё.
Основная задача же: накопить быстро данные, а потом неспеша их разгрузить в медленный порт. Кстати я не уверен, что при таком объёме данных, на скорости 115200 не будет ошибки передачи (вроде как частота не кратная 32МГц (уже не помню)). Вот.

Что значит "без цикла for-next вообще ничего не отправляет"? Если из кода убрать цикл, то получим тупо отправка 1 значения АЦП и всё.

Отредактировано RDW (2013-04-20 12:11:56)

0

52

Я про другой цикл говорю. Вот тут,если for-next  заменить incr, то данных вообще нет.
Ошибок на скорости 115200 пока не было,тьфу,тьфу,тьфу.

Код:
Gnrtr:
Enable Interrupts
For Adccount = 0 To 3694 Step 1
If Adccount = 3694 Then
Disable Interrupts
Else

 Toggle Portc.0
 Incr N
 If N = 3 Then
 Toggle Porta.3
 Adcread = Getadc(adca , 2 , 16 )
 Print #1 , "<" ; Adcread ; ">"
 N = 0
 End If

End If
Next

Return

Отредактировано Airat (2013-04-20 16:07:12)

0

53

а как выглядит замена цикла на incr?

0

54

Выглядит следующим образом.

Код:
Incr Adccount
If Adccount = 3694 Then
Gosub Send
Else
 Adcread = Getadc(adca , 2 , 16 )
 Adcreadsave(adccount) = Adcread
End If

Попутно возник еще один вопрос. Как правильно записать массив в SRAM?

Отредактировано Airat (2013-04-22 01:13:46)

0

55

Вроде бы что то начало получаться с пзс. Попутно возник еще один вопрос, как сделать задержку 500ns?

0

56

ассемблерными вставками
частота МК какая?
8МГц - 125ns
16МГц - 62,5ns
считаем сколько надо тактов пропустить и ставим к примеру nop-ы

Отредактировано RDW (2013-06-16 11:17:44)

0

57

Частота МК 32МГц. Получается мне надо будет пропустить 16 тактов = 16 раз nop?

0

58

да, или сделать что-то полезное за это время)

0

59

Вроде бы данные с пзс получаю,но данные не адекватные. Может вы подскажете,где ошибка?

Код:
$regfile = "xm256a3def.dat"
$crystal = 32000000                                         '32MHz
$hwstack = 128
$swstack = 128
$framesize = 128

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

'first enable the osc of your choice
Config Osc = Enabled , 32mhzosc = Enabled

'configure the systemclock
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1

'Настраиваем UART
Config Com4 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM4:" For Binary As #1

'Необходимые переменные для вычислений
Dim Adcreadsave(4000) As Word
Dim Adcread As Word                                         'At Adcreadsave Overlay               'Текущее значение АЦП
Dim Adccount As Word                                        'Количество измерений АЦП
Dim Incom As String * 4                                     'Прием через UART
Dim N As Byte
Dim Check As Bit
'Конфигурация портов
Config Portc.0 = Output                                     ' M ножка тактирования ПЗС линейки
Config Portc.1 = Output                                     'светодиод 1
Config Portf.3 = Output                                     'светодиод 2
Config Porta.3 = Output                                     ' Sh
Config Porta.4 = Output                                     'Icg

Led1 Alias Portc.1
Led2 Alias Portf.3
Sh Alias Porta.3
Icg Alias Porta.4
M Alias Porta.3

Config Adca = Single , Convmode = Unsigned , Resolution = 8bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 4 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B000_00_
Ch1_gain = 1 , Ch1_inp = Single_ended , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 = &B10_000 , Ch3_gain = 1 , Ch3_inp = Single_ended , Mux3 = &B11_000
Config Pina.2 = Input

Config Tce0 = Normal , Prescale = 8                         'Конфигурация таймера
On Tce0_ovf Adcvalue                                        ' Тактирование ПЗС линейки
Tce0_per = 2                                                ' 32000000/8(scale) = 4000000/2 = 2MГц = 500ns
Disable Tce0_ovf
Config Priority = Static , Vector = Application , Lo = Enabled       'Выставляем приоритет таймера
Enable Interrupts
Enable Tce0_ovf , Lo
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Print #1 , "CCD Tester based on ATXmega256A3 and TCD1304"

Adccount = 1
N = 0
Icg = 1
Sh = 1
Portc.0 = 1
Check = 0

Do

 Print #1 , ">_"
 Input #1 , Incom , Noecho                                  'Прием команды через UART
 Led1 = 1
 Waitms 150
 Led1 = 0
 If Incom = "Sts" Then
 Print #1 , "<sOK>"
 End If
  If Incom = "Get" Then
  Icg = 1                                                   'инициализация ПЗС линейки
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  Sh = 0
  Waitus 1
  Sh = 1
  Waitus 1
  Icg = 0
  Adccount = 1
  Check = 1
End If

Loop
End

'Прерывание таймера
Adcvalue:
If Check = 1 Then
Led2 = 1                                                    'Включаем таймер
If Adccount = 3694 Then                                     'Условие счетчика для количества измерений
 Led2 = 0
 Waitms 100
 Check = 0
 Gosub Uartsend
Else

 Toggle Portc.0
 Incr N
 If N = 3 Then
 'Toggle Porta.3
 Adcread = 0
 Adcread = Getadc(adca , 2 )                                'Считывание АЦП
 Adcreadsave(adccount) = Adcread
 Incr Adccount
 N = 0
 End If
 End If
End If                                                      'Увеличение значения счетчика на 1

Return

Uartsend:
Adccount = 1
For Adccount = 1 To 3694 Step 1
If Adccount = 3694 Then
Print #1 , "<cRUN>"
End If
Adcread = Adcreadsave(adccount)
Print #1 , "<a" ; Adcread ; ">"
Next
Return

Отредактировано Airat (2013-06-18 12:59:48)

0

60

В общем,переделал код. Работает, но ацп местами не успевает. Дайте, пожалуйста, совет,а еще лучше пример как еще можно ускорить ацп без использования DMA.Вот код:

Код:
$regfile = "xm256a3def.dat"
$crystal = 32000000                                         '32MHz
$hwstack = 128
$swstack = 128
$framesize = 128

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

'first enable the osc of your choice
Config Osc = Enabled , 32mhzosc = Enabled

'configure the systemclock
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1

'Настраиваем UART
Config Com4 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM4:" For Binary As #1

'Необходимые переменные для вычислений
Dim Adcreadsave(4000) As Word
Dim Adcread As Word                                         'At Adcreadsave Overlay               'Текущее значение АЦП
Dim Adccount As Word                                        'Количество измерений АЦП
Dim Incom As String * 4                                     'Прием через UART
Dim N As Byte
Dim Check As Bit
'Конфигурация портов
Config Portc.0 = Output                                     ' M ножка тактирования ПЗС линейки
Config Portc.1 = Output                                     'светодиод 1
Config Portf.3 = Output                                     'светодиод 2
Config Porta.3 = Output                                     ' Sh
Config Porta.4 = Output                                     'Icg

Led1 Alias Portc.1
Led2 Alias Portf.3
Sh Alias Porta.3
Icg Alias Porta.4
Clock Alias Portc.0

Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 4 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B000_00_
Ch1_gain = 1 , Ch1_inp = Single_ended , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 = &B10_000 , Ch3_gain = 1 , Ch3_inp = Single_ended , Mux3 = &B11_000
Config Pina.2 = Input

Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Led1 = 1
Led2 = 1
Waitms 250
Led1 = 0
Led2 = 0
Waitms 250
Print #1 , "CCD Tester based on ATXmega256A3 and TCD1304"

Do
 Print #1 , ">_"
 Input #1 , Incom , Noecho                                  'Прием команды через UART
 Led1 = 1
 Waitms 150
 Led1 = 0
 If Incom = "Sts" Then
 Print #1 , "<sOK>"
 End If
  If Incom = "Get" Then
   Icg = 0                                                  'инвертируем сигналы из-за 74НС04
   Clock = 1
   Sh = 1
    '1
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '2
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    Icg = 1
    '3
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    Sh = 0
    '4
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '5
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '6
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '7
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    Sh = 1
    '8
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '9
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '10
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    '11
    Clock = 1
    Waitus 1
    Clock = 0
    Waitus 1
    Icg = 0

      For Adccount = 1 To 3694 Step 1
      Led2 = 1
         '1
         Clock = 1
         Waitus 1
         Clock = 0
         Waitus 1
         '2
         Clock = 1
         Waitus 1
         Clock = 0
         Waitus 1
         '3
         Clock = 1
         Waitus 1
         Clock = 0
         Waitus 1
         '4
         Clock = 1
         Waitus 1

           Adcread = 0
           Adcread = Getadc(adca , 2 )                      'Считывание АЦП
           Waitus 1
           If Adccount > 32 And Adccount < 3680 Then
           Print #1 , "<a" ; Adcread ; ">"
           End If
           If Adccount = 3694 Then
           Led2 = 0
           Print #1 , "<cRUN>"
           End If

         Clock = 0
         Waitus 1
      Next
  End If
Loop

0


Вы здесь » Программирование ATMEL в BASCOM. » Разное » Считывание ПЗС линейки