앞의 글에서 설명한 내용까지 문제없이 진행되었으면, 이제는 수신된 데이터 중에서 필요한 부분만 추출하여 원하는 방법으로 데이터를 처리해 주면 된다. AK8975 data sheet 문서에 나오는 레지스터 설명은 다음과 같다. 이 중에서 실제 필요한 데이터는 0x03 ~ 0x08까지의 X,Y,Z 축에 대한 데이터이다. 따라서 이 부분만 화면에 출력해 주면 될것이다. 실제로는 이들 세가지 값을 가지고 어느 방향을 가르키는지 방위각을 계산하여야 하지만 그 부분은 지금 다루고 있는 통신과는 다른 주제이므로 여기에서는 생략하기로 하겠다. X,Y,Z 레지스터 값은 16비트 값으로 되어 있고, little endian으로 제공된다. 이러한 정보를 가지고 컴퓨터 프로그램에서 X,Y,Z 값을 출력해 보도록 하겠다. #-..
통신에 있어서 데이터를 수신하는 측에서는 수신한 데이터가 오류없이 제대로 들어왔는지 궁금할 때가 있다. 전송 선로의 길이가 길거나, 아니면 아예 선이 없는 무선 통신의 경우에는 더더욱 수신된 데이터에 대한 신뢰가 떨어지게 된다. 이러한 이유로 다양한 방법을 사용해서 수신된 데이터에 오류가 발생했는지 여부를 확인할 수 있게 한다. 쉽게 사용할 수 있는 방법이 체크섬(check sum)이다. 이 방법은 8비트 혹은 16비트 단위로 모든 데이터를 더해서 그 마지막 결과값을 추가로 데이터에 덧붙여 보내주면, 수신측에서 동일한 계산을 하여 check sum값이 같은지 비교해서 수신한 데이터의 오류를 판단할 수 있게 하는것이다. 그러나 단순한 덧셈 연산이기 때문에 어떤 데이터에 1이 더한 값이 전달되고, 다른 데이..
이번 글에서는 데이터를 수신하는 측에서 패킷의 시작과 끝을 알 수 있게 하는 방법에 대해서 설명하도록 하겠다. 패킷의 시작과 끝을 알수 있게 하는 방법은 무수히 많겠지만, 이미 잘 알고 있는 방법중에서 아이디어를 빌려오도록 하겠다. 그것은 다름아닌 HDLC(High-Level Data Link Control)를 이용하는 것이다. HDLC는 IBM의 SDLC라는 프로토콜을 국제적으로 표준화한 방법인데, 기본 적인 패킷의 구조는 다음과 같다. 위의 그림에 보이는것처럼 패킷의 시작과 끝에 8비트 크기의 Flag 필드가 있다. 이 플래그는 이진수로 '01111110'의 값을 가진다. 헥사값으로 표시하면 '0x7E'이다. 나머지 필드들은 다음에 설명하기로 하고, 이번글에서는 Flag필드에만 초점을 맞추어 설명하도..
이제 UART를 통해서, 문자형 데이터가 아닌 실제 데이터, 즉, 바이너리 데이터를 송수신하는 프로그램을 만들어 보겠다. 데이터 통신을 하기 위해서는 AVR의 UART 프로그램을 다음과 같이 수정해 주어야 한다. void uart_tx(uint8_t data) { while (!(uart->ucsr_a & UDRE)); uart->udr = data; } uint8_t uart_rx(void) { while (!(uart->ucsr_a & RXC)); return uart->udr; } void uart_init(void) { uint16_t baudrate = F_CPU/UART_BAUDRATE/16; uart->ucsr_b = 0x00; uart->ucsr_a = 0x00; uart->ucsr_c =..
UART를 이용하여 패킷 통신이 제대로 수행되는지 검사하기 위해서는 전용 프로그램이 필요하다. 앞의 글에서도 언급했듯이 일반적인 UART 터미널 프로그램은 문자형 데이터만 처리할 수 있으므로 데이터 통신을 수행할 수 있는 전용 프로그램이 필요하다. PC용 프로그램은 다양한 툴을 사용하여 개발 가능하므로 각자 자신이 구현하기 쉬운 환경을 이용하여 개발하면 된다. 이 블로그에서는 Python을 이용하여 PC용 어플리케이션을 만드는 방법에 대해서 설명하도록 하겠다. 가장 먼저 해야 할 일은 UART를 통해서 데이터 수신이 제대로 되는지부터 확인하는 것이다. 위의 그림처럼 UART 터미널에서 보여졌던 내용과 동일하게 AVR에서 보낸 메시지를 제대로 출력하는것을 볼 수 있다. 일단, AVR과 UART 통신이 제대..
직렬 패킷 통신을 구현하기 위한 예제 프로젝트 회로 구성에 대하여 알아보도록 하겠다. 아래 그림은 ATAVRSBIN의 회로도이다. ATAVRSBIN1은 10핀 커넥트로 외부와 연결된다. TWI 통신을 위하여 1번 핀 SDA와 2번 핀 SCL이 사용된다. 3번 핀은 Compass의 DRDY 신호를 위하여 사용되고, 4번핀과 5번핀은 Accelerometer와 Gyroscope의 INT 핀에 각각 연결된다. 9번 핀을 GND에, 10번 핀을 VCC에 연결하게 되어 있다. AVR과 ATAVRSBIN1과의 연결은 TWI 핀 두개와 PC1,2,3을 이용해서 연결한다. UART 통신을 위하여 RXD와 TXD핀도 연결한다. 먼저 UART를 통하여 컴퓨터와 정상적인 통신이 되는지부터 확인한다. #include #inc..
위에 보이는 그림은 ATMEL에서 만든 ATAVRSBIN1이라는 센서 모듈이다. 그림에 표시되어 있는것처럼 AK8975라는 Compass와 BMA150이라는 Accelerometer와 ITG3200이라는 Gyroscope를 포함하는 세개의 센서가 실장되어 있다. 각각의 센서들은 모두 동일한 TWI버스에 연결되어 있기 때문에 MCU는 하나의 TWI를 이용하여 각각의 센서들과 통신할 수 있다. 일반적으로 임베디드 시스템은 다른 시스템과 연동없이 자체적으로 동작되는 경우도 있지만, 컴퓨터를 비롯해서 다른 임베디드 시스템과 연동하여 동작되는 경우도 많다. 특히, 최근들어 IoT라는 개념으로 인하여 다른 시스템과의 상호 연동되는 경우가 점점 더 기본 기능처럼 되어 가고 있는 추세다. 다른 시스템과 데이터를 주고 ..
이번글에서는 두점을 잇는 선을 그리는 방법을 구현해 보도록 하겠다.인터넷에 찾아보면 다양한 선 그리는 알고리듬을 찾아 볼 수 있는데, 비교적 널리 알려진 Bresenham의 알고리듬을 적용하여 선을 그려보도록 하겠다. void lcd_draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color) { int dx = abs(x1-x0), sx = x0 -dx) { err -= dy; x0 += sx; } if (e2 < dy) { err += dx; y0 += sy; } } } 위의 코드에 대해서는 인터넷에 잘 설명되어 있으므로 굳이 여기에서는 따로 설명하지는 않겠다. 단지, 이 코드를 이용하여 간단한 예제 프로그램을 만들어서 제대로 선이..
이번에는 LCD12864의 특정 위치에 하나의 점을 표시하는 방법에 대해서 알아보겠다. 바로 앞에서 설명한 LCD12864 드라이버 코드 - Graphic mode을 읽어 보면 그래픽 모드일때 원래는 32 X 256 개의 픽셀이 있지만 세로 방향으로 한 가운데를 잘라, 오른쪽 반을 왼쪽 반의 아래부분에 이어 붙인것이라고 보면 된다고 했다. 결국 64 X 128개의 픽셀이 있는것처럼 보이는 것이다.이 중에서 특정 위치의 픽셀에 점을 찍어 보는 방법을 알아보도록 하겠다. void lcd_draw_dot(uint8_t x, uint8_t y) { uint16_t data; send_cmd(GDRAM_ADDR | (y & 0x1F)); send_cmd(GDRAM_ADDR | (y & 0x20 ? 8 : 0) |..
LCD12864 프로젝트의 첫번째 글에서 이미 얘기했듯이 LCD12864는 이름과 같이 가로 128개의 점과 세로 64개의 점으로 표시 가능한 그래픽 모드로 동작 시킬수 있다. 이번 글에서는 어떻게 그래픽모드로 동작 시켜 원하는 곳에 점을 표시할 수 있는지 설명하도록 하겠다. 먼저, 그래픽 모드로 설정하기 위한 코드를 만들어 보겠다. void lcd_set_graphic_mode(void) { send_cmd(CMD_CLR); _delay_ms(10); send_cmd(CMD_FUNC | EXTEND_INST | GRAPHIC_ON); send_cmd(CMD_HOME); } lcd_set_graphic_mode()는 텍스트 모드에서 그래픽 모드로 전환 할 수 있다. 위의 표에서 보는바와 같이 functi..