Trước hết trước khi bắt đầu các bạn nếu chưa có datasheet của dùng MSP430 thì có thể download tại đây : http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=slaa559&fileType=pdf.
Lưu ý Datasheet vẫn luôn là tài liệu quan trọng nhất khi bạn tiếp cận bất cứ dòng vi điều khiển nào , nên việc thành thạo tiếng Anh và khả năng đọc Datasheet vẫn là quan trọng nhất. Tài liệu được viết cho MSP430G2553,các chip khác có module khác mã sẽ không sử dụng được thư viện đi kèm.
1. Giới thiệu chung về bộ nhớ Flash
Bài
này sẽ hướng dẫn cách sử dụng bộ nhớ Flash của MSP430 làm bộ nhớ dữ liệu không
bị mất khi mất điện(tương tự cách dùng EEPROM với các dòng khác).
Bộ nhớ thông thường có 2 loại là bộ nhớ
chỉ đọc ROM và bộ nhớ truy cập ngẫu nhiên RAM, bộ nhớ Flash là một sự pha trộn của 2 loại bộ
nhớ này.
Đặc điểm
bộ nhớ Flash là:
+
Chi phí thấp
+
Đọc/Ghi nhanh
+
An toàn
Bộ
nhớ Flash MSP430 bao gồm nhưng Bít, Byte, địa chỉ từ và khả lập trình. Mỗi
module bộ nhớ Flash được tích hợp sẵn bộ điều khiển dùng để điều khiển các hoạt
động ghi, xóa bộ nhớ. Bộ điều khiển này gồm 3 bộ: Bộ tạo dao động chủ, bộ phát
điện áp cho lập trình, bộ xóa.
Sơ đồ khối bộ nhớ
Flash
Chú ý : Điện áp thấp nhất để có thể đọc ghi bộ
nhớ Flash là 2.2V . Dưới mức này quá trình đọc ghi sẽ gặp lỗi.
2.
Cấu
trúc bộ nhớ Flash
Bộ
nhớ Flash của MSP430 được chia thành các phần đoạn , có thể được ghi theo các
bit,byte,word nhưng khi xóa thì bắt buộc phải xóa cả Segment . Bộ nhớ flash được phân chia thành
các phần bộ nhớ chính và thông
tin. Không có sự khác biệt trong
hoạt động của các phần bộ nhớ chính và bộ nhớ dữ liệu. Lệnh hoặc dữ liệu
có thể được đặt trong một trong hai phần. Sự
khác biệt giữa hai phần có kích
thước phân đoạn và các địa chỉ
vật lý. Bộ nhớ thông
tin có bốn phân đoạn 64-byte. Bộ nhớ chính có
một hoặc nhiều 512-byte phân đoạn.
Xem bảng dữ liệu thiết bị cụ thể cho bản đồ hoàn chỉnh bộ
nhớ của thiết bị.
Các
phân đoạn được chia thành các khối:
2.1.
Segment A
Segment
A của bộ nhớ dữ
liệu có bit khóa riêng so với cái Segment
còn lại bằng bit LOCKA
trong thanh ghi FCTL1 .
Lý do là vì dữ liệu trong Segment A có
lưu một số biến mặc định được gọi ra trong một số mà có sẵn
( ví dụ như các biến định tần số DCO) ,vì vậy nó cần được bảo vệ.
-
LOCKA = 1 : Segment A không thể bằng ghi hoặc xóa và tất cả các thông tin bộ nhớ được bảo vệ khỏi tẩy suốt
chương trình.
-
LOCKA = 0 :
Segmenta có thể bị xóa và viết như bất kỳ phân đoạn bộ nhớ flash khác, và tất
cả các ô nhớ thông tin
được xoá hoàn toàn.
2.2.
Chế độ hoạt động
Khi khởi động , bộ nhớ flash được cài
đặt mặc định ở chế độ đọc . Trong chế độ đọc, bộ nhớ flash không xóa hoặc ghi được, bộ định thời flash và bộ
cấp nguồn tắt, và bộ nhớ hoạt động hệt ROM . Bộ nhớ flash MSP430
là trong hệ thống lập trình (ISP) mà
không cần thêm điện áp bên ngoài. CPU có thể lập
trình bộ nhớ flash của riêng
mình. Bộ nhớ flash viết và xóa các chế độ được
lựa chọn với các BLKWRT, WRT, MERAS,
và xóa các bit và là:
- Ghi byte hoặc word
- Ghi 1 block
- Xóa 1 Segment
- Xóa bộ nhớ chính (tất cả các phân đoạn bộ nhớ chính)
- Xóa tất cả (Bộ
nhớ chính và bộ nhớ dữ liệu)
Đọc từ hoặc viết vào bộ nhớ flash trong khi nó đang được lập
trình hoặc bị xóa đều bị cấm. Nếu CPU thực hiện được yêu cầu trong
quá trình viết hoặc xóa, các mã được thực hiện phải
có trong bộ nhớ RAM. Bất kỳ
bản cập nhật Flash có thể được bắt đầu từ trong
bộ nhớ flash hay bộ nhớ RAM.
2.3.
Bộ định thời cho Flash
Memory
Bộ định
thời của bộ nhớ Flash phải được cấp tần số trong khoảng 257 kHz đến 476 kHz để có
thể ghi và xóa được.
Các
nguồn lấy xung nhịp có thể là ACLK , MCLK , SMCLK và được cài đặt chia tần để
được tần số fFTG phù hợp . Dù cho CPU ở bất cứ chế độ nào ,khi bộ nhớ Flash
đang trong chế độ ghi hoặc xóa đều không bị ảnh hưởng cho đến khi hoạt động này
hoàn tất ( tức là không thể vô hiệu hóa các nguồn xung cấp cho Flash ).
2.4.
Chế độ xóa Flash Memory
Mức độ xóa của một bit bộ nhớ flash là
1. Mỗi bit có thể được lập trình 1->0 độc lập nhưng để lập trình lại 0->1 đòi hỏi phải xóa . Phạm vi xóa nhỏ nhất là 1 segment . Có ba
chế độ xóa lựa chọn với các bit ERASE và MERAS liệt kê trong Bảng 7-1 .
Sauk
hi set bit ERASE ,bất kỳ lệnh
ghi nào vào dải địa chỉ sẽ
kích hoạt bộ cấp điện và quá trình xóa diễn
ra. Hình 7-4
cho thấy thời gian chu kỳ xóa . Bit
BUSY được thiết lập
ngay lập tức sau khi lệnh
Write được gọi và tồn tại
đến hết quá trình xóa . BUSY, MERAS , và ERASE sẽ được tự
động xóa khi chu kỳ hoàn thành . Thời gian chu kỳ
xóa không phụ thuộc vào
số lượng bộ nhớ flash hiện trên một thiết bị . Thời gian
xóa là tương đương cho tất cả thiết bị.
Lệnh
ghi ra ngoài vùng bộ nhớ dữ liệu sẽ không có tác dụng gì và toàn bộ quá trình bị
bỏ qua.
2.5.
Các thanh ghi điều khiển
Flash Memory
Để có thể đọc ghi được bộ nhớ flash , đơn giản
thì chúng ta chỉ cần quan tâm đến thanh ghi :
-
FCTL1 ( WRT , ERASE )
-
FCTL2
-
FCTL3 (LOCKA , LOCK, BUSY )
Thanh
ghi FCTL1
Thanh
ghi FCTL2
Thanh
ghi FCTL3
2.6.
Ghi 1 byte vào Flash
Memory
Theo như ở trên , để ghi được 1 byte vào bộ
nhớ , chúng ta cần làm một vài thủ tục sau:
-
Xóa toàn bộ segment chứa byte đó,để giữ lại dữ
liệu của các byte khác trong segment đó,chúng ta có thể đọc toàn bộ segment đó
ra trước ghi xóa,và ghi lại sau khi ghi byte cần lưu vào flash.Để xóa được
segment chúng ta cần set bit ERASE =1,sau đó ghi 1 byte bất kỳ vào vị trí bất kỳ
trên segment.
-
Chờ cho đến khi quá trình xóa hoàn tất.
-
Set cờ WRT cho phép ghi
-
Ghi dữ liệu vào vị trí cần lưu
-
Clear cờ LOCK để không làm thay đổi dữ liệu
trong flash
Dưới đây là minh họa hàm ghi 1 byte vào
segment C , có giữ lại các byte khác trong segment.
void flash_write_segmentC (unsigned int value, unsigned char position)
{
char *Flash_ptr; // Flash pointer
unsigned char i=0;
char Data_temp[64];
//Ghi
64 byte cua segment ra truoc
Flash_ptr = (char *) 0x1040; // Initialize Flash segment C pointer
for(i=0;i<64;i++) Data_temp[i]=
*Flash_ptr++;// copy
value segment C
Flash_ptr = (char *) 0x1040; // Initialize Flash pointer
FCTL1 = FWKEY +ERASE; // Set Erase bit
FCTL3 = FWKEY; // Clear Lock bit
*Flash_ptr = 0; // Dummy write to erase Flash
segment
while(FCTL3&BUSY); //Wait for complete erase
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
for(i=0;i<64;i++)
{
if(i==position)*Flash_ptr++ =value;
else *Flash_ptr++ = Data_temp[i]; // Write value to flash
}
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY +LOCK;
// Set LOCK
bit
}
|
2.7.
Đọc 1 byte vào Flash
Memory
Việc đọc bộ nhớ Flash đơn giản hơn nhiều so với việc ghi,bạn chỉ đơn giản
là dùng con trỏ đọc địa chỉ của đúng byte Flash đó là được.
VD:
void flash_read_segmentC (unsigned int *var, unsigned char position)
{
char *Flash_ptr; // Segment C pointer
Flash_ptr = (char *) 0x1040; // Initialize Flash segment C pointer
Flash_ptr += position; // Jump to desired address
*var = *Flash_ptr; // copy value segment C to
variable
}
|
Đây là thư viện Flash.h các dòng MSP430 .Chú ý là không nên tùy tiện sử dụng Segment A vì trong này lưu trữ nhiều tham số quan trọng của VĐK .
Download Project tại đây : Đọc ghi bộ nhớ Flash
Download Project tại đây : Đọc ghi bộ nhớ Flash
Trong thư viện Flash.h có hàm Flash_Write_Block(...) và Flash_Read_Block đó bạn dùng để đọc ghi 1 mảng
ReplyDeleteem muốn xuất giá trị trong flash trong code của anh ra LCD de test dùng lệnh sau
ReplyDeleteFlash_Read_Block(SegmentC,Temp,0,5);
lcd_printf(buff,"C0:%d C1:%d C2:%d C3:%d C4:%d",Temp[0],Temp[1],Temp[2],Temp[3],Temp[4]);
nhưng ko đc , mong anh giúp đỡ ạ !!
Như anh thì anh để tần số hoạt động 1Mhz,nói chung là phải để tần số nuôi flash trong khoảng 500Khz đến 900Khz,mà nói báo lỗi gì em cho lên đây xem
DeleteÀ thế mà không nói trước,em download thư viện LCD trong mục MSP430_Library ý có thư viện LCD đấy.có thể viết
ReplyDeletewhile(1)
{
LCD_Home();
sprintf (buff,"C0:%d C1:%d ",Temp[0],Temp[1]);
LCD_PrintString(buff);
_delay_cycles(100000);
}
//Chú ý là để trong vòng while để hiển thị được liên tục,và khai báo stdio.h thì mới dùng dc sprintf()
Em nên tìm hiểu kỹ về hiển thị LCD chứ còn về bộ nhớ thì Flash_Read_Block(SegmentC,Temp,0,5); là xong rồi
Em chạy debug rồi pause lại,trỏ chuột vào thanh ghi nào trong code nó hiện ra địa chỉ và cả giá trị thanh ghi đấy ở thời điểm hiện tại
ReplyDeleteNó là giá trị cần ghi vào các vị trí trong segmentD ở vị trí 0 1 2 3 4.Trong code có chú thích rõ ràng rồi mà em
ReplyDeletemình muốn ghi 1 mảng các giá trị vào flash thì làm như thế nào nhỉ ? như 1 mảng số điện thoại 01225413069 thì đọan code đó như thế nào AD, với hàm Flash_Read_Block() ak.
ReplyDeleteBạn dùng Hàm Flash_Write_Block nhé,ở trên mình đã nói rồi đấy,trong code cũng có giải thích rồi
Deleteý mình là không biết cách đưa các ham số vào hàm. Minh có thể dùng : Flash_Write_Byte(SegmentD,5, 0);
DeleteFlash_Write_Byte(SegmentD,0, 1);
Flash_Write_Byte(SegmentD,1, 2);
Flash_Write_Byte(SegmentD,2, 3);
Flash_Write_Byte(SegmentD,2, 4);
Flash_Write_Byte(SegmentD,5, 5);
Flash_Write_Byte(SegmentD,4, 6);
Flash_Write_Byte(SegmentD,1, 7);
Flash_Write_Byte(SegmentD,3, 8);
Flash_Write_Byte(SegmentD,0, 9);
Flash_Write_Byte(SegmentD,6, 10);
Flash_Write_Byte(SegmentD,9, 11);
để lưu số điện thoại được không Văn Thận Phạm :)
Chán quá.bạn có thể tạo 1 mảng abc[10] chẳng hạn .Gán abc[0]=5;abc[1]=0;abc[2]=1;...v v sau đó dùng hàm Flash_Write_Block(SegmentD,&abc,5,5); như thế chẳng hạn
Delete