음.. eeprom 자체에 바로 넣을수 있는 녀석도 있었다는 사실을 발견!

#define  PROGMEM   __ATTR_PROGMEM__
#define  EEMEM   __attribute__((section(".eeprom")))

[링크 :  http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html]
[링크 :  http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html]   

[링크 : http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38417]
신고

'embeded > AVR (ATmega/ATtiny)' 카테고리의 다른 글

AVT FFT + DAC = 보청기?  (0) 2012.01.18
AVR TWI 예제  (0) 2012.01.11
AVR EEPROM / CODE section 관련  (0) 2012.01.03
AVR ATmega용 JTAG과 AVR32 호환성?  (0) 2011.12.29
ATMEL AVR 시리즈별 플래시 / 메모리 용량  (2) 2011.12.29
avr ddr pin port  (0) 2011.12.28
Posted by 구차니

댓글을 달아 주세요

매번 헷갈리는 지라...
아무튼  PORT는 값을 쓰는 용도
PIN은 값을 읽어 들이는 용도
DDR은 읽는용으로 쓸지 쓰는 용으로 쓸지를 정해주는 용도이다.
DDR 값이 0 이면 PORT 에 쓰고
DDR 값이 1 이면 PIN 으로 읽어 오면 된다.

PORTA - Port A Data Register
DDRA  - Port A Data Direction Register
PINA  - Port A Input Pins Address 

The DDxn bit in the DDRx Register selects the direction of this pin.
If DDxn is written logic one, Pxn is configured as an output pin.
If DDxn is written logic zero, Pxn is configured as an input pin. 

Three I/O memory address locations are allocated for each port,

one each for the Data Register - PORTx,
Data Direction Register - DDRx,
and the Port Input Pins - PINx.

The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write.
In addition, the Pull-up Disable - PUD bit in SFIOR disables the pull-up function for all pins in all ports when set.

[링크 : http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf] 

