Application Note of 8-bit Atmel Microcontrollers.



Atmel AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers.


Features

• Atmel® AVR® core and Atmel AVR GCC introduction

• Tips and tricks to reduce code size

• Tips and tricks to reduce execution time

• Examples application



Introduction

AVR core is an advanced RISC architecture tuned for C code. It ensures the

development of good products with more features at less cost.

When talking about optimization, we usually refer to two aspects: code size and

code speed. Nowadays, C compilers have different optimization options to help

developers get an efficient code on either size or speed.

However, good C coding gives more opportunities for compilers to optimize the

code as desired. And in some cases, optimizing for one of the two aspects affects

or even causes degradation in the other, so a developer has to balance the two

according to their specific needs. An understanding of some tips and tricks about C

coding for an 8-bit AVR helps the developers to know where to focus in improving

code efficiency.

In this application note, the tips are based on avr-gcc (C compiler). However these

tips could be implemented in other compilers or with similar compiler options, and

vice versa.





avr_optimize c code.pdf


Octal D-Type Latch with 3-STATE Outputs


General Description

The DM74LS573 is a high speed octal latch with buffered common Latch Enable (LE) and buffered common Output Enable (OE) inputs.

This device is functionally identical to the DM74LS373, but has different pinouts.



Features

- Inputs and outputs on opposite sides of package allowing easy interface with microprocessors

- Useful as input or output port for microprocessors

- Functionally identical to DM74LS373

- Input clamp diodes limit high speed




74ls537.pdf


▶ 블루투스 인터페이스 회로 만들기



[UART to USB 관련링크]

http://www.devicemart.co.kr/goods/view.php?seq=6185


UARTtoUSB1.pdf

 USB_Drivers.exe



[인터페이스 ORCAD 회로도]


발로그린 회로도..'-'..;;죄송..


블루투스와 UART to USB를 MCU와 연결하실때 주의하실점은 RX와 TX를 꼬아서 연결해야된다는 점입니다.

RX는 RX가 아니라 RX는 TX로 가야합니다. 그리고 블루투스의 전원 3,3V이며 (아니면 IC죽습니다..) RX측은 MCU 5V TTL신호의 TX와 연결되기에 2:3비의 저항을 연결해서 전압분배해주어야 블루투스 모듈이 죽지않습니다...만약 안죽고 잘 돌아(?)가더라도.. 수명이 짧아진다던가..곧 사망입니다..^^;..ㅋㅋ


 





▶ FB155BC 사용하기



FB155BC 사용자 설명서 Version 2.1을 참고하였습니다.


FB155BC 는 기존의 유선 RS232 케이블 방식을 무선으로 대체 하여 사용 할 수 있도록 만들어 졌습니다.


FB155BC 주요특징

1. Bluetooth Specification 2.1 Support

2. 8 Pins Header type로 되어 있어 제품에 쉽게 적용 가능

3. AT 명령어를 지원하며, AT 명령어를 이용하여 FB155BC 제어 가능

4. Bluetooth PDA, Bluetooth USB Dongle 등과 원활하게 연결 하여 사용 가능

5. Class2 EDR중에 가장 Compact size 제공

6. 간단하게 블루투스 펌웨어 update 기능 지원

7. 안정적인 데이터 송 수신




이번에 블루투스 모듈을 이용하여 무선송수신이 필요하여 펌테크사의 FB155BC를 구입하여 공부해보았습니다.

따라서 저처럼 맨땅에 헤딩하는 분들이 안계시길 바라는 마음에서 이와같은 저만의 메뉴얼을 만들어봅니다.

개인적으로 저의 일진행은 아래와같으며 이와같은 순서로 설명하면서 중간중간 제 의견을 첨가 하겠습니다.


[[블루투스] FirmTech사의 FB155BC 사용하기 - 1 ]

1. FB155BC 및 기타자재 구입 (FB155BC는 마스터용, 슬레이브용 각1EA)


[[블루투스] FirmTech사의 FB155BC 사용하기 - 2] 

2. 블루투스 초기설정을 위한 인터페이스회로 제작 ("ATmega128A"과 "USATR to USB " device 사용)


[[블루투스] FirmTech사의 FB155BC 사용하기 - 3]

3. 인터페이스회로에 프로그램주입 (USART 송수신 기본 P/G)

   - ATmega128로 블루투스를 사용하면 USART에 선만 사라졌다고 생각하시면 되기때문에..


[[블루투스] FirmTech사의 FB155BC 사용하기 - 4]

4. AT명령을 이용한 블루투스 설정 및 무선구간설정

5. 테스트를 위해 제작한 블루투스 마스터,슬레이브 회로로 PC와 하이퍼터미널 에코테스트

6. 실제 블루투스 무선통신 구현



---------------------------------------------------------------------------------------

펌테크사의 블루투스모듈을 사용하기에 앞서 필요한 인터페이스회로를 꾸미기 위해서는 아래의 모듈과 소자들이 필요합니다.

(만약 충분한 자금적 여유가 되신다면 인터페이스 보드를 구매하시는걸 추천합니다 ^^...아니면 시간과 얼마의 돈을 투자하셔서 하나쯤 만들어놓는것도 앞으로의 공대생활에 필요하다고 판단이 되네요..ㅎ;..)


1. UART to USB


위나 아래나..그놈이 그놈입니다..^^;. 적당히 마음에 드시는 모듈로 구매해주세요~!

만약 이 모듈이 필요없다! 직접 만들겠다? 그렇다면 RS232 to uart 통신관련 자료를 인터넷에서 찾아서 공부해서 진행해주시기 바랍니다. PC와 5V MCU와의 시리얼 통신을 위해서 MAX232칩이 필요하구요 RS232C 커넥터도 필요합니다 ^^ 이부분은 검색하시면 워낙 많이 나오는 정보라..따로 포스팅 안하겠습니다.




2. ATmega128 (MCU)


PC와의 통신I/O를 사용하기 위해서 MCU가 필요합니다. 저는 그중에서 제가 가장 좋아하는 ATmega128를 선택했습니다. 




AVR 기본회로는 충분히 아실꺼라 믿고 넘어가겠습니다. 아마 제 블로그의 ORCAD 카테고리에 회로도가 있는걸로 알고있습니다.


3. FB155BC (블루투스 모듈)




저는  위 모듈을 각각 다 구입하였는데요..최종저의 목적지가 스마트기기와 영상데이터 송수신이기때문에 HID프로파일을 지원하는 제품도 구입하였습니다. 필요에 따라 구매하시면 되시겠습니다. 갠적으로 저렴한 모듈로는 HC-06을 추천해드립니다.


4. 그외의 필요한 소자들...


블루투스 3.3V를 사용하기때문에 별도의 전원회로가 필요하며, 5V TTL신호를 사용하는 ATmega128과 블루투스간의 TX,RX USART송수신을 위해서는 전압분배 회로도도 필요합니다. 또한 ATmega128은 USART Port가 0,1번으로 2개밖에 없기때문에 ISP통신을 위한 통신 JUMPER와 블루투스 또는 UART to USB 통신을 위한 JUMPER도 따로 구성을 해주셔야 하며 5V의 신호가 블루투스로 혹시나 유입되지않도록 별도의 스위치나 다이오드를 통해 보호를 해주셔야합니다. 구구절절하게 적었지만 다음장의 회로도1장이면 아마 이 모든 설명이 필요없을것 같네요 ^^; 참고해주세요.

■ 공통 문의사항

Q1 제품은 어디서 구매하나요?


본사 및 대리점을 통하여 구입 하실 수 있습니다.

대리점에 대한 정보는 홈페이지 QUICK MENU 의 “제품 구매문의” 클릭하여 확인하여 보시기 바랍니다.

http://cafe.naver.com/firmtech7

http://www.firmtech.co.kr/main/main_kor.php


Q2 블루투스의 전송속도는 어떻게 되나요?


블루투스의 전송속도는 최대 약 1Mbps(Spec v1.2) ~ 3Mbps(Spec v2.0+EDR)입니다.

