반응형

unsigned char digit[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67};
unsigned char fnd_sel[4] = {0x08, 0x04, 0x02, 0x01};
unsigned char fnd[4];
int main()
{
 DDRC = 0xff; // led출력 설정
 DDRG = 0x0f; // TR 출력 설정
int i=0, count=0;
 while(1){
  count++;
 if (count == 10000)
   count = 0;
 fnd[3] = (count/1000)%10;
 fnd[2] = (count/100)%10;
 fnd[1] = (count/10)%10;
 fnd[0] = count%10;
  for (i=0; i<4; i++)
  { PORTC = digit[fnd[i]];
  PORTG = fnd_sel[i];
  _delay_ms(2); }

}
// 오른쪽 1의자리 부터 count
unsigned char digit[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67};
unsigned char fnd_sel[4] = {0x08, 0x04, 0x02, 0x01};
unsigned char fnd[4];
int main()
{
 DDRC = 0xff; // led출력 설정
 DDRG = 0x0f; // TR 출력 설정
int i=0, count=0;
 while(1){
  count++;
 if (count == 10000)
   count = 0;
 fnd[0] = (count/1000)%10;
 fnd[1] = (count/100)%10;
 fnd[2] = (count/10)%10;
 fnd[3] = count%10;
  for (i=0; i<4; i++)
  { PORTC = digit[fnd[i]];
  PORTG = fnd_sel[i];
  _delay_ms(2); }

}

 

 

1의자리 숫자는 컨트롤러 속도가 워낙 빨라서 변하는 값이 보이질 않네..

여기까지는 실습 예제가 있어서 쉽게 풀 수 있었다.

하지만 24시간 디지털 시계 만들기는 조금 까다로웠다.


unsigned char digit[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67};
unsigned char fnd_sel[4] = {0x08, 0x04, 0x02, 0x01};
unsigned char fnd[4];
int main()
{
 DDRC = 0xff; // led출력 설정
 DDRG = 0x0f; // TR 출력 설정
int i=0, count=0, j=0;
 while(1){
  count++;
 if (count == 1440 )
   count = 0;
 fnd[0] = (count/600)%3;
 fnd[1] = (count/60)%10;
 fnd[2] = (count/10)%6;
 fnd[3] = count%10;
  for(j=0; j<2800;j++){
  for (i=0; i<4; i++)
  { PORTC = digit[fnd[i]];
  PORTG = fnd_sel[i];
  _delay_ms(5); }}

}
시간은 정확하지 않지만 2800 부분 수정하여 정확한 시간을 맞출 수 있을 것 같다.

반응형

'Project > j-kit-128-1실습' 카테고리의 다른 글

FND_Display with Timer/Counter  (0) 2018.10.01
LED 제어  (0) 2016.02.26
FND 실습  (0) 2016.02.26
회로도 참고  (0) 2016.02.26
jkit switch 제어/ 인터럽트사용  (0) 2016.02.26
반응형

J_kit_128_1

전자 회로도 참고


jkit-128-1 회로도.pdf

 

 

 

반응형

'Project > j-kit-128-1실습' 카테고리의 다른 글

FND_Display with Timer/Counter  (0) 2018.10.01
LED 제어  (0) 2016.02.26
FND 실습  (0) 2016.02.26
FND 실습 1/100초 스탑워치, 24시간 디지털 시계만들기  (0) 2016.02.26
jkit switch 제어/ 인터럽트사용  (0) 2016.02.26
반응형

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

 unsigned int cnt=0;

unsigned int cntt=0;

void buzzer()

 PORTB = 0x02;

 _delay_ms(10);

 PORTB = 0x00;

 _delay_ms(10);

}

int main()

{

 DDRB = 0xFF;

 PORTB =0x00;

 DDRC = 0x01;

 PORTC = 0x00;

 DDRD = 0xe3;

 PORTD = 0x00;

 //PORTD = 0x40; // 1번째 녹색

 //PORTD = 0x80; // 2번째 녹색

 //PORTB= 0x01; // 3번째 녹색

 //PORTB= 0x40; // 1번째 빨강

 //PORTB= 0x80; // 2번째 빨강

 //PORTD = 0x20; // 3번째 빨강

 //  (PIND & 0xFF) == 0x0c // 선택 스위치 PIND4

 //  (PIND & 0xFF) == 0x14 // 전원부 스위치 PIND3

 // PIND4 0x10; 선택스위치

 // PIND3 0x08; 전원스위치 인터럽트

 

buzzer();

 while(1){

  PORTD = 0x40;

 if((PIND & 0x10)==0x00) // 선택 스위치

  cnt++;

 switch(cnt){  

case 1:

 PORTD = 0xc0;

 _delay_ms(20);

 break;


case 2:

 PORTD = 0xc0;

 PORTB = 0x01;

 _delay_ms(20); 

 break;


case 3:

 PORTD = 0x40;

 PORTB = 0x00;

 cnt=0;

 _delay_ms(20);

 break;

}


   if((PIND & 0x08) == 0x00){// 전원 스위치 

if(cnt == 0){

PORTC = 0x01;

_delay_ms(500);

PORTC = 0x00;

}

else if(cnt==1)

{

PORTC = 0x01;

_delay_ms(500);

PORTC = 0x00;

}

else if(cnt==2){

 PORTC = 0x01;

_delay_ms(500);

PORTC = 0x00;

}

 

 }

}


return 0;}


반응형
반응형

* 인터럽트 : 방해하다, 훼방놓다의 뜻, 긴급하거나 불규칙적인 사건의 처리, 외부와의 인터페이스, 폴링(polling)으로 처리하기에는 프로세싱 타임 낭비

HOW 

 - 현재 수행중인 일을 잠시 중단하고 급한 일을 처리

 - 일이 끝나면 본래의 일을 다시 이어서 수행

 - 이때, 급한 일을 해결하는 작업을 인터럽트 서비스 루틴이라 하는데, 각 인터럽트마다 고유의 인터럽트 서비스 루틴 존재

 - 인터럽트가 여러 개 동시에 걸리면 우선 순위에 따라 조치

* 인터럽트 서비스 루틴

 - 인터럽트가 발생하면 프로세서는 현재 수행중인 프로그램을 멈추고 상태 레지스터와 PC 등을 스택에 잠시 저장 후 인터럽트 서비스 루틴으로 점프, 인터럽트 서비스 루틴을 실행한 후에는 이전의 프로그램으로 복귀하여 정상적인 절차를 실행한다.


* 인터럽트 스위치로 1/100 스톱워치 만들기

 - 메인

1. 초기설정

2. state 변수 값 설정 : stop

3. 인터럽트 활성화

4. state 검사 후 stop 상태시 복사된 10초, 1초, 1/10초, 1/100초 변수를 디스플레이하고, go 상태면 현재의 10초, 1초, 1/10초, 1/100초 변수를 디스플레이
 - 인터럽트 INT4
1. state 값이 stop시 go 변경
2. state go 일시 stop으로 변경 후 이때 시간 값 복사 저장
 - 인터럽트 INT5
1. 변수 및 복사된 시간 값 0으로 초기화
2. state 값 stop으로 초기화

#include <avr/io.h> 

#include <avr/interrupt.h>

#define F_CPU 16000000UL

#define __DELAY_BACKWARD_COMPATIBLE__

#include <util/delay.h>

#define STOP 0

#define GO 1

volatile int cur_time = 0;

volatile int stop_time = 0;

volatile int state = STOP; 

unsigned char digit[]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67};

unsigned char fnd_sel[4] = {0x01, 0x02, 0x04, 0x08};

SIGNAL(SIG_INTERRUPT4) 

if (state == STOP)

 state = GO; 

  else 

state = STOP; 

  stop_time = cur_time; 

SIGNAL(SIG_INTERRUPT5) 

{

state = STOP; 

cur_time = 0; stop_time = 0; 

}

void init( ) 

{

DDRC = 0xff; // FND Data 

DDRG = 0x0f; // FND Select 

DDRE = 0xcf; // INT4, 5

PORTC = digit[0]; PORTG = 0x0f; EICRB = 0x0a; //falling edge 

EIMSK = 0x30; //interrupt en 

sei(); 

}


void display_fnd(int count) // 수행시간 = 약 10ms 

int i, fnd[4]; 

fnd[3] = (count/1000)%10; // 천 자리

fnd[2] = (count/100)%10; // 백 자리

fnd[1] = (count/10)%10; // 십 자리 

fnd[0] = count%10; // 일 자리 

for (i=0; i<4; i++)

{

PORTC = digit[fnd[i]];

PORTG = fnd_sel[i];

_delay_ms(2+i%2); 

}

}


