Duhas

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

623 posts in this topic

Duhas    35

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

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

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

Edited by admin
Добавил PDF

Share this post


Link to post
Share on other sites
-=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 Так чтоли ?

Share this post


Link to post
Share on other sites
Duhas    35

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

Share this post


Link to post
Share on other sites

Старт складской программы по Wi-Fi/ Bluetooth-чипам от Espressif

На склад КОМПЭЛ поступили чипы, модули и отладочные платы от компании Espressif Systems на базе ESP8266 и ESP32. Стоимость всех изделий данной линейки – в 2-3 раза ниже ближайших аналогов, чипы занимают минимальное место на плате, энергоэффективны и универсальны в применении

Подробнее...

neid    0

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

Share this post


Link to post
Share on other sites

Вебинар Литиевые ХИТы FANSO или что нужно знать инженеру о батарейках»

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

Подробнее...

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");*/
  }; 
}

Share this post


Link to post
Share on other sites
SaKV    1

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

Share this post


Link to post
Share on other sites
Geiby    5

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

Share this post


Link to post
Share on other sites
Aeore    0

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

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

Share this post


Link to post
Share on other sites
Geiby    5

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

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

Share this post


Link to post
Share on other sites
YurkaM    7

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

post-31916-1191585080_thumb.jpg

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

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

Share this post


Link to post
Share on other sites
Geiby    5

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

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

Share this post


Link to post
Share on other sites
YurkaM    7

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

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

Share this post


Link to post
Share on other sites
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 перечитывал - не пойму.

Share this post


Link to post
Share on other sites
Luck26    0

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

Share this post


Link to post
Share on other sites
YurkaM    7

для Geiby

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

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

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

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

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

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

Edited by YurkaM

Share this post


Link to post
Share on other sites
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

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

Edited by YurkaM

Share this post


Link to post
Share on other sites
Geiby    5

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

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

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

Share this post


Link to post
Share on other sites
Bugrim    2

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

Share this post


Link to post
Share on other sites
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" и будет тебе счастье!

Edited by YurkaM

Share this post


Link to post
Share on other sites
ESYA    0

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

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

Share this post


Link to post
Share on other sites
-=gga=-    1

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

Share this post


Link to post
Share on other sites
ss85    0
Я бы посоветовал тебе поставить протеус, там функций больше, да и визуально с ним работать проще.

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

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

Share this post