위의 최대 전송속도는 Base Band(물리계층)의 최대 전송속도 이며, Bluetooth Protocal Stack(profile) 상에서는 Protocal 처리 시간이 필요하기 때문에 최대 전송속도로 통신 하실 수 없습니다.

펌테크에서 제공하는 제품의 최대 전송속도는 230400bps(SPP Profile 기준) 까지 안정적으로 통신 하실 수 있습니다.


Q3 블루투스의 통신거리는 얼마나 되나요?


블루투스는 송출 출력에 따라 통신거리를 Class 로 구분 합니다.

Class 1 은 송출 출력이 100mW 이며 최대 100m 까지 통신이 가능하며, Class 2는 송출 출력 10mW이고 최대 10m 까지 통신이 가능 합니다.


Q4 블루투스 장치간의 연결과정은 어떻게 되나요?


2개의 블루투스 장치간의 연결 과정은 다음과 같습니다.

먼저, 1개의 블루투스 장치를 Slave로 설정 합니다.

Slave로 설정한 블루투스 장치가 SCAN(검색대기 및 연결대기)이라는 동작을 수행 합니다.

SCAN 동작이 진행 중이어야 Master에서 검색(Inquiry)을 했을 때 Slave를 찾을 수 있습니다.

다른 1개의 블루투스 장치를 Master로 설정 합니다.

Master로 설정한 블루투스 장치로 주변의 Slave 장치를 검색합니다.

패어링(Paring)이란 연결하고자 하는 Master와 Slave 장치간에 상호 보안에 관한 Key(Link key) 의 생성 여부를 확인 하는 절차 입니다. 패어링 절차를 진행 하기 위해서는 PIN CODE(Pass key)가 Master와 Slave가 동일해야 하며, 펌테크의 제품의 경우 Default PIN CODE가 "BTWIN"으로 고정되어 있습니다.

패어링 과정이 올바르게 진행된 경우, 2개의 블루투스 장치는 연결이 가능하며, 연결이 완료된 되면 Master / Slave 상호간에 데이터 송수신이 가능합니다.


Q5 블루투스 장치의 Master / Slave 설정 기준은 어떻게 되나요?


통상적으로 검색(Inquiry) 및 연결요청(Page)을 하는 쪽을 Master라고 하며, 검색대기(Inquiry Scan) 및 연결대기(Page Scan)를 하는 쪽을 Slave라고 합니다.

시스템 상에서의 Master / Slave 설정 기준은 Master 는 Slave에 비해 블루투스 연결과정의 전류소모가 크지만 데이터 송신시 무선 딜레이가 Slave 보다 적으므로 주로 데이터를 송신 하는나 자주 전원을 ON / OFF 하는 쪽을 Master 로 설정하는게 좋습니다.

Slave는 Master에 비해 연결과정 전류 소모량이 적은 반면 데이터 송신시 무선 딜레이가 Master 보다 더 크므로 주로 데이터 수신이나 항상 전원이 ON 되어 있는 쪽을 Slave로 설정하시는게 좋습니다.


Q6 마이컴을 이용하여, 펌테크 블루투스 장치를 제어하려면 어떻게 해야 하나요?


마이컴을 이용하여 펌테크 블루투스 장치를 제어하기 위해서는, 마이컴의 UART 통신 포트와 블루투스 장치의 UART 통신 포트를 연결하여 마이컴에서 펌테크 블루투스 장치로 제어용 AT command를 전송합니다.

(UART: Universal Asynchronous Receiver Transmitter)

마이컴의 UART 통신 포트는 신호레벨이 TTL 이므로 펌테크 블루투스 장치의 UART 통신 포트도 TTL 레벨인지 확인하고 연결 합니다. 펌테크 임베디드 모듈의 UART 통신 포트는 TTL 레벨 입니다.

마이컴의 UART 포트 중 RX 포트는 펌테크 블루투스 장치의 TX 포트와 연결하고, 마이컴의 UART 포트중 TX 포트는 펌테크 블루투스 장치의 RX 포트와 연결하면 마이컴을 이용하여 펌테크 블루투스 장치를 제어 할 수 있습니다.

조금더 자세한 사항은 펌테크 제품중에 FBDx5xMC 를 참조하시기 바랍니다.


 



Q7 블루투스 장치를 이용하여, PLC에 펌웨어를 다운로드 하기 위하여 확인 해 보아햐 할 사항?


RS-232케이블을 이용하여 PLC에 펌웨어를 다운로드 하던걸 펌테크 블루투스 장치를 이용하여 PLC에 펌웨어를 다운로드 하려면 아래와 같은 몇가지 사항을 각 PLC 업체에 문의 하거나 PLC Datasheet를 확인 해 보아야 합니다.


1. 다운로드 속도 확인

--> 기존에는 케이블을 사용 하였으면 기본적으로 PLC HOST(PC) 와 PLC간의 통신 속도를 따로 맞추지 않아도 통신이 가능 할 수도 있지만 펌테크 블루투스 제품을 이용 하시면

PLC HOST(PC)<-->블루투스    |무선구간|    블루투스<-->PLC 

유선과는 달리 블루투스라는 장치가 추가 되었기 때문에 블루투스 인터페이스(<-->)간의 통신속도가 정확하지 않으면 데이터 통신이 되지 않기 때문에 정확한 통신 속도를 확인 해야 합니다.


2. 블루투스 무선지연 시간이 문제가 되지 않는지 확인

--> 블루투스는 OSI 7 레이어에 준하는 protocal stack 에 의하여 통신 하기 때문에 protocal 처리 시간이 무선지연 시간으로 발생 됩니다.

펌테크 제품은 평균 10 ~ 30m/s 의 무선 지연시간이 발생됩니다.

대부분의 PLC 통신은 패킷 통신을 하기 때문에 한패킷 안에서 데이터와 데이터 사이의 간격이 일정한 시간이내에(10m/s이내) 데이터가 입력되지 않으면 데이터 타임 아웃을 발생 시켜 데이터 오류로 인식하는 통신 방식에서는 펌테크의 블루투스 장치를 사용 하시기가 어렵습니다.

이부분에 관해서는 해당 PLC 업체에 꼭 문의 하시기 바랍니다.


3. 기존에 사용하고 있는 RS-232 케이블의 종류 확인

--> 펌테크의 블루투스 제품은 RS-232 케이블 중에 통신 케이블(크로스 케이블)을 대치하는 제품입니다.

기존에 사용한 케이블이 통신 케이블 이면 당사의 제품을 바로 연결하시면 되고, 기존에 사용한 케이블이 연장 케이블 이면 RX, TX, RTS, CTS, DTR, DSR 을 각각 크로스로 연결해 주셔야 합니다.

이부분의 관해서는 당사 제품의 입출력 부분 Datasheet 와 PLC 의 입출력 부분 Datasheet를 꼭 확인 하시고 사용하시기 바랍니다.


Q8 블루투스 장치간의 통신거리를 연장하려면 어떤 방법이 있나요?


블루투스 장치간의 기본 통신거리는 Class 1의 경우 100m 이고 Class 2의 경우는 10m 입니다.

만약 통신거리를 연장하고자 한다면, 안테나 출력을 높이는 방법과 당사 제품 중 FB900AS 중계기를 이용하여 거리를 연장 할 수 있습니다. Planar Antenna를 사용하여 안테나 출력을 높이면 직선상의 통신 거리를 연장 할 수 있고, FB900AS는 장애물이나 꺾임이 있는 부분 또는 건물 층 간의 통신을 하고자 하는 경우에 사용합니다.

자세한 사항은 각각의 제품 소개를 참조 하시기 바랍니다.


Q9 블루투스 장치에서 흐름제어 사용이 가능한가요?


펌테크 블루투스 장치는 기본 적으로 흐름제어 신호 사용이 가능 합니다.

금전이나 인명에 관련하여 하드웨어적인 흐름제어를 사용 할 경우 당사에 문의 하신 후 사용 하시기 바랍니다.