int main()

{

init( );

while(1)

if (state == STOP)

display_fnd(stop_time);

else display_fnd(cur_time);

cur_time++;

}

}

반응형

'Project > j-kit-128-1실습' 카테고리의 다른 글

FND_Display with Timer/Counter  (0) 2018.10.01
LED 제어  (0) 2016.02.26
FND 실습  (0) 2016.02.26
FND 실습 1/100초 스탑워치, 24시간 디지털 시계만들기  (0) 2016.02.26
회로도 참고  (0) 2016.02.26
반응형

색상코드표 Colour table (triplet)



 

색상
name
rgb 색상명
name
rrggbb
(Triplet)
aliceblue f0f8ff
antiquewhite faebd7
aqua 00ffff
aquamarine 7fffd4
azure f0ffff
beige f5f5dc
bisque ffe4c4
black 000000
blanchedalmond ffebcd
blue 0000ff
blueviolet 8a2be2
brown a52a2a
burlywood deb887
cadetblue 5f9ea0
chartreuse 7fff00
chocolate d2691e
coral ff7f50
cornflowerblue 6495ed
cornsilk fff8dc
crimson dc143c
cyan 00ffff
teal 008080
darkcyan 008b8b
darkgoldenrod b8860b
darkgray a9a9a9
darkgreen 006400
darkkhaki bdb76b
darkmagenta 8b008b
darkolivegreen 556b2f
darkorange ff8c00
darkorchid 9932cc
darkred 8b0000
darksalmon e9967a
darkseagreen 8fbc8f
darkslateblue 483d8b
darkslategray 2f4f4f
darkturquoise 00ced1
darkviolet 9400d3
deeppink ff1493
deepskyblue 00bfff
dimgray 696969
dodgerblue 1e90ff
firebrick b22222
floralwhite fffaf0
forestgreen 228b22
fuchsia ff00ff
gainsboro dcdcdc
ghostwhite f8f8ff
gold ffd700
goldenrod daa520
gray 808080
green 008000
greenyellow adff2f
honeydew f0fff0
hotpink ff69b4
indianred cd5c5c
indigo 4b0082
ivory fffff0
khaki f0e68c
lavender e6e6fa
lavenderblush fff0f5
lawngreen 7cfc00
lemonchiffon fffacd
lightblue add8e6
lightcoral f08080
lightcyan e0ffff
lightgoldenrodyellow fafad2
lightgreen 90ee90
lightgrey d3d3d3
lightpink ffb6c1
색상
name
rgb 색상명
name
rrggbb
(Triplet)
lightsalmon ffa07a
lightseagreen 20b2ad
lightskyblue 87cefa
lightslategray 778899
lightsteelblue b0c4da
lightyellow ffffe0
lime 00ff00
limegreen 32cd32
linen faf0e6
magenta ff00ff
maroon 8000000
mediumaquamarine 66cdaa
mediumblue 0000cd
mediumorchid ba55d3
mediumpurple 9370db
mediumseagreen 3cb371
mediumslateblue 7b68ee
mediumspringgreen 00fa9a
mediumturquoise 48d1cc
mediumvioletred c71585
midnightblue 191970
mintcream f5fffa
mistyrose ffe4e1
moccasin ffe4b5
navajowhite ffdead
navy 000080
oldlace fdf5e6
olive 808000
olivedrab 6b8e23
orange ffa500
orangered ff4500
orchid da70d6
palegoldenrod eee8aa
palegreen 98fb98
paleturquoise afeeee
palevioletred db7093
papayawhip ffefd5
peachpuff ffdab9
peru cd853f
pink ffc0cb
plum dda0dd
powderblue b0e0e6
purple 800080
red ff0000
rosybrown bc8f8f
royalblue 4169e1
saddlebrown 8b4513
salmon fa8072
sandybrown f4a460
seagreen 2e8b57
seashell fff5ee
sienna a0522d
silver c0c0c0
skyblue 87ceeb
slateblue 6a5acd
slategray 708090
snow fffafa
springgreen 00ff7f
steelblue 4682b4
tan d2b48c
teal 008080
thistle d8bfd8
tomato ff6347
turquoise 40e0d0
violet ee82ee
wheat f5deb3
white ffffff
whitesmoke f5f5f5
yellow ffff00
yellowgreen 9acd32
반응형
반응형

