반응형
Notice
Recent Posts
Recent Comments
Link
Brise
자작 후미등 - 코드편 본문
반응형
--
자작 후미등을 MCU를 이용하여 만들었기 때문에 코드를 이용하여 후미등을 제어할 수 있다.
때문에, 이 제어를 어떻게 할 것인지 명세를 먼저 하고 코드 작업을 들어가야한다.
전체적인 상태 구조는 위와 같다.
Init 부분에서 핀 아웃풋, 인풋 / 타이머 및 인터럽트 초기화 / 모드 및 타이머 함수 초기화를 진행하고
모드 0으로 진입하며 전력 절약모드에 들어간다.
스위치를 누를 때마다 깨어나 모드를 바꾸거나 주기를 바꾼다.
타이머 인터럽트를 통해 위와 독립적으로 각 led배열 값을 이용하여 led를 표시한다.
여기서 led와 mode는 서로 concurrent하게 동작하며 상호간의 consistency를 맞춰주기 위하여 조작하는 부분은 임계영역(critical section)에서 실행된다.
작성한 소스코드들의 의존관계는 다음과 같다.
그리고 위 코드를 구현한 내용은 아래와 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /******************************************************************************* common.h 07-13-2015 Made by naudhizb 매크로,매크로 함수와 함수들 선언 *******************************************************************************/ /*** include guard ***/ #ifndef _COMMON_H_ /*** define macro ***/ #define _COMMON_H_ ////Define Macro Function //MACRO FUNCTION #define constrain(value,min,max) ((value-min)>=0)?((value-max)<=0)?value:max:min #define map(value,i_min,i_max,o_min,o_max) o_min+(value-i_min)/(i_max-i_min)*(o_max-o_min) //PORT CONTROL #define gbi(PORTX,bitX) ((PORTX & (1<<bitX))>>bitX) #define tbi(PORTX,bitX) PORTX ^= (1<<bitX) #define sbi(PORTX,bitX) PORTX |= (1<<bitX) #define cbi(PORTX,bitX) PORTX &= ~(1<<bitX) #define bi(bitX) (1<<bitX) //// HW indep한 헤더 include #include <stdio.h> #include <stdint.h> #include <math.h> /*** include guard end ***/ #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /******************************************************************************* atmega8.h 07-13-2015 Made by naudhizb HW dep 헤더 선언 *******************************************************************************/ #define F_CPU 8000000UL // CPU CLOCK RATE DEFINE #include <avr/io.h> #include <avr/interrupt.h> #include <avr/eeprom.h> #include <avr/power.h> #include <avr/sleep.h> #include <util/delay.h> #include <util/atomic.h> //#include <util/setbaud.h> #include <util/twi.h> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /******************************************************************************* atmega8_timer.h 07-13-2015 Made by naudhizb 타이머 선언 *******************************************************************************/ #ifndef _H_TIMER_ #define _H_TIMER_ #include "common.h" #include "atmega8.h" typedef enum _clock_prescaler { NO_CLOCK_SOURCE, PRESCALE_D1, //31250 PRESCALE_D8, //3906 PRESCALE_D64,//488 PRESCALE_D256,//122 PRESCALE_D1024 //30.5 } clock_prescaler; enum timer_interrupt_flags { INTERRUPT_DISABLE, INTERRUPT_ENABLE } ; void timer0_set(uint8_t PRESCALE, uint8_t INTERRUPT_FLAG); #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /******************************************************************************* atmega8_timer.c 07-13-2015 Made by naudhizb 타이머 구현 *******************************************************************************/ #include "atmega8_timer.h" void timer0_set(uint8_t PRESCALE, uint8_t INTERRUPT_FLAG) { TCCR0 = PRESCALE; //CPU ?대씫 if(INTERRUPT_FLAG==INTERRUPT_ENABLE){ sbi(TIMSK,TOIE0); sbi(TIFR,TOV0); } else { cbi(TIMSK,TOIE0); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /******************************************************************************* button.h 07-13-2015 Made by naudhizb 버튼 init 및 getter 선언 *******************************************************************************/ #ifndef _H_BUTTON #define _H_BUTTON #include "common.h" #include "atmega8.h" void button_init (void); uint8_t button_read (void); #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /******************************************************************************* button.c 07-13-2015 Made by naudhizb 버튼 init 및 getter 구현 *******************************************************************************/ #include "button.h" void button_init(void) { cbi(DDRD,DDRD2); sbi(PORTD,PORTD2); } uint8_t button_read(void) { return gbi(PIND,PIND2); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /******************************************************************************* ext_int.h 07-13-2015 Made by naudhizb ext_int init 선언 *******************************************************************************/ #ifndef _H_EXT_INT #define _H_EXT_INT #include "common.h" #include "atmega8.h" enum interrupt_flags { EXT_INTERRUPT_DISABLE, EXT_INTERRUPT_ENABLE }; enum interrupt_modes { INTERRUPT_LOW_LEVEL, INTERRUPT_LOGIC_CHANGE, INTERRUPT_F_EDGE, INTERRUPT_R,EDGE }; void ext_interrupt_init (char INTERRUPT_FLAG, char INTERRUPT_MODE); #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /******************************************************************************* ext_int.h 07-13-2015 Made by naudhizb ext_int init 구현 *******************************************************************************/ #include "ext_int.h" void ext_interrupt_init (char INTERRUPT_FLAG, char INTERRUPT_MODE) { if(INTERRUPT_FLAG == EXT_INTERRUPT_ENABLE) { sbi(GICR, INT0); sbi(GIFR, INTF0); } else { cbi(GICR, INT0); cbi(GIFR, INTF0); } if(gbi(INTERRUPT_MODE,ISC00)) sbi(MCUCR,ISC00); else cbi(MCUCR,ISC00); if(gbi(INTERRUPT_MODE,ISC01)) sbi(MCUCR,ISC01); else cbi(MCUCR,ISC01); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /******************************************************************************* led.h 07-13-2015 Made by naudhizb led init 및 setter 선언 *******************************************************************************/ #ifndef _H_LED #define _H_LED #include "common.h" #include "atmega8.h" void led_control ( uint8_t led_channel, uint8_t led_set); void led_set(uint8_t led_arr); void led_init(void); void led_debug(uint8_t swi); #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /******************************************************************************* led.c 07-13-2015 Made by naudhizb led init 및 setter 구현 *******************************************************************************/ #include "led.h" /* (PORTD,PORTD5) (PORTD,PORTD6) (PORTD,PORTD7) (PORTB,PORTB2) (PORTB,PORTB1) (PORTB,PORTB0) (PORTC,PORTC5) // for debug */ void led_control (uint8_t led_channel,uint8_t led_set) { switch(led_channel) { case 0: if(led_set) sbi(PORTD,PORTD5); else cbi(PORTD,PORTD5); break; case 1: if(led_set) sbi(PORTD,PORTD6); else cbi(PORTD,PORTD6); break; case 2: if(led_set) sbi(PORTD,PORTD7); else cbi(PORTD,PORTD7); break; case 3: if(led_set) sbi(PORTB,PORTB2); else cbi(PORTB,PORTB2); break; case 4: if(led_set) sbi(PORTB,PORTB1); else cbi(PORTB,PORTB1); break; case 5: if(led_set) sbi(PORTB,PORTB0); else cbi(PORTB,PORTB0); break; case 6: if(led_set) sbi(PORTC,PORTC5); else cbi(PORTC,PORTC5); break; default: break; } } void led_set(uint8_t led_arr) { for(int i=0;i<7;i++) led_control(i,gbi(led_arr,i)); } void led_init(void) { sbi(DDRD,DDRD5); sbi(DDRD,DDRD6); sbi(DDRD,DDRD7); sbi(DDRB,DDRB2); sbi(DDRB,DDRB1); sbi(DDRB,DDRB0); sbi(DDRC,DDRC5); } void led_debug(uint8_t swi) { led_control(6,swi); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /******************************************************************************* mode.h 07-13-2015 Made by naudhizb mode init 및 iterator 선언 *******************************************************************************/ #ifndef _H_MODE #define _H_MODE #include "common.h" #include "atmega8.h" #include "atmega8_timer.h" #include "led.h" typedef struct _led_mode { uint8_t num_of_mode; clock_prescaler freq_set; char *plight_mode_arr; uint8_t length; } led_mode; void mode_init(void); void mode_change(void); void freq_change(void); void led_iterator (void); #endif | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | /******************************************************************************* mode.c 07-13-2015 Made by naudhizb mode init 및 iterator 구현 및 mode 명세 *******************************************************************************/ #include "mode.h" const char mode_off[] = {0x00}; const char mode_full[] = {0x3F}; const char mode_half[] = {0x3F,0x3F, 0x00,0x00}; const char mode_onethird[] = {0x3F,0x3F, 0x00, 0x00,0x00,0x00}; const char mode_serial[] = {0x01, 0x01,0x02,0x02, 0x04, 0x04, 0x10,0x10, 0x20,0x20, 0x10,0x10, 0x04,0x04, 0x02,0x02}; const char mode_cross[] = {0x08, 0x08,0x14,0x14}; const char mode_light[] = {0x08}; const char mode_halflight[] = {0x08,0x08,0x00,0x00}; led_mode mode_arr[] = { { 0, NO_CLOCK_SOURCE, (char *)&mode_off[0], sizeof(mode_off)/sizeof(char) }, { 1, NO_CLOCK_SOURCE, (char *)&mode_full[0], sizeof(mode_full)/sizeof(char) }, { 2, PRESCALE_D64, (char *)&mode_half[0], sizeof(mode_half)/sizeof(char) }, { 3, PRESCALE_D64, (char *)&mode_onethird[0], sizeof(mode_onethird)/sizeof(char) }, { 4, PRESCALE_D1024, (char *)&mode_serial[0], sizeof(mode_serial)/sizeof(char) }, { 5, PRESCALE_D1024, (char *)&mode_cross[0], sizeof(mode_cross)/sizeof(char) }, { 6, NO_CLOCK_SOURCE, (char *)&mode_light[0], sizeof(mode_light)/sizeof(char) }, { 7, PRESCALE_D64, (char *)&mode_halflight[0], sizeof(mode_halflight)/sizeof(char) } }; /* NO_CLOCK_SOURCE, PRESCALE_D1, //31250 PRESCALE_D8, //3906 PRESCALE_D64,//488 PRESCALE_D256,//122 PRESCALE_D1024 //30.5 */ led_mode * p_mode_arr; char mode_cursor_max; char mode_cursor=0; char * plight_arr; char light_cursor_max; char light_cursor; clock_prescaler current_freq=0; void notify_number (int number) { for(int i=0; i<number;i++) { led_control(6,1); _delay_ms(100); led_control(6,0); _delay_ms(100); } } void mode_init(void) { mode_cursor_max = sizeof(mode_arr)/sizeof(led_mode); p_mode_arr = &mode_arr[0]; mode_cursor_max = sizeof(mode_arr)/sizeof(led_mode); plight_arr = p_mode_arr->plight_mode_arr; light_cursor_max = p_mode_arr->length; light_cursor = 0; current_freq = 0; set_sleep_mode(SLEEP_MODE_PWR_DOWN); } void mode_change(void) { // change mode cursor //exception handling if(++mode_cursor >=mode_cursor_max) { mode_cursor = 0; set_sleep_mode(SLEEP_MODE_PWR_DOWN); } // change mode ptr p_mode_arr = &mode_arr[mode_cursor]; // change light ptr plight_arr = p_mode_arr->plight_mode_arr; light_cursor_max = p_mode_arr->length; // reset light ptr cursor light_cursor = 0; set_sleep_mode(SLEEP_MODE_IDLE); // change timer current_freq = p_mode_arr->freq_set; timer0_set(current_freq,INTERRUPT_ENABLE); led_iterator(); // notify mode number notify_number(p_mode_arr->num_of_mode); } void freq_change(void) { current_freq += 1; if(current_freq >=8) current_freq = 3; // notify freq number timer0_set(current_freq, INTERRUPT_ENABLE); notify_number(current_freq); } void led_iterator (void) { // exception handling if(++light_cursor>=light_cursor_max) light_cursor = 0; led_set(*(plight_arr+light_cursor)); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /******************************************************************************* main_function.c 07-13-2015 Made by naudhizb 메인 알고리즘 및 sleep 구현 *******************************************************************************/ #include "common.h" #include "atmega8.h" #include "led.h" #include "atmega8_timer.h" #include "mode.h" //#include "iterator.h" #include "button.h" #include "ext_int.h" ////Include Header /* VARIABLE */ /** FOR ISR FUNCTION **/ extern char * plight_arr; extern char light_cursor_max; extern char light_cursor; /** FUCTION **/ void into_sleep_mode(void) { sleep_enable(); sleep_cpu(); sleep_disable(); } /** MAIN FUNCTION **/ int main(void) { led_init(); led_debug(1); mode_init(); button_init(); ext_interrupt_init(EXT_INTERRUPT_ENABLE, INTERRUPT_LOW_LEVEL); timer0_set( NO_CLOCK_SOURCE, INTERRUPT_ENABLE); _delay_ms(500); led_debug(0); sei(); while(1) { into_sleep_mode(); } return 0; } /** ISR SECTION **/ volatile unsigned int cnt=0; ISR(INT0_vect) // enable low { led_debug(1); cnt=0; while(!button_read()) { cnt++; _delay_ms(100); if(cnt>=6) led_debug(0); } if(cnt <=1); // exception handling (prevent chattering) else if(cnt<=5) { // short press --> mode change mode_change(); } else if(cnt<=10) { // long press --> freq change freq_change(); } led_debug(0); } ISR(TIMER0_OVF_vect) // iterate led { led_iterator(); } | cs |
--
반응형
'DIY > 자작 후미등' 카테고리의 다른 글
자작 후미등 - 기구편 (0) | 2015.09.24 |
---|---|
자작 후미등 - 회로편 (0) | 2015.09.24 |
자작 후미등 Specification (0) | 2015.09.01 |
Comments