آموزش راه اندازی ایسی حافظه فلشW25Q(نرم افزار پروگرام ایسی)

در اين بخش مي‌توانيد آموزش و مثال‌های مرتبط با میکروکنترلرهای AVR را مشاهده بفرمایید

مدیران انجمن: SAMAN, sinaset, شوراي نظارت

تاپیک را چگونه ارزیابی می کنید

اموزش + کتابخانه بسیار خوب و کاربردی برای ایسی
5
71%
خوب و مفید.
2
29%
جایی کاری بیشتر می داشت.
0
بدون راي
 
مجموع رای گیری: 7

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

آموزش راه اندازی ایسی حافظه فلشW25Q(نرم افزار پروگرام ایسی)

پست توسط sinaset » دو شنبه 9 اسفند 1395, 11:06 am

بنام خداوند بخشنده و مهربان
باسلام

در این تاپیک می خواهیم اموزش راه اندازی ایسی حافظه W25Q را بدهیم . تصویر 
چرا ایسی حافظه فلش؟!
همانجور که می دانید،در بعضی طرح و پروژه ها، نیاز به حافظه ها می باشد. اما در بعضی طرح ها، نیاز است،که حافظه نه خیلی زیاد باشد به اندازه "فلش مموری" "SDCARD" نه خیلی کم باشد به اندازه EEPROM .

به عنوان مثال،ما می خواهیم چند تصویر 150 کیلوبایتی را بر روی نمایشگر نمایش بدهیم! اگر بخواهیم از حافظه eeprom استفاده کنیم،چون حجم ان کم می باشد،باید از چند حافظه استفاده کنیم! اما استفاده از چند حافظه ظرفیت بالا eeprom ،که خودش هزینه ها را خیلی بالا می برد!
اگر بخواهیم از SDcard با ظرفیت 2 یا 4 گیگ استفاده کنیم، همه هزینه ها به مقدار قابل توجه ی بالا می رود! هم اینکه،بسیار از ظرفیت حافظه SDcard خالی می ماند!

اینجاست که می توان به کمک حافظه های فلش در ظرفیت 4 یا 8 مگابایت ، با قیمت ها در محدودی 1 تا 3 هزارتومان .. این خلاء را جبران کرد و طرح ها را با هزینه کمتر انجام داد.

حافظه فلش چرا اینقدر ارزان تر از حافظه eeprom می باشد!

حافظه های فلش از نسل eeprom ها هستن، اما در حافظه فلش،مدار های کنترولی بایت به صورت انفرادی ! حذف شده اند و به صورت مجموعه ی کنترول میشوند، اینکار باعث شده هزینه تمام شده کمتر شود ..

خانه ها در حافظه W25Q چگونه می باشند؟! تصویر 
حافظه فلش w25q (مدل 4 مگابایتی)به صورت 64 بلوک 64 کیلوبایتی می باشد .هر بلوک حافظه 64 کیلوبایتی، 256 صفحه است،که هر صفحه از 256 بایت می باشد.

* حافظه W25q32 ، جمعا 16384 صفحه برای نوشتن دارد

چطور درون حافظه فلش w25q نوشته میشود!

همانجور که گفتیم، حافظه فلش به دلیل استفاده از مدارات کمتر، دیگر دسترسی مستقیم به تک تک بایت ها ندارد! و باید به صورت مجموعه(صفحه به صفحه) انها را کنترول کرد!

یعنی اگر ما می خواهیم،مثلا بایت شماره 10 را بخوانیم! چون این بایت در صفحه 0 می باشد! ما باید کل این صفحه را که 256 بایت است را بخوانیم، سپس درون یک متغیر 256 بایتی بریزیم،بعد بایت شماره 10 را مطالعه کنیم.

برای نوشتن اطلاعات هم باید چنین کنیم، و باید یک صفحه را به طور کل (256 بایت)مقدار دهی کنیم.

بطور کلی مدارات درونی فلش چنین می باشد،و باید به صورت صفحه صفحه کنترولر شود و به صورت مستقیم نمی توان،به یک بایت دسترسی داشت، این در حالی است که در حافظه EEPROM به تک تک بایت می توان دسترسی مستقیم داشت!

*یک از معایت دیگر حافظه فلش این است که ، معمولا مقداری از بایت ها صفحه ها هدر می رود ( تصور کنید دو فایل دارید که حجمشان یکی 253 بایت است و دیگر 230 بایت است،هر کدام یک صفحه را اشغال کند! مقداری از حجم حافظه،هدر می رود!) *البته با روش های میشود،جلوگیری کرد،ولی خوب !

نحویه پاک کردن اطلاعات در ایسی به چه طریق می باشد.؟!

متاسفانه یکی دیگر از معایت ایسی flash همین می باشد، شما نمی توانید به صورت بایت بایت، یا صفحه صفحه! اطلاعات حافظه را پاک کنید!

به چند طریق این کار انجام می شود:

به صورت سکتور به سکتور ( 4 کیلو بایت)
به صورت بلوک 32 کیلوبایتی
به صورت بلوک 64 کیلوبایتی
به صورت کلی (پاک سازی کل)

این هم به دلیل هم کم شدن هزینه و .. می باشد.


با چه روشی هایی با ایسی ارتباط برقرار میشود؟!

پرتکل ارتباطی این ایسی همان SPI می باشد . به چندین روش (برای افزایش سرعت) می توان با ایسی ارتباط برقرار کرد، از جمله read (خواندن معمولی) ، dual Read ، quad read و..

مهمترین ریجستر ایسی کدام است ؟! تصویر 
مهمترین ریجستر ایسی ، ریجستر وضعیت 1 می باشد Status register 1 می باشد،که به کمک ان می توانید

وضعیت، رایت کردن،مشغولی،وضعیت های امنیتی ایسی و .. را ببینید (جمعه 8 بیت)


دیگر مشخصه ها: تصویر 
سرعت انتقال داده در ایسی 40MB/s می باشد
100 هزاربار چرخه کامل نوشتن و پاک کردن
20 سال زمان نگه داری اطلاعات ایسی
ولتاژ 2.7 تا 3.6 کاری


فهرست مطالب تاپیک:

ارتباط با ایسی و خواندن شماره دستگاه و شماره کارخانه
معرفی کتابخانه نوشته شده برای ایسی W25q32

..
صفحه دوم
نرم افزار پروگرام ایسی W25q32 و W25Q64
کتابخانه کمی تکمیل تر برای W25q32 و W25q64
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q

پست توسط sinaset » دو شنبه 9 اسفند 1395, 11:52 am

بنام خدا
باسلام

ارتباط با ایسی و خواندن شماره دستگاه و شماره کارخانه

اینجانب کتابخانه نیز در دست ساخت دارم،که اکنون ،نیز اماده است! ولی انشالله در اینده ان را بهتر خواهم کرد . اکنون به کمک این کتابخانه با ایسی ارتباط برقرار می کنیم!

ما در این ازمایش از مانیتور nokia n96 و میکروکنترولر Atmega32 استفاده می کنیم

به مانند تصویر نوکیا را به میکروکنترولر اتصال دهید. تصویر  پایه های ایسی را به پایه spi میکروکنترولر اتصال دهید . تصویر اما خواند نام کارخانه و دستگاه