컴파일러

비트표현

코드비젼

bit a,b,c; // 비트변수 선언

PORTA.0=0; // 출력

PORTA.0=1;

a=PORTA.0; // 입력

b=PORTA.1;

PORTA.0= ~PORTA.0; //토글

if(PORTB.0)PORTA.0=0;

if(!PORTB.0)PORTA.0=1;

AVR EDIT & AVRSTUDIO

ICC

IAR

비트 변수 선언 지원 안함

비트변수는 사용자가 구조체로 쓰기도 하지만, 불편

// bit 매크로
#define SetBit(x,y) (x|=(1<<y))
#define ClrBit(x,y) (x&=~(1<<y))
#define ToggleBit(x,y) (x^=(1<<y))
#define FlipBit(x,y) (x^=(1<<y)) // Same as ToggleBit.
#define TestBit(x,y) (x&(1<<y))
위와 같은 비트 매크로를 이용하기도 합니다.

포트 비트 조작 지원 안함

PORTA&=0xFE; // 0 출력

PORTA|=0x01; // 1 출력

출력포트 체크 및 출력

if(PORTB&0x01) PORTA&=0xFE;

if(!(PORTB&0x01)) PORTA|=0x01;

입력포트 체크 및 출력

if(PINB&0x01) PORTA&=0xFE;

if(!(PINB&0x01)) PORTA|=0x01;

 

비트 입출력 비교

코드비젼

AVR EDIT & AVRSTUDIO

ICC

IAR

if( 입력핀==0){} // PA.0==0?

if(!PINA.0){};

if(!(PINA&0x01)){};

if( 입력핀==1){} // PA.0==1?

if(PINA.0){};

if(PINA&0x01){};

출력핀=0; // PB.0=0

PORTB.0=0;

PORTB&=0xFE;

출력핀=1; // PB.0=1

PORTB.0=1;

PORTB|=0x01;

MCU에서 비트 제어를 제공 한다고 하면 컴파일러도 반드시 비트제어 표현이 가능 해야 합니다.

마스크 처리에 의한 비트제어 보다

직접 비트제어를 하는 것이 사용자 입장에서 편리합니다.

만약 포트 A.0을 읽어서 0이면 포트 B.0에 포트 A.0의 값을 반전 시켜서 넣는다고 하면

코드비젼 :

PORTB.0=~PINA.0

다른컴파일러 :

if(PINA&0x01){ PORTB&=0xFE; }

else PORTB|=0x01;

코드비젼 코드가 훨씬 간결 함을 알 수 있습니다.

컴파일러

volatile

코드비젼

 사용 안함

AVR EDIT & AVRSTUDIO

ICC

IAR

 인터럽트에서 사용하는 전역 변수는

volatile 형을 사용해야 합니다.

번거로우므로 전역변수는

모두 volatile 형으로 처리 하는 것이 편합니다.

예) volatile unsigned char i=0;

 

컴파일러

128 헤더파일

코드비젼

 #include <mega128.h>

AVR EDIT & AVRSTUDIO

 #include <avr/io.h>

ICC

 #include <iom128v.h>

IAR

 #include<iom128.h>

#include <ina90.h>


컴파일러

인터럽트

코드비젼

interrupt [EXT_INT0] void ext_int0_isr(void){}

interrupt [EXT_INT1] void ext_int1_isr(void){}

interrupt [EXT_INT2] void ext_int2_isr(void){}

interrupt [EXT_INT3] void ext_int3_isr(void){}

interrupt [EXT_INT4] void ext_int4_isr(void){}

interrupt [EXT_INT5] void ext_int5_isr(void){}

interrupt [EXT_INT6] void ext_int6_isr(void){}

interrupt [EXT_INT7] void ext_int7_isr(void){}

interrupt [TIM0_OVF] void timer0_ovf_isr(void){}

interrupt [TIM0_COMP] void timer0_comp_isr(void){ }

interrupt [TIM1_OVF] void timer1_ovf_isr(void){}

interrupt [TIM1_CAPT] void timer1_capt_isr(void){ }

interrupt [TIM1_COMPA] void timer1_compa_isr(void){ }