Q10 (주)펌테크 제품의 환경 설정 중에서, CONNECTIO MODE와 OPERATION MODE 는 무엇인가요?


CONNECTION MODE 는 Master / Slave를 연결하기 위한 방법을 선택하는 것이고, OPERATION MODE 는 당사제품중 1:N 통신이 가능한 제품의 통신 방식을 선택하는 MODE 입니다.

각각의 MODE에 관해서는 부록 A 와 부록 C 를 참조 하시기 바랍니다.


Q11 1:N 통신이 가능한 제품은 있나요?


금번 출시되는 BM1001과 BM2001(v4.0 이상) 그리고 FB755AS/AC는 1:N 통신이 가능합니다.

그러나 기존에 출시된 BM1001,BM2001(v3.7 이하)의 경우는 펌웨어 버전이 지금 출시되는 제품들과 다르므로 1:N 통신 기능을 사용할 수 없습니다. 버전을 확인 방법은 PC configuration 매뉴 상에서 Device Name에 제품명과 함께 기제되어 있습니다.

(0 => DEVICE NAME : BMx001 v3.7)


Q12 무선 랜과 같은 2.4GHz 주파수를 사용하는 무선 장치 주변에서, 블루투스 장치를 사용하면 무선장치간의 충돌이 발생하나요?


블루투스는 주파수 호핑(Frequency Hopping) 방식을 사용하므로 2.4GHz 주파수를 사용하는 무선 기기 주변이나 Noise가 많은 환경에서도 충돌 없이 안정된 무선 데이터 통신을 보장합니다. 

단 좁은 공간 내에 다수의 블루투스 장치를 사용하는 경우에는 주파수의 간섭을 받을 수 도 있습니다.


Q13 음성데이터를 송/수신 할 수 있는 블루투스 제품은 있나요?


 당사 제품 중 FB560BC는 스테레오 오디오를 송/수신 하는 제품 입니다.

FB560BC는 송신 기능을 하는 모듈과 수신 기능을 하는 모듈로 구분됩니다.

스테레오오디오 송신 기능의FB560BC(FB560BC-TX)모듈에 입력하면, 수신 기능의 FB560BC(FB560BC-RX)모듈에 연결되어 있는 출력 장치(스피커 등)에서 스테레오오디오가 출력 됩니다.

자세한 내용은 홈페이지 "제품소개"란 의 FB560BC를 참고 하십시오




Bluetooth 규격

-2.4GHz 대역의 ISM(Industrial Scientific Medical) 대역 (2.402GHz ~ 2.480GHz)

-1Mbps의 전송 속도 (실제 723kbps : 721kbps로 잘못 표기된 곳이 많음)

-간섭방지를 위한 주파수 호핑 방식 (79/23 hop, 1600 hop/sec)

-저소비전력 (대기상태 0.3mA, 송수신시 최대 30mA)

-전송거리 10m 및 Option으로 100m까지 가능

-Class 1,2,3의 송신 파워 (각 100mW, 2.5mW, 1mW)

-변조방식 : GFSK (Guassian Frequency Shift Keying)

-3채널의 Voice 지원 (A-Law, u-Law PCM, CVSD)

-Point to Point, Point to Multi 방식의 연결 가능



일단 저는 대부분의 전자소자와 모듈은 디바이스마트와 엘레파츠를 통해서 구입합니다. 직접 전자상가에 가서 부품을 보고서 구입할때도 있지만...일단 아직까지 학생인지라..^^;..시간과 자금의 여유가..ㅠㅠ 

아무튼 전반적인 블루투스 모듈의 종류를 캡쳐해서 아래에 첨부해봅니다.


블루투스모듈을 공급하는 가장 유명한 회사로는 : 펌테크(firmtech), SENA, 모본(MOVON), 우리디스플레이 정도가 됩니다.





개인적으로 저는 펌테크사의 제품을 추천하며..저렴한 가격대로 구성하실려면 우리디스플레이의 HC-06을 추천합니다.

당근이 카페나 전자소자관련 카페에서 공동구매도 많이 진행하기때문에 적절한 타이밍을 잡아서 구매하시면 되시겠습니다 ^^


아래는 펌테크사의 블루투스 프로파일에 대한 설명입니다.




그리고 블루투스를 사용하실때 CLASS1,2,3 라고 많이들 말씀하시는데 구체적으로 이것이 무엇일까요??

블루투스는 근거리 무선통신으로  CLASS 는 통신의 최대 전파범위(out power)를 의미합니다.


Class 3 radios – have a range of up to 1 meter or 3 feet 

Class 2 radios – most commonly found in mobile devices – have a range of 10 meters or 33 feet 

Class 1 radios – used primarily in industrial use cases – have a range of 100 meters or 300 feet


(1 feet = 30.48cm)

그러나..전파범위가 넓다고 꼭 좋은것만은 아닙니다 ^^;.. 기술이 그렇게 허술할리가 없지요..ㅎ 각각의 장단점이 존재합니다.

각각의 Class별 지원사양이 차이가 나지만 여기서 다루지는 않겠습니다 ㅎ


그리고 다음장부터는 제가 직접다루어본 FB155BC에 대해서 설명하겠습니다.




출처 : http://navercast.naver.com/contents.nhn?rid=122&contents_id=5531  (네이버 캐스트)


루투스(Bluetooth)는 휴대폰, 노트북, 이어폰·헤드폰 등의 휴대기기를 서로 연결해 정보를 교환하는 근거리 무선 기술 표준을 뜻한다. 주로 10미터 안팎의 초단거리에서 저전력 무선 연결이 필요할 때 쓰인다. 예를 들어 블루투스 헤드셋을 사용하면 거추장스러운 케이블 없이도 주머니 속의 MP3플레이어의 음악을 들을 수 있다. 블루투스 통신기술은 1994년 휴대폰 공급업체인 에릭슨(Ericsson)이 시작한 무선 기술 연구를 바탕으로, 1998년 에릭슨, 노키아, IBM, 도시바, 인텔 등으로 구성된블루투스 SIG(Special Interest Group)’를 통해 본격적으로 개발됐다. 이후 블루투스 SIG 회원은 급속도로 늘어나 2010년 말 기준 전세계 회원사가 13,000여 개에 이른다.


블루투스 – 야심 찬 이름의 근거리 무선 통신 기술


블루투스라는 이름은 10세기경 스칸디나비아 지역을 통일한 덴마크와 노르웨이의 국왕 해럴드 블루투스 (Harold "Bluetooth" Gormsson, ?~985 혹은 986)의 별명에서 나왔다. 그는 블루투스(Bluetooth, 푸른이빨)라는 별명을 가지고 있었는데, 블루베리를 좋아해 항상 치아가 푸르게 물들어 있었기 때문이라는 설도 있고, 파란색 의치를 해 넣었기 때문이라는 설도 있다. 참고로 블루투스는 ‘덴마크의 하랄1세’라고도 불리는데,노르웨이의 하랄1세와 헷갈리기 쉽다. 하여간 SIG는 자신들이 개발한 기술이 통신장치들을 하나의 무선 기술 규격으로 통일하기를 바라는 마음에서 공식명칭을 블루투스로 정했다. 이에 따라 블루투스의 공식 로고도 하랄의 H와 블루투스의 B를 뜻하는 스칸디나비아 룬 문자에서 따왔다.





블루투스의 원리


블루투스의 무선 시스템은 ISM(Industrial Scientific and Medical) 주파수 대역인 2400~2483.5MHz를 사용한다. 이 중 위아래 주파수를 쓰는 다른 시스템들의 간섭을 막기 위해 2400MHz 이후 2MHz, 2483.5MHz 이전 3.5MHz까지의 범위를 제외한 2402~2480MHz, 총 79개 채널을 쓴다. ISM이란 산업, 과학, 의료용으로 할당된 주파수 대역으로, 전파 사용에 대해 허가를 받을 필요가 없어 저전력의 전파를 발산하는 개인 무선기기에 많이 쓰인다. 아마추어 무선, 무선랜, 블루투스가 이 ISM 대역을 사용한다.

 

