이번에는 꽤 유용한 콤포넌트가 PSOC5에 추가되었다.

DMA 를 사용해서 CPU에 부담이 없이, LED 메트릭스를 Dynamic Scan 방식으로 제어가능하다.
또한 PWM으로 LED 밝기 조절 기능까지 들어있고, 7-SEGMENT 와 심지어 14,16 SEGMENT 도 콘트롤할 수 있다.

저는 7-SEGMENT 와 LED 비트제어 만, 제공되는 여러 함수를 이용해서 사용해 봤는데,
14,16-SEGMENT 는 써 본적이 없네요.

아뭏든 LED를 더 많이 제어하려면, MCU 중에서 다리가 많고 싼놈으로 고르시기 바랍니다.
이 콤포넌트는 seg out 이 24개까지, com out이 8개까지 가능해서,
동시에 출력 가능한 최대 LED 갯수는 24 x 8 = 192개이다.

예전에 LED 드라이브 IC 를 4천원에 SPI/I2C 방식으로 MCU에 붙여서 사용했었는데,
포트가 좀 필요하지만 LED 드라이브 IC를 안 써도 된다. 
대신 TR을 포트 갯수 만큼 달아 줘야 하지만 가격 대 성능비는 괜찮은 것 아닌가? (IC 크기가 문제없는 곳이라면)

프로그램에서는, 제공되는 함수로 디스플레이를 바꾸고 싶을 때 한번만 레지스터를 써 주면 끝이다.
계속 타이밍에 맞춰서 출력해 줘야하는 수고스러움 없이, 관심 끄고 다른 프로그램 코딩하면 되겠다.

다음은 PSOC5 에 연결할 COMMON-Cathode 타입의 7-SEGMENT 회로도 중, 
전류를 증폭하기 위해서 사용한 TR 회로 입니다.
PNP TR 출력에 연결된 저항을 바꿔서 최대 밝기를 조절해 줄 수 있다. 
다이나믹 스캔 방식이라 저항을 너무 크게 달지 않는 것이 좋다. (크면 어둡다)
대략 51 옴 정도 달면 적당할 듯 하다. (전류가 너무 많이 흐르게 했을까요? 다시한번 확인을 해 봐야겠네요.)
오렌지 색 1608 LED가 전압강하 2.2V 이네요.
따라서 전원을 3.3V 사용시 LED를 통해 흐르는 전류를 20mA로 만들려면,
1.1V(3.3V-2.2) / 0.02 = 55 옴 으로, 전력은 55*0.02*0.02(R x I x I) = 0.022W 입니다.
즉 1/45 W 네요. ^^.

51옴 정도 달면 되겠습니다.




다음은 TR 에 연결되는 FND 와 LED 회로 입니다.



위와같이 회로는 준비 됐고, PSOC5 의 새로 생긴 콤포넌트인 LED Segment and Matrix Driver [v1.10] 을 살펴보자.
TopDesign.cysch 에, 일단 제가 다 만들어 놓은 콤포넌트를 보겠습니다.
세그먼트 출력 8개, 코먼 출력 8 개로 7-SEGMENT 7개와 8개의 LED를 제어하도록 구성했습니다.



다음은 다리가 많은 모델로 고른 PSOC5 IC 입니다. 다리는 많은데 가격은 좀 비싼 놈입니다. 제가 열전대 값을 읽으려고 20-비트 ADC가 있는 놈으로 고르다 보니 가격이 비싸져버렸네요.
저와 같은 용도가 아니면 다리가 좀 많고 가격이 싼 PSOC5를 고르는 게 좋습니다.



다음은 콤포넌트 설정입니다. 여러가지를 설정할 수 있는데, 최대 출력 개수는 segment 24, common 8개 이고,
스캔 주기도 조정할 수 있습니다. 적당히 테스트하면서 조정하면 됩니다. 
나머지 설정들은 보면 아시겠죠? (common Cathode/Anode 에 따라 드라이브 타입을 조정해 주시면 되고, 내부 클럭으로 돌릴지 외부 클럭으로 돌릴지, 밝기 조절을 할지 말지.. 등이 있습니다)



이렇게 설정을 마치고 나면 자동으로 LED 드라이브 파일이 생성되고, 우와 함수 참 다양하죠?
테스트용으로는 몇 개 안쓸 것입니다. ^^




다음은 제가 만든 코드 예제 입니다.
7개의 7-SEGMENT 에 1,2,3,4,5,6,7 이 켜지고 , LED 8개가 다음과 같이 켜질 것입니다.
실제 7-SEGMENT 와 LED가 켜진 사진을 못 올리는 것이, 맡겨 놓은 회사에서 회로를 잘못 바꿔서 최종으로 