interrupt [TIM1_COMPB] void timer1_compb_isr(void){ }

interrupt [TIM1_COMPC] void timer1_compc_isr(void){ }

interrupt [TIM2_OVF] void timer2_ovf_isr(void){}

interrupt [TIM2_COMP] void timer2_comp_isr(void){ }

interrupt [TIM3_OVF] void timer3_ovf_isr(void){}

interrupt [TIM3_CAPT] void timer3_capt_isr(void){ }

interrupt [TIM3_COMPA] void timer3_compa_isr(void){ }

interrupt [TIM3_COMPB] void timer3_compb_isr(void){ }

interrupt [TIM3_COMPC] void timer3_compc_isr(void){ }

interrupt [USART0_RXC] void usart0_rx_isr(void){}

interrupt [USART0_DRE] void usart0_dre_isr(void){}

interrupt [USART0_TXC] void usart0_tx_isr(void){}

interrupt [USART1_RXC] void usart1_rx_isr(void){}

interrupt [USART1_DRE] void usart1_dre_isr(void){}

i nterrupt [USART1_TXC] void usart1_tx_isr(void){}

interrupt [ADC_INT] void adc_isr(void){}

interrupt [ANA_COMP] void ana_comp_isr(void){}

interrupt [EE_RDY] void ee_rdy_isr(void){}

interrupt [SPI_STC] void spi_isr(void){}

interrupt [TWI] void twi_isr(void){}

interrupt [SPM_RDY] void spm_rdy_isr(void){}

AVR EDIT & AVRSTUDIO

#include <avr/interrupt.h>

ISR(INT0_vect){}

ISR(INT1_vect){}

ISR(INT2_vect){}

ISR(INT3_vect){}

ISR(INT4_vect){}

ISR(INT5_vect){}

ISR(INT6_vect){}

ISR(INT7_vect){}

ISR(TIMER0_OVF_vect){}

ISR(TIMER0_COMP_vect){}

ISR(TIMER1_OVF_vect){}

ISR(TIMER1_CAPT_vect){}

ISR(TIMER1_COMPA_vect){}

ISR(TIMER1_COMPB_vect){}

ISR(TIMER1_COMPC_vect){}

ISR(TIMER2_OVF_vect){}

ISR(TIMER2_COMP_vect){}

ISR(TIMER3_OVF_vect){}

ISR(TIMER3_CAPT_vect){}
ISR(TIMER3_COMPA_vect){}
ISR(TIMER3_COMPB_vect){}
ISR(TIMER3_COMPC_vect){}

ISR(USART0_RX_vect){}
ISR(USART0_UDRE_vect){}
ISR(USART0_TX_vect){}

ISR(USART1_RX_vect){}
ISR(USART1_UDRE_vect){}
ISR(USART1_TX_vect){}

ISR(ADC_vect){}
ISR(ANALOG_COMP_vect){}
ISR(EE_READY_vect){}
ISR(SPI_STC_vect){}
ISR(TWI_vect){}
ISR(SPM_READY_vect){}

ICC

#pragma interrupt_handler ext_int0_isr: iv_INT0
void ext_int0_isr(void){ }
#pragma interrupt_handler ext_int1_isr: iv_INT1
void ext_int1_isr(void){ }
#pragma interrupt_handler ext_int2_isr: iv_INT2
void ext_int2_isr(void){ }
#pragma interrupt_handler ext_int3_isr: iv_INT3
void ext_int3_isr(void){ }
#pragma interrupt_handler ext_int4_isr: iv_INT4
void ext_int4_isr(void){ }
#pragma interrupt_handler ext_int5_isr: iv_INT5
void ext_int5_isr(void){ }
#pragma interrupt_handler ext_int6_isr: iv_INT6
void ext_int6_isr(void){ }
#pragma interrupt_handler ext_int7_isr: iv_INT7
void ext_int7_isr(void){ }

#pragma interrupt_handler timer0_ovf_isr: iv_TIMER0_OVF
void timer0_ovf_isr(void){ }
#pragma interrupt_handler timer0_comp_isr: iv_TIMER0_COMP
void timer0_comp_isr(void){ }

#pragma interrupt_handler timer1_ovf_isr: iv_TIMER1_OVF
void timer1_ovf_isr(void){ }
#pragma interrupt_handler timer1_capt_isr: iv_TIMER1_CAPT
void timer1_capt_isr(void){ }
#pragma interrupt_handler timer1_compa_isr: iv_TIMER1_COMPA
void timer1_compa_isr(void){ }
#pragma interrupt_handler timer1_compb_isr: iv_TIMER1_COMPB
void timer1_compb_isr(void){ }
#pragma interrupt_handler timer1_compc_isr: iv_TIMER1_COMPC
void timer1_compc_isr(void){ }

#pragma interrupt_handler timer2_ovf_isr: iv_TIMER2_OVF
void timer2_ovf_isr(void){ }
#pragma interrupt_handler timer2_comp_isr: iv_TIMER2_COMP
void timer2_comp_isr(void){ }

#pragma interrupt_handler timer3_ovf_isr: iv_TIMER3_OVF
void timer3_ovf_isr(void){ }
#pragma interrupt_handler timer3_capt_isr: iv_TIMER3_CAPT
void timer3_capt_isr(void){ }
#pragma interrupt_handler timer3_compa_isr: iv_TIMER3_COMPA
void timer3_compa_isr(void){ }
#pragma interrupt_handler timer3_compb_isr: iv_TIMER3_COMPB
void timer3_compb_isr(void){ }
#pragma interrupt_handler timer3_compc_isr: iv_TIMER3_COMPC
void timer3_compc_isr(void){ }

