Duhas

Примеры Кода Для Avr

559 сообщений в этой теме

Duhas    35

Здесь будут помещаться различные примеры кода и прочего обсуждаемого в других темах. Также скидывайте сюда любую полезную информацию по AVR микроконтроллерам

Он-лайн книга: "Книга по программированию микроконтроллеров AVR (ассемблер)"

Atmel AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers: Atmel AVR4027 (Оптимизация кода от Atmel).pdf

Изменено пользователем admin
Добавил PDF

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
-=gga=-    1

Вот вам один кодок, для начала. Он 100% рабочий :)

Это пример работы USART на МК Atmega16 при частоте кварца 11,059000

#include <mega16.h> //обычный хидер
#include <m8_128.h> //хидер для битов
#include <delay.h>

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// Буфер - USART Receiver buffer
#define RX_BUFFER_SIZE 100
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
  {
  rx_buffer[rx_wr_index]=data;
 rx_wr_index ++; // инкремент индекса
 if (rx_wr_index == RX_BUFFER_SIZE)
  { 
 rx_wr_index=0;
  };

 ++rx_counter;
  if (rx_counter == RX_BUFFER_SIZE)
  {
  rx_counter=0;
  rx_buffer_overflow=1;
  };
  };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
// взять символ из созданного буфера USART
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

// Глобальные переменные

void main(void)
{
// Локальные переменные

PORTD=0x00;
DDRD=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;


// Global enable interrupts
#asm("sei")

delay_ms(100);//пауза
printf("Hello world\r\n"); //отправляем строчку и переходим на новую строчку, и возвращаем калитку.
delay_ms(100);//пауза
printf("-=gga=-\r\n");	
}

Теперь то я надеюсь флуд будет удалён :) Да и это :

Народ, по активнее будьте, не жалейте коды!!!!!

PS Так чтоли ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Duhas    35

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
neid    0

не знаю, будет ли вам это полезно, просто у меня была недавно задача прошить ATmega16-16PU, и сделал я это с помощью программатора на 5 поводков, который присутствует вот по етой ссылки, и еще много полезного для начинающих: http://www.123avr.com/07.htm

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=gga=-    1

Этот программатор уже не раз обсуждался на этом форуме :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
SaKV    1

Здравствуйте. :rolleyes: Вот код написал для управления матрйчным-LCD(Программа реализована на CodeVisionAVR).

Некоторые блоки программы закоментированны, взависимости какие функции управления LCD требуются.