여러 시스템들과 같은 주파수 대역을 이용하기 때문에 시스템간 전파 간섭이 생길 우려가 있는데, 이를 예방하기 위해 블루투스는 주파수 호핑(Frequency Hopping) 방식을 취한다. 주파수 호핑이란 많은 수의 채널을 특정 패턴에 따라 빠르게 이동하며 패킷(데이터)을 조금씩 전송하는 기법이다. 블루투스는 할당된 79개 채널을 1초당 1600번 호핑한다.

 

이 호핑 패턴이 블루투스 기기 간에 동기화되어야 통신이 이루어진다. 블루투스는 기기 간 마스터(Master)와 슬레이브(slave) 구성으로 연결되는데, 마스터 기기가 생성하는 주파수 호핑에 슬레이브 기기를 동기화시키지 못하면 두 기기 간 통신이 이루어지지 않는다. 이로 인해 다른 시스템의 전파 간섭을 피해 안정적으로 연결될 수 있게 된다. 참고로 하나의 마스터 기기에는 최대 7대의 슬레이브 기기를 연결할 수 있으며, 마스터 기기와 슬레이브 기기 간 통신만 가능할 뿐 슬레이브 기기 간의 통신은 불가능하다. 그러나 마스터와 슬레이브의 역할은 고정된 것이 아니기 때문에 상황에 따라 서로 역할을 바꿀 수 있다.



블루투스 기기 연결 방법

블루투스 기기를 서로 연결하는 방법은 그다지 복잡하지 않다. 한두 번만 연결해 보면 누구라도 능히 블루투스 기기를 사용할 수 있을 것이다. 당연하겠지만, 마스터 기기, 슬레이브 기기 모두 블루투스를 지원해야 한다. 예를 들어 블루투스를 지원하는 스마트폰과 블루투스 헤드셋을 연결하는 예를 들면, 스마트폰이 마스터, 헤드셋이 슬레이브가 된다. 헤드폰 전원을 켜고 스마트폰의 블루투스를 활성화하면 이내 주변의 모든 블루투스 기기를 탐색한다.

 

그중에서 연결을 원하는 헤드폰 모델을 선택하면 즉시 연결(페어링- pairing, 두 기기를 한 쌍으로 묶는다는 의미)된다. 블루투스 기기에 따라 연결 시 암호를 입력해야 하는 경우도 있다. 예를 들어 노트북에 블루투스 마우스/키보드 등을 연결하는 경우가 그러하다. MS 윈도우 운영체제의 작업 표시줄에서 블루투스 아이콘을 클릭하여 ‘장치 추가’ 메뉴를 선택한 다음, 블루투스 기기를 탐색하여 연결하면 된다. 필요에 따라 이때 연결 암호를 입력하여 연결을 완료하면 된다. 암호는 일반적으로 슬레이브 기기에 부여된 문자 또는 숫자를 입력한다. 아울러 일단 한번 연결되면 그 이후부터는 각 기기의 전원과 블루투스를 켤 때마다 자동으로 연결된다.

 



블루투스를 지원하는 헤드셋이나 키보드는 있는데, 정작 마스터 기기가 될 노트북, 휴대폰이 블루투스를 지원하지 않을 경우가 있다. 이럴 때는 블루투스 동글(dongle, 중계기)을 사용하면 된다. 이 동글은 일반적으로 USB메모리 모양을 하고 있어 USB포트에 연결하는 방식으로 쉽게 사용할 수 있지만, 기기에 따라 별도의 전용 동글이 필요할 때도 있다.


블루투스의 발전


초창기 블루투스의 전송속도는 최대 1Mbps에 불과했다. 이는 기존 기술에 비해 6배 가량 빠른 속도였지만 고품질 음악이나 동영상과 같은 대용량 데이터를 전송하기에는 부적합한 수준이었다. 따라서 블루투스의 대중화는 생각보다 진전이 느렸고, 제한적인 용도로만 사용됐다. 하지만 시간이 지나고 새로운 버전의 블루투스가 등장하면서 속도는 눈에 띄게 향상됐다. 블루투스 2.0(2004년)은 최대 3Mbps, 블루투스 3.0(2009년)은 최대 24Mbps까지 속도가 올라갔다. 2010년에는 24Mbps 속도를 유지하면서도 손목시계용 코인 배터리로도 수년간 쓸 수 있을 정도로 소비 전력을 낮춘 블루투스 4.0까지 나왔다.

 

블루투스를 대체할 경쟁 기술도 등장했다. 2010년 발표된 와이파이 다이렉트가 그것이다. 와이파이 다이렉트는 인터넷망 없이 휴대기기 간 직접 연결해 통신할 수 있는 기술로, 기존 와이파이에 버금가는 빠른 속도가 장점이다. 하지만 그만큼 전력 소모는 심할 것으로 보인다. 향후 개인 무선 기술 경쟁구도는 저전력을 내세운 ‘블루투스 4.0’ vs 빠른 속도가 강점인 ‘와이파이 다이렉트’를 중심으로 이루어질 전망이다.


보안에 취약한 블루투스 


블루투스를 이용한 해킹은 블루재킹(bluejacking), 블루스나핑(bluesnarfing), 블루버깅(bluebugging)으로 나뉜다. 이 중 블루재킹은 단순히 스팸메시지를 뿌리는 수준으로, 귀찮은 존재긴 하지만 보안에 큰 위협을 가하지는 않는다. 하지만 모바일 기기에 저장된 일정표, 전화번호, 이메일, 문자메시지 등에 접근하는 블루스나핑, 희생자의 휴대폰을 원격 조종해 통화내용을 엿듣는 블루버깅은 치명적인 피해를 야기할 수 있다. 따라서 공공장소와 같이 유동인구가 많은 곳에서는 블루투스를 신중히 사용해야 한다. 또한 안티 바이러스나 방화벽 기능을 지원하는 모바일 기기용 보안 제품을 구비하는 것이 좋다.



블루투스는 헤드셋/핸즈프리 외에는 큰 힘을 못 쓰고 있는 상황


무선 통신을 제패하겠다는 부푼 꿈을 안고 출발한 블루투스는 현재까지 큰 힘을 못쓰고 있는 게 현실이다. 소비 전력이 낮다는 장점은 있지만 전송 속도와 비용 면에서 충분한 경쟁력을 갖추지 못했기 때문이다. 물론 차량용 헤드셋(핸즈프리)이나 스피커폰 같은 일부 기기에서는 강세를 보이고 있다. 통화할 때 핸들에서 손을 놓을 필요가 없어 안전한 운전이 가능하고, 거추장스러운 케이블이나 복잡한 연결 과정이 필요 없어 운전 중 통화할 일이 많은 전문직에게 인기를 끌고 있다.

 

하지만 휴대폰이나 노트북 등 다른 모바일 기기에서는 여전히 무선랜, NFC(근거리 통신) 등의 다른 무선 기술과 치열한 경쟁을 펼쳐야 할 상황에 놓였다. 과연 블루투스가 헤럴드 블루투스 왕처럼 무선 세계 통일을 이룰 수 있을까? 당분간은 더 지켜봐야 할 것으로 보인다.





JHKIM님의 블루투스관련자료 :

02_about Bluetooth.pdf


 

Two-wire Serial Interface

참조 : ATmega128 Datasheet, I2C protocol, etc blog data.. 

 

I2C : 어떤 IC들간에도 공통적으로 통할 있는 버스(2가닥)

오늘의 주제 :  ATmega128 에서의 TWI 사용법에 대해서... 




 

 

PD1 INT1/SDA(1) (External Interrupt1 Input or TWI Serial DAta)

 

PD0 INT0/SCL(1) (External Interrupt0 Input or TWI Serial CLock)

 

 

 

• INT1/SDA – Port D, Bit 1

