1. 1-Wire 통신의 개요
- 1-Wire 라이브러리 존재 (<=> 유명하다)
- STM32에서 HAL 라이브러리에 존재
cf. HAL(Hardware Abstraction Layer) : STMicroelectronics에서 제공하는 하드웨어 추상화 계층 라이브러리로, STM32 마이크로컨트롤러에서 하드웨어를 보다 쉽게 제어할 수 있도록 도와주는 소프트웨어 계층
1-1. 1-Wire 통신이란?
- Dallas Semiconductor Corp에서 만든 통신 방식
- 1-wire 버스를 사용하면 핀 하나만으로 통신 할 수 있고, 이 신호선으로 전원까지 공급 가능
- 1-wire bus는 선 한개로 데이터 송/수신을 하기에 1-wire bus 방식의 IC와 연결하는 MCU는 GPIO핀의 입/출력 모드 번갈아 사용
=> 1-wire에서 read_bit 함수는 1-Wire 프로토콜의 특성 때문에, 데이터 읽기 전 반드시 OUTPUT → LOW → 쉬기 → INPUT → 데이터 읽기 과정을 거쳤었음
1-2. 라이브러리 포팅하기
- 이전 시간에 생성했던 second 폴더는 FND를 STM32에서 제공하는 방식으로 제어 / first 폴더는 GPIO 통해 FND 제어
=> second 폴더로 포팅하기 - 아래 사진과 같이 Core 내에 Lib 폴더 생성 후 Inc/Src 폴더 생성
- 주변 장치 자료\온도센서\ds18b20-master의 ds18b20.c와 onewire.c는 Src 폴더에
- 주변 장치 자료\온도센서\ds18b20-master의 ds18b20.h와 ds18b20Config.h와 onewire.h는 Inc 폴더에
- 컴파일하면 에러가 뜨는데 이 에러들을 수정하는 게 오늘의 목표
1-3. 에러 수정
(1) onewire.h와 ds18b20.h의 fatal error
- Core - Properties에 들어가서 직접 include 해주기
(2) 또다른 에러 gpio.h의 fatal error 발생
- gpio.h 주석 처리하고 다시 컴파일 하면 unknown type name 'GPIO_TypeDef' 오류 발생
=> GPIO_TypeDef의 정의는 stm32f103xb.h에 정의
=> 이때 main.c에서 main.h를 include 하는데 main.h에서 stm32f103xb.h를 include 하고 있음
=> onewire.h에서 오류났으므로 여기서 main.h를 include 하자
(3) 새로운 에러 cmsis_os.h의 fatal error 발생
- 이때 cmsis_os.h를 include하는 조건은 _DS18B20_USE_FREERTOS == 1 인 경우이다
- 따라서 이 값을 0으로 설정하여 cmsis_os.h를 include하지 않도록함
- 최종적으로 else문이 수행되어 HAL_Delay(x) 의 define문이 수행
(4) 새로운 에러 tim.h의 fatal error 발생하여 주석 처리 후 다시 컴파일
=> GPIO,PIN,TIMER 설정하지 않아 생기는 오류 발생
1) GPIO, PIN 세팅하기 위해 second.ioc 설정
- 데이터시트를 보면 온도 관련 핀이 PA3_TEMP-DATA이므로 PA3 제어
- 이때 핀들에 대한 정의는 main.h에 있으므로 현재 우리가 GPIO, PIN 세팅해야 하는 ds18b20Config.h에 main.h를 include
- main.h에 정의된 PA3을 GPIO, PIN 세팅
2) Timer handler 오류는 타이머를 생성해서 해결
=> main.c에 htim2 생성됨
=> 위에서 설정해줘야 할 타이머를 htim2로 설정
=> 이때 main.h의 전역변수로 htim2가 선언되어있기에 extern 구문을 이용
cf. 전역변수를 다른 파일에서 사용하고자 할 때 extern이 필요
(5) 에러 없이 컴파일 완료
1-4. 타이머 인터럽트 사용하면서 타이머 시간 조절 방법
- 현재 Counter Period : 65535 의 의미는 0xffff
- Clock Configuration에서 어떤 거든 다 우선 8MHz로 설정되어있음
cf. 8MHz = 8 * 10^6 = 8000000 - Prescaler = (10000 - 1) 로 설정해야 만으로 나눈다는 의미
=> Counter 1을 올리기 위한 연산 - Counter Period = (800 -1) 로 설정
=> Counter가 하나씩 올라가는데 0~799까지 올라감
=> 이때 이 1단계가 올라가는데 클럭 1번이 뛸 때 올라가는 게 아닌 10000(만)번의 클럭이 흐르면 Counter 1 증가
=> 만약 Counter가 800이 되면 다시 0으로 돌아오도록 설정
결론.
① Counter Period = (800 - 1)의 의미
: Counter가 0~799까지 올라가고 다시 0으로 돌아오는데 걸리는 시간은 1초라는 의미
② Prescaler = (10000 -1)의 의미
: Counter 1을 올리는데 걸리는 시간이고 이때 우리의 클럭은 8MHz로 되어있고 우리가 Prescaler를 (10000-1)로 설정하였기에 Counter는 800Hz 클럭 신호를 따라 1씩 증가한다.
=> 800Hz로 Counter가 증가하면서, 800번(0~799) 세면 1초가 걸린다.
ex) 800Hz : 1초에 800번 counter 증가
(1) 실제로 확인해보기
* 3번째 사진에서 TIME이 아니라 TIM임
2. 인터럽트 발생 시간 조절
=> 매우 빠르게 Counter값 증가함
=> 1마이크로세컨드마다 카운트
=> 프리스케일러 값이 커질수록 클럭의 주파수가 낮아지고, 따라서 타이머가 증가하는 속도는 느려진다
=> 만약 800Hz라면 1초에 800번의 event가 발생한다는 것이고 즉 타이머가 800번 증가한다는 의미이므로
3. RCC 설정
3-1. TIM2 수정
: 8MHz -> 72MHz로 바꾸었으므로 다음과 같이 설정
=> 1마이크로세컨드에 1 tick씩 올라감
3-2. Counter Period를 0xFFFF로 하는 이유
=> while문 내의 CNT가 우리가 Counter Period의 숫자값을 작게하면 그 값보다 작은 값만 발생하기에 무한루프 발생
=> 아래 사진(좌)과 같이 include 하고 다시 수행하면 정상적으로 FND 출력
=> 이때, 우리가 클럭을 바꾸었기에 매우 빠르게 LED 숫자가 증가함
=> 아래 사진(우)과 같이 50이 아닌 450으로 바꾸고 수행하면 이전과 비슷한 속도로 증가
4. 온도 측정법
4-1. 통신 여부 확인
- main.c 내의 Ds18b20_Init(); 호출하기 전 값들과 호출 후 값들 비교
4-2. 온도 정보 확인
- ds18b20.c 내의 Ds18b20_ManualConvert함수 main.c에 넣어서 수행해보기
- 다음과 같이 온도센서의 프로브를 잡으면 온도가 올라가는 거 확인 가능
'임베디드' 카테고리의 다른 글
[오제이 튜브의 임베디드 강의] 26강. 다른 사람 소스 분석하는 방법! (0) | 2025.02.05 |
---|---|
[오제이 튜브의 임베디드 강의] 25강. 어디서도 안 알려주는 프로토콜의 원리! (1) | 2025.01.28 |
[오제이 튜브의 임베디드 강의] 23강. 온도센서를 붙여보자! (0) | 2025.01.26 |
[오제이 튜브의 임베디드 강의] 22강. STM32에서는 SPI기능을 제공한다구! (0) | 2025.01.26 |
[오제이 튜브의 임베디드 강의] 21강. FND 제어 소스 분석! (0) | 2025.01.25 |