#include <mega32.h>
#include <delay.h>
#include <mem.h>
#include <stdlib.h>
//--------------------------------------------------------------------------------------
unsigned char l_display_array[4][122];
unsigned char l_mask_array[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
/*struct IMG_DEF 
{ 
unsigned char width_in_pixels;	  
  	unsigned char height_in_pixels;	 
  	unsigned char *char_table; 
}; */
//--------------------------------------------------------------------------------------
void intn()
{									
PORTA=0x00;
DDRA=0xFF;

PORTB=0x00;
DDRB=0x07;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

MCUCR=0x00;
MCUCSR=0x00;

TIMSK=0x00;

ACSR=0x80;
SFIOR=0x00;
}
//--------------------------------------------------------------------------------------
void lcd_strobe_e(unsigned char ncontr)
{ 
delay_us(2);
  	if ( ncontr & 0x01 ) 
PORTB.1 &= 0;
  	if ( ncontr & 0x02 ) 
PORTB.2 &= 0;
  	delay_us(2);
  	PORTB.1 |= 1;
PORTB.2 |= 1;
}
//--------------------------------------------------------------------------------------
void lcd_out_ctl(unsigned char cmd, unsigned char ncontr)
{ 
PORTB.0 &= 0;
  	PORTA = cmd;
  	lcd_strobe_e(ncontr);
}
//--------------------------------------------------------------------------------------
void lcd_out_dat(unsigned char dat, unsigned char ncontr)
{ 
PORTB.0 |= 1;
PORTA = dat;
lcd_strobe_e(ncontr);
}
//-----------------------------------------------------------------
void lcd_init1(void)
{   
lcd_out_ctl(0,3);
lcd_out_ctl(0xE2,3);
delay_ms(100);   
lcd_out_ctl(0xAF,3);
  	lcd_out_ctl(0xA1,3); 
  	lcd_out_ctl(0xC0,3);
  	lcd_out_ctl(0xB8,3);
  	lcd_out_ctl(0x00+19,3);
} 
//--------------------------------------------------------------------------------------
void lcd_update(unsigned char top, unsigned char bottom)
{ 
unsigned char x, y, yt, yb, *colptr;   	
  	yb=bottom>>3;									
  	yt=top>>3;		

  	for(y=yt;y<=yb;y++)
	{ 
		lcd_out_ctl(0xB8+y,3);
//	 lcd_out_ctl(LCD_SET_COL+LCD_STARTCOL_REVERSE,3);
 		lcd_out_ctl(0x00+0,3);
		  colptr=&(l_display_array[y][0]);
		  for (x=0;x<122;x++)
   			{ 
   				if (x<61) 
				lcd_out_dat(*colptr++,1);
	 			else 
				lcd_out_dat(*colptr++,2);
   			}
	}
}
//--------------------------------------------------------------------------------------
void lcd_update_all(void)
{ 
lcd_update(0,31);
}
//--------------------------------------------------------------------------------------
void lcd_fill(unsigned char pattern)
{ 
unsigned char page, col;

  	for (page=0; page<4; page++) 
	{ 
		for (col=0; col<122; col++) 
	 	l_display_array

[col]=pattern;
	}
  	lcd_update_all();
}
//--------------------------------------------------------------------------------------
void lcd_erase(void)
{ 
lcd_fill(0x00);
  	lcd_update_all();
}
//--------------------------------------------------------------------------------------
void lcd_dot(unsigned char x, unsigned char y, unsigned char mode) 
{ 
unsigned char bitnum, bitmask, yByte;
  	unsigned char *pBuffer;
  	if ( ( x > 121 ) || ( y > 31 ) ) return;
  	yByte   = y >> 3; 
  	bitnum  = y & 0x07;
  	bitmask = l_mask_array[bitnum]; 
  	pBuffer = &(l_display_array[yByte][x]);
  	switch (mode) 
	{ 
		case 1:
	 	*pBuffer |= bitmask;
	 	break;
		  case 0:
	 	*pBuffer &= ~bitmask;
	 	break;
		  case 2:
	 	*pBuffer ^= bitmask;
	 	break;
		  default: break;
	}
}
//--------------------------------------------------------------------------------------
/*void lcd_line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int mode ) 
{ 
unsigned int length, xTmp, yTmp, i, y, yAlt;
  	int m;

  	if(x1 == x2) 
	{ 


		  if(y1 > y2) 
   			{ 
   				xTmp = x1;
	 			yTmp = y1;
	 			x1 = x2;
	 			y1 = y2;
	 			x2 = xTmp;
	 			y2 = yTmp;
   			}
		  length = y2-y1;
		  for(i=0; i<=length; i++) 
	 	lcd_dot(x1, y1+i, mode);
	} 
  	else 
  	if(y1 == y2) 
  		{ 
		  if(x1 > x2) 
   			{ 
   				xTmp = x1;
	 			yTmp = y1;
	 			x1 = x2;
	 			y1 = y2;
	 			x2 = xTmp;
	 			y2 = yTmp;
   			}

		  length = x2-x1;
		  for(i=0; i<=length; i++) 
	 	lcd_dot(x1+i, y1, mode);	   
	} 
 else 
	{ 

		  if(x1 > x2) 
   			{ 
   				xTmp = x1;
	 			yTmp = y1;
	 			x1 = x2;
	 			y1 = y2;
	 			x2 = xTmp;
	 			y2 = yTmp;
   			}		
		  if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) 
   			{ 

	 			length = x2-x1;							
	 			m = ((y2-y1)*200)/length;
	 			yAlt = y1;
	 			for(i=0; i<=length; i++) 
					  { 
						  y = ((m*i)/200)+y1;
						if((m*i)%200 >= 100)
		   				y++;
						else if((m*i)%200 <= -100)
		   				y--;

						lcd_line(x1+i, yAlt, x1+i, y, mode );
						if(length<=(y2-y1) && y1 < y2)
		   				yAlt = y+1;
						else if(length<=(y1-y2) && y1 > y2)
		   				yAlt = y-1;
						else
		   				yAlt = y;
					  }
   			} 
	   	else
   			{						
	 			if(y1 > y2)
					  { 
						  xTmp = x1;
						yTmp = y1;
						x1 = x2;
						y1 = y2;
						x2 = xTmp;
						y2 = yTmp;
					  }
	 			length = y2-y1;
	 			m = ((x2-x1)*200)/length;
	 			yAlt = x1;
	 		   	for(i=0; i<=length; i++)
					  { 
						  y = ((m*i)/200)+x1;

						if((m*i)%200 >= 100)
		   				y++;
						else if((m*i)%200 <= -100)
		   				y--;

						lcd_line(yAlt, y1+i, y, y1+i, mode);
						if(length<=(x2-x1) && x1 < x2)
		   				yAlt = y+1;
						else if(length<=(x1-x2) && x1 > x2)
		   				yAlt = y-1;
						else
		   				yAlt = y;
					  }
   			}
	}  
}*/	
//--------------------------------------------------------------------------------------
void lcd_circle(unsigned int xCenter, unsigned int yCenter, unsigned int radius, unsigned int mode) 
{ 
int tSwitch, y, x = 0;
unsigned int d;

  	d = yCenter - xCenter;
  	y = radius;
  	tSwitch = 3 - 2 * radius;

  	while (x <= y) 
	{ 
		lcd_dot(xCenter + x, yCenter + y, mode);
		  lcd_dot(xCenter + x, yCenter - y, mode);

		  lcd_dot(xCenter - x, yCenter + y, mode);
		  lcd_dot(xCenter - x, yCenter - y, mode);

		  lcd_dot(yCenter + y - d, yCenter + x, mode);
		  lcd_dot(yCenter + y - d, yCenter - x, mode);

		  lcd_dot(yCenter - y - d, yCenter + x, mode);
		  lcd_dot(yCenter - y - d, yCenter - x, mode);

		  if (tSwitch < 0) 
		tSwitch += (4 * x + 6);
		  else 
   			{ 
   				tSwitch += (4 * (x - y) + 10);
	 			y--;
   			}
		  x++;
	}
}
//--------------------------------------------------------------------------------------
/*void lcd_bitmap(unsigned int left, unsigned int top, struct IMG_DEF *img_ptr, unsigned int mode)
{ 
	unsigned int width, heigth, h, w, pattern, mask;
  	unsigned int* ptable;

  	width  = peekb(&(img_ptr->width_in_pixels));
  	heigth = peekb(&(img_ptr->height_in_pixels));
  	ptable  = (unsigned int*) peekw(&(img_ptr->char_table)); 

  	for ( h=0; h<heigth; h++ ) 
	{ 
		mask = 0x80;
		  pattern = peekb( ptable ); 
		  ptable++;
		  for ( w=0; w<width; w++ ) 
   			{
   				if ( pattern & mask ) 
				lcd_dot(w+left, h+top, mode);

	 			mask >>= 1;
	 			if ( mask == 0 ) 
					  { 
						  mask = 0x80;
						pattern = peekb( ptable );
						ptable++;
					  }	
   			}
	}
} */
//--------------------------------------------------------------------------------------
/*void lcd_glyph(unsigned int left, unsigned int top, unsigned int width, unsigned int height, unsigned int *glyph_ptr, unsigned int store_width)
{ 
	unsigned int bit_pos;
  	unsigned int byte_offset;
  	unsigned int y_bits;
  	unsigned int remaining_bits;
  	unsigned int mask;
  	unsigned int char_mask;
  	unsigned int x;
  	unsigned int *glyph_scan;
  	unsigned int glyph_offset;

  	bit_pos = top & 0x07;		
  	glyph_offset = 0;			 
  	char_mask = 0x80;			

  	for (x = left; x < (left + width); x++)
	{ 
		byte_offset = top >> 3;			
		  y_bits = height;		
		  remaining_bits = 8 - bit_pos;	
		  mask = l_mask_array[bit_pos];	
		  glyph_scan = glyph_ptr + glyph_offset;	 							  
		  while((y_bits) && (byte_offset < 4))  
   			{						 

	 			if(peekb(glyph_scan) & char_mask)
				l_display_array[byte_offset][x] |= mask;	
	 			else
				l_display_array[byte_offset][x] &= ~mask;	

	 			if(l_mask_array[0] & 0x80)
				mask >>= 1;
	 			else
				mask <<= 1;

	 			y_bits--;
	 			remaining_bits--;
	 			if(remaining_bits == 0)
					  {							  
						remaining_bits = 8;
						byte_offset++;
						mask = l_mask_array[0];
					  }		 			 
	 			glyph_scan += store_width;
   			}		  
		  char_mask >>= 1;
		  if(char_mask == 0)				
   			{ 
   				char_mask = 0x80;
	 			glyph_offset++;
   			}
	}   
}*/
//--------------------------------------------------------------------------------------
/*void lcd_box(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int mode) 
{
unsigned int i;
  	if (!width) return;
  	width--;	
  	for (i=y;i<y+height;i++) 
lcd_line(x, i, x+width, i, mode);
}*/
//--------------------------------------------------------------------------------------
/*void lcd_text_intern(unsigned int left, unsigned int top, unsigned int font, char *str, unsigned int inprogmem)
{ 
	unsigned int x = left;
  	unsigned int glyph;
  	unsigned int width;
  	unsigned int height, defaultheight;
  	unsigned int store_width;
  	unsigned int *glyph_ptr;
  	unsigned int *width_table_ptr;
  	unsigned int *glyph_table_ptr;
  	unsigned int glyph_beg, glyph_end;
  	unsigned int fixedwidth;

  	defaultheight = peekb ( &(fonts[font].glyph_height) );
  	store_width = peekb ( &(fonts[font].store_width) );
  	width_table_ptr = (unsigned int*) pgm_read_word( &(fonts[font].width_table) );
  	glyph_table_ptr = (unsigned int*) pgm_read_word( &(fonts[font].glyph_table) );
  	glyph_beg  = peekb( &(fonts[font].glyph_beg) );
  	glyph_end  = peekb( &(fonts[font].glyph_end) );
  	fixedwidth = peekb( &(fonts[font].fixed_width) );

  	if (inprogmem) 
glyph = peekb(str);

  	else 
glyph = (unsigned int)*str;

  	while(glyph != 0x00) // while(*str != 0x00)
	{	 		
		  if((glyph < glyph_beg) || (glyph > glyph_end))
	 	glyph = peekb( &(fonts[font].glyph_def) );


		  glyph -= glyph_beg;
		  if(fixedwidth == 0)
		// width=fonts[font].width_table[glyph];	
	 	width=peekb(width_table_ptr+glyph);
		  else 
	 	width = fixedwidth;

		  height = defaultheight;
		  //glyph_ptr = fonts[font].glyph_table + ((unsigned int)glyph * (unsigned int)store_width * (unsigned int)height);
		  glyph_ptr = glyph_table_ptr + ((unsigned int)glyph * (unsigned int)store_width * (unsigned int)height);

		  if(x > 121)
	 	x = 121;

		  if((x + width) > 121+1)
	 	width = 121 - x + 1;

		  if(top > 31)
	 	top = 31;

		  if((top + height) > 31+1)
	 	height = 31 - top + 1;

		  lcd_glyph(x,top,width,height,glyph_ptr,store_width);  

		  x += width;		
		  str++;			
		  if (inprogmem) 
	 	glyph = peekb(str);
		  else 
	 	glyph = (unsigned int)*str;	   
	}
}
//--------------------------------------------------------------------------------------
void lcd_text(unsigned int left, unsigned int top, unsigned int font, const char *str)
{
lcd_text_intern(left, top, font, str, 0);
}
//--------------------------------------------------------------------------------------
void lcd_text_p(unsigned int left, unsigned int top, unsigned int font, const char *str)
{ 
	lcd_text_intern(left, top, font, str, 1);
}*/
//--------------------------------------------------------------------------------------
void main(void)
{
intn();
lcd_init1();
while (1)
{		
	lcd_erase();	   

   /*	lcd_line(121,31,1,31,1);
	  lcd_line(121,1,1,1,1);
	  lcd_line(121,1,121,31,1);
	  lcd_line(1,1,1,31,1);
	  lcd_line(119,29,3,29,1);
	  lcd_line(119,3,3,3,1);
	  lcd_line(119,3,119,29,1);
	  lcd_line(3,3,3,29,1);*/				
	  lcd_circle(90,20,15,1);
	  lcd_circle(20,10,5,1);
	  lcd_update_all();
	  delay_ms(2000);		  

 /* 
	  lcd_text(5,4,FONT_SIX_DOT,"#abcdefghijkl");		  
	  lcd_text(5,20,FONT_SEVEN_DOT,"mnopqrstuwxyvz");*/		  


   /*	lcd_box(2,2,118,28,2);		  


  /*	lcd_erase();
	  lcd_text(4,7,FONT_EIGHTEEN_DOT,"12:34:56");*/		  


   /*	lcd_erase();
	  lcd_text(5,0,FONT_NINE_DOT,"EW12A03GLY");
	  lcd_text(5,16,FONT_SEVEN_DOT,"Proteus VSM");		  
	  lcd_box(0,0,121+1,31+1,LCD_MODE_XOR);	  
	  lcd_box(0,0,121+1,31+1,LCD_MODE_XOR);*/


   /*	lcd_bitmap(90, 1, &frame_bmp, 1);		  
	  lcd_erase();  */		

  /*
	  lcd_text_p(6,3,FONT_NINE_DOT,PSTR("Labcenter")); 
	  lcd_text_P(6,15,FONT_SEVEN_DOT,"Electronics");*/
  }; 
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=gga=-    1

А для какого это дисплея ? Есл можно, скажите название :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
SaKV    1

Конечно скажу эта программа написана под дисплей SED1520. Но переписать эту программу под любой другой дисплей не составляет ни какой сложности. И вот ещё что эта программа находится в разработке, и если кто хочет помочь в написании программы очень буду рад.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Geiby    5

Начинаю изучать AVR микроконтроллеры. Скажите какой купить для экспериментов? Скачал книжку "AVR микроконтроллеры. Вводный курс", пока читаю возник лишь один вопрос, а главное понятно написано. Там на AT90S2313 но их уже не производят. Возник вопрос: что такое подтяжка? Зачем она используется?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Aeore    0

Да какой угодно :) Я купил atmega128 и на днях возьму atmega16. Только платформу для испытаний осталось собрать. Будем изучать вместе :)