INT1, External Interrupt source 1.

The PD1 pin can serve as an external interrupt source

to the MCU.

SDA, Two-wire Serial Interface Data: When the TWEN bit in TWCR is set (one) to enable the Two-wire Serial Interface, pin PD1 is disconnected from the port and

becomes the Serial Data I/O pin for the Two-wire Serial Interface. In this mode, there is a spike filter on the pin to suppress spikes shorter than 50 ns on the input signal, and the pin is driven by an open drain driver with slew-rate limitation.

 

 

 

 

 

• INT0/SCL – Port D, Bit 0

INT0, External Interrupt source 0. The PD0 pin can serve as an external interrupt source to the MCU.

SCL, Two-wire Serial Interface Clock: When the TWEN bit in TWCR is set (one) to enable the Two-wire Serial Interface, pin PD0 is disconnected from the port and becomes the Serial Clock I/O pin for the Two-wire Serial Interface. In this mode, there is a spike filter on the pin to suppress spikes shorter than 50 ns on the input signal, and the pin is driven by an open drain driver with slew-rate limitation. Table 37 and Table 38 relates the alternate functions of Port D to the overriding signals.

 

 

 

Features

 

Simple yet Powerful and Flexible Communication Interface, only Two Bus Lines Needed

Both Master and Slave Operation Supported

Device can Operate as Transmitter or Receiver

7-bit Address Space allows up to 128 Different Slave Addresses

Multi-master Arbitration Support

Up to 400 kHz Data Transfer Speed

Slew-rate Limited Output Drivers

Noise Suppression Circuitry Rejects Spikes on Bus Lines

Fully Programmable Slave Address with General Call Support

Address Recognition Causes Wake-up when AVR is in Sleep Mode

 

간단히 설명을 풀자면..

I2C는 필립스사에서 처음개발하였으며, 특징으로는 오직 2가닥의 WIRE만 필요하며 /  BUS에 연결되어 소프트웨어적으로 주소지정이 가능한 각각의 장치들은 고유의 주소값과 마스터/슬레이브 관계를 가진다. (보통 마스터는 MCU가 되며, 슬레이브는 각종센서류나 메모리,출력장치가 된다)

다수의 마스터가 BUS에 연결되어있어도 장치간 충돌을 감지할수있으며 2개이상의 마스터를 초기화하여도 데이터가 변조되지않으며 통신이 가능하다.  (이는 버스구조로 인하여..)

그리고 3가지 MODE가 존재하며

1. Standard : 100kbps

2. Fast : 400kbps

3. High-speed : 3.4Mbps

AVR은 2가지 1.2. MODE만 제공한다. 

단일 칩 필터링으로 노이즈를 제거한다.

버스의 커패시턴스가 400pF을 넘지않는 한도안에서 IC연결이 가능하며 아트메가는 128개까지 가능하다. 이는 주소비트가 7bit이기 때문이다.


Two-wire Serial Interface Bus Definition

 

The Two-wire Serial Interface (TWI) is ideally suited for typical microcontroller applications.

The TWI protocol allows the systems designer to interconnect up to 128 different devices using only two bi-directional bus lines, one for clock (SCL) and one for data (SDA). The only external hardware needed to implement the bus is a single pull-up resistor for each of the TWI bus lines. All devices connected to the bus have individual addresses, and mechanisms for resolving bus contention are inherent in the TWI protocol.

 

 

>Pull-up 저항은 필요한가?  (R1,R2)

신호가 없으면 항상 High값을 유지하기때문에 BUS가 high상태라면 현재 통신이 가능하다는 뜻이 되며 이는 장치간의 충돌을 미연에 방지하는 역할을 하게 된다. 

 

As depicted in Figure 86, both bus lines are connected to the positive supply voltage through pull-up resistors. The bus drivers of all TWI-compliant devices are open-drain or open-collector. This implements a wired-AND function which is essential to the operation of the interface. A low level on a TWI bus line is generated when one or more TWI devices output a zero. A high level is output when all TWI devices tri-state their outputs,allowing the pull-up resistors to pull the line high. Note that all AVR devices connected to the TWI bus must be powered in order to allow any bus operation.

The number of devices that can be connected to the bus is only limited by the bus capacitance limit of 400 pF and the 7-bit slave address space. A detailed specification of the electrical characteristics of the TWI is given in “Two-wire Serial Interface Characteristics” on page 324. Two different sets of specifications are presented there, one

relevant for bus speeds below 100 kHz, and one valid for bus speeds up to 400 kHz



 

 

Data Transfer and Frame Format

 

Transferring Bits

 

 

Each data bit transferred on the TWI bus is accompanied by a pulse on the clock line.The level of the data line must be stable when the clock line is high. The only exception to this rule is for generating start and stop conditions

 

데이터의 유효성 : SCL이 High이면 SDA신호는 일정값을 유지해야한다. (DATA값)

                                SCL이 LOW이면 SDA신호는 변경이 가능하다.


START and STOP Conditions

 



앞서 SCL이 HIGH일때 SDA신호는 일정해야 한다고 하였다.

만약 값이 변한다면?? 그때가 바로 시작과 중단신호를 의미한다. (참 잘만든 프로토콜인듯..)

SCL = HIGH상태  -> SDA가 Falling Edge = START condition

SCL = HIGH상태  -> SDA가 rising Edge   = STOP  condition

 

그래서 DATA는 시작신호 이후에 입력될수있다.


Address Packet Format

 


Data Packet Format 


 

시작조건이 발생되면 ( SCL = HIGH상태  -> SDA가 Falling Edge ) SDA은 SCL의 클럭신호에 맞추어 DATA가 전송되는데 이는 8BIT형식이다. 만약 SLAVE가 데이터를 다 받지 못했다면 SLAVE는 SCL신호를 LOW로 잡아둠으로써 나머지 DATA를 모두 전송할수가 있다. (풀업설계의 장점이기도 하다)


Acknowledge

 

Data transfer with acknowledge is obligatory. The acknowledge-related clock pulse is generated by the master. The transmitter releases the SDA line (HIGH) during the acknowledge clock pulse.

The receiver must pull down the SDA line during the acknowledge clock pulse so that it remains stable LOW during the HIGH period of this clock pulse (see Fig.7). Of course, set-up and hold times )

must also be taken into account.

Usually, a receiver which has been addressed is obliged to generate an acknowledge after each byte has been received, except when the message starts with a CBUS address

When a slave doesn’t acknowledge the slave address

 (for example, it’s unable to receive or transmit because it’s performing some real-time function),

the data line must be left HIGH by the slave. The master can then generate either a STOP condition to abort the transfer, or a repeated START condition to start a new transfer.

If a slave-receiver does acknowledge the slave address but, some time later in the transfer cannot receive any more data bytes, the master must again abort the transfer. This is indicated by the slave generating the not-acknowledge on the first byte to follow. The slave leaves the data line HIGH and the master generates a STOP or a repeated START condition.

If a master-receiver is involved in a transfer, it must signal the end of data to the slave- transmitter by not generating

an acknowledge on the last byte that was clocked out of the slave. The slave-transmitter must release the data line

to allow the master to generate a STOP or repeated START condition.

 


요약하면, DATA전송이 끝나면 SLAVE는 의무적으로 ACK를 발생시켜야 한다. 또한 이를 위해서 MASTER는 8번째 비트까지 DATA전송을 끝내고 9번재는 그냥 클럭신호만 보내줘야한다. 그래서 SLAVE는 DATA선을 LOW로 유지하여 (신호선이 풀업상태라서 LOW로 유지된다면 ACK가 전송됐다고 판단된다) ACK를 보낸다. 그럼 마스터는 이때 DATA신호를 확인하면 ACK를 확인할수가 있다.

만약 MASTER가 전달하면 DATA를 SLAVE에서 놓치게 된다면??

MASTER는 전송하던 DATA를 무시하고 다시 STOP,START condition을 발생시켜야한다.

