نوشته اصلی توسط
kavir
سلام
من خیلی وقت پیش همین سوال رو از دوست خوبم آقای منصوری پرسیدم که به صورت نقل قول براتون می ذارم
در ضمن استفاده از پروگرامر ایشان به صورت تجاری ممنوع است
بسمه تعالی
سلام دوست عزیز
فکر می کنم با مثال قبلی که برات فرستادم مشکلت با پروژه حل بشه ولی برای اینکه انتقال اطلاعات با سرعت بالا و استفاده از بافر را خواسته بودی این توضیحات را می نویسم :
اول اینکه هیچ پروژه ای به یادم نیومد که از بافر استفاده شده باشه و حضور ذهن داشته باشم کامل توضیحش بدم لذا قسمتی از برنامه کامپیوتری و برنامه میکروی اون پروگرمر را برات توضیح میدم . امیدوارم با این توضیحات بتونی برای هر پروژه دیگری که به ذهنت رسید این توابع را بگونه ای تغییر دهی که کارت راه بیفته .
اول برنامه کامپیوتری :
static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
این تابع برای خواندن یک پیج از روی حافظه میکروست (هم فلش و هم رام){
int n;
unsigned char cmd[4];آدرس شروع پیچ را با این متغیر به میکرو می فرستیم
int address = 0;
int wbytes = n_bytes;
int blocksize;مشخص کننده طول بلوک اطلاعاتی است که باید یکجا از میکرو ارسال شود.
unsigned char * buffer = m->buf;این بافر همون بافری است که حاوی اطلاعاتی است که از روی میکرو خوانده می شود
int function;
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_READFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_READEEPROM;
} else {
return -2;
این چند خط بالا برای تشخیص اینه که می خواهیم از روی رام بخوانیم یا از روی فلش }
while (wbytes) {
if (wbytes > USBASP_READBLOCKSIZE) {
blocksize = USBASP_READBLOCKSIZE;
wbytes -= USBASP_READBLOCKSIZE;
} else {
blocksize = wbytes;
wbytes = 0;
}
اینجا آدرس را در دوبایت به میکرو میفرستیم
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
حال که تمامی پارامتر های تابع ارسال تکمیل شده ارسال می کنیم .
n = usbasp_transmit(1, function, cmd, buffer, blocksize);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong reading bytes %x\n",
progname, n);
exit(1);
}
مقدار بافر و آدرس را با توجه به تعداد بایتهای بلوک آپدیت می کنیم
buffer += blocksize;
address += blocksize;
این تابع برای نمایش نواراست(Progress bar)
report_progress (address, n_bytes, NULL);
}
return n_bytes;
}
این تابع برای نوشتن یک پیج روی میکرو است
static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int n;
unsigned char cmd[4];این متغیر برای ارسال آدرس و اندازه پیج استفاده می شود
int address = 0;
int wbytes = n_bytes;
int blocksize;
unsigned char * buffer = m->buf;
unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
int function;
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_WRITEFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_WRITEEEPROM;
} else {
return -2;
}
while (wbytes) {
if (wbytes > USBASP_WRITEBLOCKSIZE) {
blocksize = USBASP_WRITEBLOCKSIZE;
wbytes -= USBASP_WRITEBLOCKSIZE;
} else {
blocksize = wbytes;
wbytes = 0;
blockflags |= USBASP_BLOCKFLAG_LAST;
}
cmd[0] = address & 0xFF;بایت پایین آدرس
cmd[1] = address >> 8;بایت بالای آدرس
cmd[2] = page_size & 0xFF;بایت پایین اندازه پیج
cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4);
blockflags = 0;
ارسال با تابع مخصوصش
n = usbasp_transmit(0, function, cmd, buffer, blocksize);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong count at writing %x\n",
progname, n);
exit(1);
}
اصلاح بافر و آدرس برای ارسال بلوک بعدی
buffer += blocksize;
address += blocksize;
report_progress (address, n_bytes, NULL);
}
return n_bytes;
}
و حالا برنامه میکرو :
uchar usbFunctionRead(uchar *data, uchar len}(این تابع برای خواندن اطلاعات فلش یا رام و ارسال به یو اس بی است
uchar i;
/* check if programmer is in correct read state */
if ((prog_state != PROG_STATE_READFLASH) &&
(prog_state != PROG_STATE_READEEPROM)) {
return 0xff;
}
در اینجا بافری را که باید به کامپیوتر بفرستیم پر می کنیم
/* fill packet */
for (i = 0; i < len; i++) {
if (prog_state == PROG_STATE_READFLASH) {
data[i] = ispReadFlash(prog_address);
} else {
data[i] = ispReadEEPROM(prog_address);
}
prog_address++;
}
/* last packet? */
if (len < 8) {
prog_state = PROG_STATE_IDLE;
}
طول بافر پر شده را برمی گردانیم
return len;
}
این تابع برای نوشتن یک پیج روی رام یا فلش میکروست
uchar usbFunctionWrite(uchar *data, uchar len) {
uchar i;
/* check if programmer is in correct write state */
if ((prog_state != PROG_STATE_WRITEFLASH) &&
(prog_state != PROG_STATE_WRITEEEPROM)) {
return 0xff;
}
for (i = 0; i < len; i++) {
if (prog_state == PROG_STATE_WRITEFLASH) {
/* Flash */
if (prog_pagesize == 0) {
/* not paged */
ispWriteFlash(prog_address, data[i], 1);
} else {
/* paged */
ispWriteFlash(prog_address, data[i], 0);
prog_pagecounter --;
if (prog_pagecounter == 0) {
ispFlushPage(prog_address, data[i]);
prog_pagecounter = prog_pagesize;
}
}
} else {
/* EEPROM */
ispWriteEEPROM(prog_address, data[i]);
}
prog_nbytes --;
if (prog_nbytes == 0) {
prog_state = PROG_STATE_IDLE;
if ((prog_blockflags & PROG_BLOCKFLAG_LAST) &&
(prog_pagecounter != prog_pagesize)) {
/* last block and page flush pending, so flush it now */
ispFlushPage(prog_address, data[i]);
}
}
prog_address ++;
}
return 0;