반응형

/* Atmega128 mtx128-s2보드와 ds3231 rtc모듈, char LCD wc0802C 제품으로 시계를 만들었다.

기능들을 함수로 빼놓았기 때문에 나중에 회로도와 핀맵만 맞는다면 사용할 수 있다.

회로도 그리기 너무 귀찮다아아

*/


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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
 * char_lcd.c
 *
 * Created: 2019-01-21 오후 4:25:21
 * Author : admin
 */
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include <stdio.h>
 
#define PORT_DATA PORTD
#define PORT_CONTROL PORTC
#define DDR_DATA DDRD
#define DDR_CONTROL DDRC
 
#define RS_PIN 0
#define RW_PIN 1
#define E_PIN 2
 
#define COMMAND_CLEAR_DISPLAY 0x01
#define COMMAND_8_BIT_MODE 0x38
#define COMMAND_4_BIT_MODE 0x28
 
#define COMMAND_DISPLAY_ON_OFF_BIT 2
#define COMMAND_CURSOR_ON_OFF_BIT 1
#define COMMAND_BLINK_ON_OFF_BIT 0
 
extern uint8_t MODE;
 
void LCD_Pulse_enable();
void LCD_write_data(uint8_t data);
void LCD_write_command(uint8_t command);
void LCD_clear();
void LCD_init();
void LCD_write_string(char *string);
void LCD_goto_XY(uint8_t row, uint8_t col);
//////////////////////////////////////////////////////////
 
void LCD_Pulse_enable(){
    PORT_CONTROL |= (1<<E_PIN);
    _delay_us(1);
    PORT_CONTROL &= ~(1<<E_PIN);
    _delay_us(1);
}
void LCD_write_data(uint8_t data){
    PORT_CONTROL |= (1<<RS_PIN);
    if(MODE == 8){
        PORT_DATA = data;
        LCD_Pulse_enable();
    }
    else{
        PORT_DATA = data& 0xf0;
        LCD_Pulse_enable();
        PORT_DATA = (data<<4)&0xf0;
        LCD_Pulse_enable();
    }
    _delay_ms(2);
}
void LCD_write_command(uint8_t command){
    PORT_CONTROL&= ~(1<<RS_PIN);
    
    if(MODE ==8){
        PORT_DATA =command;
        LCD_Pulse_enable();
    }
    else {
        PORT_DATA = command & 0xf0;
        LCD_Pulse_enable();
        PORT_DATA = (command <<4& 0xf0;
        LCD_Pulse_enable();
    }
    _delay_ms(2);
}
void LCD_clear(){
    LCD_write_command(COMMAND_CLEAR_DISPLAY);
    _delay_ms(2);
}
void LCD_init(){
    _delay_ms(50);
    if(MODE == 8){
        DDR_DATA =0xff;
    }
    else DDR_DATA |= 0xf0;
    PORT_DATA = 0x00;
    DDR_CONTROL |= (1<<RS_PIN)|(1<<RW_PIN)|(1<<E_PIN);
    
    PORT_CONTROL &= ~(1<<RW_PIN);
    
    if(MODE == 8){
        LCD_write_command(COMMAND_8_BIT_MODE);
    }
    else{
        LCD_write_command(0x02);
        LCD_write_command(COMMAND_4_BIT_MODE);
    }
    
    uint8_t command = 0x08|(1<<COMMAND_DISPLAY_ON_OFF_BIT);
    LCD_write_command(command);
    
    LCD_clear();
    
    LCD_write_command(0x06);
}
void LCD_write_string(char *string){
    uint8_t i;
    for(i=0;string[i];i++){
        LCD_write_data(string[i]);
    }
}
void LCD_goto_XY(uint8_t row, uint8_t col){
    col %=16;
    row%=2;
    
    uint8_t address = (0x40*row)+col;
    uint8_t command =0x80+address;
    
    LCD_write_command(command);
}
 
uint8_t MODE = 4;
 
#define I2C_SCL PD0
#define I2C_SDA PD1
 
unsigned int sec, min, hour, day, month, year, week;
 
 
void uartInit(long buadrate)
{
    UCSR0A = 0x00// ready flag clear
    UCSR0B = 0x18// rx, tx enable
    UCSR0C = 0x06// tx data len : 8bit
    UBRR0H = 0;
    switch(buadrate){
        case 115200:
        UBRR0L = 8;
        break;
        
        case 57600:
        UBRR0L = 16;
        break;
        
        case 38400:
        UBRR0L = 25;
        break;
        
        case 19200:
        UBRR0L = 51;
        break;
        
        case 14400:
        UBRR0L = 68;
        break;
        
        case 9600:
        UBRR0L = 103;
        break;
        
        // Default 19200
        default:
        UBRR0L = 51;
        break;
    }
}
void send_data(unsigned char data)
{
    while(!(UCSR0A&0x20)); // 송신데이터를 받을 준비가 될때까지 대기
    UDR0 = data;
}
void SendLine(char *string)
{
    while(*string != '\0')
    {
        send_data(*string);
        string++;
    }
}
 
void init_i2c(){
    DDRD |= (1<<I2C_SCL);
    DDRD |= (1<<I2C_SDA);
    
    TWBR = 32// 200khz
}
void i2c_start(){
    TWCR = (1<< TWINT)|(1<<TWSTA)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT))); // 시작완료 대기
}
void i2c_transmit(uint8_t data){
    TWDR = data;
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    while(!(TWCR&(1<<TWINT))); // 전송완료 대기
}
uint8_t i2c_receive_ACK(){
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    while(!(TWCR&(1<<TWINT)));
    return TWDR;
}
uint8_t i2c_receive_NACK(){
    TWCR = (1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT))); // 수신완료 대기
    return TWDR;
}
void i2c_stop(){
    TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
    _delay_us(100);
}
 
