АЦП и вывод через USART - я чайник :)

Здесь принимаются все самые невообразимые вопросы... Главное - не стесняйтесь. Поверьте, у нас поначалу вопросы были еще глупее :)
Ответить
Родился
Сообщения: 19
Зарегистрирован: Пт янв 08, 2010 21:52:40

Сообщение Plantis »

Хочу разобраться с программирование микроконтроллеров ATMega.

На AP0 подаю синусойду. Вывожу данные через USART

Код функции общения с АЦП (функция read_adc)

Код: Выделить всё

 #define ADC_VREF_TYPE 0x40
    
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

Основной код:

Код: Выделить всё


while (1){
putchar('\n');
   
adc = read_adc(0);  

putchar(adc);

delay_ms(20); 

      };  

}
То, что выводиться через USART

Код: Выделить всё

©<LF>
e<LF>
b<LF>
¤<LF>
ю<LF>
<138><LF>
R<LF>
u<LF>
Б<LF>
э

Изображение


Вопрос: Почему через USART передаются данные не в виде цифр, а в виде символом. ""Я так понимаю, что каждому символу соответствует число которое выдает АЦП"" - как бы жаргон.

Помогите плз.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

putchar() в дословном переводе "выдать символ" - с чего вы взяли, что символ и число это одно и то же? сделайте printf("%u\n",adc); и будет вам счастье :) а первый putchar('\n'); выкиньте нафиг
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Родился
Сообщения: 19
Зарегистрирован: Пт янв 08, 2010 21:52:40

Сообщение Plantis »

Сработало! Спасибки. Я уже часа 2 мучаюсь. В инете лазаю.

а как убрать <LF>?
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Plantis писал(а):Сработало! Спасибки. Я уже часа 2 мучаюсь. В инете лазаю.

а как убрать <LF>?
это у вас, похоже, монитор UART-а так показывает, на самом деле это невидимый символ перевода строки.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

Я так понимаю, что каждому символу соответствует число которое выдает АЦП
Ну да, у Вас в VMLAB в настройках TTY указана опция "Display RX as ASCII" , вот терминал и интерпретирует принятые значения как коды символов в ASCII. Символы, которые при обычном выводе не имеют значка, обозначаются аббревиатурой в скобках. Хотите числа - поставьте соответствующую опцию вывода. :idea:

<LF>=Line Feed, перевод строки; говорит терминалу, чтобы он передвинул курсор на новую строку. В реальном терминале отображаться не будет. Просто VMLAB делает так, чтобы мы видели все, что реально идет через UART.
а как убрать <LF>?
Не писать в конце "/n". Тогда все значения будут в одну строку, что, в общем-то, лучше в случае, если Вы будете сопрягать свое творение с программой на ПК (типа осцил /вольтметр).

[IMHO]Для такой задачи использовать С - извращение. :shock: На асме гораздо быстрее работает (что для АЦП немаловажно), гораздо более компактный код... Недавно сам по приколу писал подобную штуку, с маджонгом и гейшами :)) :

Код: Выделить всё

;ADC on COM port (c) YS 2009
;DEVICE: ATmega48; CLOCK: internal, 8MHz

.include "D:\vmlab\include\m48def.inc"

.def t=R16
.def t1=R17

.cseg
.org 0

