Увеличение количества каналов ацп (atmega8)

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 9
Зарегистрирован: Пт фев 22, 2013 06:40:26
Откуда: Россия, Чита

Сообщение Savrula »

Всем доброго времени, по ходу ваяния моего проекта возникло 2 вопроса:
1) как прикрутить к ацп второй (в моем случае их должно быть 2) канал.
2) как из байта вывести в порт единички и нули побитно (взял 0ой бит, вывел в порт; взял 1ый, вывел в порт и т.д.)
Суть первого вопроса, первый канал ацп цифрует данные для изменения задающей частоты 3х фазного безколлекторного двигателя, с этим проблем нет. Второй же канал цифрует данные с потенциометра для изменения задержки таймера-счетчика Т2 в меге8, который работает в режиме СТС, и по совпадению вызывает прерывание, в котором собственно и нужна побитовая отправка в порт.
Почитав Евстифеева и погуглив некоторое время выяснил, что если во время оцифровки ацп изменить биты MUX3:0 в регистре ADMUX, то следующая оцифровка будет с канала который в MUX3:0 указали. Еще я понял т.к. регистр OCR2в Т2 меги8 8-битный и я использую 8 битное цифрование в ацп, то мне нужно будет в OCR2 записать результат оцифровки без каких либо арфиметических операций. Но что-то не удалось у меня это сделать. Протеус при моделировании ниже приведенного кода, почему-то решил что я хочу вместо потенциометра1 (управление двигой) поменять собственно это управление на потенциометр2 (который должен изменять задержку таймера). Буду рад помощи в любых ее проявлениях.
собственно код (где кракозябры это пометки для собственных нужд, также в архиве проект и протеус):
Спойлер
  • ;********************************************************************
    ; 8,0 Ìãö
    ;********************************************************************
    .include "m8def.inc"
    ;********************************************************************

    ;********************************************************************
    .equ XTAL=8000000
    .equ baudrate=9600
    .equ bauddivider=XTAL/(16*baudrate)-1


    ;********************************************************************
    ;((fclk/(2*êîýô. äåë.))/íóæíóþ ÷àñòîòó)=ÖÛÔÐÓ (timer_c) OCR1AH/L

    .def temp= r16 ;
    .def temp_1=r17
    ;********************************************************************
    ;data segment
    ;********************************************************************
    .dseg

    image: .byte 10 //10 sell memory for 10x8 image
    ;********************************************************************
    ;
    ;********************************************************************
    ; Inicializacija MK
    ;********************************************************************
    .cseg
    .org SRAM_START+10

    .org 0 ; int vector
    rjmp reset ; ïðîöåññîðà
    .org OC2addr; Timer/Counter2 Compare Match
    rjmp imageout
    .org OC1Aaddr
    rjmp TIM1_COMPAB ; Timer1 CompareA Handler
    .org URXCaddr
    rjmp URXCaddr ; USART, Rx Complete
    .org UDREaddr
    rjmp UDREaddr ; USART Data Register Empty
    .org UTXCaddr
    rjmp UTXCaddr ; USART, Tx Complete
    .org ADCCaddr
    rjmp complete ;ADC conversion complete


    ;********************************************************************

    reset:

    ;********************************************************************
    ;stek
    ;********************************************************************
    ldi temp, low(RAMEND)
    out SPL, Temp
    ldi temp, high(RAMEND)
    out SPH, Temp
    ;********************************************************************
    ;port
    ;********************************************************************
    ldi temp, 0xFF ; âñå ïîðòû PB
    out DDRB, temp ; íà âûõîä
    ldi r16, 0b10000000 // PD7 pinout
    out DDRD, r16

    ;*******************************************************************
    ; ADC settings
    ;*******************************************************************
    ldi r18,(1<<ADLAR)|(1<<REFS0)//0b00100000 AVCC,8bit, ADC0
    out ADMUX, r18
    ldi r18,(1<<ADEN)|(1<<ADFR)|(1<<ADIE)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) //0b11101110, adc enable, freerun mode,interrupt enable,ck=128
    out ADCSRA, r18

    ;********************************************************************
    ; timer1 16 bit
    ;********************************************************************
    ldi temp, 0 ;
    out TCNT1H, temp ;
    out TCNT1L, temp ;
    out TCCR1A, temp ;
    ldi temp, (1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10); clk/1,
    out TCCR1B, temp ; ðåæèì CTC
    ldi temp, high(1335) ; ñòàðøèé
    out OCR1AH, temp ; áàéò ê.ä.
    ldi temp, low(1335) ; ìëàäøèé
    out OCR1AL, temp ; áàéò ê.ä
    ldi temp, (1<<OCIE1A)|(1<<OCIE2) ; ðàçðåøåíèå ïðåðûâàíèé T2 and T1
    out TIMSK, temp ; ïî ñîâïàäåíèþ
    ldi temp_1, 0 ; îáíóëèì temp_1
    ;********************************************************************
    ;timer-counter 2 settings, 8-bit
    ;********************************************************************
    ldi r16, (1<<OCF2) //
    out TIFR, r16
    ldi r16, (1<<CS20)//|(1<<CTC2)
    out TCCR2, r16
    ldi r16, 108
    out OCR2, r16
    ;********************************************************************
    ;usart settings
    ;********************************************************************
    ldi r16, low(bauddivider) //speed
    out UBRRL, r16 //value
    ldi r16, high(bauddivider)//write
    out UBRRH, r16 //in register
    ldi r16, (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(0<<UDRIE) //ïðåðûâàíèÿ çàïðåùåíû, ïîðòû ââîäà âûâîäà ìîäóëÿ âêëþ÷åíû
    out UCSRB, r16 //çàïèñàëè
    ldi r16, 0
    out UCSRA, r16
    ldi r16, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1) //1 byte, non parity mode, 1 stop bit
    out UCSRC, r16


    ldi XL, 0x60 //starting cell RAM
    ldi XH, 0

    ;********************************************************************
    ;Îñíîâíàÿ ïðîãðàììà
    ;********************************************************************

    sei ; ðàçðåøåíèå ïðåðûâàíèé
    loop:

    rcall uart_rcv //æäåì áàéò


    rjmp loop ;

    ;********************************************************************
    ; îáðàáîò÷èê ïðåðûâàíèé òàéìåðà
    ;********************************************************************
    TIM1_COMPAB:
    in temp, SREG ;
    push temp ; SREG
    com temp_1 ;
    andi temp_1, 0b11111111 ; îñòàâèì 0-îé áèò
    out PORTB, temp_1 ; âûâîä â ïîðò

    pop temp ; SREG
    out SREG, temp ; âîññòàíîâèì


    reti ; âûõîä èç ïðåðûâàíèÿ
    ;********************************************************************
    uart_rcv:
    sbis UCSRA,RXC //jdem byte
    rjmp uart_rcv //in cycle
    ;*************************************
    ;cycle write in RAM
    ;*************************************
    in R16,UDR //byte poluchen, zabrali

    st X+, r16
    rjmp loop
    ret
    ;**************************************
    //adc int
    ;**************************************
    complete:
    ldi r18,(1<<ADLAR)|(1<<REFS0)|(0<<MUX0)//0b00100000 AVCC,8bit, ADC0
    out ADMUX, r18

    ldi ZL,low(Table*2) //write in Z Table:
    ldi ZH,high(Table*2)
    in r19,ADCH //write result in r19
    ldi r20,0
    lsl r19
    rol r20
    add ZL, r19
    adc ZH, r20
    lpm r20,Z
    adiw Z,1 //lpm read and write OCR r30 r31
    lpm r21, Z
    out OCR1AH,r21
    out OCR1AL,r20

    ldi r18,(1<<ADLAR)|(1<<REFS0)|(1<<MUX0)//0b00100000 AVCC,8bit, ADC1 adc for timer2
    out ADMUX, r18
    in r18, ADCH
    out OCR2, r18

    reti
    ;***********************************
    ;integer timer-counter 2
    ;***********************************
    imageout:
    ldi XL, 0x60 //starting cell RAM
    ldi XH, 0
    ld r18, X+
    //out ,r18
    //onebyte out in port

    reti
    Table:
    .dw 1333
    .dw 1331
    .dw 1329
    .dw 1327
    .dw 1325
    .dw 1323
    .dw 1321
    .dw 1319
    .dw 1317
    .dw 1315
    .dw 1313
    .dw 1311
    .dw 1309
    .dw 1307
    .dw 1305
    .dw 1303
    .dw 1301
    .dw 1299
    .dw 1297
    .dw 1295
    .dw 1293
    .dw 1291
    .dw 1289
    .dw 1287
    .dw 1285
    .dw 1283
    .dw 1281
    .dw 1279
    .dw 1277
    .dw 1275
    .dw 1273
    .dw 1271
    .dw 1269
    .dw 1267
    .dw 1265
    .dw 1263
    .dw 1261
    .dw 1259
    .dw 1257
    .dw 1255
    .dw 1253
    .dw 1251
    .dw 1249
    .dw 1247
    .dw 1245
    .dw 1243
    .dw 1241
    .dw 1239
    .dw 1237
    .dw 1235
    .dw 1233
    .dw 1231
    .dw 1229
    .dw 1227
    .dw 1225
    .dw 1223
    .dw 1221
    .dw 1219
    .dw 1217
    .dw 1215
    .dw 1213
    .dw 1211
    .dw 1209
    .dw 1207
    .dw 1205
    .dw 1203
    .dw 1201
    .dw 1199
    .dw 1197
    .dw 1195
    .dw 1193
    .dw 1191
    .dw 1189
    .dw 1187
    .dw 1185
    .dw 1183
    .dw 1181
    .dw 1179
    .dw 1177
    .dw 1175
    .dw 1173
    .dw 1171
    .dw 1169
    .dw 1167
    .dw 1165
    .dw 1163
    .dw 1161
    .dw 1159
    .dw 1157
    .dw 1155
    .dw 1153
    .dw 1151
    .dw 1149
    .dw 1147
    .dw 1145
    .dw 1143
    .dw 1141
    .dw 1139
    .dw 1137
    .dw 1135
    .dw 1132
    .dw 1129
    .dw 1126
    .dw 1123
    .dw 1120
    .dw 1117
    .dw 1114
    .dw 1111
    .dw 1108
    .dw 1105
    .dw 1102
    .dw 1099
    .dw 1096
    .dw 1093
    .dw 1090
    .dw 1087
    .dw 1084
    .dw 1081
    .dw 1078
    .dw 1075
    .dw 1072
    .dw 1069
    .dw 1066
    .dw 1063
    .dw 1060
    .dw 1057
    .dw 1054
    .dw 1051
    .dw 1048
    .dw 1045
    .dw 1042
    .dw 1039
    .dw 1036
    .dw 1033
    .dw 1030
    .dw 1027
    .dw 1024
    .dw 1021
    .dw 1018
    .dw 1015
    .dw 1012
    .dw 1009
    .dw 1006
    .dw 1003
    .dw 1000
    .dw 997
    .dw 994
    .dw 991
    .dw 988
    .dw 985
    .dw 982
    .dw 979
    .dw 976
    .dw 973
    .dw 970
    .dw 967
    .dw 964
    .dw 961
    .dw 958
    .dw 955
    .dw 952
    .dw 949
    .dw 946
    .dw 943
    .dw 940
    .dw 937
    .dw 934
    .dw 931
    .dw 928
    .dw 925
    .dw 922
    .dw 919
    .dw 916
    .dw 913
    .dw 910
    .dw 907
    .dw 904
    .dw 901
    .dw 898
    .dw 895
    .dw 892
    .dw 889
    .dw 886
    .dw 883
    .dw 880
    .dw 877
    .dw 874
    .dw 871
    .dw 868
    .dw 865
    .dw 862
    .dw 859
    .dw 856
    .dw 853
    .dw 850
    .dw 847
    .dw 844
    .dw 841
    .dw 838
    .dw 835
    .dw 832
    .dw 829
    .dw 826
    .dw 823
    .dw 820
    .dw 817
    .dw 814
    .dw 811
    .dw 808
    .dw 805
    .dw 802
    .dw 799
    .dw 796
    .dw 793
    .dw 790
    .dw 787
    .dw 784
    .dw 781
    .dw 778
    .dw 775
    .dw 772
    .dw 769
    .dw 766
    .dw 763
    .dw 760
    .dw 757
    .dw 754
    .dw 751
    .dw 748
    .dw 745
    .dw 742
    .dw 739
    .dw 736
    .dw 733
    .dw 730
    .dw 727
    .dw 724
    .dw 721
    .dw 718
    .dw 715
    .dw 712
    .dw 709
    .dw 706
    .dw 703
    .dw 700
    .dw 697
    .dw 694
    .dw 691
    .dw 688
    .dw 685
    .dw 682
    .dw 679
    .dw 676
    .dw 673
    .dw 670
    .dw 665

    ;********************************************
    //trash
    ;********************************************
    //âûáîðêà ÿ÷åéêè (10øò.)
    /*inc r22
    in R16,UDR //áàéò ïðèøåë, çàáèðàåì
    cp r22, r23
    breq image0
    inc r22
    cp r22, r23
    breq image1
    inc r22
    cp r22, r23
    breq image2
    inc r22
    cp r22, r23
    breq image3
    inc r22
    cp r22, r23
    breq image4
    inc r22
    cp r22, r23
    breq image5
    inc r22
    cp r22, r23
    breq image6
    inc r22
    cp r22, r23
    breq image7
    inc r22
    cp r22, r23
    breq image8
    inc r22
    cp r22, r23
    breq image9
    //segment write
    image9:
    sts image+9, r16
    ldi r23, 64
    rjmp loop
    image8:
    sts image+8, r16
    ldi r23, 53
    rjmp loop
    image7:
    sts image+7, r16
    ldi r23, 44
    rjmp loop
    image6:
    sts image+6, r16
    ldi r23, 35
    rjmp loop
    image5:
    sts image+5, r16
    ldi r23, 27
    rjmp loop
    image4:
    sts image+4, r16
    ldi r23, 20
    rjmp loop
    image3:
    sts image+3, r16
    ldi r23, 14
    rjmp loop
    image2:
    sts image+2, r16
    ldi r23, 9
    rjmp loop
    image1:
    sts image+1, r16
    ldi r23, 5
    rjmp loop
    image0:
    sts image, r16 //write in SRAM value UDR
    ldi r23, 2 */

    //âûâîä â ïîðò èç ñòàðîãî ñïîñîáà çàïèñè â ïàìÿòü
    /*lds r16, image0
    out DDRD, r16
    lds r16, image1
    out DDRD, r16
    lds r16, image2
    out DDRD, r16
    lds r16, image3
    out DDRD, r16
    lds r16, image4
    out DDRD, r16
    lds r16, image5
    out DDRD, r16
    lds r16, image6
    out DDRD, r16
    lds r16, image7
    out DDRD, r16
    lds r16, image8
    out DDRD, r16
    lds r16, image9
    out DDRD, r16 */

    /*
    ldi r22, -1
    ldi r23, 0
    ðåãèñòðû ñ÷åò÷èêè ïðèíÿòûõ ïîñûëîê è çàïèñàííûõ ÿ÷ååê */