이는 ACK를 통해서 알수있는 SLAVE 쪽에서 주소값이 일치하지 않으면 SDA를 HIGH로 만들면 된다.

(이는 MASTER가 송신, SLAVE가 수신하는 경우를 예로 든것이다)



  

 

 

Combining Address and Data Packets Into a Transmission




 


*출처 :  유명환강사님자료



위의 그림은 데이터송신에 대한 일련의 과정을 하나의 그림으로 나타낸것이다. 자세한 소스는 맨아래의 "AVR STUDIO용 C언어 예제"소스라는 그림을 참조하길 바란다.

 

Overview of the TWI Module

The TWI module is comprised of several submodules, as shown in Figure 94. All registers drawn in a thick line are accessible through the AVR data bus.


 



Scl and SDA Pins

These pins interface the AVR TWI with the rest of the MCU system. The output drivers contain a slew-rate limiter in order to conform to the TWI specification. The input stages contain a spike suppression unit removing spikes shorter than 50 ns. Note that the internal pull-ups in the AVR pads can be enabled by setting the PORT bits corresponding to

the SCL and SDA pins, as explained in the I/O Port section. The internal pull-ups can in some systems eliminate the need for external ones.

 

Bit Rate Generator Unit

 

마스터모드에서 SCL의 주기를 조절할때 사용한다. 이는 TWBR레지스터를 통해서 설정할수가 있다.

This unit controls the period of SCL when operating in a Master mode. The SCL period is controlled by settings in the TWI Bit Rate Register (TWBR) and the Prescaler bits in the TWI Status Register (TWSR). Slave operation does not depend on Bit Rate or Prescaler settings, but the CPU clock frequency in the slave must be at least 16 times higher

than the SCL frequency. Note that slaves may prolong the SCL low period, thereby reducing the average TWI bus clock period. The SCL frequency is generated according to the following equation:

 



 

• TWBR = Value of the TWI Bit Rate Register

• TWPS = Value of the prescaler bits in the TWI Status Register

Note: TWBR should be 10 or higher if the TWI operates in Master mode. If TWBR is lower than 10, the master may produce an incorrect output on SDA and SCL for the reminder of the byte. The problem occurs when operating the TWI in Master mode, sending Start + SLA  + R/W to a slave (a slave does not need to be connected to the bus for the condition to

happen).

 

 

 

 

 

Bus Interface Unit

 

This unit contains the Data and Address Shift Register (TWDR), a START/STOP Controller and Arbitration detection hardware. The TWDR contains the address or data bytes to be transmitted, or the address or data bytes received. In addition to the 8-bit TWDR, the Bus Interface Unit also contains a register containing the (N)ACK bit to be transmitted or received. This (N)ACK Register is not directly accessible by the application software. However, when receiving, it can be set or cleared by manipulating the TWI Control Register (TWCR). When in Transmitter mode, the value of the received (N)ACK bit can be determined by the value in the TWSR.

 The START/STOP Controller is responsible for generation and detection of START, REPEATED START, and STOP conditions. The START/STOP controller is able to detect START and STOP conditions even when the AVR MCU is in one of the sleep modes, enabling the MCU to wake up if addressed by a master.

If the TWI has initiated a transmission as master, the Arbitration Detection hardware continuously monitors the transmission trying to determine if arbitration is in process. If the TWI has lost an arbitration, the Control Unit is informed. Correct action can then be taken and appropriate status codes generated.

 

Address Match Unit  :  NOT needed in the MASTER MODE

 

mutil master mode에서는 반드시 TWAR레지스터가 필요하다.


The Address Match unit checks if received address bytes match the 7-bit address in the TWI Address Register (TWAR). If the TWI General Call Recognition Enable (TWGCE) bit in the TWAR is written to one, all incoming address bits will also be compared against the General Call address. Upon an address match, the Control Unit is informed,

allowing correct action to be taken. The TWI may or may not acknowledge its address, depending on settings in the TWCR. The Address Match unit is able to compare addresses even when the AVR MCU is in sleep mode, enabling the MCU to wake up if addressed by a master. If another interrupt (e.g., INT0) occurs during TWI Power-down

address match and wakes up the CPU, the TWI aborts operation and return to it’s idle state. If this cause any problems, ensure that TWI Address Match is the only enabled interrupt when entering Power-down.

 

 

Control Unit

 

The Control unit monitors the TWI bus and generates responses corresponding to settings in the TWI Control Register (TWCR). When an event requiring the attention of the application occurs on the TWI bus, the TWI Interrupt Flag (TWINT) is asserted. In the next clock cycle, the TWI Status Register (TWSR) is updated with a status code identifying

the event. The TWSR only contains relevant status information when the TWI Interrupt Flag is asserted. At all other times, the TWSR contains a special status code indicating that no relevant status information is available. As long as the TWINT flag is set, the SCL line is held low. This allows the application software to complete its tasks

before allowing the TWI transmission to continue.  The TWINT flag is set in the following situations:

 

 

• After the TWI has transmitted a START/REPEATED START condition

• After the TWI has transmitted SLA+R/W

• After the TWI has transmitted an address byte

• After the TWI has lost arbitration

• After the TWI has been addressed by own slave address or general call

• After the TWI has received a data byte

• After a STOP or REPEATED START has been received while still addressed as a slave

• When a bus error has occurred due to an illegal START or STOP condition

 

  

TWI Register Description



 







If set, this bit enables the recognition of a General Call given over the Two-wire Serial Bus


 

  

. Using the TWI

 

이부분은 인터럽트방식으로 TWI통신을 사용할때를 설명한것이다. 보통 인터럽트로 통신을 많이 사용하며, 앞서 설명한 부분들과 C언어예제들은 모두 폴링방식이다. 혼동하지 않길 바란다.


The AVR TWI is byte-oriented and interrupt based. Interrupts are issued after all bus events, like reception of a byte or transmission of a START condition. Because the TWI is interrupt-based, the application software is free to carry on other operations during a TWI byte transfer. Note that the TWI Interrupt Enable (TWIE) bit in TWCR together with

the Global Interrupt Enable bit in SREG allow the application to decide whether or not assertion of the TWINT flag should generate an interrupt request. If the TWIE bit is cleared, the application must poll the TWINT flag in order to detect actions on the TWI bus.

 When the TWINT flag is asserted, the TWI has finished an operation and awaits application response. In this case, the TWI Status Register (TWSR) contains a value indicating the current state of the TWI bus. The application software can then decide how the TWI should behave in the next TWI bus cycle by manipulating the TWCR and TWDR Registers.

 

Figure 95 is a simple example of how the application can interface to the TWI hardware.In this example, a master wishes to transmit a single data byte to a slave. This description is quite abstract, a more detailed explanation follows later in this section. A simple code example implementing the desired behavior is also presented.


  

1. The first step in a TWI transmission is to transmit a START condition. This is done by writing a specific value into TWCR, instructing the TWI hardware to transmit a START condition. Which value to write is described later on. However, it is important that the TWINT bit is set in the value written. Writing a one to TWINT clears the flag. The TWI will not start any operation as long as the TWINT bit in TWCR is set. Immediately after the application has cleared TWINT, the TWI will initiate transmission of the START condition

 

2. When the START condition has been transmitted, the TWINT flag in TWCR is set, and TWSR is updated with a status code indicating that the START condition has successfully been sent.

 

3. The application software should now examine the value of TWSR, to make sure that the START condition was successfully transmitted. If TWSR indicates otherwise, the application software might take some special action, like calling an error routine. Assuming that the status code is as expected, the application must load SLA+W into TWDR. Remember that TWDR is used both for address and data. After TWDR has been loaded with the desired SLA+W, a specific value must be written to TWCR, instructing the TWI hardware to transmit the SLA+W present in TWDR. Which value to write is described later on. However, it is important that the TWINT bit is set in the value written. Writing a one to TWINT clears the flag. The TWI will not start any operation as long as the TWINT bit in TWCR is set. Immediately after the application has cleared TWINT, the TWI will initiate transmission of the address packet.

 