به کمک این تابع،کدها را می خوانیم

کد: انتخاب همه

 W25Q_Manufacturer_Device_ID(&Read_1,&Read_2);     //خواندن شماره کارخانه و دستگاه


که در برنامه بدین شکل میشود:

کد: انتخاب همه

/*******************************************************
Project : خواندن نام دستگاه و کارخانه ايسي فلش
Version : v1
Date    :1395.12.09
Author  :sinaset
centralclubs.com

Chip type         : ATmega32A
AVR Core Clock frequency: 16.000000 MHz
*******************************************************/

#include <mega32a.h>
#include <delay.h>
#include <stdio.h>   
#include <spi.h>
#include "lib\tftlcd_functions.h"
#include "w25q.h"           //خواندن کتابخانه ايسي


void main(void)
{
unsigned char str[30],Read_1=0,Read_2=0; 
int g=0;

DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// SPI Clock Rate: 500.000 kHz
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (1<<SPR0);
SPSR=(0<<SPI2X);
DDRB.2=1;    //پايه براي ترانزيستور که به کمک ان پاور مانيتور کنترولر ميشود
PORTB.2=0;

  lcd_init();//آماده کردن ال سي دي براي شروع کار
  lcd_set_font_color(WHITE);
  lcd_fa_num();
  lcd_text_highlight_color(BLUE);
  lcd_text_highlight_on();   

   FLASH_CS_HIGH();
   delay_ms(500);
   
   W25Q_Manufacturer_Device_ID(&Read_1,&Read_2);     //خواندن شماره کارخانه و دستگاه
   
  lcd_init();//آماده کردن ال سي دي براي شروع کار
  lcd_set_font_color(WHITE);
  lcd_fa_num();   
  lcd_text_highlight_color(BLUE);
  lcd_text_highlight_on(); 
  lcd_goto_xy(10,20); 
  lcd_putsf_mix("بنام خدا",1);
  delay_ms(1000);
  lcd_clear_screen();
   
  sprintf(str,"MAINFUCT:0x%x   DEVICE:0x%x",Read_1,Read_2);   //نمايش نام و کارخانه دستگاه
  lcd_goto_xy(40,180);
  lcd_putsf_mix(str,1);   
 
  //کد کارخانه ايسي مي باشد EF
      
   while(1);

}


[لینک خارجی برای کاربران مهمان مخفی است، لطفا برای مشاهده لینک ثبت نام نموده و یا وارد سایت شوید]برنامه و کدها .

