Điều gì gây ra việc BẬT một chân đầu ra duy nhất trên Microchip PIC16F690 để tự động TẮT một pin khác trên cùng một cổng?


7

Điều gì gây ra việc BẬT một chân đầu ra duy nhất trên Microchip PIC16F690 để tự động TẮT một pin khác trên cùng một cổng? Tôi có thể giải quyết vấn đề này bằng cách viết một byte cho toàn bộ cổng, điều khiển đồng thời tất cả các chân, thay vì chỉ một chút để kiểm soát trạng thái pin. Tôi đang sử dụng trình biên dịch Hi-Tech C tại đây. Tôi đang xác định trạng thái của pin với 9 đèn LED mỗi cái tiêu tốn 3 mA. Đây là cách dưới thông số kỹ thuật tối đa.

Tệp tiêu đề mplab có chân 0 trên cổng A được khai báo như sau:

volatile       bit RA0  @ ((unsigned)&PORTA*8)+0;

Tôi đang bật pin bằng cách viết một giá trị cao cho nó.

RA0 = 1;

Có phải vấn đề mà trình biên dịch đang coi "1" là một byte và ghi vào toàn bộ cổng không? Tôi có cần phải đúc nó không? Nếu vậy, không nên có trình biên dịch cho tôi một lỗi?

RA0 = (bit) 1;

Nếu tôi viết cho toàn bộ cổng, mọi thứ sẽ hoạt động như mong đợi:

PORTA = 0b00000001;

Câu trả lời:


16

Đó là vấn đề đọc-sửa-ghi nổi tiếng, bạn sẽ tìm thấy chi tiết trong bảng dữ liệu. Bạn phải viết cho toàn bộ đăng ký, như bạn đã tìm thấy. Các thiết bị 18F và 16 bit không gặp sự cố. Có một mô tả tốt trên trang 2 trong tài liệu này . Thay đổi bit trong thanh ghi "bóng" sau đó ghi thanh ghi vào cổng đầu ra thường được sử dụng để giải quyết vấn đề.


Bạn có chắc đây là vấn đề? Tôi sẽ tưởng tượng rằng RA0 = 1 sẽ tạo ra ASM sử dụng BSF, điều này không ảnh hưởng đến các bit 1-7. Bạn nên kiểm tra tệp danh sách lắp ráp. Tôi nghĩ Hi-Tech C tạo nó tự động dưới dạng tệp .lst.
ajs410

2
BSF thực sự không ảnh hưởng đến tất cả các bit 0-7, mặc dù tất cả chúng ta mong muốn nó thì không. Xem techref.massmind.org/techref/readmodwrite.htm .
davidcary

1

Đảm bảo rằng bạn có cổng bạn đang sử dụng được xác định là kỹ thuật số. ANSEL = 0;

Nếu một cổng được định nghĩa là tương tự và bạn thực hiện đọc kỹ thuật số, nó sẽ trả về 0. Vì vậy, khi PIC F16xxx thực hiện thao tác đọc-sửa-ghi, nó sẽ đọc 0 trên tất cả các chân tương tự. Sau đó được ghi 0 trở lại tất cả các chân này.

Nếu bạn có ANSEL được đặt thành 1 cho PORT B, mã bên dưới sẽ bật PORT B ​​trong 500ms, sau đó đọc PORTB là 0b00000000 (vì nó là tương tự). Sau đó tắt PORTB vì nó nghĩ rằng nó đã tắt.

    ANSEL = 0b11111111;
    TRISB = 0;
    PORTB = 0b11111111;
    __delay_ms(500);
    current = PORTB;
    PORTB = current;
    __delay_ms(500);

Đảm bảo rằng bạn đặt bit ANSEL tương ứng thành 0 cho bất kỳ mã pin nào bạn muốn sử dụng làm kỹ thuật số!


0

Tôi sử dụng trình biên dịch của Microchip. Nó có một tệp tiêu đề trong đó tất cả các thanh ghi có một liên kết với các bit được xác định. Vì vậy, trong mã của tôi, tôi viết:

LATAbits.LATA0 = 1;

Ngoài ra, tôi sẽ sử dụng thanh ghi chốt thay vì thanh ghi PORT để đặt đầu ra. Tôi nghĩ rằng một số chip không quan tâm, nhưng một số làm.


2
PIC 16F không có thanh ghi LAT, do đó có vấn đề.
Leon Heller

2
@Leon Heller: Các thanh ghi chốt riêng biệt là một tính năng của các bộ phận PIC Công cụ chung sau này không may được tích hợp vào các bộ phận PIC của Microchip cho đến loạt 18F; Thật kỳ lạ khi GI lưu ý vấn đề với các thanh ghi PORTx đọc / ghi vào những năm 1980, nhưng Microchip đã không giải quyết nó trong nhiều thập kỷ.
supercat

0

Tôi chắc chắn 99% trình biên dịch đang làm điều này. Bất kỳ cấu trúc nào được xác định để truy cập vào pin đều có sự mơ hồ trong đó trình biên dịch đang giải quyết để tạo hành vi này. Việc truyền bit có thể giúp ích nhưng tôi không biết làm thế nào (bit) được định nghĩa nên tôi không chắc chắn. Trình biên dịch sẽ không nhất thiết cung cấp cho bạn một lỗi nếu giá trị được ghi vào chân là loại thích hợp - Tôi đoán mặt nạ (bit) có thể kích hoạt một số logic để duy trì trạng thái của các chân khác nhưng vẫn trả về như cũ gõ như hằng số của bạn.

Không có gì đáng ngạc nhiên khi việc ghi vào cổng chính nó hoạt động - nhưng làm việc với các chân riêng lẻ phức tạp hơn nhiều. Có một lỗi trong mã được cung cấp, nó không có nghĩa là được sử dụng với trình biên dịch này hoặc bạn chỉ không sử dụng nó một cách chính xác.


3
Không có gì để làm với điều đó!
Leon Heller

Vâng, thực sự trình biên dịch C có thể là lý do cho nhiều vấn đề. Vấn đề này là do trình biên dịch gây ra, vì có lẽ nó đang sử dụng một cái gì đó như XORWF, tuy nhiên đó không phải là lỗi của trình biên dịch. Lập trình viên nên sử dụng một thanh ghi bóng. Vì vậy, cuối cùng, bạn đã đúng, @LeonHeller. Tôi bắt đầu ghét trình biên dịch C, đặc biệt là XC8 ngày nay ..
abdullah kahraman

-2

Viết toàn bộ cổng thành 1 cho bạn thấy vấn đề. Trong hệ nhị phân, đó là 0b00000001, vì vậy trên thực tế bạn đang tắt bảy bit đầu tiên và bit cuối cùng bật.

Bạn cần sử dụng các toán tử nhị phân để đảm bảo rằng bạn chỉ thực hiện thay đổi đối với bit cụ thể đó. Làm cái này:

PORTA = PORTA | 1;
// Equivalently:
current = PORTA;
new = current | 1;
PORTA = new;

Nếu các chân 2-8 hiện đang ở mức cao, thao tác OR sẽ trả về giá trị true và bit sẽ vẫn được đặt.

Để làm cho một chút thấp, sử dụng một hoạt động nhị phân AND:

PORTA &= 1;

Lưu ý rằng một số trình biên dịch sẽ có các macro cụ thể để thực hiện việc này (ví dụ: _BV () trên avr-gcc) và một số micros sẽ có các địa chỉ cụ thể được đặt bí danh cho từng bit ngoại vi để bạn không phải thực hiện chu trình đọc-sửa-ghi này ( bộ nhớ dải bit trên Cortex-M3)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.