Common-Anode 타입으로 만들어 와서 지금 설명하는 내용과 좀 다릅니다. 이해 바랍니다.





다음은 main.c 파일에 있는, 테스트용으로 제가 만든 예제 소스코드입니다. (아주 간단하게~~^^)

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
/* ========================================
 *
 * Copyright YOUR COMPANY, THE YEAR
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF your company.
 *
 * ========================================
*/
#include "project.h"
 
int main(void)
{
    LED_Driver_1_Start();
    
    CyGlobalIntEnable; /* Enable global interrupts. */
 
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    LED_Driver_1_PutChar7Seg('1',0);
    LED_Driver_1_PutChar7Seg('2',1);
    LED_Driver_1_PutChar7Seg('3',2);
    LED_Driver_1_PutChar7Seg('4',3);
    LED_Driver_1_PutChar7Seg('5',4);
    LED_Driver_1_PutChar7Seg('6',5);
    LED_Driver_1_PutChar7Seg('7',6);
    LED_Driver_1_SetDisplayRAM(0x55,7);
    
    for(;;)
    {
        /* Place your application code here. */
    }
}
 
/* [] END OF FILE */
cs



마지막으로 위의 내용에서 설명드린 것과 그대로 동작하는 프로젝트 파일을 첨부합니다.

fnd_com_K.Bundle01.zip


이전 글에 TR(MMBT3904)의 내부 다이오드를 이용해서 오도 측정하는 방법 중, 

H/W 상의 설명은 충분하다고 생각이 됩니다.
(사실 저도 정확하게 잘 모릅니다. 그냥 실제로 써 먹을 수만 있으면 된다고 생각하고 있습니다. ^^)

다이오드 온도 센싱을 위해 수학함수 쓰다가 컴파일러 오류 나서 고치고,
온도 값을 받아서 UART 에 floating point 로 출력하다가 컴파일러 오류나서 고치다 보니 한동안 멍~하네요.

이제 겨우 본론으로, 간단하게(저도 잘 모르는 관계로) 다이오드 온도측정과 열전대 온도측정에 관해서 말씀 드리겠습니다.
일단 동작은 모두 잘 됩니다.

다이오드(TR 내부의 다이오드) 온도센싱의 회로도와 열전대 회로도를 다시 한번 올려 보겠습니다.

[#1 다이오드 온도측정 회로도]





[#2 열전대 온도측정 회로도]




추가로 이번에 안 사실인데, 열전대를 거꾸로 달면 온도가 올라갈수록 전압이 낮아져서 온도가 떨어지는 것처럼 동작하더군요.
주의 : 열전대는 방향이 있습니다. 


다음은 PSOC5 의 콤포넌트를 배치하는 Topdesign.cysch 입니다.



다른 MCU와 좀 색다른 프로그램 환경이지만, 
1. Differential 20-Bit ADC 5ch 사용하고, 
2. current mode DAC 1개 , 
3. 칩내부 온도 센싱 (프로그램에서는 사용 안했음),
4. 열전대 온도 테이블 계산 콤포넌트,
5. UART 1개
를 사용했습니다.

[첨부한 예제 프로그램 설명]
Diode 로 측정된 온도를 프로그램에서는 Cold Junction Temperature 라고 부르고,
열전대로 측정한 온도를 Hot Junction Temperature 라고 부르더군요.
2개의 온도를 측정해서(물론 여러가지 처리를 합니다. sw 노이즈 필터, 열전대 테이블 보상 등등),
서로 더해주면 최종 열전대로 측정된 온도가 나옵니다.
이것을 UART로 출력 합니다.

이정도면 됐을까요? 이해 안되시면 댓글에 질문하시고, 저도 잘 모르지만 한번 해 본 것밖에 차이는 없습니다. ^^

예제 파일 첨부합니다. 


아~ 놔.. 열통 터지네. 이번에는 sprintf 함수에 아무리 float 값을 써도 이상하게 나와서 찾아보니,

이것도 컴파일러 문제일 듯 하네요. 또 라이브러리쪽에 뭘 써 넣어야 하는군요.

다음과 같이 수정하면 printf/sprintf 함수에서 floating point 값을 표시할 수 있습니다.

1. 프로젝트를 클릭하고, 다시 마우스 우클릭한 다음 Build Setting 을 클릭.




2. Linker 의 Use newlib-nano Float Format 을 True 로 고치고, 
command line 의 Custom Flags 에 -u _printf_float 라고 써 넣음.


+ Recent posts