#pragma interrupt_handler usart0_rx_isr: iv_USART0_RX
void usart0_rx_isr(void){ }
#pragma interrupt_handler usart0_dre_isr: iv_USART0_DRE
void usart0_dre_isr(void){ }
#pragma interrupt_handler usart0_tx_isr: iv_USART0_TX
void usart0_tx_isr(void){ }

#pragma interrupt_handler usart1_rx_isr: iv_USART1_RX
void usart1_rx_isr(void){ }
#pragma interrupt_handler usart1_dre_isr: iv_USART1_DRE
void usart1_dre_isr(void){ }
#pragma interrupt_handler usart1_tx_isr: iv_USART1_TX
void usart1_tx_isr(void){ }

#pragma interrupt_handler adc_isr: iv_ADC
void adc_isr(void){ }
#pragma interrupt_handler ana_comp_isr: iv_ANA_COMP
void ana_comp_isr(void){ }
#pragma interrupt_handler ee_rdy_isr: iv_EE_RDY
void ee_rdy_isr(void){ }
#pragma interrupt_handler spi_isr: iv_SPI_STC
void spi_isr(void){ }
#pragma interrupt_handler twi_isr: iv_TWSI
void twi_isr(void){ }
#pragma interrupt_handler spm_rdy_isr: iv_SPM_RDY
void spm_rdy_isr(void){ }

IAR

#pragma pack=INT0_vect

__interrupt void INT0_interrupt(void){ }
#pragma pack=INT1_vect
__interrupt void INT1_interrupt(void){ }
#pragma pack=INT2_vect
__interrupt void INT2_interrupt(void){ }
#pragma pack=INT3_vect
__interrupt void INT3_interrupt(void){ }
#pragma pack=INT4_vect
__interrupt void INT4_interrupt(void){ }
#pragma pack=INT5_vect
__interrupt void INT5_interrupt(void){ }
#pragma pack=INT6_vect
__interrupt void INT6_interrupt(void){ }
#pragma pack=INT7_vect
__interrupt void INT7_interrupt(void){ }

#pragma pack=TIMER3_CAPT_vect
__interrupt void TIMER3_CAPT_interrupt(void){ }
#pragma pack=TIMER3_COMPA_vect
__interrupt void TIMER3_COMPA_interrupt(void){ }
#pragma pack=TIMER3_COMPB_vect
__interrupt void TIMER3_COMPB_interrupt(void){ }
#pragma pack=TIMER3_COMPC_vect
__interrupt void TIMER3_COMPC_interrupt(void){ }
#pragma pack=TIMER3_OVF_vect
__interrupt void TIMER3_OVF_interrupt(void){ }
#pragma pack=TIMER2_COMP_vect
__interrupt void TIMER2_COMP_interrupt(void){ }
#pragma pack=TIMER2_OVF_vect
__interrupt void TIMER2_OVF_interrupt(void){ }
#pragma pack=TIMER1_CAPT_vect
__interrupt void TIMER1_CAPT_interrupt(void){ }
#pragma pack=TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_interrupt(void){ }
#pragma pack=TIMER1_COMPB_vect
__interrupt void TIMER1_COMPB_interrupt(void){ }
#pragma pack=TIMER1_COMPC_vect
__interrupt void TIMER1_COMPC_interrupt(void){ }
#pragma pack=TIMER1_OVF_vect
__interrupt void TIMER1_OVF_interrupt(void){ }
#pragma pack=TIMER0_COMP_vect
__interrupt void TIMER0_COMP_interrupt(void){ }
#pragma pack=TIMER0_OVF_vect
__interrupt void TIMER0_OVF_interrupt(void){ }

#pragma pack=USART1_RXC_vect
__interrupt void USART1_RXC_interrupt(void){ }
#pragma pack=USART1_vect
__interrupt void USART1_interrupt(void){ }
#pragma pack=USART1_TXC_vect
__interrupt void USART1_TXC_interrupt(void){ }
#pragma pack=USART0_RXC_vect
__interrupt void USART0_RXC_interrupt(void){ }
#pragma pack=USART0_UDRE_vect
__interrupt void USART0_UDRE_interrupt(void){ }
#pragma pack=USART0_TXC_vect
__interrupt void USART0_TXC_interrupt(void){ }

#pragma pack=ADC_vect
__interrupt void ADC_interrupt(void){ }

#pragma pack=ANA_COMP_vect
__interrupt void ANA_COMP_interrupt(void){ }

#pragma pack=SPI_STC_vect
__interrupt void SPI_STC_interrupt(void){ }

#pragma pack=TWI_vect
__interrupt void TWI_interrupt(void){ }

#pragma pack=EE_RDY_vect
__interrupt void EE_RDY_interrupt(void){ }

#pragma pack=SPM_RDY_vect
__interrupt void SPM_RDY_interrupt(void){ }


컴파일러

인터럽트 허가/금지

코드비젼

#asm("sei")

#asm("cli")

AVR EDIT & AVRSTUDIO

sei();

cli();

ICC

SEI();

CLI();

IAR

__enable_interrupt();

__disable_interrupt();


컴파일러

메인함수

코드비젼

void main(void){}

AVR EDIT & AVRSTUDIO

int main(void){}

ICC

void main(void){}

IAR

void main(void){}


컴파일러

FLASH

코드비젼

flash table[] = { 1, 2, 3 };

c= table[x];

i= table[x];

AVR EDIT & AVRSTUDIO

prog_uchar table[] = { 1, 2, 3 };

c=pgm_read_byte(&table[x]);

i=pgm_read_word(&table[x]);

ICC

__flash int table[] = { 1, 2, 3 };
__flash char hello[] = "Hello World";
__flash char *ptr1;
char * __flash ptr2;
__flash char * __flash ptr3;

IAR

__flash char str[] = {"abcdefg"};