Подтяжка - резистор, который подключается к выходу микроконтроллера. Так выход представляет из себя, грубо говоря, открытый сток, который торчит наружу. Включение подтяжки позволяет подключить к нему внутри микроконтроллера резистор (вторым концом наверх - +Vdd).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Geiby    5

Всеравно насчет подтяжки не понял. Подтяжка-резистор одним концом на ногу вторым на +?

Что такое открытый сток (извините если вопрос выглядит глупым)? Собственно для чего?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
YurkaM    7

Внутри АВР-ок есть встроенные резисторы подтяжки. Их можно програмно включать или отключать.

post-31916-1191585080_thumb.jpg

Так выход представляет из себя, грубо говоря, открытый сток, который торчит наружу.

Нет, никакой там не открытый сток, а полноценный выход. Подтяжка полезна когда нога контроллера включена как вход.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Geiby    5

Почему она полезна когда нога как вход? Как это влияет? Как я понял на ногу подается некоторое (малое)положительное напряжение.

Кстати Юра а ты с каких AVRок начинал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
YurkaM    7

С 90S2313 начинал.. Вру! - с Z80 начинал (Spectrum)

Когда нога сконфигурирована как вход (регистр DDRx за это отвечает), то его входное сопротивление очень велико и нога как-бы болтается в воздухе, ловя всякие наводки. Включив подтяжку мы "поднимаем" потенциал на ноге к VCC (т.е. к +) через резистор. Теперь к примеру кнопку можно зацепить между входом МК и нулём. Нажал кнопку - на входе 0, отпустил - на входе +5 через внутренний резистор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Geiby    5