Link to post
Share on other sites
-=gga=-    1

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Similar Content

    • By small girl
      Привет, ребят! Кто возьмется написать на С протокол взаимодействия для сети микроконтроллеров. База: STM32 с bluetooth модулем HC-06,- slave. ПК - master?

      За вознаграждение
    • By LegionKC
      Добрый день.
      Экспериментирую с платой TP4056 и MK ATmega8, конкретнее - пытаюсь собрать простенькое зарядное устройство с выводом параметров при зарядке/разрядке на АЦП МК. Для измерения тока нашел ACS712. Думаю, что получится выводить ток при зарядке (т.е. когда идет питание на TP4056 и нагрузка отключена) и при разрядке (питание выключено, нагрузка подключена). Нагрузка - резистор. Возникла проблема с измерением напряжения на АКБ. Вернее, проблема с отсутствием идей как это сделать. Может какую-нибудь схему делителя напряжения нужно сделать? Прошу помочь советом. Схему из пэинта прилагаю.
      Спасибо.
       

    • By Геннадий Быков
      Уважаемые электронщики и им сочувствующие!
      Хочу на даче собрать макет морского маяка в человеческий рост. Но для этого необходима схема управляющая светодиодами. Основное, схема должна иметь независимое питание(Солнечная панель) и быть слаботочной (5-9 вольт). Как вижу я. Маяк ориентировочно высотой 1,50-1,80 м. В маяке, с низу до верха 6 окошек (по одному 5мм светодиоду). И на верху сам маяк из 8-ми 0,5 ваттных светодиодов установленных по кругу. С наступлением темноты, включаются диоды на "1 этаже" и раз в 5-10 минут происходит действие. Диоды поэтажно (снизу вверх) начинают загораться (как будто кто-то поднимается вверх по ступеням) и после загорания самого верхнего окна, через пару секунд, включается маяк. Поочередно по кругу (эффект метеора), со скоростью 2-3 сек на круг, делает оборотов 10 и выключается. Потом в обратной последовательности гасятся окошки (светодиоды) сверху в низ и остаются два нижних, периодически и независимо включающиеся и выключающиеся (эффект присутствия). И вновь через 5-10 минут вышеописанное действие. Буду очень признателен любым советам, ссылкам, помощью. Немного умею паять, немного знаю Ардуино. Готов в разумных пределах спонсировать, разработку и сборку.
    • By Vladislav7
      Добрый день.
       
      Необходимо разработать схему для изготовления печатной платы с установленным микроконтроллером (подобрать подходящий), также подобрать все электронные компоненты и написать программу.
      Цель следующая:
      Необходимо с помощью одного контроллера управлять двумя цепями состоящими из 15 светодиодов (мощность одного = 0,1 Вт) каждая, диоды одноцветные.
      При включении одной кнопки начинает мигать одна цепь. При включении второй - вторая. Возможность одновременного включения кнопок.
      Необходим датчик индикации на кнопке, который будет мигать в такт светодиодной цепи. Принцип кнопки как у аварийной сигнализации.
       
      Спасибо.
  • Сообщения

    • Моё мнение не претендует на истину и всего лишь мнение, опирающееся на свой опыт и имеющиеся факты. Например я атеист но таки есть некий "вселенский разум", который имеет много разных имён и названий. Но что то однозначно есть, независимо от верю/не верю. Как радиация и магнитное поле. Приборы фиксируют это нечто, значит это есть. А человеку свойственно всё объяснять с понятной ему точки зрения, по мере возможности, и естессно давать названия. Тому как всё непонятное и необъяснимое его пугает и настораживает. Увидел тарелка летит- нло, икона мироточит- чудо, один подрезал другого и сам влетел в столб- бог наказал.
    • Просто человек ,,вооообще,, нИкак ,нЕчего непонимает даже в разводке квартирной,ему реле не подключить,меняй фазу(хотя все правильно нарисовали),неменяй,ему ровно... Дорогой гость Сергей,тебе нужно найти реле на 220,протянуть по одному проводу от лампочек из каждого места посещения ,,фазного,,,который идет от двойного выключателя и хотябы один нулевой с любой лампочки...и всё соединить согласно схеме начертанной специально для вас очень подробно,даже в цвете соответствующим ,подписанному каждым элиментом,это ты понимаешь?если и это страшно,не нужно ручки к проводам тянуть....
    • Процесс называется самоиндукцией... 
    • Не сказал потому что „апарат“ самыи примитивный будет.   Зажал две жестянки, чиркнул, перегрело или не догрело - подправил. паралельно наверно кнопку поставлю для ручного управления. Требования к схеме минимальные....
    • Благодарствую ТС-у.
      До Волгограда дошло за 4дня.
      С уважением к Вам и вашему ремеслу.
    • Ладно. Ну допустим это был брат близнец. Тогда куда он так быстро изчес в открытом просматриваемом пространстве? Рыжего кота на зелёной траве видно за километр. Ох, не зря египтяне кошек почитали как посланников небес, призванных следить за людьми и оберегать их жилища от грызунов. В индии вообще 2000 священных культов и животных. Восточная культура тоже кишит фауной как булка изюмом. На Руси всю животину называли братьями нашими меньшими и божьими тварями т.е сотворённых богом (природой) для нужд божьих (природы) и его усмотрению. Только человек трактуя по своему использует их в своих целях, кого в суп кого на шапку. Мульт Тайная жизнь домашних животных в некой степени показывает что они есть часть разумного мира. Даже растения проявляют признаки разума. Например они запоминают того кто сломал ветку и испытывают шок когда обидчик рядом. Почему у одних цветы растут а у других вянут? Они чувствуют флюиды тонкого мира, недоступного сенсорике людей как собака чует "запах страха" т.е выбросом гормонов в кровь испугавшегося человека. Кто от души ухаживает за растениями у того они и растут хорошо. В лесу человек ощущает некую необъяснимую истому, спокойствие и очищение. Надо чаще выбираться из каменных джунглей на природу. Гороскоп друидов тоже во многом прав, ведь люди веками наблюдали за флорой и делали выводы. Флора и фауна земли древнее и мудрее человека. Думаю к этому стоит хотя бы иногда прислушаться, сопоставить факты и подумать.