اکنون اگر برنامه رو پروگرام کنید،به مانند تصویر زیر به شما کد کارخانه و دستگاه داده میشود  تصویر نکات:
*کدکارخانه همه ایسی ها EF می باشد
*در پرتئوس ایسی w25q وجود ندارد، ایسی گذشته شده نمادین می باشد.و فایل شبیه ساز خراب اجرا میشود!
(
باتشکر.
(**کتابخانه معرفی شده در این پست،قدیمی می باشد و اشکالات فراوان دارد،از کتابخانه ها معرفی شده در پست بعد،برای مثال بالا استفاده کنید**)
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q

پست توسط sinaset » دو شنبه 11 اردیبهشت 1396, 5:05 pm

بنام خدا
باسلام


معرفی کتابخانه نوشته شده برای ایسی W25q32

مدتی قبل کتابخانه ی برای w25q32 نوشته ام،که خدا شکر،عملکرد خوبی نیز داشته،و به کمک ان توانسته ام،تصاویر مختلفی را بر روی LCD N96 نمایش بدهم!

قابلیت ها این کتابخانه تا به امروز:

پشتیبانی از ایسی حافظه W25q32 (حافظه w25q64 بزودی..!)
نوشتن و خواندن بر روی همه صفحه هات ایسی!
پاک سازی ایسی (به صورت سکتور 4 کیلوباتی،32 کیلوبایتی،64 کیلوبایتی)، فرمت کل ایسی.
رفتن به حالت کم مصرف و بیرون امدن از حالت کم مصرف.
مقدار دهی کارخانه ی به ریجستر (ریجستر اصلی،یعنی ریجستر شماره 1)
*بررسی پر یا خالی بودن یک صفحه !
**اطلاعات میزان پر بودن ایسی! به حجم و درصد !
**تابع نوشتن از اولین صفحه خالی موجود در ایسی!
*فرمت کردن ایسی به 3 روش مختلف.

کل توابع نوشته شده به اسم :

کد: انتخاب همه

unsigned char W25Q_read_StatustReg(unsigned char RG);       //خواندن وضعيت ريجسترها
void W25Q_Write_StatusReg(unsigned char Data);            //نوشتن در ريجستر وضعيت
void wait_busy(void);                            //خواندن وضعيت ريجسترها
void W25Q_Write_Disable(void);                     //غير فعال سازي قابليت نوشتن بر روي ايسي
void W25Q_Write(void);                           //فعال سازي نوشتن بر روي ايسي
unsigned char W25Q_busy(void);                     //خواندن وضعيت بيت مشغولي
unsigned char W25Q_wel(void);                      //خواندن وضعيت بيت نوشتن

void W25Q_Page_Program(unsigned long int  Number_PAGE, unsigned char *Page_Data);      //نوشتن در يک صفحه ايسي
void W25Q_Page_Program_Res(unsigned int  *Number_PAGE_Res, unsigned char *Page_Data)  ; //نوشتن از اخرين صفحه

void W25Q_Read_Data(unsigned long int  Number_PAGE,unsigned char *Page_Data);       //خواندن يک صفحه ايسي
void W25Q_Manufacturer_Device_ID(unsigned char *Manufacturer_id,unsigned char *Device_id);//نام وکارخانه سازنده ايسي
void W25Q_Sector_Erase(unsigned long int address );          //پاک سازي سکتورهاي 4 کيلوبايتي
void W25Q_BlockErase_32(unsigned long int address );         //حذف بلوک هايي 32 کيلوبايتي حافظه
void W25Q_BlockErase_64(unsigned long int address );         //حذف بلوک هايي 64 کيلوبايتي حافظه
void W25Q_Chip_Erase(void );                      //پاک کردن کل حافظه
void SPI_Flash_WAKEUP(void);                      //بيدار شدن از مد کم مصرف خاموشي
void SPI_Flash_PowerDown(void);                     //رفتن به مد کم مصرف خاموشي
void Factoty_rest_Reg(void);                      //مقدار دهي کارخانه ي براي ريجستر 1
void Format_ic(char Type_format);                   //فرمت کردن حافظه
unsigned char Check_page(long int Page);                //بررسي پر يا خالي بودن يک صفحه
void Info_data_ic(unsigned  int *write, unsigned  int *no_write,unsigned  int *KByte_Used,char *Percent_Used);



معرفی کوتاه توابع:


تابع خواندن وضعیت ریجستر ها "W25Q_read_StatustReg"

این تابع از نوع مقدار برگشتی می باشد.
همانجور که می دانید ما دو ریجستر در ایسی W25q که وضعیت را به ما شرح میدهد(که مهمترین ان ریجستر شماره 1 می باش) به کمک این تابع می توانیم وضعیت دو ریجستر را بخوانیم!

برای خواند باید چنین کنیم

unsigned char status
(1)status=W25Q_read_StatustReg

که درون پرانتز باید شمار ریجستر را نام ببریم،که در مثال بالا ریجستر شماره 1 را انتخاب کرده ایم ،اگر قصدا داشته باشیم ریجستر شماره 2 را بخوانیم باید عدد 2 را قرار میدهیم.

تابع نوشتن در ریجستر "W25Q_Write_StatusReg"

این تابع نیز برای نوشتن در ریجستر می باشد. باید مابین () مقدار مد نظر را در ریجستر بنویسید به مانند:

;(W25Q_Write_StatusReg(0x00

تابع صبر تا زمانی که ایسی از مشغول بیرون بی اید "wait_busy"

اگر از این تابع استفاده ،تا زمانی که ایسی مشغول باشد،درون این تابع نیز باقی خواهد ماند

;()wait_busy

همچنین اگر قصدا داشته باشه وضعیت بیت نوشتن را به صورت جداگانه فقط بخوانید از تابع مقدار برگشتی زیر استفاده کنید:

()W25Q_busy

تابع فعال سازی و غیر فعال سازی نوشتن ایسی W25Q_Write و W25Q_Write_Disable

زمانی که قصد داشته باشید در ریجستری یا بایت اطلاعاتی بنویسید،به کمک این تابع ایسی را باید فعال کرد

;()W25Q_Write

و برای غیر فعال کردن ان نیز (که معمولا زیاد نیاز نمی شود!) از تابع :

;()W25Q_Write_Disable

همچنین اگر قصدا داشتید وضعیت بیت نوشتن را بخوانید از تابع مقدار برگشتی زیر استفاده کنید.

;()W25Q_wel

تابع نوشتن بر روی صفحه هات حافظه ایسی W25Q_Page_Program

اگر قصد داشته باشید. اطلاعاتی برروی صفحه هات ایسی بنویسید از تابع W25Q_Page_Program می توانید استفاده کنید این تابع بدین شکل می باشد

(آرایه دیتا ،شماره صفحه)W25Q_Page_Program

آرایه دیتا باید، یک ارایه 8 بیتی، 256 تایی باشد(*نهایت 256 بایت،کمتر از ان نیز میشود،اما صفحه شما هدر میرود و خالی می ماند!)، شماره صفحه نیز باید بين 0 تا 16384 باشد. (تعداد صفحه هات ایسی w25q32)

به عنوان مثال:

;"بنام خداوند بخشنده و مهربان"=[unsigned char str[256

;(W25Q_Page_Program(0,str

تابع نوشتن بر روی ایسی از اولین صفحه خالی موجود در ایسی W25Q_Page_Program_Res


زمانی نیاز است،بدون از دست دادن وقت! از اولین صفحه خالی نوشته شده در ایسی،شروع به نوشتن در ایسی کنیم ! به عنوان مثال، ایسی تا صفحه 30 ان نوشته شده! ما می خواهیم از صفحه 31 به بعد شروع به نوشتن کنیم،برای این منظور از این تابع استفاده خواهیم کرد:

نحویه استفاده از این تابع دستور قبلی تفاوتی ندارد(کدهای لازم برای انجام بهتر دستور درون تابع گذاشته شده،برای همین کارها ساده شده است)

;(W25Q_Page_Program_Res(0,str


تابع خواندن اطلاعات صفحه هات حافظه ایسی W25Q_Read_Data

این تابع نیز کار بخصوصی برای کار کردن ندارد! باید شماره صفحه، و ارایه 256 بایتی به عنوان معرفی کنید،تا اطلاعات صفحه بر روی ایسی ارایه بارگزاری شود.

;[unsigned char str[256

;(W25Q_Read_Data(0,str

نام و نام کارخانه ایسی W25Q_Manufacturer_Device_ID

به کمک تابع بالا می توانید شماره کارخانه و دستگاه را بخوانید
تابع از نوع برگشتی می باشد، شما باید دو متغیر به ان بدهید،تا اطلاعات را به درون ان به ریزد (به مانند مثال اول تاپیک)

;unsigned char man,dev

;(W25Q_Manufacturer_Device_ID(man,dev

دستورات پاک سازی سکتور،سکتور 32 کیلوبایتی،سکتور64 کیلوبایتی،کل حافظه

در صورتی که قصدا داشته باشید سکتورها را به صورت 4 کیلوبایتی پاک سازی کنید باید از دستور W25Q_Sector_Erase استفاده کنید

بدین شکل

;(W25Q_Sector_Erase(0
بین () باید شماره سکتور ایسی باشد،که در این ایسی بین 0 تا 1024 می باشد

اگر قصد داشته باشید به صورت 32 کیلوبایتی حافظه را پاک کنید باید بدین شکل عمل کنید:

;(W25Q_BlockErase_32(0

بین () باید شماره سکتور32 کیلوبایتی ایسی باشد،که در این ایسی بین 0 تا 128 می باشد

اگر قصد داشته باشید به صورت 64 کیلوبایتی حافظه را پاک کنید باید بدین شکل عمل کنید:

;(W25Q_BlockErase_64(0

بین () باید شماره سکتور32 کیلوبایتی ایسی باشد،که در این ایسی بین 0 تا 64 می باشد.

اگر قصد داشته باشید کل حافظه را فرمت کنید،باید از دستور زیر استفاده کنید

;()W25Q_Chip_Erase

فرمت ایسی به سه روش مختلف Format_ic

اگر قصد داشته باشید ایسی را به سه شکل مختلف،یعنی سکتور 4 کیلوبایتی،سکتورهای 32 و سکتورهای 64 بایتی، از این دستور می توانید استفاده کنید،تا کل اطلاعات حافظه پاک شود.

;(نوع فرمت)Format_ic

//عدد 0 فرمت سکتور به سکتور
//عدد 1 فرمت بلاک هاي 32 کيلوبايتي
//عدد 2 فرمت بلاک ها 64 کيلوبايتي


تابع رفتع و بیرون امدن از مد کم مصرف SPI_Flash_WAKEUP و SPI_Flash_PowerDown

اگر قصد داشته باشید ایسی را به مد کم مصرف ببرید باید از تابع زیر استفاده کنید:
;()SPI_Flash_PowerDown

و اگر قصدا داشته باشید ان را از ان مد در بی اورید باید از تابع زیر استفاده کنید:
;()SPI_Flash_WAKEUP

تابع مشخص شدن خالی یا پر بودن صفحه ایسی Check_page

به کمک این تابع برگشتی می توانید متوجه بشوید،صفحه ایسی پر می باشد یا خالی!

unsigned char status

(status=Check_page(0

مقدار () همان صفحه مورد نظر ما می باشد، اگر مقدار برگشتی 0 باشد،یعنی صفحه خالی می باشد،اگر مقدار برگشتی 1 باشد، یعنی صفحه پر می باشد!


اخرین تابع، Info_data_ic

به کمک این تابع می توانیم بفهیم چه مقدار از حافظه ایسی پر می باشد (به کیلوبایت،درصد،تعداد صفحه هات خالی و تعداد صفحه هات پر )

این تابع نیز به صورت برگشتی می باشد،و برای استفاده نیز باید چند متغیر به ان داد.

;unsigned int write,no_write,KByte_Used,Percent_Used

;(void Info_data_ic( &write, &no_write,&KByte_Used,&Percent_Used


متغیر write مقدار،صفحه هات پر را معرفی می کنید متغیر no_write تعداد صفحه هات خالی، متغیر KByte_Used مقدار استفاده از حافظه به کیلوبایت، درصد استفاده از ایسی را به ما می گوید Percent_Used (از 100 درصد)

کد همه کتابخانه نوشته شده :

کد: انتخاب همه

#ifndef __FLASH_H
#define __FLASH_H
 
/*
بنام خداوند بخشنده و مهربان
کتابخانه نوشته شده براي ايسي حافظه
W25Q
V=0.9 Beta
by sinaset
centralclubs.com
Data:1395.12.09
*/
#define SIZE  256   //اندازه هر صفحه ايسي حافظه
#define W25Q_WriteEnable      0x06    //فعال سازي وضعيت نوشتن
#define W25Q_WriteDisable        0x04    //غير فعال سازي وضعيت نوشتن
#define W25Q_ReadStatusReg      0x05    //خواندن رجيستر وضعيت 1
#define W25Q_ReadStatusReg2      0x35    //خواندن رجيستر وضعيت 1
#define W25Q_WriteStatusReg      0x01    //نوشتن در ريجستروضعيت
#define W25Q_ReadData          0x03    //خواندن ديتا
#define W25Q_FastReadData        0x0B    //خواند سريع ديتا
#define W25Q_FastReadDual        0x3B    //خواند سريعت ديتا،دوبرابر
#define W25Q_PageProgram        0x02    //نوشتن در يک صفحه ايسي
#define W25Q_BlockErase32       0x52    //پاک کردن يک بلوک ايسي
#define W25Q_BlockErase64      0xD8    //پاک کردن يک بلوک ايسي
#define W25Q_SectorErase      0x20   //پاک کردن يک بلوک ايسي
#define W25Q_ChipErase           0x60    //پاک کردن کل چيپ
#define W25Q_PowerDown         0xB9    //چيپ در وضعيت کم مصرف
#define W25Q_ReleasePowerDown   0xAB    //
#define W25Q_ManufactDeviceID   0x90    //معرفي کد کارخانه و ايسي
#define FLASH_CS_HIGH() (PORTB|=(1<<4))  //وضعيت غير فعال سازي براي ايسي         
#define FLASH_CS_LOW() (PORTB &=~(1<<4))  // وضعيت فعال سازي براي حافظه

#pragma used+
unsigned char W25Q_read_StatustReg(unsigned char RG);       //خواندن وضعيت ريجسترها
void W25Q_Write_StatusReg(unsigned char Data);            //نوشتن در ريجستر وضعيت
void wait_busy(void);                            //خواندن وضعيت ريجسترها
void W25Q_Write_Disable(void);                     //غير فعال سازي قابليت نوشتن بر روي ايسي
void W25Q_Write(void);                           //فعال سازي نوشتن بر روي ايسي
unsigned char W25Q_busy(void);                     //خواندن وضعيت بيت مشغولي
unsigned char W25Q_wel(void);                      //خواندن وضعيت بيت نوشتن

void W25Q_Page_Program(unsigned long int  Number_PAGE, unsigned char *Page_Data);      //نوشتن در يک صفحه ايسي
void W25Q_Page_Program_Res(unsigned int  *Number_PAGE_Res, unsigned char *Page_Data)  ; //نوشتن از اخرين صفحه

void W25Q_Read_Data(unsigned long int  Number_PAGE,unsigned char *Page_Data);       //خواندن يک صفحه ايسي
void W25Q_Manufacturer_Device_ID(unsigned char *Manufacturer_id,unsigned char *Device_id);//نام وکارخانه سازنده ايسي
void W25Q_Sector_Erase(unsigned long int address );          //پاک سازي سکتورهاي 4 کيلوبايتي
void W25Q_BlockErase_32(unsigned long int address );         //حذف بلوک هايي 32 کيلوبايتي حافظه
void W25Q_BlockErase_64(unsigned long int address );         //حذف بلوک هايي 64 کيلوبايتي حافظه
void W25Q_Chip_Erase(void );                      //پاک کردن کل حافظه
void SPI_Flash_WAKEUP(void);                      //بيدار شدن از مد کم مصرف خاموشي
void SPI_Flash_PowerDown(void);                     //رفتن به مد کم مصرف خاموشي
void Factoty_rest_Reg(void);                      //مقدار دهي کارخانه ي براي ريجستر 1
void Format_ic(char Type_format);                   //فرمت کردن حافظه
unsigned char Check_page(long int Page);                //بررسي پر يا خالي بودن يک صفحه
void Info_data_ic(unsigned  int *write, unsigned  int *no_write,unsigned  int *KByte_Used,char *Percent_Used);
//اطلاعات ميزان استفاده
//void W25Q_Page_Program_Erase(unsigned long int  Number_PAGE, unsigned char *Page_Data); //همزمان پاک کردن و نوشتن در ايسي

unsigned char W25Q_read_StatustReg(unsigned char RG) //خواندن وضعيت ريجسترها
{
unsigned char Data=0;
   // W25Q_Write();
    FLASH_CS_LOW();
    if (RG==1)spi(W25Q_ReadStatusReg);   //خواندن وضعيت ريجستر   
    if (RG==2)spi(W25Q_ReadStatusReg2);   //خواندن وضعيت ريجستر
    Data= spi(0);
    spi(0);
    FLASH_CS_HIGH();
    return Data;         
}

void wait_busy(void) //خواندن وضعيت ريجسترها
{
while ((W25Q_read_StatustReg(1)&0x01)==0x01);
}
void W25Q_Write(void)   //فعال سازي نوشتن بر روي ايسي
{
FLASH_CS_LOW();
spi(W25Q_WriteEnable);
FLASH_CS_HIGH(); 
}


void W25Q_Write_Disable(void)  //غير فعال سازي قابليت نوشتن بر روي ايسي
{
FLASH_CS_LOW();
spi(W25Q_WriteDisable);
FLASH_CS_HIGH(); 
}

unsigned char W25Q_busy(void)    //خواندن وضعيت بيت مشغولي
{
unsigned char Data=0;

    FLASH_CS_LOW();
    spi(W25Q_ReadStatusReg);   
    Data= spi(0);
    spi(0);
    FLASH_CS_HIGH(); 
    if(Data & 0x80) Data=1;   
    else Data=0;
    return Data;
}

unsigned char W25Q_wel(void)   //خواندن وضعيت بيت نوشتن
{
unsigned char Data=0;

    FLASH_CS_LOW();
    spi(W25Q_ReadStatusReg);   
    Data= spi(0);
    spi(0);
    FLASH_CS_HIGH(); 
    Data=Data<<1;
   if(Data & 0x80) Data=1;   
   else Data=0;
   return Data;
}

void W25Q_Sector_Erase(unsigned long int address )   //پاک سازي سکتورهاي 4 کيلوبايتي
{
unsigned char Data1,Data2,Data3;
//شماره سکتور بايد بين 0 تا 1024 باشد
//هر سکتور 4 کيلوبايت را حذف مي کند
address=address*SIZE*16;

Data1= (address>>16);
Data2= (address>>8);
Data3= (address);

   W25Q_Write();
   wait_busy();
   FLASH_CS_LOW();
   spi(W25Q_SectorErase);      //پاک کردن سکتور   
   spi(Data1);
   spi(Data2);
   spi(Data3);
   FLASH_CS_HIGH();
   wait_busy();          
}

void W25Q_BlockErase_32(unsigned long int address )    //حذف بلوک هايي 32 کيلوبايتي حافظه
{
unsigned char Data1,Data2,Data3;
//شماره بلوک بايد بين 0 تا 128 باشد
//در اين روش 64 کيلوبايت حذف ميشود
address=address*SIZE*128;
Data1= (address>>16);
Data2= (address>>8);
Data3= (address);
   W25Q_Write();
   FLASH_CS_LOW();
   spi(W25Q_BlockErase32);      //پاک کردن سکتور   
   spi(Data1);
   spi(Data2);
   spi(Data3);
   FLASH_CS_HIGH();
   wait_busy();
// delay_ms(900);            
}

void W25Q_BlockErase_64(unsigned long int address )      //حذف بلوک هايي 64 کيلوبايتي حافظه
{
//شماره بلوک بايد بين 0 تا 64 باشد
//در اين روش 64 کيلوبايت حذف ميشود
unsigned char Data1,Data2,Data3;

address=address*SIZE*256;
Data1= (address>>16);
Data2= (address>>8);
Data3= (address);
   W25Q_Write();
   wait_busy();
   FLASH_CS_LOW(); 
   
   spi(W25Q_BlockErase64);      //پاک کردن سکتور   
   spi(Data1);
   spi(Data2);
   spi(Data3);
   
   FLASH_CS_HIGH();
   wait_busy();            
}

void W25Q_Chip_Erase(void )   //پاک کردن کل حافظه
{
   W25Q_Write(); 
   wait_busy();
   FLASH_CS_LOW();
   spi(W25Q_ChipErase);      //پاک کردن سکتور   
   FLASH_CS_HIGH();
   wait_busy();            
}

void W25Q_Write_StatusReg(unsigned char Data)   //نوشتن در ريجستر وضعيت
{

   W25Q_Write();
   FLASH_CS_LOW();
   spi(W25Q_WriteStatusReg);      //نوشتن وضعيت
   spi(Data);
   spi(0);
   FLASH_CS_HIGH(); 
}

void W25Q_Manufacturer_Device_ID(unsigned char *Manufacturer_id,unsigned char *Device_id)//نام وکارخانه سازنده ايسي
{
    FLASH_CS_LOW();
    spi(W25Q_ManufactDeviceID);
    spi(0x00);
    spi(0x00);
    spi(0x00);
    *Manufacturer_id= spi(0);
    *Device_id= spi(0);
    FLASH_CS_HIGH();
  // delay_ms(10);   
}

void W25Q_Page_Program(unsigned long int  Number_PAGE, unsigned char *Page_Data)//نوشتن در يک صفحه ايسي
{                                              
//شماره صفحه بايد بين 0 تا 16384 باشد
//تعداد بايت براي ذخيره نبايد بيشتر از 256 بايت باشد
int g=0;
unsigned char Data1,Data2,Data3;

Number_PAGE=(Number_PAGE*256);   

Data1= (Number_PAGE>>16);
Data2= (Number_PAGE>>8);
Data3= (Number_PAGE);

    W25Q_Write(); 
    FLASH_CS_LOW();
    spi(W25Q_PageProgram);      //نوشتن
    spi(Data1);
    spi(Data2);
    spi(Data3);
    for(g=0;g<SIZE;g++)spi(Page_Data[g]);
    FLASH_CS_HIGH();
    //delay_us(750);
   wait_busy();
}
/*
void W25Q_Page_Program_Erase(unsigned long int  Number_PAGE, unsigned char *Page_Data)//همزمان پاک کردن و نوشتن در ايسي
{
//براي استفاده از اين تابع،ادرس اول صفحه شما بايد ابتدا سکتور باشد
//ايسي فلش مورد استفاده جمعا 1024 سکتور 4 کيلو بايتي دارد که در هر بلوک 16 سکتور وجود دارد
//بهتر است براي استفاده از  تابع،از صفحه 0 شروع با ذخير اطلاعات کنيد
unsigned int g,p;
unsigned char block=0,sector;
float M=0.0;
block=(Number_PAGE/256);
sector=(Number_PAGE/16);
M=(Number_PAGE/16)%10;

if(M==1.00000 || M==2.00000 || M==3.00000 || M==4.00000 || M==5.00000 || M==6.00000 || M==7.00000 || M==8.00000 || M==9.00000 || M==0.00000 ){
W25Q_Sector_Erase(sector); 
}
W25Q_Page_Program(Number_PAGE,Page_Data);
}
*/

void W25Q_Read_Data(unsigned long int  Number_PAGE,unsigned char *Page_Data)//خواندن يک صفحه ايسي
{
//شماره صفحه بايد بين 0 تا 16384 باشد
//تعداد بايت براي ذخيره نبايد بيشتر از 256 بايت باشد
int g=0;
unsigned char Data1,Data2,Data3;
Number_PAGE=(Number_PAGE*256);   
Data1= (Number_PAGE>>16);
Data2= (Number_PAGE>>8);
Data3= (Number_PAGE);

  //  W25Q_Write(); 
    FLASH_CS_LOW();
    spi(W25Q_ReadData);     //خواندن
    spi(Data1);
    spi(Data2);
    spi(Data3);   
    for(g=0;g<SIZE;g++)Page_Data[g]=spi(0);
    FLASH_CS_HIGH();
}

void SPI_Flash_PowerDown(void)  //به خواب رفتن
{
     FLASH_CS_LOW();                
    spi(W25Q_PowerDown);   
   FLASH_CS_HIGH();                        
    delay_us(3);                  
}   

void SPI_Flash_WAKEUP(void)    //بيدار شدن از خواب

     FLASH_CS_LOW();               
    spi(W25Q_ReleasePowerDown);                            
    FLASH_CS_HIGH();                   
}

void Factoty_rest_Reg(void)      //ريست کردن ريجستر شماره 1

  W25Q_Write_StatusReg(0x00);                  
} ;

void Format_ic(char Type_format)   //فرمت کردن کل حافظه
{
//عدد 0 فرمت سکتور به سکتور
//عدد 1 فرمت بلاک هاي 32 کيلوبايتي
//عدد 2 فرمت بلاک ها 64 کيلوبايتي
int g;

  if(Type_format==0)for(g=0;g<1024;g++)W25Q_Sector_Erase(g);
  if(Type_format==1) for(g=0;g<128;g++)W25Q_BlockErase_32(g);
  if(Type_format==2) for(g=0;g<64;g++)W25Q_BlockErase_64(g);
                     
} ;

unsigned char Check_page(long int Page)   //اطلاع از پر بودن يا نبودن اطلاعات در يک صفحه
{

//برگشت عدد 0 يعني اين صفحه خالي مي باشد و چيزي بر روي ان نوشته نشده
//برگشت عدد 1 يعني در اين صفحه مقداري اطلاعات نوشته شده است
int g,c=0;
unsigned char Buff[256],DATA;
bit No_write=0;

   W25Q_Read_Data(Page,Buff);

    for(g=0;g<256;g++)
    {
    DATA=Buff[g];
    if(DATA==0xff)c++;
    }
   
   if(c<250)No_write=1;               
   else if(c>250)No_write=0; 
   
   return No_write ;                  
};

void W25Q_Page_Program_Res(unsigned int  *Number_PAGE_Res, unsigned char *Page_Data)
//نوشتن در اخرين صفحه خالي ايسي
{
/*
به کمک اين تابع مي توانيد از اخرين صفحه نوشته  شده  به بعد ، ايسي استفاده کنيد و شروع به نوشتن بکنيد
تصور کنيد اخرين صفحه نوشته شده در ايسي499 مي باشد
ما در متغير
Page_Data
ديتا خود را قرار ميدهيم
تابع ابتدا شروع مي کند اخرين صفحه نوشته شده را پيدا مي کند سپس از صفحه بعد از ان ديتا ما را ذخير مي کند
ادرس صفحه نوشته شده را در متغير
Number_PAGE_Res
قرار ميدهد که شما نيز مي توانيد  ان را به کمک متغير درون برنامه خود برداريد
به عنوان مثال ما در برنامه بدين طريق ديتا را ميدهيم و ادرس را دريافت مي کنيم

W25Q_Page_Program_Res(&ADDRESS,BUF)
براي خواندن
W25Q_Read_Data(ADDRESS,BUFF)
يا مي توانيد ادرس صفحه ذخيره شده را در متغير ديگر ذخيره کنيد و ان را داشته باشيد
*/
unsigned int g,Check;
unsigned long int Address;

    for(g=0;g<16384;g++){
    Check=Check_page(g);
    if(Check==0)Address=g,g=16384;
    }
    *Number_PAGE_Res=Address;
    W25Q_Page_Program(Address,Page_Data);

}


void Info_data_ic( unsigned  int *write, unsigned  int *no_write,unsigned  int *KByte_Used,char *Percent_Used)
//اطلاعات مربوط به حافظه
{
// متغير اول تعداد صفحه هات نوشته شده را پيدا مي کند
//متغير دوم تعداد صفحه هات خام و نوشته نشده را پيدا مي کند
//متغير سوم حجم استفاده شده از ايسي را ذکر مي کند
//متغير چهارم نيز درصد استفاده شد از ايسي را ذکر مي کند

unsigned  int g,c=0,WR_Y=0,WR_N=0;
bit check=0;


    for(g=0;g<16384;g++)
    {
   check=Check_page(g); 
   if(check==1)WR_Y++;
   if(check==0)WR_N++;
    }
    *no_write=WR_N;
    *write=WR_Y;
    *KByte_Used=(WR_Y/4);
    *Percent_Used= (WR_Y/4)/40;               
};
#pragma used-

#endif


[لینک خارجی برای کاربران مهمان مخفی است، لطفا برای مشاهده لینک ثبت نام نموده و یا وارد سایت شوید]کتابخانه از اینجا .(*[لینک خارجی برای کاربران مهمان مخفی است، لطفا برای مشاهده لینک ثبت نام نموده و یا وارد سایت شوید]موقت و کمکی)

انشالله در پست های اینده مثال های با این کتابخانه معرفی میشود. همچنین سعی می شود،تا در اینده نرم افزار برای اپلود اطلاعات به ایسی ساخته و معرفی شود.

پیشنهاد و انتقادی بود حتما بفرمایید. ضمنا فروش!!!! این کدها و .. حرام می باشد!.

باتشکر.
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

New Member
پست: 1
تاریخ عضویت: جمعه 7 مهر 1396, 10:53 am

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط fdrvhv » دو شنبه 24 مهر 1396, 1:57 pm

تشکر بابت این آموزش. فقط لطفا فایل ها را نمیشه دانلود کرد.

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط sinaset » دو شنبه 24 مهر 1396, 2:32 pm

باسلام .
کتابخانه را یک بار دیگر در سایت دیگری اپلود کردم،(در پست قبلی ان را قرار دادم).
برای دیدن عکس و .. بهتر تا زمانی که سرویس پرشین گیگ درست شود صبر کنید (معمولا هر چند مدت یک بار چنین میشود،پرشین گیگ تقریبا بهتر از اکثر سرویس ها اپلود می باشد)
باتشکر.
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

New Member
پست: 8
تاریخ عضویت: دو شنبه 20 آذر 1396, 10:27 am
سپاس‌های ارسالی: 10 بار
سپاس‌های دریافتی: 3 بار

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط HA M ID » جمعه 20 بهمن 1396, 2:06 pm

سلام
وقتتون بخیر

ممنونم ازتون بابت این کتابخونه
جهت استفاده از این کتابخونه برنامه ی تست زیر رو نوشتم ولی در LCD چیزی نشون نمیده.گویا عملیات نوشتن و خوندن درست صورت نمیگیره.
ممنون میشم راهنمایی کنید. 

کد: انتخاب همه

#include <mega2560.h>

#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD functions
#include <alcd.h>
#include <Stdlib.h>
// Declare your global variables here
#include <string.h>
// SPI functions
#include <spi.h>
#include <w25q.h>
unsigned char ch_totalrain[16];
unsigned char saving_flash[256]="777777";
unsigned char flash_read[256];


void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Port E initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRE=(0<<DDE7) | (0<<DDE6) | (0<<DDE5) | (0<<DDE4) | (0<<DDE3) | (0<<DDE2) | (0<<DDE1) | (0<<DDE0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTE=(0<<PORTE7) | (0<<PORTE6) | (0<<PORTE5) | (0<<PORTE4) | (0<<PORTE3) | (0<<PORTE2) | (0<<PORTE1) | (0<<PORTE0);

// Port F initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRF=(0<<DDF7) | (0<<DDF6) | (0<<DDF5) | (0<<DDF4) | (0<<DDF3) | (0<<DDF2) | (0<<DDF1) | (0<<DDF0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTF=(0<<PORTF7) | (0<<PORTF6) | (0<<PORTF5) | (0<<PORTF4) | (0<<PORTF3) | (0<<PORTF2) | (0<<PORTF1) | (0<<PORTF0);

// Port G initialization
// Function: Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRG=(0<<DDG5) | (0<<DDG4) | (0<<DDG3) | (0<<DDG2) | (0<<DDG1) | (0<<DDG0);
// State: Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTG=(0<<PORTG5) | (0<<PORTG4) | (0<<PORTG3) | (0<<PORTG2) | (0<<PORTG1) | (0<<PORTG0);

// Port H initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRH=(0<<DDH7) | (0<<DDH6) | (0<<DDH5) | (0<<DDH4) | (0<<DDH3) | (0<<DDH2) | (0<<DDH1) | (0<<DDH0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTH=(0<<PORTH7) | (0<<PORTH6) | (0<<PORTH5) | (0<<PORTH4) | (0<<PORTH3) | (0<<PORTH2) | (0<<PORTH1) | (0<<PORTH0);

// Port J initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRJ=(0<<DDJ7) | (0<<DDJ6) | (0<<DDJ5) | (0<<DDJ4) | (0<<DDJ3) | (0<<DDJ2) | (0<<DDJ1) | (0<<DDJ0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTJ=(0<<PORTJ7) | (0<<PORTJ6) | (0<<PORTJ5) | (0<<PORTJ4) | (0<<PORTJ3) | (0<<PORTJ2) | (0<<PORTJ1) | (0<<PORTJ0);

// Port K initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRK=(0<<DDK7) | (0<<DDK6) | (0<<DDK5) | (0<<DDK4) | (0<<DDK3) | (0<<DDK2) | (0<<DDK1) | (0<<DDK0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTK=(0<<PORTK7) | (0<<PORTK6) | (0<<PORTK5) | (0<<PORTK4) | (0<<PORTK3) | (0<<PORTK2) | (0<<PORTK1) | (0<<PORTK0);

// Port L initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRL=(0<<DDL7) | (0<<DDL6) | (0<<DDL5) | (0<<DDL4) | (0<<DDL3) | (0<<DDL2) | (0<<DDL1) | (0<<DDL0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTL=(0<<PORTL7) | (0<<PORTL6) | (0<<PORTL5) | (0<<PORTL4) | (0<<PORTL3) | (0<<PORTL2) | (0<<PORTL1) | (0<<PORTL0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// OC1C output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<COM1C1) | (0<<COM1C0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer3 Stopped
// Mode: Normal top=0xFFFF
// OC3A output: Disconnected
// OC3B output: Disconnected
// OC3C output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=(0<<COM3A1) | (0<<COM3A0) | (0<<COM3B1) | (0<<COM3B0) | (0<<COM3C1) | (0<<COM3C0) | (0<<WGM31) | (0<<WGM30);
TCCR3B=(0<<ICNC3) | (0<<ICES3) | (0<<WGM33) | (0<<WGM32) | (0<<CS32) | (0<<CS31) | (0<<CS30);
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// Timer/Counter 4 initialization
// Clock source: System Clock
// Clock value: Timer4 Stopped
// Mode: Normal top=0xFFFF
// OC4A output: Disconnected
// OC4B output: Disconnected
// OC4C output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer4 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR4A=(0<<COM4A1) | (0<<COM4A0) | (0<<COM4B1) | (0<<COM4B0) | (0<<COM4C1) | (0<<COM4C0) | (0<<WGM41) | (0<<WGM40);
TCCR4B=(0<<ICNC4) | (0<<ICES4) | (0<<WGM43) | (0<<WGM42) | (0<<CS42) | (0<<CS41) | (0<<CS40);
TCNT4H=0x00;
TCNT4L=0x00;
ICR4H=0x00;
ICR4L=0x00;
OCR4AH=0x00;
OCR4AL=0x00;
OCR4BH=0x00;
OCR4BL=0x00;
OCR4CH=0x00;
OCR4CL=0x00;

// Timer/Counter 5 initialization
// Clock source: System Clock
// Clock value: Timer5 Stopped
// Mode: Normal top=0xFFFF
// OC5A output: Disconnected
// OC5B output: Disconnected
// OC5C output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer5 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR5A=(0<<COM5A1) | (0<<COM5A0) | (0<<COM5B1) | (0<<COM5B0) | (0<<COM5C1) | (0<<COM5C0) | (0<<WGM51) | (0<<WGM50);
TCCR5B=(0<<ICNC5) | (0<<ICES5) | (0<<WGM53) | (0<<WGM52) | (0<<CS52) | (0<<CS51) | (0<<CS50);
TCNT5H=0x00;
TCNT5L=0x00;
ICR5H=0x00;
ICR5L=0x00;
OCR5AH=0x00;
OCR5AL=0x00;
OCR5BH=0x00;
OCR5BL=0x00;
OCR5CH=0x00;
OCR5CL=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1C) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);

// Timer/Counter 3 Interrupt(s) initialization
TIMSK3=(0<<ICIE3) | (0<<OCIE3C) | (0<<OCIE3B) | (0<<OCIE3A) | (0<<TOIE3);

// Timer/Counter 4 Interrupt(s) initialization
TIMSK4=(0<<ICIE4) | (0<<OCIE4C) | (0<<OCIE4B) | (0<<OCIE4A) | (0<<TOIE4);

// Timer/Counter 5 Interrupt(s) initialization
TIMSK5=(0<<ICIE5) | (0<<OCIE5C) | (0<<OCIE5B) | (0<<OCIE5A) | (0<<TOIE5);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=(0<<ISC31) | (0<<ISC30) | (0<<ISC21) | (0<<ISC20) | (0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EICRB=(0<<ISC71) | (0<<ISC70) | (0<<ISC61) | (0<<ISC60) | (0<<ISC51) | (0<<ISC50) | (0<<ISC41) | (0<<ISC40);
EIMSK=(0<<INT7) | (0<<INT6) | (0<<INT5) | (0<<INT4) | (0<<INT3) | (0<<INT2) | (0<<INT1) | (0<<INT0);
// PCINT0 interrupt: Off
// PCINT1 interrupt: Off
// PCINT2 interrupt: Off
// PCINT3 interrupt: Off
// PCINT4 interrupt: Off
// PCINT5 interrupt: Off
// PCINT6 interrupt: Off
// PCINT7 interrupt: Off
// PCINT8 interrupt: Off
// PCINT9 interrupt: Off
// PCINT10 interrupt: Off
// PCINT11 interrupt: Off
// PCINT12 interrupt: Off
// PCINT13 interrupt: Off
// PCINT14 interrupt: Off
// PCINT15 interrupt: Off
// PCINT16 interrupt: Off
// PCINT17 interrupt: Off
// PCINT18 interrupt: Off
// PCINT19 interrupt: Off
// PCINT20 interrupt: Off
// PCINT21 interrupt: Off
// PCINT22 interrupt: Off
// PCINT23 interrupt: Off
PCMSK0=(0<<PCINT7) | (0<<PCINT6) | (0<<PCINT5) | (0<<PCINT4) | (0<<PCINT3) | (0<<PCINT2) | (0<<PCINT1) | (0<<PCINT0);
PCMSK1=(0<<PCINT15) | (0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (0<<PCINT8);
PCMSK2=(0<<PCINT23) | (0<<PCINT22) | (0<<PCINT21) | (0<<PCINT20) | (0<<PCINT19) | (0<<PCINT18) | (0<<PCINT17) | (0<<PCINT16);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);

// USART0 initialization
// USART0 disabled
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);

// USART1 initialization
// USART1 disabled
UCSR1B=(0<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1) | (0<<RXEN1) | (0<<TXEN1) | (0<<UCSZ12) | (0<<RXB81) | (0<<TXB81);

// USART2 initialization
// USART2 disabled
UCSR2B=(0<<RXCIE2) | (0<<TXCIE2) | (0<<UDRIE2) | (0<<RXEN2) | (0<<TXEN2) | (0<<UCSZ22) | (0<<RXB82) | (0<<TXB82);

// USART3 initialization
// USART3 disabled
UCSR3B=(0<<RXCIE3) | (0<<TXCIE3) | (0<<UDRIE3) | (0<<RXEN3) | (0<<TXEN3) | (0<<UCSZ32) | (0<<RXB83) | (0<<TXB83);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 500.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (1<<SPR0);
SPSR=(0<<SPI2X);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTA Bit 0
// RD - PORTA Bit 1
// EN - PORTA Bit 2
// D4 - PORTA Bit 3
// D5 - PORTA Bit 4
// D6 - PORTA Bit 5
// D7 - PORTA Bit 6
// Characters/line: 16
lcd_init(16);
  FLASH_CS_LOW();
  W25Q_Write();
  W25Q_Chip_Erase(); 
while (1)
    {
       W25Q_Write();
   
      W25Q_Page_Program(0,saving_flash);

      W25Q_Read_Data(0,flash_read);
   
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("save data:");
    lcd_puts(flash_read);
    delay_ms(100);
    }
}
 


دز lcd مینویسه:  data: 
و دیگه چیزی نمینویسه.در حالی که باید بنویسه
save data:777777

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط sinaset » جمعه 20 بهمن 1396, 2:31 pm

سلام بر شما.
خواهش میکنم.

قبل از چاپ متن،از دستور sprintf و بریزد تویه رشته،بعد رشته رو چاپ کنید. ببینید بازهم جواب نمیدهد!

ضمن اینکه بهتراست قبل از شروع، ابتدا ببینید بررسی کنید ببینید،ایسی ارتباطش صحیح می باشد یا که خیر،به کمک دستور زیر
W25Q_Manufacturer_Device_ID
متغیر اول که درون این تابع گذاشته میشود،نام کارخانه درونش نوشته میشود و متغیر دوم،ایدی ..
unsigned char Read_1,Read_2
[unsigned char str[16
(W25Q_Manufacturer_Device_ID(&Read_1,&Read_2
سپس
(sprintf(str,"MAINFUCT:0x%x DEVICE:0x%x",Read_1,Read_2

;(lcd_puts(str

ببینید ایدی ها درست و .. داده میشود.
اگر داده نشد،ارتباطات و سخت افزار خودتون را چک کنید.
باتشکر.
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

New Member
پست: 8
تاریخ عضویت: دو شنبه 20 آذر 1396, 10:27 am
سپاس‌های ارسالی: 10 بار
سپاس‌های دریافتی: 3 بار

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط HA M ID » جمعه 20 بهمن 1396, 6:24 pm

بله آی دی رو به درستی نشان میده و زمانی که از printf استفاده می کنم در lcd هم نمایش میده چیزی رو
ولی اونی نیست که من در خط قبلش ذخیره کردم.گویا خوندن از فلش مشکل نداره و نوشتن در فلش مشکل داره
واقعا نیاز دارم و نمی دونم چرا به درستی کار نمی کنه!!!؟؟؟
لطف می کنید درباره ی این دوخط هم توضیح بدین؟؟ //#define FLASH_CS_HIGH() (PORTB|=(1<<4)) //وضعيت غير فعال سازي براي ايسي
//#define FLASH_CS_LOW() ((PORTB &=~(1<<4))) // وضعيت فعال سازي براي  

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط sinaset » جمعه 20 بهمن 1396, 7:38 pm

سلام .

اون دو دستوری که اشاره کردید،مربوط به فعال سازی و غیر فعال سازی ایسی می باشد. * نیازی نیست شما از ان استفاده کنید،جاهایی که لازم بوده استفاده شده،مگر اینکه قصد داشته باشید کار بخصوصی انجام بدید.

کتابخانه خودتون رو اینطور تعریف کنید "include "w25q.h

از دستور sprintf استفاده کردید؟! مستقیم اطلاعات رو نخونید اول به کمک sprintf تبدیلش کنید به رشته %s اگر جواب نگرفتید برای اینکه بفهمید اصلا دستوری در حافظه ذخیره شده یا خیر

یکی از متغیر ها [saving_flash[0 (به عنوان مثال 0 ) رو به کمک دستور sprintf به صورت هگزا دسیمال بگیرید %xو چاپ کنید. ببینید چه خروجی به شما داده میشود.
ضمن اینکه نیازی نیست از سه دستور زیر استفاده کنید و از برنامه خود حذفشون کنید (منظور در برنامه که نوشتید،نه از کتاب خانه اصلی برنامه)
FLASH_CS_LOW();
W25Q_Write();
W25Q_Chip_Erase();
این رو جایگزین کنید
W25Q_BlockErase_64(0);

** دستور W25Q_Chip_Erase(); نباید زیاد استفاده شود!

امتحان کنید و در صورت امکان نتیجه رو باجزییات بیشتر اعلام کنید.
باتشکر.
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

New Member
پست: 8
تاریخ عضویت: دو شنبه 20 آذر 1396, 10:27 am
سپاس‌های ارسالی: 10 بار
سپاس‌های دریافتی: 3 بار

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط HA M ID » جمعه 20 بهمن 1396, 8:30 pm

نکاتی که امر فرمودید رو انجام دادم.
خروجی دستور زیر

کد: انتخاب همه

lcd_clear();
    lcd_gotoxy(0,0);
      sprintf(str,"saving_flash: %x",saving_flash[0]);
    lcd_puts(str);
    delay_ms(1000);


عدد 37 هست که برای مثال وقتی saving_flash[256]="777777" رو به saving_flash[256]="477777" تغییر میدم خروجی میشه 34

خروجی دستور زیر هم

کد: انتخاب همه

    lcd_clear();
    lcd_gotoxy(0,0);
      sprintf(str,"flash_read : %x",flash_read[0]);
    lcd_puts(str);
    delay_ms(1000);   


عدد صفر هست یعنی flash_read : 0

خروجی دستور زیر هم

کد: انتخاب همه

lcd_clear();
    lcd_gotoxy(0,0);
      sprintf(str,"flash_read : %s",flash_read[0]);
    lcd_puts(str);
    delay_ms(1000);

علامتی شبیه به اهم هست.

Colonel II
Colonel II
نمایه کاربر
پست: 7010
تاریخ عضویت: سه شنبه 26 آذر 1387, 4:20 pm
سپاس‌های ارسالی: 9183 بار
سپاس‌های دریافتی: 21042 بار
تماس:

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط sinaset » جمعه 20 بهمن 1396, 9:06 pm

سلام بر شما

خروجی شما کاملا صحیح است!

37 به اسکی میشود عدد 7

شما بجایی %s این %c رو جاگزین کنید انشالله مشکلتان حل خواهد شد.

---
همچنین می توانید،این رو هم در پایان امتحان کنید

کد: انتخاب همه

sprintf(str,"flash_read : %s",flash_read); 


باتشکر.
"قرآن"(کلام خدا) ...راه سعادت و خوشبختی.

New Member
پست: 8
تاریخ عضویت: دو شنبه 20 آذر 1396, 10:27 am
سپاس‌های ارسالی: 10 بار
سپاس‌های دریافتی: 3 بار

Re: آموزش راه اندازی ایسی حافظه فلش W25Q(معرفی کتابخانه)

پست توسط HA M ID » جمعه 20 بهمن 1396, 9:40 pm

سلام و بسیار ممنونم بابت پاسخگوییتون
saving_flash درواقع آرایه ایست که ذخیره میشه در فلش
آرایه ایی که از فلش می خونیم flash_read هست
همانظور که در بالا اشاره کردم اصلا خروجی درستی نمیده.
یعنی write یا read در فلش مشکل ذارن که احتمال زیاد write مشکل داره.

بسیار سپاسگذارم از وقتی که برای بنده میذارید
آخرین ويرايش توسط 1 on HA M ID, ويرايش شده در 0.

ارسال پست

بازگشت به “آموزش و مثال‌ها AVR”