PIC 16F526, 아 이런 초기화 할게 또 있다..

디지털 I/O를 사용하기 위해 초기화 해야할게 또 있었다.

으휴… 첨에는 되는 것 처럼 보이더니 조금 지나자 출력핀의 전압이 어중간하게 나타났다.

 다시 이 놈이다. Table 6-3: I/O PINS ORDER OF PRECEDENCE 는 PortB 와 PortC의 우선순위에 관한 설명이다.

기본 값으로 첫번째 줄이 배정되고 그것을 해지 했을 때 다음 순위로 넘어 가는 것 같다. ADCON0 레지스터의 AN0, AN1 값(7번과 6번 비트)을 클리어 해서 AN0, AN1을 끄니 PortB는 디지털로 바뀌었다.

PortC도 같이 변한 줄 알았는데 PortC는 그대로 있었다. OPTION 레지스터에서 T0CS(5번 비트)를 끄면 RC5가 살아났다.
그래서 다른 것도 같이 되는 줄 알았다.
왜냐하면 그 레지스터의 설명에는 그것 밖에 없었으니까.
그런데 또 RC0, RC1, RC2에서 어중간한 값이 나왔다.
C2IN+, C2IN-, CVref, C2out이 문제인것 같다.
이 것들은 ADC와 비슷한 컴퍼레이터2 다.

컴퍼레이터가 2개 있으니까 그 중 2번째 컴퍼레이터.
데이터시트에서 컴퍼레이터 항목을 찾아보니 CM1CON0, CM2CON0 레지스터가 있다.
지금 해결할 것은 2번 컴퍼레이터니까 CM2CON0 을 바꿔야한다.
역시나 비트 3번에 C2ON 이 있다.
기본 값으로 C2ON은 세팅(1)되어있고 그 뜻은 “Comparator is on”이다.
CM2CON0은 W 레지스터 거치지 않고 직접 읽고 쓰기가 가능하다.
3번 비트인 C2ON을 클리어 하는 명령을 프로그램 초반에 배치했다.
컴퍼레이터 기능이 꺼지면 2번 컴퍼레이터와 관계된 C2IN-, C2IN+, CVref, C2out이 다 꺼진다.
그러므로 PortC는 모두 디지털로 활성화된다.

그러고 보니 CM1CON0에서도 C1ON을 꺼두는 것이 좋겠다. 지금까지의 테스트에서는 CM1CON의 C1ON을 끄지 않고도 잘 동작했지만 표 6-3을 보니 PortB의 2순위가 컴퍼레이터1 이다. 혹시 모르니 초기화 코드에서 CM1CON의 C1ON도 함께 끄도록 해야겠다.

으으… 데이터시트의 I/O 포트 설명하는 곳에서 “디지털 핀으로 사용할 때” 라는 항목이 있었다면 이 고생을 면했을텐데…

PIC 16F526 프로그래밍, 기초 입출력 부터 확인할 것

아 정말… 개떡같은 초기화 값들이다.
PIC 프로그래밍이 어려운 것은 아니다. 워낙 단순해서 쉽게 풀어갈 수 있다. 그러나 초기값. 이 초기값들이 문제다. 그냥 LED 하나 켜 보는데 이 고생을 하다니… -_-; PIC에 기능이 많을 수록 쓰지 않는 기능들을 끄느라 데이터시트를 마구 뒤져야 한다. 에긍…
프로그래밍이 되긴 되는지, 동작은 하는지, 프로그래밍의 실수 이전에 프로그래머가 제대로 동작하는지를 확인하고 싶었다. 기계가 안 되는데 로직의 문제인 줄 알고 들여다 보고 있는 실수를 피하기 위해서다.
간단하게 LED 하나를 깜빡거리는 정도면 테스트가 된다. 더 간단한 것으로는 그냥 켜 보는거 정도.
우선 포트이름과 초기 설정값들을 세팅하기 위해 Microchip 폴더의 MASM Suite 폴더에서 16F526.inc 파일을 읽었다. Configuration Bit 설정을 위한 명칭과 설정값이 들어있다. 그리고 각 포트와 특별 레지스터들의 비트 이름도 포함되어 있다. 그냥 숫자로 써도 되지만 나중에 프로그램을 수정할 때 알아보기 쉽게 하려면 여기에 있는 이름을 쓰는 것이 좋다.
또 Sample 디렉토리에는 16F526 프로그래밍을 위한 코드 탬플릿도 들어있다. 이 파일을 사용하면 초기화 설정이 더 쉬워진다. 내부 클럭을 사용하는 세팅값 변경 등 외울 수도 없는 것들이 들어있다. 당연히 템플릿 파일을 불러들여 내 프로그램에 맞게 수정해 사용한다. 실제 프로그램 해야 할 부분은 비어있고, 초기 설정 부분만 쓰여있다.

