Thông báo

Collapse
No announcement yet.

Các vấn đề cơ bản về I/O Port (Revised 12/02/09)

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • mrcuongcon
    replied
    Có ai để ý đến trở treo trong AVR là bao nhiêu không? Hôm trước mình có quét phím, nhưng không dùng trở treo ngoài, các phím như là có vấn đề vì nó rất dễ bị nhiễu.

    Leave a comment:


  • minoan
    replied
    Mình đang đọc ATmega8 về I/O nhưng có chỗ chưa hiểu, ai biết chỉ dùm cái bảng nó nói cái gì vậy? Có thể nói cụ thể 1 pin không?

    Leave a comment:


  • VNarmy
    replied
    Revised ngày 12/02/09: Một số chú ý

    Cảm ơn Blackmoon đã đóng góp.

    Leave a comment:


  • Kilodeth
    replied
    T: Tri-state
    P: Pulled Up
    Khi khởi tạo ở Codevision, mặc định PUD=0 nên chế độ T có cấu hình
    DDRx=0, PORTx=1, PUD=0
    Attached Files

    Leave a comment:


  • Le Thi Bich
    replied
    em dung CodevisionAVR thấy ở thẻ PORTS khi khởi tạo có các chể độ 0;1 khi chọn output và T;P khi chọn là input, em cũng phán đoán lờ mờ nhung chưa hiểu cặn kẽ lắm, thấy các anh thảo luận cũng vỡ ra thêm nhiều điều nhưng và là học mót nên vẫn lờ mờ các anh có thể nói chi tiết hơn về trạng thái 0,1,T,P cho em mở mắt mới được không ạ

    Leave a comment:


  • Kilodeth
    replied
    Code:
    //PB0: lay tin hieu
    //PB1..5: hien thi LED
    
    bit dotx10, dotx1; //hien thi dau cham
    char codex10=0, codex1=0; //hien thi so chuc-don vi
    char code[17]={63,6,91,79,102,109,125,7,127,111,119,124,57,94,121,113,128};//bang ma  
    char active_HIGH,active_LOW,active_nible;  
    ........
    
    while(1){
    for(active_HIGH=1; active_HIGH<6; active_HIGH++) //set tung chan
    {
    	PORTB = (1<<active_HIGH); //hàng quét
    
    	switch (active_HIGH){
    		case 1: active_nible = code[codex10]<<1;
    			break;
    		case 2: active_nible = code[codex10]>>3 + dotx10*(1<<5);
    			break;
    		case 3: active_nible = code[codex1]<<1;
    			break;
    		case 4: active_nible = code[codex1]>>3 + dotx1*(1<<5);
    			break;
    		default: active_nible = 0; break;
    	}
    	for(active_LOW=1; active_LOW < 6; active_LOW++){
    		DDRB = (1<<active_HIGH);  //thiet lap ngo ra muc cao
    		if (active_LOW < active_HIGH) DDRB|= (1<<active_LOW)&active_nible;
    		else if (active_LOW > active_HIGH) DDRB|= (1<<active_LOW)&(active_nible<<1);
    		else goto skip_delay;
    		delay_ms(1);
    	skip_delay:
    	}
    }
    }
    }
    Không tự tin đây là chương trình hiển thị hoàn chỉnh, bạn nào dùng proteus kiểm tra giúp mình. Phù..

    Leave a comment:


  • Kilodeth
    replied
    Ứng dụng cho 5 chân
    (Một điều cần lưu ý là mạch gốc led bị vẽ sai, hình này là đã chỉnh sửa lại, không hiểu sao Atmel lại có thể xuất bản mà sơ xuất đến thế)


    Phân tích theo hình,
    - Để quét digit 1 cần phải mức cao chân PB1, PB2,
    - Digit 2 thì mức cao PB3, PB4, ứng dụng này không dùng mức cao PB5
    - Đối chiếu các chân còn lại thấy có sự tương tự nhau ở hai digit, vậy chỉ cần xác lập một mảng đối chiếu là đủ cho cả hai.
    - Nếu lưu tổ hợp từng đoạn cho cả hai digit, tổng thể lên tới 10 x 10 = 100 byte (thậm chí 16 x 16 =256, không khoa học
    Bảng tổng hợp quan hệ chức năng sáng từng LED và từng chữ số

    Với giải thuật sơ lược như vừa nêu, tôi có viết một đoạn chương trình nhận các số hàng chục và đơn vị (codex10, codex1) và các bit dấu chấm (dotx10, dotx1), xuất ra thành 2 LED-7seg với 2 dấu chấm. Mô phỏng thử trên AVRStudio thấy chạy được, chú ý đây chỉ là đoạn chương trình chính hiển thị số. Quá trình lấy dữ liệu không được đề cập, tuy nhiên có thể lấy dữ liệu dễ dàng bằng ngắt hoặc chuyển đoạn chương trình này thành chương trình phục vụ ngắt timer thay vì dùng hàm delay.

    Leave a comment:


  • Kilodeth
    replied
    OK, giải pháp sơ bộ thì có từ khi đặt vấn đề, tuy nhiên câu cú lê thê và xét thấy không phù hợp lắm với tiêu đề topic nên ngại không gởi.

    Cơ bản, giả sử nối mạch như sau

    Để LEDA sáng, PORTx = 1, PORTy = 0, đồng thời cả hai chân phải được thiết lập ngõ ra. DDRx,y=1
    Ngược lại, LEDB sáng khi PORTx=0, PORTy=1, DDRx,y=1
    Các trường hợp khác ví dụ PORTx=PORTy, hoặc một trong hai chân thiết lập ngõ vào thì cả hai led đều không thể sáng (điện trở treo xem như quá lớn, bất chấp có hay không). Tuy nhiên nếu dùng 2 chân này chỉ để lái 2 led thì cũng chẳng có gì hay ho để nói.
    Nếu nối thêm một chân nữa, ta sẽ có 6 LED theo thứ tự LEDxy, LEDyx, LEDxz, LEDzx, LEDyz, LEDzy
    Muốn LEDxy sáng, PORTx=1, PORTy=0, DDRx,y=1 tương tự câu trên

    Tuy nhiên nếu chỉ muốn một mình LEDxy sáng còn các LED khác tắt thì còn khả năng tắt chức năng ngõ vào ở chân còn lại. Nếu để ngõ ra mức nào cũng có thể làm ảnh hưởng các LED khác. Nói cách khác chỉ còn cách cho DDRz=0, không quan tâm PORTz vì không ngại trở treo làm ảnh hưởng. Tuy nhiên hay nhất vẫn nên chọn PORTz=0 để ngõ vào có trở kháng thật sự cao, không làm ảnh hưởng.
    Để nhiều hơn một LED sáng đồng thời thì phải theo điều kiện là có cùng chân có cùng cực tính, ví dụ LEDxy, xz có thể sáng đồng thời, LEDxy và yz thì không thể.
    Tóm lược chức năng sáng cho 3 pin, 6 LED như sau

    Tiếp theo, muốn sáng theo một tập hợp nào đó ví dụ sáng các LED xy, xz, yx thì phải quét xoay vòng, có thể lợi dụng chức năng sáng cùng cực tính như trên nhưng vấn đền hơi phức tạp vì ảnh hưởng đến dòng tải, ảnh hưởng độ sáng nên không đề cập. Cách quét sau cho phép một lúc chỉ có một LED sáng:
    1. Xoay vòng các chân X, Y, Z thiết lập ngõ ra, mức 1
    2. Ở từng trạng thái, xoay vòng các chân còn lại, nếu LED nào sáng thì thiết lập ngõ ra, mức 0 cho chân tương ứng; LED nào tắt thì set ngõ vào, mức 0
    Phát triển cái này lên thành ma trận, người ta gọi là ma trận charlieplexed. Tổng quát, với N chân có thể lái được N(N-1) led. Tuy nhiên điểm yếu của phương pháp này là trong một thời điểm chỉ cho phép sáng 1 led. Độ rộng xung tối đa là 1/N/(N+1)
    Last edited by Kilodeth; 20-09-2008, 03:20.

    Leave a comment:


  • sun_rise
    replied
    @KiloDeth:
    Bạn giúp cấu hình cho các chân và giải thuật quét cho mạch này với, một cách để hiểu thêm về I/O port AVR.
    Đây là đặt vấn đề, không phải hỏi sao???
    Đây đúng là sơ đồ cơ bản của led7seg nhưng đúng như bạn nói, không sử dụng sơ đồ chân như 2 hình bạn đưa ra phía dưới và nó được điều khiển chỉ với 5 chân I/O.
    Bạn tự đặt vấn đề và tự trả lời đi nhá!
    Vui hơn rồi chứ

    Leave a comment:


  • Kilodeth
    replied
    Nguyên văn bởi duc thang Xem bài viết
    Cứ theo bảng tóm tắt 20 là xong.
    Bit PUD làm nhứt đầu.
    Ở hình 26, trang 55, có thêm các bit control Rpu (Alternate port Functions). Các bit này điều khiển ở đâu (không tìm thấy thanh ghi chứa các bit này).
    Cái đó lại là chuyện khác, đó là khi bạn dùng tới các chức năng khác của port. PUOExn, PUOVxn và một mớ rắc rối nữa là các tín hiệu do bản thân phần cứng AVR tự cấp phát khi cài đặt các thanh ghi SFR, hoặc khi có tín hiệu vào ra (tín hiệu khi chân đang ở chức năng chuyên dụng). Người sử dụng không cần cài đặt (muốn cài cũng không được), cũng không cần quan tâm đến các tín hiệu này làm gì. Chỉ cần cấu hình chức năng chính xác là được.
    Lấy ví dụ chức năng TxD và RxD của chân PD1,0. Không cần cài in/out gì cả cho PD1,0, chỉ cần set các bit RXEN và TXEN là các chân RxD, TxD tự nhận trách nhiệm In/Out tương ứng. Tín hiệu ra không phải bằng cách ghi lên PORTD.1 mà do bộ UART tự phát cấp phát.
    Một ví dụ khác là chứ năng SPI, cái này thì khác UART, muốn thu/phát được dữ liệu phải set các chân MISO, MOSI, SCK vào/ra tương ứng chứ bản thân SPI không kiểm soát.

    Cũng cám ơn bạn đã đặt ra nhiều vấn đề tưởng như đơn giản mà ...

    Leave a comment:


  • duc thang
    replied
    Cứ theo bảng tóm tắt 20 là xong.
    Bit PUD làm nhứt đầu.
    Ở hình 26, trang 55, có thêm các bit PUOExn, PUOVxn control Rpu (Alternate port Functions). Các bit này điều khiển ở đâu (không tìm thấy thanh ghi chứa các bit này).

    Leave a comment:


  • Kilodeth
    replied
    Cho em túm cái vụ Rpu này phát:

    Hoàn toàn có thể chọn hoặc không chọn trở treo cho từng chân, ngay trong cùng một port

    Tham khảo Table 20, trang 52 datasheet ATmega16:

    1. Nếu không chọn trở treo, DDxn = 0, PORTxn = 0, PUD có thể bằng 0 (hoặc 1, bất kỳ)
    2. Nếu chọn trở treo, DDxn = 0, PORTxn = 1 và PUD = 0

    Vậy PUD để chi, khi chỉ cần DDxn và PORTxn là có thể thoải mái cấu hình từng chân rồi? Mình không biết, có lẽ làm nhiều đến lúc cần mới biết
    Last edited by Kilodeth; 15-09-2008, 14:21.

    Leave a comment:


  • VNarmy
    replied
    Nguyên văn bởi duc thang Xem bài viết
    Căn cứ vào data sheet (ATMega 16)
    Trang 51, 52 và 57 : bit PUD control cho điện trở Ppu. Bit PUD ở thanh ghi SFIOR chỉ control chung cho cả port, làm sao chọn riêng cho từng pin như DDxn hoặc PORTxn ?
    Xem kỹ lại thì: if PUD =1 thì disable tòan bộ Rpu của VĐK, còn if PUD = 0 thì còn tùy thuộc ngã ra của DDxnvà PORTDxn.
    Điều khiển Rpu cho từng pin thấy khá phức tạp.
    Tôi cũng đang ở mức tìm hiểu AVR qua tài liệu thôi, viết từng ứng dụng cụ thể để tìm hiểu nó. Mong được học hỏi thêm.
    Thế nếu 2 hay nhiều chân trong cùng 1 port cùng chọn trở treo thì con trở đó được nối thế nào???
    Việc dùng PUD để chọn trở treo có thể thực hiện dễ dàng qua một mạch NAND (xem sơ đồ khối của cổng)

    Leave a comment:


  • duc thang
    replied
    Căn cứ vào data sheet (ATMega 16)
    Trang 51, 52 và 57 : bit PUD control cho điện trở Ppu. Bit PUD ở thanh ghi SFIOR chỉ control chung cho cả port, làm sao chọn riêng cho từng pin như DDxn hoặc PORTxn ?
    Xem kỹ lại thì: if PUD =1 thì disable tòan bộ Rpu của VĐK, còn if PUD = 0 thì còn tùy thuộc ngã ra của DDxnvà PORTDxn.
    Điều khiển Rpu cho từng pin thấy khá phức tạp.
    Tôi cũng đang ở mức tìm hiểu AVR qua tài liệu thôi, viết từng ứng dụng cụ thể để tìm hiểu nó. Mong được học hỏi thêm.

    Leave a comment:


  • VNarmy
    replied
    Nguyên văn bởi duc thang Xem bài viết
    Điện trở kéo lên Rpu hình như chỉ chọn cho cả port, không chọn riêng từng pin được ?
    Căn cứ vào đâu vậy???

    Leave a comment:

Về tác giả

Collapse

VNarmy Tìm hiểu thêm về VNarmy

Bài viết mới nhất

Collapse

Đang tải...
X