Спасибо! Теперь понял. Подтяжка обязательно нужна когда вывод является входом иначе МК не сможет определить когда будет 0 или будет ложно срабатывать при ловле случайной помехи. Этот вопрос закрыт. Теперь следующий, по работе таймера TCNTO:Таймер постоянно считает- напимер в любой момент времени считать с него и там будет какоето число от 0 до 255, или только при обращении к нему он будет считать- например обратился к нему, считал 0, обратился к нему во второй раз считал 1 и т.д. . Просто не пойму как работает кусочек программы которая формирует секундную задержку(частота 2400Гц):

Idi r17,30 ; Начальное значение счетчика 30

Idi r18,80 ; Начальное значение маркера 80

TimeLoop:

out TSNTO,r16 ; сохраняем содержимое таймера в r16

cp r16,r18; сравниваем r16 и r18

brne TimeLoop;Есни не равны то переходим к началу цикла

subi r18,-80;прибавляем 80 к r18

dec r17,30; уменьшаем r17 на 1

brne TimeLoop; К началу цикла

Вопрос таков если таймер постоянно работает то не может ли в начале цикла таймер сразу быть равным 80 и не отсчитает 80 циклов или если например 79 то отсчитает 1 вместо 80?

Прошу помощи разьеснить мне, а то эту страницу в книге уже раз 7 перечитывал - не пойму.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Luck26    0