1. Bank Select 문제 처음 맞이한 문제는 Bank Select 였다. 메모리가 4개 영역으로 나눠 있었고 각각이 Bank를 의미하고 있다. PIC 16F84 프로그래밍 때 STATUS 레지스터의 RP0 값을 바꿔서 뱅크를 선택했는데, 여기서도 그런 방법으로 하는 것일까.. 확인해야 했다. DataSheet 4-3 STATUS 레지스터의 내용을 보니 PA0 값이 있다.

PA0: Program Page Preselect bit

1 = Page 1 (000h-1FFh)

0 = Page 0 (200h-3FFh)

기본 값이 0 으로 Page0 을 가리킨다. 주소가 200h~3FFh 이다. 1로 세팅하면 Page1 을 카리키고 주소가 000h~1FFh 다.
REGISTER FILE MAP을 보면 Page1를 세팅해야 할 것 같은데… 마침 사용해야할 PORTB, PORTC가 모두 Bank0 에 있어서 그냥해도 될 것 같기도 하고… 갈수록 헷갈린다. STATUS PA0를 세팅하기도 하고 클리어하기도 하면서 PORTB, PORTC를 변경해 보았다. PA0값이 무엇이든 PORTC 값이 변하는 것으로 봐선 PA0값을 설정하지 않아도 괜찮은 것 같다. 으음…

2. TRIS 설정하기 역시 16F84 때의 기억에 의하면 IO 포트를 사용하기 위해 TRIS 레지스터를 설정해야 한다. 그런데 REGISTER MAP에 TRIS가 없다. 이거 참… 혹시나 하고 찾아보니 명령어에 TRIS 들어 있다. W 레지스터 처럼 REGISTER MAP에는 없지만 공통으로 접근할 수 있는 영역에 TRIS가 있는거다. 설정하는 방법은 W에 TRIS 설정값을 넣고 TRIS 명령어로 값을 쓴다.
3. PortB가 동작하지 않는다 TRISB의 3번은 항상 입력이고 나머지는 I/O 중 하나를 선택해 사용할 수 있다. 6번 7번 은 사용하지 않으니까 값은 [xx00 1000] ~ [xx111111] 을 사용한다. 나는 4번과 5번에 스위치를 달아 입력으로 사용할 예정이니 b’00111000′ 값을 설정했다. 테스트 값으로 0번~2번 비트에 값을 써 보았지만 변하지 않았다. -_-; 혹시나 해서 4번과 5번 비트도 출력으로 정하고 출력을 내보니 이것은 변한다. 0번~3번까지가 출력으로 안 되는거다. 스위치 순서를 바꿀 수도 있겠지만 원인을 알지 못하면 앞으로의 프로그래밍도 장담할 수 없다.
이것 때문에 하루가 지나는 동안(물론 다른 일도 많이 했지만) 답을 찾을 수 없었다. 혹시 ADC 기능 때문인가… 하고 ADC 기능을 끄기 위한 내용을 찾아 보았다. 역시 Data Sheet에 나와있다.. -_-;

9.1.2 ANALOG MODE SELECTION

The ANS<1:0> bits are used to configure pins for analog input. Upon any Reset, ANS<1:0> defaults to 11. This configures pins AN0, AN1 and AN2 as analog inputs. The comparator output, C1OUT, will override AN2 as an input if the comparator output is enabled. Pins configured as analog inputs are not available for digital output. Users should not change the ANS bits while a conversion is in process. ANS bits are active regardless of the condition of ADON.