Вложения
source.rar
(29.83 КБ) 140 скачиваний
Реклама
Родился
Сообщения: 9
Зарегистрирован: Пт фев 22, 2013 06:40:26
Откуда: Россия, Чита

Сообщение Savrula »

может у кого кусок кода есть на асме, где ацп во фриранмоде перебирает каналы?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20102
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Чего там перебирать? В регистр мультиплексора заслать что нужно, и всё.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Родился
Сообщения: 9
Зарегистрирован: Пт фев 22, 2013 06:40:26
Откуда: Россия, Чита

Сообщение Savrula »

я это понимаю, я не могу понять как это реализовать, чтоб у меня потенциометры не замещались друг другом, наверно проблема в том где разместить запись о смене канала. в своих изысканиях дошел аш до 14 страницы гугла :) и вот самое близкое что удалось найти
ссылка:
Спойлерhttp://controllersystems.com/books/praktika_programmirovaniya_atmel_avr/programma-acp.html
там листинг 10.11, как я понял смена канала должна быть в прерывании от ацп, еще немного покурив даташит на ингле от меги8 нашел рекомендации по размещению смены канала:
Спойлер1. When ADFR or ADEN is cleared
2. During conversion, minimum one ADC clock cycle after the trigger event
3. After a conversion, before the Interrupt Flag used as trigger source is cleared
что я (гугл транслейт) перевел как
1. Когда ADFR или ADEN очищается
2. Во время преобразования АЦП минимум один такт после запуска события
3. После преобразования, прежде Флаг прерывания используется как источник запуска сбрасывается
и вот из этих трех пунктов непонятен третий.
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Кривой перевод... надо на инглише читать а не переводам верить.

