Embeded/ARM Cortex-M4

UART - PC, 블루투스 통신

gharlic 2015. 7. 10. 20:17

무선 통신

 마이크로프로세서 간의 통신, 마이크로프로세서와 PC간의 통신등을 위해 사용되는 방법 중

가장 흔하게 사용하는 방법이 UART통신이다.

로봇과 컨트롤러간의 신호전달, 디버깅을 위해 PC에서 값을 확인할 때 등 다양하게 사용된다.

무선통신은 하나의 기기가 Master가 되고 마스터의 중계를 받는 복수의 Slave가 있다.

 

마스터(Master) 초기화 소스

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
char cPC;
 
char cBT;
 
int pcState=0;
 
int btState=0;
 
char buffer_pc[256];
 
char buffer_bt[32];
 
 
 
 
 
 
 
 
 
void Init_USART(void){
 
        GPIO_InitTypeDef GPIO_InitStructure; //GPIO 초기화용 Structure를 선언 
        USART_InitTypeDef USART_InitStructure; // USART 초기화용  Structure를 선언 
        NVIC_InitTypeDef NVIC_InitStructure; // NVIC 초기화용 Structure 선언 
 
 
        // Enable peripheral
 
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //GPIOA를 Enable시킴 GPIOA는 AHB1에 위치
 
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // USART1을 Enalble 시킴 USART1은 APB2에 위치
 
 
 
        // Configure USART Interrupt
 
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // UART Interrupt을 등록함.핸들러는 TImer처럼 고정되어있음
 
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f; // Preemption 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f; // Sub 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ채널의 cmd를 Enable함.
 
        NVIC_Init(&NVIC_InitStructure); // NVIC 초기화
 
 
 
        // GPIO AF config
 
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
 
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
 
 
 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; // USART(또는 UART)의 TX 핀번호
 
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
 
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
        GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
 
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10; // USART(또는 UART)의 RX 핀번호
 
        GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
 
        // Configure UART peripheral
 
        USART_InitStructure.USART_BaudRate   = 115200; //Baudrate설정.
 
        USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 전송하는 패킷의 길이는 8bit씩 전송함을 명시
 
        USART_InitStructure.USART_StopBits   = USART_StopBits_1; // stopbit는 1개임을 의미
 
        USART_InitStructure.USART_Parity     = USART_Parity_No ;
 
        USART_InitStructure.USART_HardwareFlowControl  = USART_HardwareFlowControl_None;
 
        USART_InitStructure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode에서 RX, TX를 설정
 
        USART_Init(USART1, &USART_InitStructure); //  USART초기화
 
 
 
        // Enable USART receive interrupt
 
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
 
 
        USART_Cmd(USART1, ENABLE);
 
}
 
void Init_USART2_BT(void){
 
        GPIO_InitTypeDef GPIO_InitStructure; //GPIO 초기화용 Structure를 선언 
        USART_InitTypeDef USART_InitStructure; // USART 초기화용  Structure를 선언 
        NVIC_InitTypeDef NVIC_InitStructure; // NVIC 초기화용 Structure 선언 
 
 
        // Enable peripheral
 
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //GPIOA를 Enable시킴 GPIOA는 AHB1에 위치
 
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // USART1을 Enalble 시킴 USART1은 APB2에 위치
 
 
 
        // Configure USART Interrupt
 
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // UART Interrupt을 등록함.핸들러는 TImer처럼 고정되어있음
 
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f; // Preemption 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f; // Sub 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ채널의 cmd를 Enable함.
 
        NVIC_Init(&NVIC_InitStructure); // NVIC 초기화
 
 
 
        // GPIO AF config
 
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
 
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
 
 
 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5; // USART(또는 UART)의 TX 핀번호
 
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
 
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
        GPIO_Init(GPIOD, &GPIO_InitStructure);
 
 
 
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6; // USART(또는 UART)의 RX 핀번호
 
        GPIO_Init(GPIOD, &GPIO_InitStructure);
 
 
 
        // Configure UART peripheral
 
        USART_InitStructure.USART_BaudRate   = 115200; //Baudrate설정.
 
        USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 전송하는 패킷의 길이는 8bit씩 전송함을 명시
 
        USART_InitStructure.USART_StopBits   = USART_StopBits_1; // stopbit는 1개임을 의미
 
        USART_InitStructure.USART_Parity     = USART_Parity_No ;
 
        USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
 
 
 
        USART_InitStructure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode에서 RX, TX를 설정
 
 
 
        USART_Init(USART2, &USART_InitStructure); //  USART초기화
 
 
 
        // Enable USART receive interrupt
 
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
 
 
 
        USART_Cmd(USART2, ENABLE);
 
}
 