__flash char str1[]={"12345"};

__flash char str2[]={"23456"};

char __flash * __flash *strP;

flash fdata[][100]={{0x02,0xf0,.......},{0x00,....}};
char flash *p ;

p = &fdata[0][0];


컴파일러

내부 EEPROM

코드비젼

eeprom int foo = 0x1234;
eeprom char table[] = { 0, 1, 2, 3, 4, 5 };

int i=3;

foo=i;

i-foo;

AVR EDIT & AVRSTUDIO

#include <avr/eeprom.h>

eeprom_write_dword((uint32_t*)0, i);

i= eeprom_read_dword((uint32_t*)0);

eeprom_write_byte((uint8_t*)EE_ADD, c);
c= eeprom_read_byte((uint8_t*)EE_ADD);
eeprom_write_dword((uint32_t*)EE_ADD, L);
L= eeprom_read_dword((uint32_t*)EE_ADD);

ICC

//Initializing EEPROM
#pragma data:eeprom
int foo = 0x1234;
char table[] = { 0, 1, 2, 3, 4, 5 };
#pragma data:data

//Accessing EEPROM
int i;
EEPROM_READ(0x1, i); // read 2 bytes into i
int i;
EEPROM_WRITE(0x1, i); // write 2 bytes to 0x1

EEPROMWriteBytes(int location, void *ptr, int size)
EEPROMReadBytes(int location, void *ptr, int size)

IAR

__eeprom int i;
int temp;
i=23; //write 23 to EEPROM
temp=i; //read from EEPROM into temp


컴파일러

delay

코드비젼

#include <delay.h>

delay_us(1000); // 1msec

delay_ms(1000); // 1sec

AVR EDIT & AVRSTUDIO

# define F_CPU 16000000UL

#include <util/delay.h>

_delay_us(1000); // 1msec

_delay_ms(1000); // 1sec

ICC

IAR


mega128 위주로 작성된 자료이므로 다른 다비이스에서는 내용이 다를 수 있습니다.

디바이스 헤더 파일 참고해서 맞는 것을 사용하세요

컴파일러를 모두 사용하는 것이 아니므로 일부 틀린 내용이 있을 수 있습니다.

또, 컴파일러 버전에 따라서 계속 변경 되는 부분이 발생 합니다.

잘못된 부분 / 빠진 부분/ 버전에 따라서 달라진 부분

아래 댓글로 알려주시면 수정 하겠습니다. ^^


반응형

'Study > 8-bit MCUs' 카테고리의 다른 글

B/T LED Control circuit  (0) 2017.04.10
led 제어 현재 상황  (0) 2016.02.26
pwm duty  (0) 2015.06.11
Atmega128을 이용하여 Duty 50%, 10[Khz] Clock을 출력하는 방법  (0) 2015.06.11
Atmega128 타이머 참고  (0) 2015.06.09
반응형

PWM 기본 파형은 위와 같습니다.

여기서 PWM Period는 일정합니다. Frequency는 1/Period이므로 이역시 일정합니다.

대신 On시간과 Off 시간의 비율을 변화시켜 전체적인 평균값을 조절해서 속도나 밝기를 제어하는 것입니다.

 

답변1) 이전에는 Frequecy대신 Cycle이란 말도 사용했는데, 이는 같은 의미입니다.

 

답변2) 맞습니다.

 

답변3) Duty = On시간/Period x 100(%) 로 표현합니다. 즉 Duty = 90%라고 하면 위그림에서 제일 아래쪽것과 비슷한 형태로 전체 주기에 대해 90%가 On이고, 나머지 10%동안은 OFF라는 의미입니다.

 

답변4)최소 0%는 이해가 되는데, 최대 3188%의 의미는 모르겠네요... 100%면 충분한데, 단지 3188%까지 설정을 가능하겠지만 굳이 그렇게 사용할 필요는 없을것입니다.

 

답변5) 이부분이 쉽지 않습니다.

Duty는 어짜피 속도제어이지만 Frequency 설정은 그때그때마다 다릅니다.

모터는 인덕터(코일)로 이루어진 부하입니다. 따라서 주파수를 너무 높이면 코일특성때문에 전류가 잘 흐르지 않아서 최대 출력을 내지 못하거나, Duty 비율에 따른 속도가 비례적이지 않고, 어느정도 Duty값인 높이면 갑자기 속도가 증가합니다.

그렇다고 기본주파수를 낮추면 회전이 자연스럽지 못하고, 마치 스테핑모터처럼 움직이고, 모터내에서 소음이 발생합니다.

 

반면에 전구와 같은 인덕터 성분이 없는 부하는 주파수를 높이는 것이 좋습니다.

 

보통 모터는 수백Hz내와 전구밝기조절의 경우 수kHz정도를 사용합니다.

 

반응형
반응형

1. GPIO방법은 간단하죠

DDRA.0=1; // out
while(1){

PORTA.0=1; delay_us(50); PORTA.0=0; delay_us(50);

}

장점 : 임의의 포트에 출력 할 수 있습니다.

단점 : 다른 코드가 존재하는 경우 주파수를 맞추기 어렵습니다.



 


2. (비교매치)타이머 인터럽트를 사용하는 방법

오버플로우 인터럽트를 사용 할 수도 있으나 비교매치 인터럽트가 정확합니다.

DDRA.0=1; // out
TCCR0=0x0B; OCR0=24; TIMSK=2; //16000000/32/(1+24)=20000Hz=50us
SREG=0x80; // sel

interrupt [TIM0_COMP] void timer0_comp_isr(void){ // 50us 주기

PORTA.0=~PORTA.0; // PA0 토글
}

장점 : 임의의 포트에 출력 할 수 있습니다.