Ну, собственно что непонятно? написано же "следующее измерение". Когда возникло прерывание - предыдущее измерение закончилось, и в тот же самый момент фиксируется положение мультиплексора и производится процедура запоминания аналогового сигнала на входе(чтобы во время измерения напряжение на входе не влияло на результат измерения).
Т.е. фактически когда вы поставили в прерывании нужный канал, то реальное его измерение произойдет через два измерения.
Тут наверно проще было бы не автоматическое измерение производить, а в режиме однократного запуска. т.е. прерывание, сменили канал, запустили преобразование, считали текущее значение. так точно можно быть уверенным в измерении нужного канала.
Либо устанавливать номер канала в прерывании а считывать значение измерения со сдвигом. установили первый канал - считали третий, установили второй - считали первый, установили третий - считали второй... и так в цикле.
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20102
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Alexeyslav писал(а):сменили канал, запустили преобразование
Ещё хорошо бы паузу выдержать чтобы напряжение стабилизировалось.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Родился
Сообщения: 9
Зарегистрирован: Пт фев 22, 2013 06:40:26
Откуда: Россия, Чита

Сообщение Savrula »

Alexeyslav писал(а):Кривой перевод... надо на инглише читать а не переводам верить.
моих познаний в англ. языке не хватает для сего, и я понял из литературы что канал сменится по окончании текущего оцифровывания, и мне нужен фриранмод, я оборотами двигла регулирую частоту вращения зеркала (шестигранной призмы) которая с определенной частотой разворачивает лазер (проектор я делаю), посему мне нужен фриранмод, собственно опять же в процессе гугления выяснилось что смена каналов в фриранмоде, не подберу подходящего слова, геморна, выражаясь грубо, ну а собственно цикл сделать можно 1ой канал, 1ой канал впустую, 2ой канал, моих познаний не хватает для осуществления сего, и как совместить смену числа в регистре таймера для вывода изображения (8 бит) с со сменой числа загруженного из таблицы (16 битный таймер), я не могу допетрить, а по паузе для стабилизации, можно, думаю опять же сделать преобразование в пустую, на ассемблере кроме как командой nop не могу придумать задержку, а включать в сею программу еще какой-либо счетчик не хочется и возможно не хватит моих познаний, на си видел библиотеку задержек delay, но си не хочу пока что осваивать, по некоторым авторитетным для меня мнениям ассемблер по полкам раскладывает суть алгоритма программы, а си, даже не знаю как сказать, не то чтобы легче или понятней, вобщем хочется постичь ассемблер :)
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Почему тебе нужен именно фриранмод? Единственное его преимущество - не надо запускать преобразование каждый раз и несколько укороченный цикл преобразования, тем самым повышается немного частота опроса. Но то что вы пытаетесь делать два преобразования на одно измерение - однозначно проще будет запускать вручную сразу после окончания преобразования - это будет всего на несколько тактов больше на цикл измерения, причем на частоте работы АЦП а не системной тактовой частоты.
Ещё хорошо бы паузу выдержать чтобы напряжение стабилизировалось.
После переключения канала АЦП простаивает 1 или 2 такта именно с этой целью.
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

Ещё хорошо бы паузу выдержать чтобы напряжение стабилизировалось.
После переключения канала АЦП простаивает 1 или 2 такта именно с этой целью.
Таки и дополнительно подождать нехудо. Я наблюдал "фантомное" напряжение на соседнем отключенном канале, когда быстро переключал входы. :) Так что все же надо дать конденсатору выборки перезарядиться.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Ответить

Вернуться в «AVR»