void USART1_IRQHandler(void)
 
{
 
        if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) // RX에 무슨 값이 들어왔는가?를 확인하는 방법.
 
        {
 
                cPC = USART_ReceiveData(USART1);//마이크로 컨트롤러 내부의 RX에 일정 값이 들어모녀 한글자, 한글자씩 저장함.
 
                switch(cPC){
 
                case '0': 
                        pcState=0;
 
                        break;
 
                case '1': 
                        pcState=1;
 
                        break;
 
                default:
 
                        pcState=0;
 
                        break;
 
                }
 
       }
 
}
 
void USART2_IRQHandler(void)
 
{
 
        while(USART_GetITStatus(USART2, USART_IT_RXNE)) // RX에 무슨 값이 들어왔는가?를 확인하는 방법.
 
        {
 
                cBT = USART_ReceiveData(USART2);//마이크로 컨트롤러 내부의 RX에 일정 값이 들어모녀 한글자, 한글자씩 저장함.
 
                USART_SendData(USART1, cBT); //오로지 한개의 문자만 보낼수 있음.
 
        }
 
}
 
void USART_puts(USART_TypeDef* USARTx, volatile char *s){
 
        while(*s){
 
                // wait until data register is empty
 
                while( !(USARTx->SR & 0x00000040) );
 
                USART_SendData(USARTx, *s);
 
          *s++;
 
        }
 
}
cs

 

슬레이브(Slave) 초기화 소스

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
char cPC;
 
char cBT;
 
int pcState=0;
 
int btState=0;
 
char buffer_pc[32];
 
char buffer_bt[32];
 
 
 
 
 
 
 
 
 
void Init_USART(void){
 
        GPIO_InitTypeDef GPIO_InitStructure; //GPIO 초기화용 Structure를 선언 
        USART_InitTypeDef USART_InitStructure; // USART 초기화용  Structure를 선언 
        NVIC_InitTypeDef NVIC_InitStructure; // NVIC 초기화용 Structure 선언 
 
 
        // Enable peripheral
 
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //GPIOA를 Enable시킴 GPIOA는 AHB1에 위치
 
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // USART1을 Enalble 시킴 USART1은 APB2에 위치
 
 
 
        // Configure USART Interrupt
 
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // UART Interrupt을 등록함.핸들러는 TImer처럼 고정되어있음
 
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f; // Preemption 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f; // Sub 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ채널의 cmd를 Enable함.
 
        NVIC_Init(&NVIC_InitStructure); // NVIC 초기화
 
 
 
        // GPIO AF config
 
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
 
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
 
 
 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; // USART(또는 UART)의 TX 핀번호
 
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
 
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
        GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
 
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10; // USART(또는 UART)의 RX 핀번호
 
        GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
 
        // Configure UART peripheral
 
        USART_InitStructure.USART_BaudRate   = 115200; //Baudrate설정.
 
        USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 전송하는 패킷의 길이는 8bit씩 전송함을 명시
 
        USART_InitStructure.USART_StopBits   = USART_StopBits_1; // stopbit는 1개임을 의미
 
        USART_InitStructure.USART_Parity     = USART_Parity_No ;
 
        USART_InitStructure.USART_HardwareFlowControl  = USART_HardwareFlowControl_None;
 
        USART_InitStructure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode에서 RX, TX를 설정
 
 
 
        USART_Init(USART1, &USART_InitStructure); //  USART초기화
 
 
 
        // Enable USART receive interrupt
 
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
 
 
        USART_Cmd(USART1, ENABLE);
 
}
 
