Nếu đây là lần đầu tiên đến với Điện Tử Việt Nam, bạn có thể đọc phần Hỏi đáp bằng cách nhấn vào liên kết. Có thể bạn cần đăng kí trước khi có thể gửi bài . Để bắt đầu xem bài viết, chọn diễn đàn bạn muốn thăm dưới đây.
XIN MỌI NGƯỜI GIÚP ĐỠ ,GIẢI THÍCH GIÙM LỆNH NÀY VỚI.CẢM ƠN NHIỀU
*(((char*)&block_number)+3)
tôi đoán ý bạn là bạn không hiểu kiểu dữ liệu được gán cho biến được trình bày như trên đúng không?
Đây là cách để ép kiểu dữ liệu. Cũng khá lằng nhằng nhưng hãy phân tích từ từ ra.
///////////
xét trường hợp đơn giản hơn là thế này: giả sử bạn khai báo
char* c;
int16* p;
int16 a;
char b;
b= *c;
a=*p;
//giá trị được trỏ bởi biến con trỏ c là giá trị 8 bit.
//giá trị được trỏ bởi biến con trỏ p là giá trị 16 bit;
sẽ không hợp lệ nếu bạn viết: b=*p;
để lấy giá trị 8 bit trỏ từ con trỏ p bạn phải làm thế này:
b=*((char*)p);
//////////
giờ đến trường hợp gần với câu hỏi của bạn nhất nhe: hãy xem a và b khác nhau như thế nào nhé
int16 block_number; //block_number là giá trị 16 bít
int16 a; // a la bien 16bit
char b; //b la bien 8 bit
block_number=0x05af;
a=*(&block_number) //
b=*((char *)&block_number)
kết quả là: a=0x05af;
b=0xaf;
///
Tôi đoán không nhầm thì bài toán của bạn sử dụng trong hoàn cảnh lấy các dữ liệu 8bit từ một array mà phần tủ lớn hơn 8 bit,
vd int16 block_number[10];
Hi vọng bạn hiểu!
lệnh mình dùng cụ thể trong hàm sau:
char mmc_open_block(int32 block_number){
block_number*=512;
SS=0; // set SS = 0 (on)
SPI_WRITE(0x51); // send mmc read single block command
SPI_WRITE(*(((char*)&block_number)+3)); // arguments are address
SPI_WRITE(*(((char*)&block_number)+2));
SPI_WRITE(*(((char*)&block_number)+1));
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1; // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)
if((mmc_response(0xFE))==1) return 1; // wait for data token
return(0);
}
NẾU block_number là 2 thì số phải điền vào 4 BYTE của 4 hàm SPI_WRITE () chính giữa là số 512 tức là 0X200 và lần lượt các byte :0x00;0x00;0x02;0x00
nếu block thứ 3 thi điền vào số 1024=0x400 và 4 byte phải điền là 0x00;0x00;0x04;0x00
BẠN PUMA CÓ THỂ GIẢI THÍCH GIÙM MÌNH KHÔNG?CẢM ƠN BẠN NHIỀU.
lệnh mình dùng cụ thể trong hàm sau:
char mmc_open_block(int32 block_number){
block_number*=512;
SS=0; // set SS = 0 (on)
SPI_WRITE(0x51); // send mmc read single block command
SPI_WRITE(*(((char*)&block_number)+3)); // arguments are address
SPI_WRITE(*(((char*)&block_number)+2));
SPI_WRITE(*(((char*)&block_number)+1));
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1; // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)
if((mmc_response(0xFE))==1) return 1; // wait for data token
return(0);
}
NẾU block_number là 2 thì số phải điền vào 4 BYTE của 4 hàm SPI_WRITE () chính giữa là số 512 tức là 0X200 và lần lượt các byte :0x00;0x00;0x02;0x00
nếu block thứ 3 thi điền vào số 1024=0x400 và 4 byte phải điền là 0x00;0x00;0x04;0x00
BẠN PUMA CÓ THỂ GIẢI THÍCH GIÙM MÌNH KHÔNG?CẢM ƠN BẠN NHIỀU.
//////////////
khi bạn khai báo 1 biến 16 bit hoặc 32 bit thì trình dịch CCS nó sẽ sắp xếp địa chỉ theo thứ tự tăng dần ứng với byte thấp nhất đến byte cao nhất.
//////////////
như vậy với các lệnh:
SPI_WRITE(*(((char*)&block_number)+3)); // arguments are address
SPI_WRITE(*(((char*)&block_number)+2));
SPI_WRITE(*(((char*)&block_number)+1));
SPI_WRITE(*((char*)&block_number)); ////////////////////////////
/////
Có nghĩa là ghi các byte từ cao nhất đến thấp nhất của block_number;
Với block_number = 512 thì sắp sếp theo thứ tự tăng dần trong bộ nhớ sẽ là 0x00 0x02 0x00 0x00
Với block_number =2 thì sắp sếp theo thứ tự tăng dần trong bộ nhớ sẽ là 0x02 0x00 0x00 0x00
/// bạn chú ý là bố trí theo thứ tự tăng dần trong bộ nhớ nó ngược với khi biểu diễn giá trị hexa nhé, khi biểu diễn 1 giá trị theo hexa:
512 = 0x00 00 02 00 ;
2 = 0x00 00 00 02 ;
////////////////////////////////////////////
vấn đề của bạn là: với biến block_number là biến 32 bit, nếu bạn không trình bày ép kiểu (char*) thì để lấy ra từng byte thì bạn sẽ không bao giờ lấy được từng byte của biến 32bit.
giải thích nhé: giả sử biến block_number được bố trí bắt đầu từ địa chỉ 100 trong RAM (tùy loại VDK mà bố trí trong vùng RAM nào để thao tác, cái này viết ASM hoặc MPLAB C sẽ rõ, ở CCS thì nó tự động làm). Lúc này trình dịch sẽ bố trí địa chỉ như sau:
&block_number = 100; và (&block_number + 1) = 104; và (&block_number + 2) = 108
Do đó nếu bạn *(&bock_number + 1) có nghĩa là bạn sẽ lấy dữ liệu từ địa chỉ 104;
nhưng viết *(((char*)&block_number) + 1) có nghĩa bạn sẽ lấy dữ liệu từ địa chỉ 101;
Hi vọng bạn hiểu được vấn đề!
Với CCS thì như vậy chứ ở MPLAB C thì nó chặt chẽ hơn trong việc khai báo bố trí bộ nhớ cho các biến.
Mình đồng ý với hướng build AM5 bằng 7500F, nhưng nếu có thể cố thêm ngân sách thì nên lên RX 7600 ngay từ đầu. 4GB VRAM của RX 6500 XT bắt đầu khá chật với nhiều game mới, còn RX 7600 sẽ dùng thoải mái hơn trong vài năm tới.
Trong thời buổi vật giá leo thang, việc sắm một bộ máy tính chơi game đáp ứng đủ tiêu chí "ngon, bổ, rẻ" là ưu tiên hàng đầu của nhiều bạn trẻ. Lúc này, combo sử dụng vi xử lý AMD Ryzen 5 7500F kết hợp cùng card màn hình Radeon...
AMD Ryzen 9 9950X3D không chỉ là một bộ vi xử lý đơn thuần; nó là lời khẳng định về sức mạnh của kiến trúc Zen 5 kết hợp cùng công nghệ 3D V-Cache đột phá. Trong bối cảnh thị trường linh kiện PC cạnh tranh khốc liệt, đây được xem...
Bộ đôi Ryzen 9 9950X3D2 và Radeon RX 9070 XT 16GB là sự kết hợp phần cứng cao cấp nhất của AMD hiện nay. Đây không chỉ là một dàn máy tính để giải trí thông thường, mà là công cụ làm việc mạnh mẽ dành cho những ai có nhu cầu xử lý cường...
Khi ráp một bộ máy tính cấu hình cao, việc cân đối ngân sách cho từng linh kiện là rất quan trọng. Sự kết hợp giữa vi xử lý AMD Ryzen thế hệ mới có công nghệ 3D V-Cache và card đồ họa Radeon RX 9070 XT đang là lựa chọn rất đáng tiền....
Comment