uint8_t bcd_to_decimal(uint8_t bcd){
    return (bcd>>4*10 +(bcd&0x0f);
}
uint8_t decimal_to_bcd(uint8_t decimal){
    return (((decimal/10)<<4)|(decimal%10));
}
 
int main(void)
{    
    LCD_init();
    char lcd_buff[100];
    init_i2c();
    
    sec = min = hour = day = month = year = week= 0;
    char str[1000];
    
    uint8_t address = 0x68;
    // 초 분 시 요일 일 월 연
    uint8_t date[] = {0,10,12,2,10,10,19};
    
    
    i2c_start();
    i2c_transmit(address <<1);
    i2c_transmit(0);
    for (int i =0; i<7;i++){
        i2c_transmit(decimal_to_bcd(date[i]));
    }
    i2c_stop();
    DDRA = 0xff;
    PORTA = 0x00;
    
    while (1
    {
        i2c_start();
        i2c_transmit(address <<1);
        i2c_transmit(0);
        i2c_stop();
        
        i2c_start();
        i2c_transmit((address<<1)+1);
        
        sec = bcd_to_decimal(i2c_receive_ACK());
        min = bcd_to_decimal(i2c_receive_ACK());
        hour = bcd_to_decimal(i2c_receive_ACK());
        week = bcd_to_decimal(i2c_receive_ACK());
        day = bcd_to_decimal(i2c_receive_ACK());
        month = bcd_to_decimal(i2c_receive_ACK());
        year = bcd_to_decimal(i2c_receive_NACK());
        
        i2c_stop();
        
        LCD_goto_XY(0,0);
        sprintf(lcd_buff,"%d/%d/%d",year,month,day);
        LCD_write_string(lcd_buff);
        LCD_goto_XY(1,0);
        sprintf(str,"%d:%d:%d",hour,min,sec);
        LCD_write_string(str);
        
        /* LCD example
        LCD_goto_XY(1,1);
        LCD_write_string("hi");
        */
        
        //sprintf(lcd_buff,"%d/%d/%d",year,month,day);
        //sprintf (str, "%d sec, %d min, %d hour, %d week, %d day, %d month, %d year\r\n",sec,min,hour,week,day,month,year);
        //sprintf(str,"%d sec\r\n",sec);
        
    }
    return 0;
}
cs


반응형
반응형

j-kit-128을 이용하여 전체적인 시스템을 구현중입니다.

현재까지

1.led
2.buzzer(PWM적용 필요)
3.fnd
4.timer
5.switch(Ext interrupt 구현 필요)
6.serial통신

//미구현
7.adc_dimmer
8.cds
9.i2c
10. 추가로 wifi모듈을 달아서 wifi 통신도 해 볼 예정입니다.

미구현 항목들은 기능에 대한 숙지가 부족하여 좀더 공부 할 필요가 있을 것 같습니다.
j-kit-128을 이용하여 복습하고, 해당 키트를 이용하여 공부하시는 분들에게 도움이 되고자? 만들게 되었습니다.

기능 구현 및 개선이 되는대로 업로드 하겠습니다.
저도 부족한 점이 많기에 많은 가르침 부탁드립니다.


=======================================================================================

추가적으로 기능 구현한 내용


1. CDS (adc값 읽기)

2. extSwitch (외부 키 인터럽트)


// 추가 구현 예정

void init_pwmDimmer();//pwm dimmer

void init_i2c();//i2c 온도센서

void init_pwmMotor(); //pwm motor

void init_pwmBuzzer(); //pwm buzzer

void init_INTSerial(); // uart인터럽트


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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
 
#define FND_NUM0 0x3f
#define FND_NUM1 0x06
#define FND_NUM2 0x5b
#define FND_NUM3 0x4f
#define FND_NUM4 0x66
#define FND_NUM5 0x6d
#define FND_NUM6 0x7d
#define FND_NUM7 0x27
#define FND_NUM8 0x7f
#define FND_NUM9 0x6f
 
#define FND_SEL1 0x01
#define FND_SEL2 0x02
#define FND_SEL3 0x04
#define FND_SEL4 0x08
 
unsigned int fnd[10]= {FND_NUM0,FND_NUM1,FND_NUM2,FND_NUM3,FND_NUM4,FND_NUM5,FND_NUM6,FND_NUM7,FND_NUM8,FND_NUM9};
unsigned int fnd_sel[4= {FND_SEL1,FND_SEL2,FND_SEL3,FND_SEL4};
unsigned int count=0, sec=0;
 
char textBuff[100];
unsigned int extCount=0;
 
void init_led();
void init_buzzer();
void init_fnd();
void init_switch();
void init_timer();
void init_serial();
void init_adc();
void init_extSwitch();
 
/* 미구현
void init_pwmDimmer();//pwm dimmer
void init_i2c();//i2c 온도센서
void init_pwmMotor(); //pwm motor
void init_pwmBuzzer(); //pwm buzzer
void init_INTSerial(); // uart인터럽트
*/
 
void fnd_display(int num);
void SendByte(char data);
void SendLine(char *string);
char ReceiveByte();
uint16_t read_adc(uint8_t channel);
 
void test_led();
void test_buzzer();
void test_fnd();
void test_switch();
void test_serial();
void test_timer();
void test_adc();
void test_extSwitch();
 
int main(void)
{
    init_led();
    init_buzzer();
    init_fnd();
    init_switch();
    init_timer();
    init_serial();
    init_adc();
    init_extSwitch();
    sei();
    while (1)
    {
        //test_led();
        //test_buzzer();
        //test_fnd();
        //test_switch();
        //test_timer();
        //test_serial();
        //test_adc();
        //test_extSwitch();
    }
}
 
void init_led(){
    DDRA = 0xff;
    PORTA = 0x00;
}
void test_led(){
    PORTA = 0x00;
    _delay_ms(1000);
    PORTA = 0xff;
    _delay_ms(1000);
}
void init_buzzer(){
    DDRB = 0x10;
}
void test_buzzer(){
    PORTB = 0x10;
    _delay_ms(10);
    PORTB = 0x10;
    _delay_ms(10);
}
void init_fnd(){
    DDRC = 0xff;
    DDRG = 0x00;
}
void test_fnd(){
    fnd_display(1234);
}
void fnd_display(int num){
    int fnd1,fnd2,fnd3,fnd4;
    fnd1 = num%10;
    fnd2 = (num/10)%10;
    fnd3 = (num/100)%10;
    fnd4 = num/1000;
 
    PORTC = fnd[fnd1];
    PORTG = fnd_sel[0];
    _delay_ms(1);
    PORTC = fnd[fnd2];
    PORTG = fnd_sel[1];
    _delay_ms(1);
    PORTC = fnd[fnd3];
    PORTG = fnd_sel[2];
    _delay_ms(1);
    PORTC = fnd[fnd4];
    PORTG = fnd_sel[3];
    _delay_ms(1);
}
void init_switch(){
    // pull-up
    DDRE = 0x00;
    PORTE = 0x30;
}
void test_switch(){
    init_led();
    if((PINE & 0x20)== 0x00)
    PORTA = 0xff;
    if((PINE & 0x10)== 0x00)
    PORTA = 0x00;
}
void init_timer(){
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 = 0x04// 분주비 64
    TCNT0 =256-5// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    /*
    Timer set
    1/16000000 = 0.0000000625
    64분주
    0.0000000625* 64 = 0.000004
    0부터 250회 돌면 0.000004 *250 = 0.001
    OVF 발생 count 증가
    1000번 발생하면 1초 가 된다.
    */
}
void test_timer(){
    init_fnd();
    init_serial();
    fnd_display(sec);
    sprintf(textBuff,"%d\r\n",sec);
    SendLine(textBuff);
}
void init_serial(long BaudRate){
    UBRR0H = 0;
    switch(BaudRate)
    {
        case 115200:
        UBRR0L = 8;
        break;
        
        case 57600:
        UBRR0L = 16;
        break;
        
        case 38400:
        UBRR0L = 25;
        break;
        
        case 19200:
        UBRR0L = 51;
        break;
        
        case 14400:
        UBRR0L = 68;
        break;
        
        case 9600:
        UBRR0L = 103;
        break;
        
        // Default 115200
        default:
        UBRR0L = 8;
        break;
    }
    UCSR0A = 0x00;
    UCSR0B = 0x18;
    UCSR0C = 0x06;  // 8 bit
}
void SendByte(char data)
{
    while((UCSR0A & 0x20== 0x00);
    UDR0 = data;
}
/*** Function for sending line ***/
void SendLine(char *string)
{
    while(*string != '\0')
    {
        SendByte(*string);
        string++;
    }
}
 
char ReceiveByte(){
    while(!(UCSR0A & (1<<RXC0)));
    return UDR0;
}
void test_serial(){
    SendByte('A');
    _delay_ms(10);
    SendLine("Hello World");
    
    if((ReceiveByte() == 'a'&& (ReceiveByte() =='b')){
        SendByte('o');
        SendByte('k');
    }
}
void init_adc(){
        ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)); //16Mhz/128 = 125Khz
        ADMUX |= (1<<REFS0);       //AVCC(5V)
        ADCSRA |= (1<<ADEN);      //ADC 인에이블
}
uint16_t read_adc(uint8_t channel){
    ADMUX &= 0xF0;
    ADMUX |= channel;
    
    ADCSRA |= (1<<ADSC);      //변환 시작
    while(ADCSRA&(1<<ADSC));//변환 완료되기를 기다림.
    
    return ADCW;  //ADC값 반환
}
void test_adc(){
    init_adc();
    init_fnd();
    uint16_t adcValue =0;
    adcValue = read_adc(0);
    sprintf(textBuff,"adcValue : %d\r\n",adcValue);
    SendLine(textBuff);
    fnd_display(adcValue);
    _delay_ms(100);
}
void init_extSwitch(){
    DDRE = 0x00;
    PORTE = 0xf0;
    EICRB =0x0a;
    
    EIMSK = 0x30// INT4, INT5 사용
}
void test_extSwitch(){
    init_fnd();
    fnd_display(extCount);
}
 
ISR(INT4_vect){
    extCount++;
}
ISR(INT5_vect){
    extCount--;
}
ISR(TIMER0_OVF_vect){
    TCNT0 =256-(256-5);
    count++;
    if (count >=1000){
        sec++; count=0;
    }
}
cs



jkit_190122.zip


반응형

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

[j-kit-128] jkit 128 기능구현하기  (0) 2018.12.10
Sonar_GPS - C#Window Form  (0) 2018.10.21
Sonar_GPS  (0) 2018.10.11
Serial 통신_ 문자열 전송  (0) 2018.10.01
Serial 통신_Uart0_문자 1개  (0) 2018.10.01
반응형

j-kit-128을 이용하여 전체적인 시스템을 구현중입니다.

현재까지

1.led
2.buzzer(PWM적용 필요)
3.fnd
4.timer
5.switch(Ext interrupt 구현 필요)
6.serial통신

//미구현
7.adc_dimmer
8.cds
9.i2c
10. 추가로 wifi모듈을 달아서 wifi 통신도 해 볼 예정입니다.

미구현 항목들은 기능에 대한 숙지가 부족하여 좀더 공부 할 필요가 있을 것 같습니다.
j-kit-128을 이용하여 복습하고, 해당 키트를 이용하여 공부하시는 분들에게 도움이 되고자? 만들게 되었습니다.

기능 구현 및 개선이 되는대로 업로드 하겠습니다.
저도 부족한 점이 많기에 많은 가르침 부탁드립니다.

- datasheet 및 회로도 참고 자료 : http://www.devicemart.co.kr/1059759

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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define FND_NUM0 0x3f
#define FND_NUM1 0x06
#define FND_NUM2 0x5b
#define FND_NUM3 0x4f
#define FND_NUM4 0x66
#define FND_NUM5 0x6d
#define FND_NUM6 0x7d
#define FND_NUM7 0x27
#define FND_NUM8 0x7f
#define FND_NUM9 0x6f
 
#define FND_SEL1 0x01
#define FND_SEL2 0x02
#define FND_SEL3 0x04
#define FND_SEL4 0x08
 
unsigned int fnd[10]= {FND_NUM0,FND_NUM1,FND_NUM2,FND_NUM3,FND_NUM4,FND_NUM5,FND_NUM6,FND_NUM7,FND_NUM8,FND_NUM9};
unsigned int fnd_sel[4= {FND_SEL1,FND_SEL2,FND_SEL3,FND_SEL4};
unsigned int count=0, sec=0;
 
void init_led();
void init_buzzer();
void init_fnd();
void init_switch();
void init_timer();
void init_serial();
 
/* 미구현
void init_adc();
void init_cds();
void init_i2c();
*/
 
void fnd_display(int num);
void SendByte(char data);
void SendLine(char *string);
char ReceiveByte();
 
void test_led();
void test_buzzer();
void test_fnd();
void test_switch();
void test_serial();
void test_timer();
 
int main(void)
{
    init_led();
    init_buzzer();
    init_fnd();
    init_switch();
    init_timer();
    init_serial();
    sei();
    while (1)
    {
        //test_led();
        //test_buzzer();
        //test_fnd();
        //test_switch();
        //test_timer();
        //test_serial();
        
    }
}
 
void init_led(){
    DDRA = 0xff;
    PORTA = 0x00;
}
void test_led(){
    PORTA = 0x00;
    _delay_ms(1000);
    PORTA = 0xff;
    _delay_ms(1000);
}
void init_buzzer(){
    // PWM 제어 필요
    DDRB = 0x10;
}
void test_buzzer(){
    PORTB = 0x10;
    _delay_ms(10);
    PORTB = 0x10;
    _delay_ms(10);
}
void init_fnd(){
    DDRC = 0xff;
    DDRG = 0x00;
}
void test_fnd(){
    fnd_display(1234);
}
void fnd_display(int num){
    int fnd1,fnd2,fnd3,fnd4;
    fnd1 = num%10;
    fnd2 = (num/10)%10;
    fnd3 = (num/100)%10;
    fnd4 = num/1000;
 
    PORTC = fnd[fnd1];
    PORTG = fnd_sel[0];
    _delay_ms(1);
    PORTC = fnd[fnd2];
    PORTG = fnd_sel[1];
    _delay_ms(1);
    PORTC = fnd[fnd3];
    PORTG = fnd_sel[2];
    _delay_ms(1);
    PORTC = fnd[fnd4];
    PORTG = fnd_sel[3];
    _delay_ms(1);
}
void init_switch(){
    // pull-up
    DDRE = 0x00;
    PORTE = 0x30;
}
void test_switch(){
    init_led();
    if((PINE & 0x20)== 0x00)
    PORTA = 0xff;
    if((PINE & 0x10)== 0x00)
    PORTA = 0x00;
}
void init_timer(){
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 = 0x04// 분주비 64
    TCNT0 =256-5// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    /*
    Timer set
    1/16000000 = 0.0000000625
    64분주
    0.0000000625* 64 = 0.000004
    0부터 250회 돌면 0.000004 *250 = 0.001
    OVF 발생 count 증가
    1000번 발생하면 1초 가 된다.
    */
}
void test_timer(){
    init_fnd();
    fnd_display(sec);
}
void init_serial(long BaudRate){
    UBRR0H = 0;
    switch(BaudRate)
    {
        case 115200:
        UBRR0L = 8;
        break;
        
        case 57600:
        UBRR0L = 16;
        break;
        
        case 38400:
        UBRR0L = 25;
        break;
        
        case 19200:
        UBRR0L = 51;
        break;
        
        case 14400:
        UBRR0L = 68;
        break;
        
        case 9600:
        UBRR0L = 103;
        break;
        
        // Default 115200
        default:
        UBRR0L = 8;
        break;
    }
    UCSR0A = 0x00;
    UCSR0B = 0x18;
    UCSR0C = 0x06;  // 8 bit
}
 
void SendByte(char data)
{
    while((UCSR0A & 0x20== 0x00);
    UDR0 = data;
}
 
/*** Function for sending line ***/
void SendLine(char *string)
{
    while(*string != '\0')
    {
        SendByte(*string);
        string++;
    }
}
 
char ReceiveByte(){
    while(!(UCSR0A & (1<<RXC0)));
    return UDR0;
}
 
void test_serial(){
    SendByte('A');
    _delay_ms(10);
    SendLine("Hello World");
    
    if((ReceiveByte() == 'a'&& (ReceiveByte() =='b')){
        SendByte('o');
        SendByte('k');
    }
}
 
ISR(TIMER0_OVF_vect){
    TCNT0 =256-(256-5);
    count++;
    if (count >=1000){
        sec++; count=0;
    }
}
 
cs


반응형

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

jkit-128-1 추가 기능 구현  (0) 2019.01.22
Sonar_GPS - C#Window Form  (0) 2018.10.21
Sonar_GPS  (0) 2018.10.11
Serial 통신_ 문자열 전송  (0) 2018.10.01
Serial 통신_Uart0_문자 1개  (0) 2018.10.01
반응형

* Dot Matrix

 

1. 하트를 그리고, 그 하트를 방향키를 이용하여 움직인다.

 

2. 불켜기 게임을 Dotmatrix로 구현한다. 25개를 다 켜면 HLED가 ON/OFF

 

3. 폭탄 피하기 게임

 

* Key Matrix

 

1. 핸드폰 영문자판 흉내내기

 - 키매트릭스를 핸드폰 자판이라 생각하고 LCD에 글을 써보자

 

* HLED 녹화하기

 - 타이머 인터럽트를 이용해서 구현하기

 

 

 

** 고난도 프로젝트

 

LCD에 Key입력을 받아 명령을 수행한다.

 

MTR RI 30 모터를 오른쪽으로 30도 이동 

MTR LE 15 모터를 왼쪽으로 15도 이동

 

...

반응형
반응형

 

// 서보모터 구현하기

Timer/Counter와 Delay를 이용하여 구현

 

1. Timer/Counter를 이용하여 구현

 

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
 
/*
 * avr_motor_0910.cpp
 *
 * Created: 2018-09-10 오후 2:07:45
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <stdio.h>
#include <avr/interrupt.h>
 
 
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
 
unsigned int tCount =0;
unsigned int servoCount =0;
 
ISR (TIMER0_OVF_vect){ // 100us
    TCNT0 = 256 -50;
    tCount ++;    
    if ( tCount>= 0 && tCount<=7) PORTB = 0xff;
    else if (tCount>7 && tCount <230) PORTB = 0x00;
    else tCount=0;
}
int main(void)
{
    /* Replace with your application code */
    DDRB = 0xff;
    DDRE = 0x00// 스위치
 
    PORTE = 0x70;
    PORTB = 0x01;
    
    io_init();
    lcd_init();
    
    int flag =0;
    TIMSK = 0x01;
    TCCR0 = 0x03;
    TCNT0 = 256 -50;
    sei();
    while (1
    {    
    
    
    }
}
 
 
cs

 

 

2. delay함수를 이용하여 구현

 

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
 
/*
 * avr_motor_0910.cpp
 *
 * Created: 2018-09-10 오후 2:07:45
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <stdio.h>
#include <avr/interrupt.h>
 
 
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
 
unsigned int tCount =0;
unsigned int servoCount =0;
 
 
int main(void)
{
    /* Replace with your application code */
    DDRB = 0xff;
    DDRE = 0x00// 스위치
 
    PORTE = 0x70;
    PORTB = 0x01;
    
    io_init();
    lcd_init();
    
    int flag =0;
    while (1
    {    
    
        
        
        if (((PINE & 0x10)== 0x00)&& flag ==0){
            
            for (int i=0; i<100;i++){
                PORTB = 0xff;
                _delay_us(700);
                PORTB = 0x00;
                _delay_us(19300);
            }
            flag =1;
        }
        else if (((PINE & 0x20)==0x00)&& flag==0){
                    for (int i = 0; i<100;i++){
                        PORTB = 0xff;
                        _delay_us(2300);
                        PORTB = 0x00;
                        _delay_us(17700);
                    }
            flag=1;
        }
        else if (((PINE &0x40)== 0x00)&& flag==0){
            for (int i = 0; i<100;i++){
                PORTB = 0xff;
                _delay_us(1500);
                PORTB = 0x00;
                _delay_us(18500);
            }
            flag =1;
        }
        else if (PINE==0xff) flag=0;
    
    }
}
 
 
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
/*
 * avr_motor_0910.cpp
 *
 * Created: 2018-09-10 오후 2:07:45
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <stdio.h>
 
void DC_Motor30(){
    PORTB = 0x40;
    _delay_us(30);
    PORTB = 0x20;
    _delay_us(70);
}
void DC_Motor50(){
    PORTB = 0x40;
    _delay_us(50);
    PORTB = 0x20;
    _delay_us(50);
}
void DC_Motor70(){
    PORTB = 0x40;
    _delay_us(70);
    PORTB = 0x20;
    _delay_us(30);
}
void Step_MotorFW(){
    PORTB = 0x01;
    _delay_ms(20);
    PORTB = 0x02;
    _delay_ms(20);
    PORTB = 0x04;
    _delay_ms(20);
    PORTB = 0x08;
    _delay_ms(20);
}
void Step_MotorBW(){
    PORTB = 0x08;
    _delay_ms(20);
    PORTB = 0x04;
    _delay_ms(20);
    PORTB = 0x02;
    _delay_ms(20);
    PORTB = 0x01;
    _delay_ms(20);
}
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
 
int main(void)
{
    /* Replace with your application code */
    DDRB = 0x0f;
    DDRE = 0x00// 스위치
 
    PORTE = 0x70;
    PORTB = 0x01;
    
    io_init();
    lcd_init();
 
    char temp[16];
    int degree =0,flag =0, current_degree=0;;
    
 
    while (1
    {        
 
        if (((PINE & 0x10)==0x00)&& flag ==0){
            if(degree >=15) degree = degree-15;
        flag =1;
        }
        else if (((PINE & 0x20)==0x00)&& flag ==0){
            if(degree <360) degree     = degree+15;
            flag=1;
        }
        else if(PINE == 0xff){
            flag=0;
        }
        // 스텝모터 동작(미완성)
        if (((PINE & 0x40== 0x00)&& flag ==0){ 
            if (current_degree < degree)
                PORTB= PORTB <<1;
                _delay_ms(20);
                if (PORTB ==0x10){ PORTB = 0x01;
                    _delay_ms(20);
                }
            }
            flag=1;
        }
        else if (PINE ==0xff) flag =0;
        sprintf(temp,"> %d    ", degree);
        lcd_putsf(0,0,"  Input Degree  ");
        lcd_putsf(0,1,temp);
    }
}
 
 
cs

 

// 여러 방법이 있지만, 여기서는  

void Step_MotorFW(){
    PORTB = 0x01;
    _delay_ms(20);
    PORTB = 0x02;
    _delay_ms(20);
    PORTB = 0x04;
    _delay_ms(20);
    PORTB = 0x08;
    _delay_ms(20);
}

// 4차례를 순서대로 이동시켜야 스텝모터가 동작 한다.

 

반응형
반응형
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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0, min=0,hour=0;
unsigned int mode =0, ampm =0;
unsigned int flag=0;;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =6;
    count++;
    if (count >1000){
        sec++; count=0;
        if(sec>=60){
            min++; sec=0;
            if (min>=60){
                hour++; min=0;
                if(hour>12){
                    hour=0;
                    if(ampm == 0) ampm =1;
                    else if(ampm ==1) ampm=0;
                    count =0;
                }
            }
        }
    }
}
 
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    DDRE = 0x8f// 스위치 
    PORTE = 0x70; // 추후 확인 필요
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =6// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    while (1
    {
        //input
        if (((PINE && 0x10)== 0x00&& flag ==0){
            mode++;
            flag=1;
            if (mode >=2)
            mode=0;
        }
        else if (PINE ==0xff) flag=0;    
        
        //display
        switch(mode){
            case 0:
            mode =1;
            sprintf(temp,"%d  :  %d  :  %d  %s",hour,min,sec,(ampm=0)?"AM":"PM");
            lcd_putsf(0,0,"  Normal Mode  ");
            lcd_putsf(0,1,temp);
        
            case 1:
            mode =0;
            sprintf(temp,"%d  :  %d  :  %d  %s",hour,min,sec,(ampm=0)?"AM":"PM");
            if (sec%2 ==0){
                temp[2]=temp[3= ' ';
            }
            lcd_putsf(0,0,"  Modify Mode  ");
            lcd_putsf(0,1,temp);
        }
        
 
    }
}
cs

 

 

// 스위치 DDRE 설정 다시 확인 후 시계 만들기 완성 소스

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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
#define LED_SEL1 (*(volatile unsigned char *)0xA000)
#define LED_SEL2 (*(volatile unsigned char *)0xB000)
#define FND (*(volatile unsigned char *)0x8000)
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0, min=0,hour=0;
unsigned int mode =0, ampm =0;
unsigned int flag=0;
unsigned int saveSec=0, saveMin=0,saveHour=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =6;
    count++;
    if (count >1000){
        sec++; count=0;
        if(sec>=60){
            min++; sec=0;
            if (min>=60){
                hour++; min=0;
                if(hour>12){
                    hour=0;
                    if(ampm == 0) ampm =1;
                    else if(ampm ==1) ampm=0;
                    count =0;
                }
            }
        }
    }
}
 
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    DDRE = 0x8f// 스위치 
    PORTE = 0xff
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =6// 6에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    mode =0;
    sei();
    char temp[16];
    int sel =0;
    while (1
    {
        
        //input
        if (((PINE & 0x10)== 0x00&& flag ==0 ){    
            sel=0;
            mode++;
            if(mode >=2)mode =0;
            flag=1;
        }    
        // 숫자 증가 input
        else if (((PINE & 0x20)== 0x00)&& flag==0 && mode==1 ){
            if (sel==0){hour++;
                if (hour >=60) hour =0;
            }
            else if (sel ==1){ min++;
                if(min>=60) min=0;
            }
            else if(sel ==2){ sec++;
                if(sec>=60) sec=0;
            }
            else if(sel==3){
                if (ampm ==0) ampm =1;
                else if (ampm ==1)  ampm=0;
            }
            flag=1;
        }
        // 숫자 선택 셀 증가
        else if (((PINE & 0x40)== 0x00)&& flag==0 && mode==1 ){
            sel++;
            if (sel >=4) sel=0;
            flag=1;
        }
        else if (PINE == 0xff){ flag=0;    
        }
        
        //display
        switch(mode){
            case 0:
            sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");
            lcd_putsf(0,0,"  Normal Mode  ");
            lcd_putsf(0,1,temp);
                break;
            case 1:
            sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");    
            if (sec%2 ==0){
                if(sel==0)temp[1= temp[2=' ';
                else if(sel==1)temp[5= temp[6=' ';
                else if(sel==2)temp[9= temp[10=' ';
                else if (sel==3)temp[12= temp[13=' ';
                else sel =0;
            }
            lcd_putsf(0,0,"  Modify Mode  ");
            lcd_putsf(0,1,temp);
                break;
        }
    }
}
cs

 

 

 

 

/*

// SW4, SW5, SW6

SW4 입력시 모드가 바뀌며, Nomal Mode , Modify Mode가 있다.

Modify Mode 에서는 SW5 과 SW6을 입력하여 시간과 AM/PM을 변경 할 수 있다.

*/

 

 

반응형
반응형
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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =256-25;
    count++;
    if (count >625){
        sec++; count=0;
    }
}
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x07// 분주비 1024
    TCNT0 =256-25// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 1024
    0.0000000625 *1024 = 0.000064 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.016384
    약 61번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    
    while (1
    {
        sprintf(temp,"%d",sec);
        lcd_putsf(0,0,temp);        
    }
}
cs

 

// 해당 소스는 정확한 1초가 아니다.

 

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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =256-5;
    count++;
    if (count >500){
        sec++; count=0;
    }
}
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =256-5// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    
    while (1
    {
        sprintf(temp,"%d",sec);
        lcd_putsf(0,0,temp);        
    }
}
cs
반응형

+ Recent posts