void Init_USART2_BT(void){
 
 
 
        GPIO_InitTypeDef GPIO_InitStructure; //GPIO 초기화용 Structure를 선언 
        USART_InitTypeDef USART_InitStructure; // USART 초기화용  Structure를 선언 
        NVIC_InitTypeDef NVIC_InitStructure; // NVIC 초기화용 Structure 선언 
 
 
        // Enable peripheral
 
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //GPIOA를 Enable시킴 GPIOA는 AHB1에 위치
 
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // USART1을 Enalble 시킴 USART1은 APB2에 위치
 
 
 
        // Configure USART Interrupt
 
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // UART Interrupt을 등록함.핸들러는 TImer처럼 고정되어있음
 
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f; // Preemption 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f; // Sub 인터럽트 우선순위 설정
 
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ채널의 cmd를 Enable함.
 
        NVIC_Init(&NVIC_InitStructure); // NVIC 초기화
 
 
 
        // GPIO AF config
 
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
 
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
 
 
 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5; // USART(또는 UART)의 TX 핀번호
 
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
 
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
        GPIO_Init(GPIOD, &GPIO_InitStructure);
 
 
 
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6; // USART(또는 UART)의 RX 핀번호
 
        GPIO_Init(GPIOD, &GPIO_InitStructure);
 
 
 
        // Configure UART peripheral
 
        USART_InitStructure.USART_BaudRate   = 115200; //Baudrate설정.
 
        USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 전송하는 패킷의 길이는 8bit씩 전송함을 명시
 
        USART_InitStructure.USART_StopBits   = USART_StopBits_1; // stopbit는 1개임을 의미
 
        USART_InitStructure.USART_Parity     = USART_Parity_No ;
 
        USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
 
        USART_InitStructure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode에서 RX, TX를 설정
 
 
 
        USART_Init(USART2, &USART_InitStructure); //  USART초기화
 
 
 
        // Enable USART receive interrupt
 
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
 
 
 
        USART_Cmd(USART2, ENABLE);
 
}
 
void USART1_IRQHandler(void)
 
{
 
        if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) // RX에 무슨 값이 들어왔는가?를 확인하는 방법.
 
        {
 
                cPC = USART_ReceiveData(USART1);//마이크로 컨트롤러 내부의 RX에 일정 값이 들어모녀 한글자, 한글자씩 저장함.
 
                switch(cPC){
 
                case '0': 
                        pcState=0;
 
                        break;
 
                case '1': 
                        pcState=1;
 
                        break;
 
                default:
 
                        pcState=0;
 
                        break;
 
                }
 
        }
 
}
 
 
 
void USART2_IRQHandler(void)
 
{
 
        if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) // RX에 무슨 값이 들어왔는가?를 확인하는 방법.
 
        {
 
                cBT = USART_ReceiveData(USART2);//마이크로 컨트롤러 내부의 RX에 일정 값이 들어모녀 한글자, 한글자씩 저장함.
 
 
 
        }
 
}
 
void USART_puts(USART_TypeDef* USARTx, volatile char *s){
 
       while(*s){
 
              // wait until data register is empty
 
              while( !(USARTx->SR & 0x00000040) );
 
              USART_SendData(USARTx, *s);
 
              *s++;
 
       }
 
}
 
cs

 

USB로 연결된 PC는 Compert Master라는 프로그램을 통해 전송 받은 값을 확인할 수 있다.

1
2
3
sprintf(buffer,"%d\n", 변수);
 
USART_puts(USART1, buffer_pc);
cs

 

아래 코드를 통해 마이크로프로세서 간 통신이 가능하다.

1
USART_SendData(USART2, 변수);
cs

이 게시물의 소스는 char형 한글자 단위로 전송되게 된다.

만약 문자열을 전송하고 싶다면 별도로 큐를 만들어서 쌓게 해야할 것이다.

 

블루투스 통신은?

굉장히 간단하게도 유선으로 연결된 UART의 Tx와 Rx를 블루투스 모듈로 옮겨 연결하기만 하면 된다.

단 블루투스 모듈이 UART를 지원해야한다.

반응형

'Embeded > ARM Cortex-M4' 카테고리의 다른 글

초음파 센서  (0) 2015.07.10
스태핑 모터 상 제어  (0) 2015.07.10
Sink방식과 Source방식  (0) 2015.07.10
DAC(Digital-Analog Converter)  (0) 2015.07.10
ADC(Analog-Digital Converter)  (0) 2015.07.10