4. When the address packet has been transmitted, the TWINT flag in TWCR is set, and TWSR is updated with a status code indicating that the address packet has successfully been sent. The status code will also reflect whether a slave acknowledged the packet or not.

 

 

5. The application software should now examine the value of TWSR, to make sure that the address packet was successfully transmitted, and that the value of the ACK bit was as expected. If TWSR indicates otherwise, the application software might take some special action, like calling an error routine. Assuming that the status code is as expected, the application must load a data packet into TWDR. Subsequently, a specific value must be written to TWCR, instructing the TWI hardware to transmit the data packet present in TWDR. Which value to write is described later on. However, it is important that the TWINT bit is set in the value written. Writing a one to TWINT clears the flag. The TWI will not start any operation as long as the TWINT bit in TWCR is set. Immediately after the application has cleared TWINT, the TWI will initiate transmission of the data packet.

 

6. When the data packet has been transmitted, the TWINT flag in TWCR is set, and TWSR is updated with a status code indicating that the data packet has successfully been sent. The status code will also reflect whether a slave acknowledged the packet or not.

 

7. The application software should now examine the value of TWSR, to make sure that the data packet was

uccessfully transmitted, and that the value of the ACK bit was as expected. If TWSR indicates otherwise, the application software might take some special action, like calling an error routine. Assuming that the status code is as expected, the application must write a specific value to TWCR, instructing the TWI hardware to transmit a STOP condition. Which value to write is described later on. However, it is important that the TWINT bit is set in the value written. Writing a one to TWINT clears the flag. The TWI will not start any operation as long as the TWINT bit in TWCR is set. Immediately after the application has cleared TWINT, the TWI will initiate transmission of the STOP

condition. Note that TWINT is NOT set after a STOP condition has been sent.

 

 

Even though this example is simple, it shows the principles involved in all TWI transmissions.

 

These can be summarized as follows:

• When the TWI has finished an operation and expects application response, the TWINT flag is set. The SCL line is pulled low until TWINT is cleared.

 

• When the TWINT flag is set, the user must update all TWI Registers with the value relevant for the next TWI bus cycle. As an example, TWDR must be loaded with the value to be transmitted in the next bus cycle.

 

• After all TWI Register updates and other pending application software tasks have been completed, TWCR is written. When writing TWCR, the TWINT bit should be set. Writing a one to TWINT clears the flag. The TWI will then commence executing whatever operation was specified by the TWCR setting.

In the following an assembly and C implementation of the example is given. Note that the code below assumes that several definitions have been made for example by using include-files.

 

  

 

AVR studio C언어 예제소스 





 

 

 

 

각 함수에 대한 설명은 스크롤을 아래로 내리시면 볼수있습니다.


 void I2C_start(void)

{

I2C_DIR=SDIROUT;

sda(1);

scl(1);I2C_delay();

sda(0);I2C_delay();

}

 

 

void I2C_stop(void)

{

I2C_DIR=SDIROUT;

scl(1);I2C_delay();

sda(0);I2C_delay();

sda(0);I2C_delay();

sda(1);I2C_delay();

}

 

void init_ds1307(void){

I2C_start();

I2C_write(ADDRTC);

I2C_write(0x00);

I2C_write(0x00);

I2C_stop();

I2C_start();

I2C_write(ADDRTC);

I2C_write(0x00);

I2C_write(sec);

I2C_write(min);

I2C_write(hr);

I2C_write(dy);

I2C_write(dt);

I2C_write(mn);

I2C_write(yr);

I2C_write(0x10); // sqwe:enable 1Hz output

I2C_stop();

}

 

 

 

 

 

 

void writebyte(unsigned char addr, unsigned char data)

{

I2C_start();

I2C_write(ADDRTC);

 

I2C_DIR=SDIROUT;

I2C_write(addr);

I2C_write(data);

I2C_stop();

}

 

 

unsigned char readbyte(unsigned char addr)

{

unsigned char byte;

I2C_start();

I2C_write(ADDRTC);

I2C_write(addr);

I2C_start();

I2C_write(ADDRTC|1);

byte = I2C_read(NACK);

I2C_stop();

return byte;

}

 

unsigned char I2C_read(unsigned char b)

{

unsigned char data, i;

sda(1);I2C_delay();I2C_delay();I2C_delay();

scl(0);I2C_delay();I2C_delay();

for(i=1;i<=8;i++)

{

scl(1);I2C_delay();

I2C_DIR=SDIRIN;

data=data<<1;

data = data | ((I2C_IN>>1)&0x01);

I2C_DIR=SDIROUT;

scl(0);I2C_delay();

}

sda(b);I2C_delay();

scl(0);I2C_delay();

scl(1);I2C_delay();

if(b==NACK)

sda(1);I2C_delay();

scl(0);I2C_delay();

sda(1);I2C_delay();

return data;

}

 

 

 

void I2C_write(unsigned char data)

{

unsigned char i;

I2C_DIR=SDIROUT;

scl(0);I2C_delay();

for(i=1;i<=8;i++)

{

sda(data>>7);I2C_delay();

scl(1);I2C_delay();

data=data<<1;

scl(0);I2C_delay();

}

 

sda(0);I2C_delay();

scl(0);I2C_delay();

scl(1);I2C_delay();

scl(0);I2C_delay();

sda(1);I2C_delay();

}

 

 

void main(void)

{

unsigned char i;

init_devices();

init_ds1307();

writebyte(0x00,0x00); // 00번지()0 값을 쓴다.

 

while(1)

{

Display();

FourDigit=readbyte(0); // 초값을 읽어온다.

}

}

 

 

 

 

------------------함수의 설명-------------------

I2C_start();

SDA 출력 방향을 AVR이 출력하는 것으로 함

SCL, SDA : High

SDA : Low로 떨굼

 

 

I2C_stop();

SDA 출력 방향을 AVR이 출력하는 것으로 함

SCLHigh

SDALow

SDAHigh

 

 

init_ds1307();

I2C_start(); 를 실행한다.

DS1307 칩을 초기화 한다.

시간, , 초 등을 초기 값으로 초기화 한다.

동작 확인용 LED를 달기 위하여,

1Hz를 사용 가능하도록 설정한다.

 

 

void writebyte(unsigned char addr, unsigned char data);

writebyte(어드레스, 데이터)

설명 : 어드레스에 데이터를 쓴다.

SDA 출력을 AVR에서 출력하는 것으로 한다.

1.SCLLow로 떨군다.

2.최상위 비트부터 한 비트 쓴다.

3.SCLHigh로 올린다.

4.담 비트 준비

1,2,3,48번 반복한다.

Ack를 체크한다.(그냥 무시하고 지나가고 있다.)

 

 

nsigned char readbyte(unsigned char addr);

데이터 = readbyte(어드레스)

설명 : 어드레스에서 데이터를 읽는다.

SDA핀을 AVR에서 입력 받는 것으로 한다.

1. SCLHigh로 올린다.(I2C에서 데이터 수신 받을 때 안

정적인 쪽은 클럭이 High일 때이므로)

2. 최상위비트부터 한 비트 받는다.

3. SCLLow로 떨군다.

4. 담 비트 받을 준비한다.

1,2,3,48번 반복한다.

Ackn을 받는다.

 

unsigned char I2C_read(unsigned char b);

데이터 = I2C_read();

현재 번지에서 데이터를 읽어 온다.

ACK를 굳이 읽을 이유가 없어서, ACK는 강제로 1로 주고

있다.

 

void I2C_write(unsigned char data);

I2C_write

현재의 어드레스에 데이터를 쓴다.

ACK0을 실어준다.

 

 

도움이 되실지 모르겠습니다. I2C로 EEPROM의 내용을 R/W하는 예제입니다.


//=======================================

// MAIN PROJECT FILE

//=======================================

//

#include <avr/io.h>

#include <stdio.h>


#include <util/twi.h>


#include "eeprom24lc32.h"

#include "lcd.h"

#include "button.h"