Здраствуйте. Помогите разобраться. Пользуюсь CVAVR. Приобрёл недавно программатор AVRISP mkII - In-System Programmer. Первое что сделал - воткнул его в USB. Комп обнаружил новое устройство, но драйвер я найти на него не смог. Хотя с программатором в упаковке был диск. Может и не нужно устанавливать ничего?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
YurkaM    7

для Geiby

Честно говоря, для начинающих это какой-то неудачный пример. Хоть и несколько строчек, но как-то всё хитро завёрнуто :huh:

Ну, во-первых опечатки:

out TSNTO,r16 ; сохраняем содержимое таймера в r16
должно быть: in r16,TCNT0

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

В данном примере даже если не обнулять TSNT0 перед началом цикла, ошибка может быть только при первом проходе цикла. Из внутреннего цикла выходим когда счетчик сравняется с маркером r18, и потом сразу же этот маркер увеличивается на 80, т.е. по-любому счётчику опять придётся тикнуть именно 80 раз.

ИМХО, пример какой-то идиотский :wacko: К чему весь этот гемморой не понятно, возможно просто он вырван из контекста какой-то задачи, где это оправдано...

Изменено пользователем YurkaM

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
YurkaM    7
Здраствуйте. Помогите разобраться. Пользуюсь CVAVR. Приобрёл недавно программатор AVRISP mkII - In-System Programmer.... но драйвер я найти на него не смог. Хотя с программатором в упаковке был диск. Может и не нужно устанавливать ничего?