ANS 레지스터의 0번 1번 비트를 사용해 아날로그 입력 핀을 선택하도록 되어 있다. 기본값은 11. 이것은 PortB의 0~3번 포트를 아날로그 입력핀으로 사용한다는 뜻이다. 그리고 친절하게도 이 값이 설정되어 있으면 Digital 출력은 사용할 수 없다라고… 되어있다. 끄응.. ANS 비트 값은 ADON이 세팅되어 있는 동안에는 바꿀 수 없다는 내용도 있다. 그런데 REGISTER File Map이나 Special Function Register 에는 ANS 레지스터가 없다. ANS는 ADCON0 레지스터의 6번 7번 비트값으로 존재했다. 후우우… 이 값들을 0으로 세팅하고 나니 PortB를 마음대로 컨트롤 할 수 있다. 이제 PortB의 2번에 연결한 LED에 불이 들어온다. 깜빡이기도 한다. 으휴~~
4. PortC가 제대로 동작하지 않는다. PortB 문제를 해결하고 나니 프로그램 진도가 잘 나갔다. 그런데 PortC 쪽에 연결한 HEF4094와 FND가 생각한대로 동작하지 않았다. HEF4094와의 통신이 문제인가 하고 항목을 열심히 찾았지만 프로그램 상의 문제는 없어 보였다. 또 뭐가 문젠가… MPLAB SIM으로 값의 변화를 추적하던 중에 PortC의 5번 비트가 변하지 않았다. 이 값이 변하지 않으니 HEF4094도 정상동작을 하지 않은거다. 다른 비트들은 잘 되는데 왜 5번 비트만 이런가… 이 문제를 찾는데 오래걸렸다. -_-; 역시 ADC 기능 때문인가 했는데 PortC에는 ADC 가 걸려있지 않다.
PortB 때도 참조했던 I/O PINS ORDER OF PRECEDENCE 라는 표(Table 6-3)를 보고서 T0CKI 라는 것에 문제가 있을 것이라 짐작했다. 이 표에 의하면 PortB도 0번~2번까지 AN0이 우선 배정되는 것으로 나와있다. 3단계 순서 중에 GPIO가 가장 나중으로 세팅된다..
PortC 항목을 보니 이것도 ADC 기능을 위한 세팅이 우선이고 GPIO가 나중이다. 그 중에서 0번~4번은 클럭이나 레퍼런스와 관련되어 있는 듯 한데 ADC가 OFF되면서 함께 기능이 꺼진듯 했다. 확실한 것이 아니다. 어떤 이유인지는 몰라도 그런것 같았다. 왜냐하면 0번~4번은 원하는 대로 동작하고 있었으니까. 비트 5번은 그러니가 RC5는 T0CKI 이라는 항목에 먼저 배정되어 있어서 GPIO로 동작하지 않을 것이라고 추측했다.
데이터시트를 찾아보니 T0CKI는 OPTION 레지스터의 5번 비트 값이다. Timer0 Clock Source Select Bit 라는 내용. 에휴… 지친다. 내가 이것을 어찌 짐작이나 하고 미리 찾을 수 있겠는가. 기본값이 1로 되어 있다.

T0CS: Timer0 Clock Source Select

bit(1) 1 = Transition on T0CKI

pin 0 = Internal instruction cycle clock (CLKOUT)

둘다 GPIO를 쓰겠다는 말로는 안 보이지만, 1로 해서 안 되고 있으니 0으로 해봐야지.
TRIS 처럼 OPTION 레지스터를 바꾸는 것도 W 레지스터를 사용하지 않고 OPTION 이라는 명령어를 사용한다. 이것도 해봐서 안 되길레 명령어 세트를 보고 찾았다. 한번에 되는게 없다. 이제 PortC의 5번도 잘 된다. 으으음… HEF4094와의 통신문제라고 생각하고 통신 부분을 열심히 뜯어 고쳤는데… 시간이 아깝다. 프로그래밍 초반에 PortC의 출력들을 모두 테스트 했어야 했는데 대충 넘어간 것이 결국 많은 시간을 소비하게 했다.
프로젝트가 커지기 전에 확실히 해 둘 것들은 확실하게 확인하는게 좋다.
PIC 16F526에서 디지털 입출력 포트를 사용하기 위해 ADC 입력 핀들을 OFF하고 T0CKI 도 설정을 해야한다… 이것이 오늘의 배움이다.