int main()

{

long data, saved_data;

short rtn;

char string[80];


EprmInit(400); // 400 kHz TWI 전송속도

LcdInit();


data = 0x12345678;


if((rtn=EprmWriteNByte(0x500, (char *)&data, sizeof(data)))<0)

{

sprintf(string, "write error: %d", (int) rtn);

LcdMove(0,0); LcdPuts(string);


while(1);

}


// verify


if((rtn=EprmReadNByte(0x500, (char *)&saved_data, sizeof(saved_data)))<0)

{

sprintf(string, "write error: %d", (int) rtn);

LcdMove(0,0); LcdPuts(string);


while(1);

}

else

{

LcdMove(0,0); LcdPuts("Saved Data = ");


sprintf(string, "0x%lx", saved_data);

LcdMove(1,0); LcdPuts(string);

}


while(1);

}



//=======================================

// EEPROM24LC32.H

//=======================================

//


#ifndef __EEPROM24LC32_H__

#define __EEPROM24LC32_H__


void  EprmInit(unsigned int kHz);

short EprmWriteByte(short addr, char data);

short EprmWriteNByte(short addr, char data[], int n);

short EprmReadNByte(short addr, char data[], int n);


#endif


//=======================================

// EEPROM24LC32.C

//=======================================

//

//===========================================
// eerpom24lc32.c
//
// EEPROM 24LC32 구동 프로그램
//===========================================
//
#include <avr/io.h>
#include <util/twi.h>
#include <util/delay.h>

#include "lcd.h"

#include "eeprom24lc32.h"

#define DEVICE 0x00 // Device Select Bit
#define SLA_W (0xA0 | (DEVICE << 1))
#define SLA_R (0xA0 | (DEVICE << 1) | 0x01)

static short setAddr(short addr);

//====================================================
// TWI 버스를 초기화한다.
//====================================================
//
void EprmInit(unsigned int kHz)
{
TWSR = 1<<TWPS0; // 비트율 프리스케일러값을 16으로 한다.

// 비트율 설정
TWBR = (unsigned char) ((F_CPU/(kHz*1000L) - 16L)/(2L*4L));
}

//===================================================
// 1바이트 데이터를 24LC32A EEPROM에 쓴다.
//
// addr : 데이터를 쓸 EEPROM 주소
// 0x00 ~ 0xFFF
//  data : 쓸 데이터
//
// return :
// 0 - 성공
//   -1 - 쓰기 실패
//===================================================
//
short EprmWriteByte(short addr, char data)
{
short rtn;

//-----------------------------------
//  데이터를 쓸 EEPROM 주소를 보낸다.
//-----------------------------------
if((rtn=setAddr(addr)) < 0)
return rtn;

//-----------------------------------
// 데이터 전송
//-----------------------------------
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);

while(!(TWCR & (1<<TWINT))); // DATA가 보내질 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_MT_DATA_ACK) // DATA 전송후 슬레이브로 부터 ACK를 받았는 지 검사
return -3;

//----------------------------------
// STOP 조건을 보낸다.
//----------------------------------
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
while((TWCR & (1<<TWSTO))); // STOP조건이 보내질 때까지 기다린다.

return 0;
}

//===================================================
// n 바이트 데이터를 EEPROM에 쓴다.
//
// addr : EEPROM 주소 
// 0x00 ~ 0xFFF
//  data : 쓸 데이터를 저장한 버퍼주소
//  n : 쓸 데이터 개수
//
// return :
// 양수 - 다음 쓸 EEPROM 주소
//   -1 - 쓰기 실패
//===================================================
//

short EprmWriteNByte(short addr, char *data, int n)
{
int i, rtn;

for(i=0; i<n; i++)
{
if((rtn=EprmWriteByte(addr, *data))<0)
return rtn;
addr++;
data++;
}

return addr;
}

//===================================================
// n 바이트 데이터를 EEPROM으로부터 읽어들인다.
//
// addr : EEPROM 주소 
// 0x00 ~ 0xFFF
//  data : 읽은 데이터를 저장할 버퍼
//  n : 읽을 데이터 개수
//
// return :
//    0 - 성공
//   -1 - 읽기 실패 
//===================================================
//
short EprmReadNByte(short addr, char data[], int n)
{
int i;

//----------------------------------------
// 읽을 데이터의 주소를 보낸다.
//----------------------------------------
if(setAddr(addr) < 0)
return -5;

//---------------------------------------
// REPEATED START
//---------------------------------------
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START 조건을 보낸다.
while(!(TWCR & (1<<TWINT))); // START조건이 보내질 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_REP_START) // 정상적으로 REPEATED START조건이 보내졌는 지 검사한다.
return -6;


//--------------------------------------
// SLA_R를 보낸다.
//--------------------------------------
TWDR = SLA_R;
TWCR = (1<<TWINT) | (1<<TWEN);

while(!(TWCR & (1<<TWINT))); // SLA_R이 보내질 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_MR_SLA_ACK) // SLA_R 전송후 슬레이브로 부터 ACK를 받았는 지 검사
return -7;

//----------------------
// 데이터 읽기
//----------------------
for(i=0; i<n-1; i++)
{
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN); // TWI동작을 시작한다.  데이터를 받으면 ACK를 보낸다.
while(!(TWCR & (1<<TWINT))); // 데이터를 받을 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_MR_DATA_ACK)
return -8;
data[i] = TWDR; // 데이터를 읽는다.
}

// 마지막 바이트를 받으면 ACK를 보내지 않는다.

TWCR = (1<<TWINT) | (1<<TWEN); // TWI동작을 시작한다. 데이터를 받으면 ACK를 보내지 않는다.
while(!(TWCR & (1<<TWINT))); // 데이터를 받을 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_MR_DATA_NACK)
return -9;
data[i] = TWDR; // 마지막 데이터를 읽는다.

//-----------------------------
// STOP 조건을 보낸다.
//-----------------------------

TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
while(TWCR & (1<<TWSTO)); // STOP조건이 보내질 때까지 기다란다.
return 0;
}


//=========================================-------===================
// eeprom에 데이터를 쓰기/읽기를 위한 제어 및 주소 바이트를 보낸다.
//
//  addr : 데이터를 쓰기/읽기를 할 주소
//
// return :
// 0   - 성공
//   음수 - 전송 실패
//===================================================================
//
static short setAddr(short addr)
{
while(1)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START 조건을 보낸다.
while(!(TWCR & (1<<TWINT))); // START조건이 보내질 때까지 기다린다.
if((TWSR & TW_STATUS_MASK) != TW_START) // 정상적으로 START조건이 보내졌는 지 검사한다.
return -10;

TWDR = SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN); // SLA_W를 보낸다.
while(!(TWCR & (1<<TWINT))); // SLA_W가 보내질 때까지 기다린다.

if((TWSR & TW_STATUS_MASK) == TW_MT_SLA_ACK)
break;
else // eeprom이 준비되지 않았음
{
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); // STOP 조건을 보낸다.
while(TWCR & (1<<TWSTO)); // STOP조건이 보내질 때까지 기다란다.
}
};

//--------------------------------------------------------
// eeprom 주소를 상위바이트, 하위바이트 순으로 보낸다.
//--------------------------------------------------------

TWDR = (unsigned char) (addr >> 8);
TWCR = (1<<TWINT) | (1<<TWEN); // 상위바이트 전송
while(!(TWCR & (1<<TWINT))); // DATA가 보내질 때까지 기다린다.

// DATA 전송후 슬레이브로 부터 ACK를 받았는 지 검사
if((TWSR & TW_STATUS_MASK) != TW_MT_DATA_ACK)
return -12;

TWDR = (unsigned char) addr; // 하위바이트 전송
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))); // DATA가 보내질 때까지 기다린다.

// DATA 전송후 슬레이브로 부터 ACK를 받았는 지 검사
if((TWSR & TW_STATUS_MASK) != TW_MT_DATA_ACK)
return -13;

return 0;
}


+ Recent posts