단점 : 다른 인터럽트가 존재하는 경우 주파수 오차가 발생합니다.




3. CTC 토글모드를 사용하는 방법

DDRB.5=1; // out
TCCR1A=0x40; TCCR1B=9; TCCR1C=0x80; OCR1A=799; //16000000/ 1/(1+799)=20KHz=50us
장점 : 정확한 주파수를 출력

단점 : 특정핀에서만 출력이 가능, 50% 듀티만 가능




4. FAST PWM 출력을 사용하는 방법

DDRB=0x20; // PB5 out
TCCR1A=0x82; TCCR1B=0x1A;
// FAST PWM, 16Mhz/8분주=0.5usec
OCR1A=99; ICR1=199;
// 0.5usec*(1+199)=100usec=10KHz

장점 : 정확한 주파수를 출력, 임의의 듀티도 가능

단점 : 특정핀에서만 출력이 가능



예) AT90USB1287 OC2B 핀으로 주파수 출력

void PWM_START(void)

{

DDRD |= 0x03; // PD6 is now an output

OCR2B = 128; // set PWM for 50% duty cycle

//Output Compare Register 0~255 숫자. 127인 경우 5:5듀티임.

TCCR2A |= (1 << COM2B1); // set none-inverting mode

TCCR2A |= (1 << WGM21) | (1 << WGM20); // set fast PWM Mode

TCCR2B |= (1 << CS22)|(1 << CS21)|(0 << CS20); // set prescaler to 64 and starts PWM

}

void PWM_STOP(void)

{

TCCR2A = 0x00; //Normal port operation, OC2 disconnected

DDRD &= ~0x03;

}




예) Atmega329pa pwm test OC1A 핀으로 주파수 출력

void fnInit_Timer(void) //100msec //OK

{

//Clear OC1A/OC1B on Compare Match (Set output tolow level).

//MODE:Fast PWM, 9-bit

//TOP:0X01FF

//clkI/O/8 (From prescaler)


TCCR1A=0x82; TCCR1B=0x19; // 1Mhz = Fast PWM, 9-bit

OCR1AL=124; ICR1L=249; // 1M / 4K(부저주파수) = 250이며 0부터 시작이기 때문에 (250-1)

}



위에서 1+799 라든가 1+199라고 적은 것은

0~799, 800

0~199, 200

0~99, 100

카운터가 0부터 시작하기 때문에 1 적은 수를 넣어줘야지 정확한 카운트가 됩니다.

다른 종류PWM이 한가지 더 있지만 생략합니다.


반응형
반응형
타이머에 관련된 것만 체크하면
mcu 클럭이 있고(외부 16Mhz X-TAL 혹은 내부8MHz 등)
TCNT 카운터용 타이머 클럭이 있습니다.
16Mhz를 프리스케일러를 사용해서 분주 시켜서 타이머 클럭을 만들고
그 클럭마다 1씩 TCNT가 증가합니다.


// TCCR0 FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
// TCCR0=1:1/1, TCCR0=2:1/8, TCCR0=3:1/32, TCCR0=4:1/64, TCCR0=5:1/128, TCCR0=6:1/256, TCCR0=7:1/1024
//
// Compare Output Mode & Waveform Generation Mode
// TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
//
// TCCR1B ICNC1 ICES1 ? WGM13 WGM12 CS12 CS11 CS10
// TCCR1B=1:1/1, TCCR1B=2:1/8, TCCR1B=3:1/64, TCCR1B=4:1/256, TCCR1B=5:1/1024
//
// TIMSK OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0

// Compare Overflow InputCapture CompareA CompareB Overflow Compare Overflow
//=====================================================

// 타이머0 오버플로우 인터럽트
TCCR0=4; TCNT0=6; TIMSK=1; //16000000/ 64/250=1000Hz=1ms, (256-250)=6
TCCR0=5; TCNT0=131; TIMSK=1; //16000000/ 128/125=1000Hz=1ms, (256-125)=131
TCCR0=5; TCNT0=6; TIMSK=1; //16000000/ 128/250= 500Hz=2ms, (256-250)=6
TCCR0=6; TCNT0=6; TIMSK=1; //16000000/ 256/250= 250Hz=4ms, (256-250)=6
TCCR0=7; TCNT0=6; TIMSK=1; //16000000/1024/250=62.5Hz=16ms, (256-250)=6

// 타이머0 매치 인터럽트
TCCR0=0x0B; OCR0= 49; TIMSK=2; //16000000/ 32/(1+ 49)=10000Hz=100us
TCCR0=0x0C; OCR0=249; TIMSK=2; //16000000/ 64/(1+249)= 1000Hz=1ms
TCCR0=0x0D; OCR0=124; TIMSK=2; //16000000/ 128/(1+124)= 1000Hz=1ms
TCCR0=0x0D; OCR0=249; TIMSK=2; //16000000/ 128/(1+249)= 500Hz=2ms
TCCR0=0x0E; OCR0=249; TIMSK=2; //16000000/ 256/(1+249)= 250Hz=4ms
TCCR0=0x0F; OCR0=155; TIMSK=2; //16000000/1024/(1+155)= 100.16..Hz=9.984ms
TCCR0=0x0F; OCR0=249; TIMSK=2; //16000000/1024/(1+249)= 62.5Hz=16ms