AVR studio имеет свои дрова на него.

Кстати, на диске, думаю есть инсталяшка AVR Studio. В процессе установки там можно установить галку чтобы поставились дрова для твоего девайса.

"Start the AVR Studio installation. During this installation the dialog box in the figure below will be presented to the user"

Если АВР Студио уже установлен, делай так:

Install USB driver after AVR Studio is installed

The USB driver can be installed even after AVR Studio have been installed by following these steps:

1. Open "Control Panel" on the PC (Windows 95 and Windows NT does not support USB)

2. Select "Add or Remove Programs"

3. Select "AVRStudio4" in the list of programs

4. Click on the "Change" button

5. Select "Modify"

6. Select "Install/upgrade USB Driver"

The USB driver is now properly installed on the PC

Но, по-моему, этот программатор/отладчик без АВР Студио работать вообще не может.

Изменено пользователем YurkaM

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Geiby    5

Таксссс. Понятно! Я тоже подумал что ошибка очень даже возможна при первом цикле, в остальных никогда.

Не, это просто пример. Акак ты посоветуешь сделать задержку на 2400 циклов?

Кстати ты на ассемблере пишешь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Bugrim    2

Помогите найти документацию на ATmega8515 желательно на руском!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
YurkaM    7

Скачивал большую книжку "Микроконтроллеры AVR семейства Mega А.В.Евстифеев 2007" с natahaus.ru. Там про все мега. Весит больше 10 метров, качество отличное. Если сам не найдёшь, могу залить на какой-нить файлообменник.

ps: А всё ж лучше иметь это в бумажном виде!

Вот живые ссылки (проверял):

http://rapidshare.com/files/30768468/Mikro...MEGA._2007_.rar

http://natahaus.ifolder.ru/1907153

Вообще на натахауз заходишь, регишся, потом вбиваешь в поиск по сайту "микроконтроллер AVR" или просто "AVR" и будет тебе счастье!

Изменено пользователем YurkaM

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ESYA    0

помогите разобраться с VMLAB .

как в VMLAB на вход мк подать импульсный сигнал 40 импульсов в секунду

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=gga=-    1

Я бы посоветовал тебе поставить протеус, там функций больше, да и визуально с ним работать проще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ss85    0
Я бы посоветовал тебе поставить протеус, там функций больше, да и визуально с ним работать проще.