rjmp RESET      ; Reset Handler
rjmp EXT_INT0   ; IRQ0 Handler
rjmp EXT_INT1   ; IRQ1 Handler
rjmp PCINT0     ; PCINT0 Handler
rjmp PCINT1     ; PCINT1 Handler
rjmp PCINT2     ; PCINT2 Handler
rjmp WDT        ; Watchdog Timer Handler
rjmp TIM2_COMPA ; Timer2 Compare A Handler
rjmp TIM2_COMPB ; Timer2 Compare B Handler
rjmp TIM2_OVF   ; Timer2 Overflow Handler
rjmp TIM1_CAPT  ; Timer1 Capture Handler
rjmp TIM1_COMPA ; Timer1 Compare A Handler
rjmp TIM1_COMPB ; Timer1 Compare B Handler
rjmp TIM1_OVF   ; Timer1 Overflow Handler
rjmp TIM0_COMPA ; Timer0 Compare A Handler
rjmp TIM0_COMPB ; Timer0 Compare B Handler
rjmp TIM0_OVF   ; Timer0 Overflow Handler
rjmp SPI_STC    ; SPI Transfer Complete Handler
rjmp USART_RXC  ; USART, RX Complete Handler
rjmp USART_UDRE ; USART, UDR Empty Handler
rjmp USART_TXC  ; USART, TX Complete Handler
rjmp ADC_CCPL   ; ADC Conversion Complete Handler
rjmp EE_RDY     ; EEPROM Ready Handler
rjmp ANA_COMP   ; Analog Comparator Handler
rjmp TWI        ; 2-wire Serial Interface Handler
rjmp SPM_RDY    ; Store Program Memory Ready Handler

EXT_INT0  :
EXT_INT1  :
_PCINT0    :
_PCINT1    :
_PCINT2    :
WDT       :
TIM2_COMPA:
TIM2_COMPB:
TIM2_OVF  :
TIM1_CAPT :
TIM1_COMPA:
TIM1_COMPB:
TIM1_OVF  :
TIM0_COMPA:
TIM0_COMPB:
TIM0_OVF  :
SPI_STC   :
USART_UDRE:
USART_TXC :
ADC_CCPL  :
EE_RDY    :
ANA_COMP  :
TWI       :
SPM_RDY   :

  reti

RESET:

  ldi t,HIGH(RamEnd) ;stack initialization
  out SPH,t
  ldi t,LOW(RamEnd)
  out SPL,t

  ldi t,0
  sts PRR,t          ;no power reduction

                     ;ADC initialization

  ldi t,0b00000001   ;disable digital input on ADC0/PC0 pin
  sts DIDR0,t

  ldi t,0b01000000   ;Vref=Vcc, input=ADC0 pin
  sts ADMUX,t

  ldi t,0b10000111   ;ADC enable, ADC clock=62,5KHz
  sts ADCSRA,t

                     ;UART initialization

  ldi t,0b10011000   ;RX complete interrupt enable, RX enable, TX enable
  sts UCSR0B,t

  ldi t,0b00000110   ;async, no parity, one stopbit, 8 bit character
  sts UCSR0C,t

  ldi t,0            ;work at 19200Bps
  sts UBRR0H,t
  ldi t,25
  sts UBRR0L,t

  ldi ZH,HIGH(HelloMessage*2)
  ldi ZL,LOW(HelloMessage*2)

  rcall SendMessage

  sei

LOOP:                ;main loop

  rjmp LOOP



USART_RXC:           ;USART RX complete interrupt handler

  cli

  lds t,UCSR0A
  sbrc t,FE0     ;Error?
  rjmp FRAMING_ERROR

  lds t,UDR0

  cpi t,'i'
  breq SEND_INFO

  cpi t,'c'
  breq CONVERT_VALUE

  rjmp ERROR_UNKNOWN

CONVERT_VALUE:

  ldi t,0b11000111   ;Start conversion
  sts ADCSRA,t

WAIT_ADC:

  lds t,ADCSRA
  sbrc t,ADSC
  rjmp WAIT_ADC

  lds t,ADCL
  sts UDR0,t

  rcall WaitUART

  lds t,ADCH
  sts UDR0,t

  rcall WaitUART

  ldi t,0xD
  sts UDR0,t

  rcall WaitUART

  ldi t,0xA
  sts UDR0,t

  rcall WaitUART

  rjmp RX_END

ERROR_UNKNOWN:

  ldi ZH,HIGH(ErrorMessage2*2)
  ldi ZL,LOW(ErrorMessage2*2)

  rcall SendMessage

  rjmp RX_END


SEND_INFO:

  ldi ZH,HIGH(InfoMessage*2)
  ldi ZL,LOW(InfoMessage*2)

  rcall SendMessage



  rjmp RX_END

FRAMING_ERROR:

  ldi ZH,HIGH(ErrorMessage1*2)
  ldi ZL,LOW(ErrorMessage1*2)

  rcall SendMessage