// 타이머1 오버플로우 인터럽트
TCCR1B=1; TCNT1=49536; TIMSK=4; //16000000/ 1/16000=1000Hz=1ms, (65536-16000)=49536
TCCR1B=1; TCNT1=33536; TIMSK=4; //16000000/ 1/32000= 500Hz=2ms, (65536-32000)=33536
TCCR1B=2; TCNT1=63536; TIMSK=4; //16000000/ 8/ 2000=1000Hz=1ms, (65536- 2000)=63536
TCCR1B=2; TCNT1=61536; TIMSK=4; //16000000/ 8/ 4000= 500Hz=2ms, (65536- 4000)=61536
TCCR1B=2; TCNT1=45536; TIMSK=4; //16000000/ 8/10000= 200Hz=5ms, (65536-10000)=45536
TCCR1B=2; TCNT1=35536; TIMSK=4; //16000000/ 8/20000= 100Hz=10ms, (65536-20000)=35536
TCCR1B=4; TCNT1=59286; TIMSK=4; //16000000/256/ 6250= 10Hz=100ms,(65536- 6250)=59286
TCCR1B=4; TCNT1= 3036; TIMSK=4; //16000000/256/62500= 1Hz=1sec, (65536-62500)= 3036

// 타이머1 A매치 인터럽트
TCCR1B=0x09; OCR1A=1474; TIMSK=0x10; //14745600/ 1/(1+ 1474)=9997.01695Hz=100.02984us
TCCR1B=0x09; OCR1A=1599; TIMSK=0x10; //16000000/ 1/(1+ 1999)=10KHz=100us
TCCR1B=0x09; OCR1A=15999; TIMSK=0x10; //16000000/ 1/(1+15999)=1000Hz=1ms
TCCR1B=0x09; OCR1A=31999; TIMSK=0x10; //16000000/ 1/(1+31999)= 500Hz=2ms
TCCR1B=0x0A; OCR1A= 1999; TIMSK=0x10; //16000000/ 8/(1+ 1999)=1000Hz=1ms
TCCR1B=0x0A; OCR1A= 3999; TIMSK=0x10; //16000000/ 8/(1+ 3999)= 500Hz=2ms
TCCR1B=0x0A; OCR1A= 9999; TIMSK=0x10; //16000000/ 8/(1+ 9999)= 200Hz=5ms
TCCR1B=0x0A; OCR1A=19999; TIMSK=0x10; //16000000/ 8/(1+19999)= 100Hz=10ms
TCCR1B=0x0C; OCR1A= 6249; TIMSK=0x10; //16000000/256/(1+ 6249)= 10Hz=100ms
TCCR1B=0x0C; OCR1A=31249; TIMSK=0x10; //16000000/256/(1+31249)= 2Hz=500ms
TCCR1B=0x0C; OCR1A=62499; TIMSK=0x10; //16000000/256/(1+62499)=1Hz=1sec

// 타이머2 매치 인터럽트
TCCR2=0x0B; OCR2=249; TIMSK=0x80; //16000000/ 64/(1+249)=1000Hz=1ms
반응형
반응형

/*     avr studio4

win avr gcc

atmega8a

*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>

 unsigned int cnt=0; //선택스위치 count
 int timer0ck = 0;
 char offcnt = 0; // sleep모드 변수
 volatile unsigned int flag0 =0; //전원스위치 flag

ISR(TIMER0_OVF_vect){//1초에 한번 실행하는 timer
  if(++TCNT0> 600000){//10분
  TCNT0 = 0;
  timer0ck++;
  }
 }
void timerin(void){ //타이머 설정
  TIMSK = 0x01; // Timer/Counter0 Overflow Interrupt Enable
 TCNT0 = 250;//1.024ms
 TCCR0 = 0x07;// timer/conter control resister 분주비 1024
}
void timerout(void){ //타이머 초기화
  TIMSK = 0x00;
 TCNT0 = 0;//1.024ms
 TCCR0 = ~0x07;// timer/conter control resister  분주비 1024
}
void buzzer(void){// 부저
 PORTB = 0x02;
  _delay_ms(100);
  PORTB = ~0x02;
  }
ISR(INT0_vect){ // 전원스위치 인터럽트
  buzzer();
 volatile unsigned int flag0 = (flag0++)%2;
   if((PIND = 0x04)==0xff){
   offcnt++;
   if(offcnt >2){
    sleep_cpu(); //sleep모드
   offcnt = 0;}
  }// 2~3초간 누를시 sleep모드   
}
ISR(INT1_vect){ // 선택스위치 인터럽트
  buzzer();
   cnt++;
  switch(cnt){
    case 0:
    PORTD=0x20; // led1
      break;
    case 1: 
    PORTD=0x60; // led2
      break;
    case 2:
    PORTD=0xd0; // led3
     break;
    default:
    PORTD=0x20; // led1
     cnt=0;
      break;
   }
 }
int main(){
 PORTD = 0x00;//초기값
 PORTC = 0x00; // 초기값
 DDRB = 0x02; // 부저
 DDRC = 0x01; // 후면 led
 DDRD = 0x47; // 전면 led 출력 & 스위치 입력 & 인터럽트 INT0

 MCUCR = 0xb0; //MCU control resister
 sleep_enable();
 sleep_cpu(); // sleep mode 진입
 
 while(1){
  while(flag0==0){ //flag 0 일경우 sw누를경우 flag 증가
   PORTD = 0x20;
   PORTC = ~0x01;
   void timerout();
  }
  while(flag0 ==1){//flag 1 일경우
   if((PIND &0x20)==0xff){
    PORTC = 0x01;
   void timerin();
    if(timer0ck%4 ==1){
     void timerout();
    }
   // 타이머를 10분
   }
  else if((PIND & 0x60) ==0xff){
   PORTC = 0x01;
   void timerin();
    if(timer0ck%4 ==2){
     void timerout();
    }
   // 타이머를 20분
   }
  if((PIND & 0xd0) == 0xff){
   PORTC = 0x01;
   void timerin();
    if(timer0ck%4 ==3){
     void timerout();
    }
   // 타이머를 30분
   }
  }
  }
 return 0;
}

 

 

반응형

+ Recent posts