Страница 1 из 3

Прикошачиваем генератор к UART (Help!)

Добавлено: Чт апр 07, 2011 19:31:59
MrHowl22
Сразу скажу, дело муторное. В код я вникал достаточно долго. Хотя,может мало опыта. Или кто уже имел дело с этой прогой.

Нашел я, значит, в сети схему генератора. С исходным кодом, всеми ништяками.
http://www.rlocman.ru/shem/schematics.html?di=69926

Но, захотелось, чтоб стал это генератор универсальным. Ну, т.е. чтоб можно было по UART свои сигналы подгружать.
Ну, программку в Delphi? Которая в Com закидывает 256 символов – сварганил быстро

Открыл я, значит, исходник. И дело встало. С UART не работал, значит. :shock:
Передвинул кнопки, подцепил Com. Пробовал и так и эдак. Но, ничего внятно не заработало.

И так, что возжелал я получить.

Скажем, чтоб вместо генерации шума…

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

if (SG.flag==1)
		{
		GICR|=(1<<INT0);//set external interrupt to enable stop
		if (SG.mode==7)
			{
			//Noise
			do
			{
				R2RPORT=rand();               //                Генерация шума!!!!!!!!!
			}while(SG.flag==1);
			//set signal level to 0
			R2RPORT=0x00;
			//display generator OFF
			Menu_Update(SG.ON);
			//stop external interrupt
			GICR&=~(1<<INT0);
			//start timer menu active
			Timer2_Start();
			}
…контроллер начинал ожидать приема по UART. И когда принимал 255 символов, записывал в массив.
После чего, чтобы этот массив можно было генерировать, как и все вложенные в исходный код программы.

Собственно, у кого есть идеи? Приму любую помощь от более опытных. Буду весьма признателен.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Чт апр 07, 2011 22:40:25
Jack_A
MrHowl22 писал(а):После чего, чтобы этот массив можно было генерировать, как и все вложенные в исходный код программы.
Нешта я не разумею : как это можно "генерировать массив", если он уже принят по UART?

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пт апр 08, 2011 10:00:44
MrHowl22
Я в том плане, что "генерировать" - выдавать с выхода генератора.


PS
Ну, я так понял, это сложно. И на интерес ни кто заниматься таким не будет...

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вс апр 17, 2011 20:53:49
YS
Если честно, я не совсем понял вопрос. Ну взять и начать его воспроизводить после приема. В чем проблема? :dont_know:

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вс апр 24, 2011 18:24:01
MrHowl22
YS писал(а):Если честно, я не совсем понял вопрос. Ну взять и начать его воспроизводить после приема. В чем проблема? :dont_know:
Ну, взять построить телепорт отсюда и до Китая... На словах все просто. Если б мне так было просто, я бы совета не просил.
Например, я не понимаю, как они там задают частоту.
Да и на эмуляторе не могу толком настроить UART. Ругается невозможностью эмуляции каких-то там регистров.

Если это такая не проблема, то может хотя бы с нуля примерчик, который бы принимал 255 байт в массив, а потом его можно бы было вывести. Под Atmega 16 на 16 МГЦ

В идеале с возможностью регулировки частоты.

Программа примерно такого алгоритма
1. Ждет приема по UART
2. Принимает 255 символов в массив
3. Если массив не заполнен, а байты не идут в течении, скажем, 10 сек, заполнить остаток массива нулями.
4. Предложить выставить частоту генерации. (Ждем нового приема по UART)
5. Генерировать по нажатию кнопки ОК. (Ждем нового приема по UART)

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

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вс апр 24, 2011 19:35:52
YS
Да и на эмуляторе не могу толком настроить UART. Ругается невозможностью эмуляции каких-то там регистров.
Я уже много раз выражался по поводу эмуляторов. Купите макетку и тестируйте на ней. Сам так делаю, и советую всем.
Если это такая не проблема, то может хотя бы с нуля примерчик, который бы принимал 255 байт в массив, а потом его можно бы было вывести. Под Atmega 16 на 16 МГЦ
Простой пример со следующей логикой работы:

- изначально ожидает команды по UART;
- по приему команды CMD_FWD_BUFFER переходит в режим приема буфера, после приема 255 байт переходит обратно в режим ожидания команды;
- командами CMD_START_OUT/CMD_STOP_OUT можно запустить/остановить вывод массива в ЦАП на порту A.

Прошу прощения, писал на скорую руку (проверял только на компилируемость), так что не исключены ошибки. Но общая идеология такая.

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

//Device: ATmega16 @ 16MHz
#include <avr/io.h>
#include <avr/interrupt.h>

#define ST_IDLE			0
#define ST_RCV_BUFFER	1

#define CMD_FWD_BUFFER	1
#define CMD_START_OUT	 2
#define CMD_STOP_OUT	  3

volatile char wfm[255],status=ST_IDLE;

int wfmidx=0;

void ClearWfm(void)
{
  int i;

  for (i=0; i<255; i++)
    wfm[i]=0;

  wfmidx=0;
}

ISR (TIMER1_COMPA_vect)
{
  PORTA=wfm[wfmidx];

  ++wfmidx;

  if (wfmidx==255)
    wfmidx=0;
}

ISR (USART_RXC_vect)
{
  char v_udr=UDR;
  
  if (status==ST_IDLE) //understanding byte as command
  {
    if (v_udr==CMD_FWD_BUFFER) //PC is going to transmit a waveform buffer
	{
	  ClearWfm();
	  status=ST_RCV_BUFFER;
    }

    if (v_udr==CMD_START_OUT) //Starting timer, which controls DAC
	  TCCR1B=(1<<CS10);

	if (v_udr==CMD_STOP_OUT) //Stopping timer
	  TCCR1B=0;
  }
  
  if (status==ST_RCV_BUFFER) //if buffer reception is in progress
  {
    wfm[wfmidx]=v_udr;

	++wfmidx;

	if (wfmidx==255) //buffer is full, waiting for a next command
              {
	  status=ST_IDLE;
                wfmidx=0;
              }
  } 
}

void main(void)
{
  //port setup - connect R-2R DAC to portA
  DDRA=0xFF;
  PORTA=0;

  //UART setup: 8-N-1 @ 76800bps

  UCSRB=(1<<RXCIE) | (1<<RXEN);
  UBRRL=12;

  // T/C1 setup - enabling timer 1 interrupt on compare match
  //and setting OC1 value
  TIMSK=OCIE1A;
  OCR1A=0x0190;

  ClearWfm();

  sei();

  while (1);
}
P.S.

Форматирование кода почему-то расползлось... :dont_know:

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн апр 25, 2011 08:50:54
MrHowl22
О, суперспасибо. Попробуем...

Я сдал плату протравить знакомым травильщикам, но они мне ее уже месяц делают. ((( А покупать готовый макет - дорого и бессмыслено.

ЗЫ
Ых, выглядит красиво, а проверить не выходит. Протеус же должен эмулировать... А не эмулирует. Ну, что я делаю не так? :(

Еще мне прислали фотку бракованой платы, дабы продемонстрировать, что мой текстолит не просто где-то валяется, а честно испаганивается в попытках выполнить мой заказ. Еще к фотке были приложены извинения, на тему, что не поймут в чем дело, что такое впервые. И что еще через недельку, наверно, может быть... :shock:

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн апр 25, 2011 17:16:24
YS
Ну, что я делаю не так?
Вы используете эмуляторы вместо железа, это главная беда. :)

С платой понял.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн апр 25, 2011 23:20:49
MrHowl22
Нашел програмку на асемблере, работает на эмуляторе без проблем. По приходу на UART байта, сразу выкидывает на порт А.
Жаль, нельзя такие сложные асемблерныеконструкции кидать с С код, как есть. А то бы с прогой из первого поста замиксовал бы. создал бы массив, в который всю этабадяга последовательно складывалась бы. А там уже можно бы было и с реализацией выводы на ЦАП разобраться.

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

.include "m16def.inc" // файл определений atmega_16
.CSEG
         .ORG $000        ; (RESET) 
         RJMP   Reset
         .ORG $016
         RJMP   RX_OK     ; (USART,RXC) USART, Rx Complete
.ORG   INT_VECTORS_SIZE      	; Конец таблицы прерываний

      
.org 0x050 
.def temp1=r16 
start:
//------указатель адреса стека---------
reset:
ldi R16,low(ramend)
out spl,R16
ldi R16,high(ramend)
out sph,R16
//------------------------------------

//------настройка ввод/вывод----------
    ldi     r16, 0xFF
    out     DDRa, r16    ;порт А на вывод
   

//------------------------------------
;USART initializationUCSRA 7 11
;Communication Parameters: 8 Data, 1 Stop, Even Parity
;USART Receiver: On
;USART Transmitter: On
;USART Mode: Asynchronous
;USART Baud Rate: 9600
 
uart_init:	LDI 	R16, $00
		OUT 	UBRRH,R16
		LDI 	R16, $33
		OUT 	UBRRL,R16
 		LDI 	R16,$25
		OUT 	UCSRC, R16
		LDI 	R16,$00
		OUT 	UCSRA, R16
		LDI 	R16,$98
		OUT 	UCSRB, R16
		sei ; Включить глобальных прерываний
	; тело программы
		loop:
     	rjmp loop



;Обработка прерывания по окончании приема байта
 
RX_OK:  PUSH	R16
		IN	R16,SREG
		PUSH	R16
 
		IN	R16,UCSRA	;Читаем статус из UCSRA
		IN	R17,UDR		;Читаем данные из UDR
		ANDI 	R16,$1C
		BREQ	_END	;Проверяем на ошибки
		CLR  	R17
 _END:
 					    ;в R17 находится принятый байт
		POP	R16
		OUT	SREG,R16
		POP	R16
		out porta,r17
		RETI
Ладно, чет седня башка не варит уже. пойду спать.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вт апр 26, 2011 15:54:26
YS
А то бы с прогой из первого поста замиксовал бы. создал бы массив, в который всю этабадяга последовательно складывалась бы.
Так в моем посте в массив и складывается. :dont_know:

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Ср апр 27, 2011 16:38:51
MrHowl22
Складывается. Но, чет не работает на эмуляторе. Чет не так или с эмулятором или с прогой. Или я чет не могу запустить по человечески. Там же, он должен воспринимать байты, как команды, так что, не понятно. Толи, не воспринимает, то-ли непринимает. Это только по регистрам смотреть.

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


Шас попробую...


Укоротил код до минимума. Не работает... Непонятно, в чем дело.

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

//Device: ATmega16 @ 16MHz
#include <avr/io.h>
#include <avr/interrupt.h>

#define ST_IDLE         0
#define ST_RCV_BUFFER   1

#define CMD_FWD_BUFFER   1
#define CMD_START_OUT    2
#define CMD_STOP_OUT     3

volatile char wfm[255];

int wfmidx=0;


ISR (TIMER1_COMPA_vect)
{
  PORTA=wfm[wfmidx];

  wfmidx=wfmidx+1;

  if (wfmidx==255)
    wfmidx=0;
}


ISR (USART_RXC_vect)
{
  char v_udr=UDR;
      wfm[wfmidx]=v_udr;

   wfmidx=wfmidx+1;

   if (wfmidx==255) //buffer is full, waiting for a next command
                
     TCCR1B=(1<<CS10);
			   
              
   
}

void main(void)
{
  //port setup - connect R-2R DAC to portA
  DDRA=0xFF;
  PORTA=0;
  
   //UART setup: 8-N-1 @ 76800bps

  UCSRB=(1<<RXCIE) | (1<<RXEN);
  UBRRL=12;

  // T/C1 setup - enabling timer 1 interrupt on compare match
  //and setting OC1 value
  TIMSK=OCIE1A;
  OCR1A=0x0190;

    sei();

  while (1);
    
}

Ладно, потом еще покумекаю.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пт апр 29, 2011 00:19:27
MrHowl22
Так, UART работает...
Не адекватно, правда. Копаем дальше.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пт апр 29, 2011 19:23:54
YS
Укоротил код до минимума. Не работает... Непонятно, в чем дело.
Как раз в том и дело, что укоротили. Вы снесли весь конечный автомат.

Прежде чем укорачивать, разберитесь как работает полная версия...

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пт апр 29, 2011 20:48:09
MrHowl22
Понянтное дело, что после урезания она будет работать не так, как изначальная. Но, в общем и целом, запустилась. Интегрировал куски кода в ту большую прогу из первого поста. Теперь UART запускается, принимает (что он принимает - другой вопрос, ибо потом генерирует какую-то страшную кривульку, но принимает и складывает куда надо).

Хотел разобраться, как красиво и быстро подшить этот полученый массив в ту готовую прогу. Но, в ней все сигналы генерируются из массивов- констант. И просто так заменить константу на переменную не выходит. прога компилируется, но не выполняет надлежащих функций. Там какие-то асемблерные вставки в основе генерации; массивы указателей, на которых все держится и прочий высокоинтеллектуальный кошмар..

Захотелось таки взять книгу по программированию в WinAVR и основательно почитать. Но, адекватной, которую недавно скачивал, не нашел. Жаль...

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пт апр 29, 2011 21:36:51
YS
Захотелось таки взять книгу по программированию в WinAVR
Для начала я бы советовал разобраться с программирванием под x86 на "обычном" С.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн май 02, 2011 12:42:53
MrHowl22
Значицца, так... В исходной программе константы массивов занесены в секции, пронумерованные, соответственно в памяти read_only

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

const uint8_t squarewave[] __attribute__ ((section (".MySection2")))= //square wave
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Даже если не указывать,что это константы, толку не будет. Если же не указывать, где размещен массив, то в него можно без проблем принимать данные. Но, вот подпрограмма воспроизведения, написанная на асемблере, в котором я мало что шарю,продолжает обращаться к памяти программ, выдавая хаотичный набор данных.

А я надеялся, что можно будет тихо-мирно заменить одну из констант на циклически перезаписуемую переменную, да идело с концом. Ан нет... Печально.

Блин, я програмирование на ассемблере помню только основы, и то смутно... Что эта подпрога делает? Нет, ну в теории,понятно,что она должна делать. а вот как она это делает...

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

void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{
asm volatile(	"eor r18, r18 	;r18<-0"	"\n\t"
				"eor r19, r19 	;r19<-0"	"\n\t"
				"1:"						"\n\t"
				"add r18, %0	;1 cycle"			"\n\t"
				"adc r19, %1	;1 cycle"			"\n\t"	
				"adc %A3, %2	;1 cycle"			"\n\t"
				"lpm 			;3 cycles" 	"\n\t"
				"out %4, __tmp_reg__	;1 cycle"	"\n\t"
				"sbis %5, 2		;1 cycle if no skip" "\n\t"
				"rjmp 1b		;2 cycles. Total 10 cycles"	"\n\t"
				:
				:"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTA)), "I" (_SFR_IO_ADDR(SPCR))
				:"r18", "r19" 
	);
}

Небольшая програмка с выводом на ЖК показала, что UART принимает вне зависимости от поданого байты, либо 0 либо 128. А иногда, 128, которую тут жу сбрасывает в 0. Сперва я думал, этокосяк моей самописной программы - пересыльщика. Но, при тестировании оной на терминале, показало, что если ошибки при пересылке и встречаются, то не настолько критичные, чтобы превратить синус в хаотичный набор меандров.
ISR (USART_RXC_vect)
{
uint8_t v_udr=UDR;
sig[wfmidx]=v_udr;

++wfmidx;
LCDclr();
//LCDGotoXY(0, 1);
//CopyStringtoLCD(CLR2, 0, 1 );
LCDGotoXY(0, 1);
printf(" %5 bit", v_udr);

if (wfmidx==256)
wfmidx=0; //buffer is full, waiting for a next command
}

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вс май 22, 2011 20:05:51
MrHowl22
В mega 16 инверсный reset? Вроде, его надо для работы сажать на питание через 10КОм. А как быть, если программатор? Полностью отключать от питания и подрубать к нему?

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Вс май 22, 2011 20:36:28
YS
Программатор сам прижмет RESET.
Что эта подпрога делает?
Загружает данные из памяти программ (lpm) и выводит в порт.

Это инкремент адреса:

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

            "add r18, %0   ;1 cycle"         "\n\t"
            "adc r19, %1   ;1 cycle"         "\n\t"   
            "adc %A3, %2   ;1 cycle"         "\n\t"
Загрузка данных из памяти программ:

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

"lpm          ;3 cycles"    "\n\t"
И цикл:

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

            "sbis %5, 2      ;1 cycle if no skip" "\n\t"
            "rjmp 1b      ;2 cycles. Total 10 cycles"   "\n\t"
Код несколько заморочен оттого, что написан инлайном по правилам GCC. Я ассемблерные функции обычно пишу в отдельном файле, так проще.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн май 23, 2011 01:08:14
DX168B
Эх.... По этому я не пишу программы для МК на Си, так как мне,
ещё не совсем опытному кодеру int main(){while(1){Танец_С_Бубном(_infinite);}}
будет обеспечен по полной программе. :)))
Да и в Си для AVR, после ассемблера буду чувствовать себя слепым котёнком, не видя,
что там происходит на аппаратном уровне, хоть Си и облегчает организацию
сложных и не очень, алгоритмов.

Re: Прикошачиваем генератор к UART (Help!)

Добавлено: Пн май 23, 2011 15:30:50
MrHowl22
Ладно, вопрос такой. В Uniprof как выставить фьюзы в Atmega 16 под разные внутренние тактовые и под внешний кварц 16 Мгц.

А то, когда последний раз через нее прошивал, вроде по даташиту смотрел, а все равно забачил контроллер. Считывает вот так
Изображение