RX_END:

  sei

  reti

                     ;Subroutines

SendMessage:

  lpm

  mov t,R0

  cpi t,0
  breq SEND_END

  sts UDR0,t

  rcall WaitUART

  ldi t,1
  ldi t1,0

  add ZL,t
  adc ZH,t1

  rjmp SendMessage

SEND_END:

  ret

WaitUART:           ;wait while sending the character

  lds t,UCSR0A
  sbrs t,UDRE0
  rjmp WaitUART

  ret
                      ;Predefinied messages
ErrorMessage1:

.db "Framing error",0xD,0xA,0

ErrorMessage2:

.db "Unknown command",0xD,0xA,0

InfoMessage:

.db "Commands: i-help, c-start conversion",0xD,0xA,0,0

HelloMessage:

.db "ADC on COM port by YS",0xD,0xA,0



Символы 0xD, 0xA в конце строк - это <CR><LF> - перевод строки и возврат курсора в начало. Для передачи данных бесполезны. Создают красоту для глаза.

[/IMHO]
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

YS, покритикую ваши советы.

во-первых, изменить отображение в отладочном терминале - это не значит, заставить программу выводить ЧИСЛА, это есть самообман. для вывода в терминал надо формировать символьные представления чисел.

во-вторых, ваш ассемблерный код, как обычно, начинается с кучи rjmp, которые все уполно выдают за таблицу векторов прерываний. именно за такой подход ассемблер считают плохим языком программирования.

в третьих, если вы такой любитель "компактного кода", то в вашей "таблице" сразу писали бы reti - стало бы на 2 байта короче программа! :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

во-первых, изменить отображение в отладочном терминале - это не значит, заставить программу выводить ЧИСЛА, это есть самообман.
Возможно, мы не поняли друг-друга. В моем понимании число - это собственно байт. Символами ЭВМ не оперирует. Передаваемый "символ" - тоже число, код картинки в таблице ASCII.

Так что в любом случае программа выводит именно ЧИСЛА, а мы, по-видимому, хотим КАРТИНКУ ЧИСЛА, составленную из КАРТИНОК символов, соответствующих кодам ASCII. Это уже вопрос к автору, что конкретно он хочет на выходе.
если вы такой любитель "компактного кода", то в вашей "таблице" сразу писали бы reti
Тогда программа потеряет в читаемости. Написание на ассемблере укорачивает программу не на два байта и даже не на десять...
которые все уполно выдают за таблицу векторов прерываний.
А что-же это такое на самом деле? :)))
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

[quote="YS]А что-же это такое на самом деле? :)))[/quote]на самом деле это десяток или сколько-то там подряд идущих коротких джампов :) если случайно в серединке одну строку убрать, то, если вы не семи пядей во лбу и не помните наизусть все вектора в конкретно взятом МК, то пара вечеров на поиски ошибки вам гарантирована :) а если число случайно захотите собрать этот код для какой-нибудь меги128 - вот тут-то мы вообще похохочем долго-долго...

ваш подход - повод давать сторонникам Си едкие замечания о проблемах переносимости программ на ассемблере даже в пределах одного семейства МК... ну и другую критику так же :)

кстати, STS для записи в регистры тоже не всегда удачный вариант в плане переносимости :) хотя, конечно, в целом, ассемблер дает много возможностей :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

... на самом деле это десяток или сколько-то там подряд идущих коротких джампов ...


Видимо, в этом и заключается отличие миропонимания ортодоксальных приверженцев С от миропонимания ортодоксов ассемблера :) .
... если случайно в серединке одну строку убрать, ...
То мы получим программу для другого контроллера. Этот код - отражение аппаратной сути железа, и с ним ничего не поделать. Кстати, отчасти поэтому я пишу имена прерываний. И еще, необязательно помнить все прерывания поименно - достаточно знать их количество. Считаем строчки, сравниваем с количесвом прерываний... Дальше понятно? :wink:
... о проблемах переносимости программ на ассемблере ...
О какой переносимости может идти речь применительно к прошивке? :shock: Это же код, изначально заточенный под конкретное железо! Другое железо - другой функционал - другая прошивка...