А я бы рекомендовал купить или спаять опытную модель. Так как в протеусе много известных проблем. Да и вообще что может быть лучше чем живое устройство?:)

В протеусе, например, нельзя подключить отладчик к JTAG.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=gga=-    1

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

А спаять устройство не всегда возможно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: myrka
      Доброго дня! 
      Купил на барахолке вот такую плату





      на последней фото 2 черных провода в дальнейшем соединены 
      Это бегущая строка от игровых автоматов, на ней 2-мя цветами отображаются слоганы, хочу перепрошить в целях обучения.
      Вопросы:
      1) встречал ли кто-то описание этой микросхемы? (я в интернете не нашел, потратил 2 дня)
      2) есть на микросхеме разъем (10 ножек хорошо видно на последнем фото), как узнать их имена, за что отвечает каждая ножка? (есть некоторые предположения, но сомневаюсь в них)
      3) можно ли через CP2102-USB-UART-MODULE перепрошить вот эту микросхему, если да то как соединить?
    • Автор: Atreides
      Добрый день. Мне требуется реализовать программный юарт на атмеге16. Он нужен для того, чтобы принятые по нему данные отправить на аппаратный юарт. В интернете нашел примеры кода, но понять его мне трудно. Прошу вас словами в общих чертах объяснить принцип реализации программного юарта. Буду рад примерам, которые, на ваш взгляд, являются наиболее простыми и понятными. Заранее спасибо.
    • Автор: karomag
      Добрый день.
      Экспериментирую с подключение 7-сегментного индикатора к мк stm32. Индикатор с общим катодом. Соответственно для вывода цифры необходимо на анод каждого сегмента подать 1, а на общий катод 0. И тут я не могу понять какие токи будут через порты. Теоретически, пины МК подключенные через резистор 300 Ом к аноду (напряжение МК 3.3 В) то ток будет 4 мА, тогда на общем катоде должно быть 7 * 4 = 28 мА (цифра 8, т.е. горят все сегменты). Т.е. это небольшое, но превышение макс тока на ногу 20 мА. И надо общий вывод подключать через транзисторный ключ.
      Взял мультиметр. Результаты замера: ток каждого сегмента ~2.5 мА, ток общего катода 5 мА. Вот тут я подумал о школе Хогвардс))) Как все таки рассчитывается все таки ток на общем выводе? 
    • Автор: art_budka
      Ищу подрядчика для разработки проекта робота-рисовальщика. Есть бюджет, ТЗ. 
      Устройство представляет собой манипулятор передвигающий головку в плоскости XY в пределах жесткой рамы на которой установлены двигатели и направляющие перемещения. Головка представляет собой блок, отвечающий за передвижение закрепленного в фиксаторе объекта-пера по оси Z на расстояние до 20 мм. Фиксатор на элементе подъёма головки должен обеспечить жесткое закрепление предметов массой 10 - 80 грамм - кистей, шариковых ручек, карандашей и маркеров диаметром от 5 до 20 мм.
      Решение необходимо для обеспечения точных, многократно повторяющихся перемещений “пера” над плоской поверхностью. Для формирования движений в устройстве должна быть реализована электромеханическая схема, подключенная посредством USB-интерфейса к персональному компьютеру для отправки команд на манипулятор и получения обратной связи от контроллера манипулятора. 
      ТЗ, смета и бюджет через art_budka@rambler.ru 
    • Автор: EugenArt
      Всем доброго времени суток!
      в поиске не смог найти инфо, поэтому создал тему, не ругайте, если ошибся с веткой.
      Идея следующая, есть автомагнитола deh-3600MP c выходом Ip-bus.Хочу подружить магнитофон с мп3 плеером (есть от фм-трансмиттера, завтра куплю платку отдельного мп3). Сразу подчеркну, что хочу управление плеером (треки, теги, пауза и т.д) с головного устройства.
      предполагаю схему так:  ip-bus - avr - mp3 player.
      алгоритм avr-mp3 несложен и открыт, а вот описание протокола ip-bus нигде нет, форум витат.спб уже изучил, есть кусок кода работы авр и ip-bus, но не очень понятно, может подскажете набор команд ip-bus или что происходит по событию нажатию кнопки вперед/назад.
      Заранее благодарен.