[링크 : http://donghwada.tistory.com/entry/ATmega-Pin-Configurations-DDR-PORT-PIN]
신고
Posted by 구차니
TAG Atmel, AVR, DDR, pin, port

댓글을 달아 주세요

embeded/ARM2010.05.03 01:04
암용 JTAG 중에 자작가능한 것으로 Wiggler 라는 녀석이 있다.
eleparts에서 완제품 팔기도 하고, 회로도 구해서 만들수도 있다.
예전에 주워온 PalmPalm 보드에서 지원가능한지는 모르겠다.

아무튼 74AC244 칩이 핵심인듯
그러고 보니.. AVR에는 74HC244인데 호환이 되려나?


[링크 : http://www.eleparts.co.kr/front/productdetail.php?productcode=017023007001000006&sort=]


[링크 : http://www.frozeneskimo.com/electronics/arm-tutorials/jtag-wiggler-clone/]

검색을 해보니
74HC/HCT vs.74AC/ACT

"AC / ACT stands for Advanced CMOS Logic (ACL for short).
 HC / HCT stands for High-speed CMOS Logic (HCL).

The AC and ACT subfamilies are faster than the HC and HCT subfamilies, and draw some more power in some circuits. All chips in the AC* subfamily have lower output resistance than HC* and can sink and source 24 mA at logic levels and up 70 mA (typ) per gate for motor loads. As a result AC* gates can handle more than twice the current of HC* gates (50 - 70 mA vs. 24 mA). Note, though, that while most HC* chips have a 25 mA limit, the HC* driver chips such as the 74HC240 and the 74HC245 (i.e., buffers) can handle 35 mA per device, and a maximum of 75 mA per chip.

The AC & ACT families also draw about twice as much current as the HC & HCT chips (but we speaking here of microamps, so it's usually not a huge deal).

It is occasionally possible to find (high quality) motors that you can drive directly from an HC chip. For intermittent operation, such as you get with a quadcore, you COULD drive very efficient (i.e., very low-current) motors directly. You would definitely need a capacitor (say 0.47 uF) across each motor to keep the noise under control.

[링크 : http://www.extremetesting.tv/forums/showthread.php?t=16755]

머.. 결론은 It works! 라는데.. 흐음..

아래 문서에는 74HC244로 되어있다.
[링크 : http://files.tomek.cedro.info/electronics/doc/jtag/doc/openocd_preliminary_20060102.pdf]

아무튼, PalmPalm은 PXA255 칩이고 이녀석은 ARMv5TE 계열이고 Intel XScale 인데
[링크 : http://en.wikipedia.org/wiki/XScale]

일단은 Wiggler에서 지원하니 Wiggler 호환에서도 되지 않을려나?
[링크 : http://www.macraigor.com/cpus.htm]
신고
Posted by 구차니

댓글을 달아 주세요

원래 목적은, 임의의 인터럽트를 소프트웨어적으로 발생시키는 건데
딱히 그에 맞는 문서를 발견하지 못했다.

그와 유사한 것은
외부 인터럽트의 경우 입력으로 설정되어 있더라도, 핀값을 설정해서 임의로 인터럽트를 발동시킬수 있다고 한다.

[링크 : http://gnc.chungbuk.ac.kr/?module=file&act=procFileDownload&file_srl=38154&sid=bdc58bb2e09e0bbfb91e3d176e68a1cf]
신고
Posted by 구차니

댓글을 달아 주세요

타이머는 처음인데.. 머가 먼지 모르겠다 ㅠ.ㅠ
#include "stdio.h"
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"

static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

static int uart_putchar(char c, FILE *stream)
{
  if (c == '\n') uart_putchar('\r', stream);
  loop_until_bit_is_set(UCSR0A, UDRE);
  UDR0 = c;

  return 0;
}

#define OVERFLOW 256
#define TICKS_PER_SEC 1000
#define Prescaler 64

volatile unsigned int tic_time;

ISR(TIMER0_OVF_vect)
{
	tic_time++;
	TCNT0 = OVERFLOW - (F_CPU / TICKS_PER_SEC / Prescaler);
}

int main(void)
{
	/* for USART */
	UBRR0H = 0;
	UBRR0L = 8; // 115k with U2X = 0
	UCSR0A = 0x00; // U2X = 0;
	UCSR0B = 0xD8;
	UCSR0C = 0x06; //Asyncronous - no parity - 1bits(stop) - 8bits(data)

	DDRD = 0x00;

	stdout = &mystdout;

	TCCR0 = 0x04;     // Prescaler 설정
	TCNT0 = OVERFLOW - (F_CPU / TICKS_PER_SEC / Prescaler);// 오버플로우에 사용될 초기값
	TIMSK = 0x01;     // 오버플로우 인터럽트 허용
	sei();

	int count = 0;
	for(;;)
	{
		if(tic_time == 1000)
		{
			tic_time = 0;
			printf("c %d\n",count++);
		}
	}
    return 0;
}
일단 사용법을 몰라서. 구글 검색하다 나온 rcan 님의 블로그 내용을 일단 복사해서 붙여넣었다.
[링크 : http://rcan.net/560]


기본적인 내용은 printf() 사용하는 것들이고, F_CPU는 cpu 클럭에 관한 선언문으로
AVRStudio wizard 사용시 클럭을 넣어주면 생성되는 변수이다.

타이머 관련 내용은 다음과 같다.

ISR(TIMER0_OVF_vect) // 8bit Timer0 에 대한 인터럽트 루틴
TCCR0;             // 타이머 프리스케일러
TCNT0;             // 타이머/타운터용 초기값
TIMSK;              // 타이머 오버플로우시 인터럽트 발생

일단 TCCR0를 보자면


타이머/카운터 제어용 레지스터로서,

Bit 7 – FOC0: Force Output Compare
Bit 6, 3 – WGM01:0: Waveform Generation Mode
Bit 5:4 – COM01:0: Compare Match Output Mode
Bit 2:0 – CS02:0: Clock Select

에 대한 설정을 하게 된다.

TCCR0 = 0x04 에서 0은 WGM01:0=0 으로 아래의 테이블을 보면(엄밀하게는 0x48 값의 위치이다)
Timer/Counter Mode of OperationNormal로 되어있다.

Normal Mode


이 모드에서는 0에서 부터 255까지(8bit 타이머) 증가하며,
별도의 카운터 값 리셋은 하지 않으나 오버플로우 된상태로 계속 더하므로,
실질적으로 255다음에 0부터 계속 증가하게 된다. (TCNT0는 수정하는 즉시 그 값부터 증가하게 됨)


TCCR0 = 0x04 에서 4는 CS02=1로 아래의 테이블을 보면
clkT0S/64 (From prescaler) 라고 되어있다. 즉, 입력 클럭을 64로 나누어서 느긋하게 증가시킨다.




그리고 TCNT0
카운트를 위한 변수이고, 8bit timer/counter 이므로 0x00 에서 0xFF 즉, 0 에서 255 값을 가지며
255가 되면 overflow interrupt를 발생시킨후 0부터 다시 숫자를 증가시킨다. (normal mode)

그런데 이 변수에 복잡한 수식으로 값을 넣는 이유는 정확한 시간을 발생하기 위해서이다.
클럭마다 다르겠지만, 일단 클럭을 위에서 1/64로 주므로 64 clock 마다 1씩 증가된다.
16Mhz 에서 64clock 마다 인터럽트를 생성하면(F_CPU / Prescaler) 1초에 250,000 번 발생하게 되고
이 오버플로우 갯수를 세어 1000번을 묶으면 (tic_time == 1000 그리고 F_CPU / TICKS_PER_SEC / Prescaler)
1초에 250번의 오버플로우가 발생하게 된다.
그런데 오버플로우 값은 255 까지(총 256) 이므로, 0부터 증가해서 255까지 timer를 증가시키면
1초가 맞지 않게 되므로, TCNT0의 값을 OVERFLOW - 250 으로 하여 초기값을 맞춰주게 된다.
결과적으로 TCNT0의 값은 6이 된다.
(음.. OVERFLOW가 255여야 하지 않을려나..)



그리고 TIMSK는 이름대로 타이머 인터럽트 마스크 레지스터로,

Bit 1 – OCIE0: Timer/Counter0 Output Compare Match Interrupt Enable
Bit 0 – TOIE0: Timer/Counter0 Overflow Interrupt Enable

오버플로우시에 인터럽트를 발생시키거나
OCR0(Output Compare Register) 값과 TCNT0의 값이 동일할때 인터럽트를 발생시키도록 설정한다.

TIMSK = 0x01; 이므로 TOIE0가 설정되었고, 이 값은 overflow 시에만 인터럽트를 발생시키도록 한다.


신고
Posted by 구차니

댓글을 달아 주세요

  1. 제가 잘못 이해한건지...
    16Mhz에서 64clock마다 Counter를 증가시켜 250번(설정값)이 오버플로우되면 인트럽트가 발생하는거 아닌지요??

    2013.04.10 22:36 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 아.. 착각했나 보네요
      255로 overlfow시에 인터럽트 발생하니
      255 - 6 으로 한거인데 말이죠 ㅠ.ㅠ

      감사합니다

      2013.04.11 00:26 신고 [ ADDR : EDIT/ DEL ]


ATMega128의 데이터 시트에 나와있는, IO핀 연결 방법이다.
Pxn내부에는 다이오드와 캐패시터가 달려있고,
외부에는 풀업 저항을 달아주면 된다고 나와 있는데..

실제로 키트에다가 VCC - 스위치 - 풀업저항 - 핀 으로 연결하니
손이 근처에만 가도 눌린것 처럼 인식을 하는데.. 아마 안테나 처럼 민감해져서 그런게 아닐까 싶다.

안정적으로 확실하게 하기 위해서는


이런식으로 구성을 해주면 누를때만 1이 되고 떼면 0 으로 인식하게 된다.

일단 PORTD와 PORTE가 외부 인터럽트로 사용이 가능한데,
PORTE의 0번과 1번 핀은 UART0로 사용되므로,
디버깅을 위해서 printf를 UART0으로 사용할 경우에는 PORTD를 사용하여 테스트를 해보도록 한다.

소스코드



신고
Posted by 구차니

댓글을 달아 주세요

#include "stdio.h"

static int uart_putchar(char c, FILE *stream);

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
                                         _FDEV_SETUP_WRITE);

static int
uart_putchar(char c, FILE *stream)
{
  if (c == '\n')
    uart_putchar('\r', stream);
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
  return 0;
}

int
main(void)
{
  init_uart();
  stdout = &mystdout;
  printf("Hello, world!\n");

  return 0;
}
winavr의 설명에 의하면 위의 예제가 printf를 사용하기 위한 초기화라고 나와있다.
(일단 설명서는 잘 읽어야 제맛)

위의 예제는 범용적인 것이고,
실제로 적용하기 위해서는 두부분을 수정해야 한다.

 loop_until_bit_is_set(UCSRA, UDRE);
 UDR = c;

초기화해준 포트에 따라서

UART0를 했다면 UCSR0A / UDR0
UART1을 했다면 UCSR1A / UDR1

로 수정을 해주면된다.


UDRE는 선언상, 비트플래그의 순서로 배열되어 있으므로
굳이 UDRE0 / UDRE1 로 수정해주지 않아도 이상은 없었다.

참고로 stdio.h를 포함하면 3KB 정도 크기가 증가한다(ELF 기준)
"사본"은 아래 소스에서 printf 관련을 전부 삭제한것이다.


atmega128 에서 uart0 를 115200-N-8-1로 16MHz 클럭에서 초기화한 뒤 printf() 하는 예제

소스코드


신고
Posted by 구차니

댓글을 달아 주세요

  1. 112

    잘보고 갑니다`

    2009.11.04 04:22 신고 [ ADDR : EDIT/ DEL : REPLY ]

us-tech 사의 제품을 사용해서, 아래 링크의 예제를 사용하려고 했더니.
outp 매크로를 이용하는 구버전이라서 조금 고민하다가 데이터시트를 읽고 시도했다.

    /* for USART */
    UBRR0H = 0;
    UBRR0L = 8; // 115200bps with U2X = 0
    UCSR0A = 0x00; // U2X = 0;
    UCSR0B = 0xF8;
    UCSR0C = 0x06; // Asyncronous - no parity - 1bits(stop) - 8bits(data)


USART Baud Rate Register (UBRR) 은 일종의 divider의 설정값으로, 클럭을 분기하는데 사용하는 값이라고 생각이 된다.
아무튼 16.0MHz 같은녀석은, Error 율이 0% 인녀석이 일반적으로 사용하는 115k 이하에는 없으므로 그리 좋지 않다.

그리고 U2X는
Bit 1 – U2Xn: Double the USART Transmission Speed
This bit only has effect for the asynchronous operation. Write this bit to zero when using synchronous operation.
Writing this bit to one will reduce the divisor of the baud rate divider from 16 to 8 effectively doubling the transfer rate for asynchronous communication
라고 나와있 듯, asynchronous 모드에서만 작동이 되며, 클럭을 두배로 증가시켜 에러율을 줄이는 효과를 보인다.

아무튼, USART / UART를 설정하는데 사용되는 레지스터는
UCSR0A, UCSR0B, UCSR0C 세가지가 있으며

UCSR0A에는 U2X를 제외하면 실질적으로 전부 Status 레지스터이다.
• Bit 7 – RXCn: USART Receive Complete
• Bit 6 – TXCn: USART Transmit Complete
• Bit 5 – UDREn: USART Data Register Empty
• Bit 4 – FEn: Frame Error
• Bit 3 – DORn: Data OverRun
• Bit 2 – UPEn: Parity Error
• Bit 1 – U2Xn: Double the USART Transmission Speed
• Bit 0 – MPCMn: Multi-Processor Communication Mode

UCSR0B에는 인터럽트와 , TX / RX enable 를 설정하며
• Bit 7 – RXCIEn: RX Complete Interrupt Enable
• Bit 6 – TXCIE: TX Complete Interrupt Enable
• Bit 5 – UDRIEn: USART Data Register Empty Interrupt Enable
• Bit 4 – RXENn: Receiver Enable
• Bit 3 – TXENn: Transmitter Enable
• Bit 2 – UCSZn2: Character Size
• Bit 1 – RXB8n: Receive Data Bit 8
• Bit 0 – TXB8n: Transmit Data Bit 8

UCSR0C에는 눈에 익숙한 N-8-1 (No Parity - 8bit data - 1bit stop) 이러한 설정값을 조절한다.
• Bit 7 – Reserved Bit
• Bit 6 – UMSELn: USART Mode Select
• Bit 5:4 – UPMn1:0: Parity Mode
• Bit 3 – USBSn: Stop Bit Select
• Bit 2:1 – UCSZn1:0: Character Size
• Bit 0 – UCPOLn: Clock Polarity


데이터를 TX로 출력하려면 UDR0 = data; 를 하면된다.


소스코드



[링크 : http://www.us-technology.co.kr/lecture/lecture_main.asp?mode=1&smode=6]
신고
Posted by 구차니

댓글을 달아 주세요

요즘에는 대부분의 메인보드에 USB만 있을뿐 LPT(패러럴)나 COM(시리얼)이 없는 경우도 상당히 많다.
하지만 AVR을 프로그래밍 하려면 롬 라이터가 있어야 하는데,
이 장비의 경우 고가인데다가, 칩의 핀수에 맞는 커넥터를 구매 하여야 한다.

그런 이유로 현실적인 대안은 USB 시리얼/패러럴이나
시리얼 / 패러럴이 달린 구형 메인보드, 혹은 최상급의 메인보드를 구매 해야 한다.

그렇다고 하기에는 이래저래 돈이 많이 드는 관계로 조금이라도 덜 들고 편한쪽을 택하라면
USB ISP를 구매 하는게 좋을듯 하다.

유니텍의 경우 패러럴 포트를 내부에 26핀으로 별도로 꺼내서 유니텍에서 별도 판매 하는
패러럴 포트를 구매 하면 되지만, 이래저래 가격 부담도 크고, 유니텍스럽게 택배비는 착불이라서 기분도 나쁘고
그냥 USB ISP를 사는게 가장 효율적인 방안으로 생각이 된다.


---
나머지는 구매 후 적도록 ^^;
STK-500 이라는 것과 호환이 되고, USB-ISP 역시 일종의 USB 시리얼로 COM포트로 인식하고
(보드는 USB 시리얼 + STK500 제어용 칩으로 구성) 시리얼로 프로그램을 전송한다.
데이터 시트 상으로는 시리얼 프로그래밍에 관한 항목이 있으므로 이부분을 좀더 읽어 봐야 할 듯 하다.
신고
Posted by 구차니
TAG AVR, iSP, usb

댓글을 달아 주세요

결론 : 실패
원인 : 아직 모름..

일단 Ponyprog에서 포트 자동 탐지를 끄라고 한다.
  • PonyProg2000 (Freeware programmer esp. for PIC, ATmega, serial EEPROMs)
    • The INI file must be modified to get PonyProg to work: change „AutoDetectPorts=NO“!

[출처 : http://www-user.tu-chemnitz.de/~heha/bastelecke/Rund%20um%20den%20PC/USB2LPT/liste.htm.en]

일단 ponyprog.ini의 내용은 아래와 같다.



그리고 나서 해보니 먼가 되는듯한데.. 여전히 -16오류, 장치를 발견하지 못한다고 한다.
그래서 계속 검색을 해보니.. 그런 이유로 USB ISP가 나온거라는 식으로 되어 있어서 좌절 OTL

USB LPT / 도킹 전부 임베디드 장비에서 패러럴이 아닌 프린트 포트로 인식을 해서 안된대나..
일부 외국산 장비중에는 인식하는것도 있지만 강원전자꺼는 드라이버 문제인지 안된다고 한다.

[링크 : http://kldp.org/node/46808]
신고
Posted by 구차니

댓글을 달아 주세요