Однако не поймите меня неправильно. Я отнюдь не категорический противник С. Критерием оправданности использования С в прошивке микроконтроллера для меня является использование в проекте серьезной метематики, ибо написание, скажем, тригонометрических функций на асме я считаю мягкой формой мазохизма. :) Мой принцип можно сформулировать так: если главная задача контроллера в устройстве - дергать ногами и пересылать данные (ИМХО боьшинство "домашних" применений), то единственно правильный выбор - ассемблер. Здесь использование С даст больше проблем, чем плюсов. Если же контроллер будет преимущественно обрабатывать данные, да еще и по сложным алгоритмам с крутой математикой (обработка сигнала), то, конечно, разумно писать на высокоуровневом языке, чтобы не думать кроме алгоритма еще и, скажем, о размещении данных по регистрам - в этом случае нам это менее важно.

Отдельный случай - знакомство с МК начинающих. Все ЯВУ в той или иной мере скрывают работу железа. Как уже говорилось, в определенных случаях это удобно. Но не в том случае, когда собственно и стоит задача разобраться в устройстве контроллера. Так что начинать стоит однозначно с ассемблера.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

уж большего приверженца ассемблера на этом сайте, чем я, вам еще поискать придется! :) только не надо говорить, что ваш подход - по-настоящему верный.

верный подход не ваш или мой, а тот, который позволяет избежать проблем в его использовании. и поэтому все ИСПОЛЬЗУЕМЫЕ вектора надо описывать ТОЛЬКО так:

Код: Выделить всё

   .org VECTOR_ADDR
   rjmp VECTOR_PROC
а не используемые - вообще не указывать в программе. константы VECTOR_ADDR описаны в соответствующих include-файлах для каждого МК (как правило, их имена одинаковы, а адреса могут быть разными). в этом случае ничего помнить не придется - ни количество, ни размер вектора ни того, в каком именно порядке они определены в памяти - это сделает ассемблер САМ. и позволит на другой МК перенести программу с МИНИМУМОМ правки - если порты все одинаковые (что маловероятно, конечно) - может вообще ничего править не придется!!!

если бы все руководствовались минимальным набором правил приличия при написании ассемблерных программ - значительно меньше было бы критики этого подхода...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

ARV писал(а):

Код: Выделить всё

   .org VECTOR_ADDR
   rjmp VECTOR_PROC
Ух ты! :shock:
и позволит на другой МК перенести программу
А зачем? Если схема спроектирована под конкретный МК с конкретной прошивкой? МК это же не компьютер, на котором сегодня сидишь в Opera, а завтра рубишься в NFS. Обычно они выполняют функции, специфичные для данной схемы и принципиально непереносимые.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18756
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

YS писал(а):А зачем? Если схема спроектирована под конкретный МК с конкретной прошивкой? МК это же не компьютер, на котором сегодня сидишь в Opera, а завтра рубишься в NFS. Обычно они выполняют функции, специфичные для данной схемы и принципиально непереносимые.
не знаю, как у вас, а у меня постепенно проекты наполняются разными функциями и наступает момент, когда возможностей текущего Мк недостаточно - приходится переходить на другой. что же всю программу заново переписывать?! или из одной проги в другую кусок вставить - надо писать так, чтобы куски не пришлось переделывать...

ассемблер - это ЯЗЫК, а не набор камней для забивания зверя. когда на нем разговариваешь свободно, все становится проще - как и с тем же английским :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

что же всю программу заново переписывать?! или из одной проги в другую кусок вставить - надо писать так, чтобы куски не пришлось переделывать...
Ну, имена регистров скорее всего поправить придется, если эти МК не из одной серии. А вообще AVR совместимы сверху-вниз. А где можно писать без привязки к конкретным регистрам - я так и стараюсь делать.
ассемблер - это ЯЗЫК, а не набор камней для забивания зверя.
Правильно... Набор "камней" - это семейство процессоров... :)))
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Ответить

Вернуться в «Теория»