⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 PIC MMC and FAT Sample code
💻 C
字号:
// --- Coding Preprocessor Directives ---
#CASE

// --- Device Initializations ---
#INCLUDE "generic.h"
#DEFINE STARTUP_DELAY 500
//#PRIORITY TIMER2,TIMER1,RTCC
#IF DEFINED(__PCM__)
// --- Device Initializations ---
// Device Specifications - PIC16F877
// Program memory: 8192x14  Data RAM: 367  Stack: 8
// I/O: 33   Analog Pins: 8
// Data EEPROM: 256
// FUSES: Oscillation Selection - LP,XT,HS,RC
//				Watchdog Timer - NOWDT,WDT
//				Power-Up Timer - NOPUT,PUT
//				Code Protection - PROTECT,PROTECT_5%,PROTECT_50%,NOPROTECT
//				Brown-Out Reset - NOBROWNOUT,BROWNOUT
//				Low-Voltage Programming - LVP,NOLVP
//				Data EEPROM Memory Code Protection - CPD,NOCPD
//				Flash Program Write - WRT,NOWRT
#DEVICE PIC16F877 ADC=10 *=16
#INCLUDE "16F877.h"
#FUSES HS, NOWDT, PUT, NOBROWNOUT, NOLVP, NOPROTECT
#USE DELAY (CLOCK=20000000)
#USE RS232 (BAUD=115200, XMIT=PIN_C6, RCV=PIN_C7)

#ELIF DEFINED(__PCH__)
//	Device Specifications - PIC18F458
// Program memory: 16384x16  Data RAM: 1536  Stack: 31
// I/O: 33   Analog Pins: 8
// Data EEPROM: 256
// FUSES: Oscillation Selection - LP,XT,HS,RC,EC,EC_IO,H4,RC_IO
//				Oscillator Switch Enable - NOOSCSEN,OSCSEN
//				Power Up Timer - PUT,NOPUT
//				Brown Out Detect - NOBROWNOUT,BROWNOUT
//				Brown Out Voltage - BORV20,BORV27,BORV42,BORV45
//				Watchdog Timer - WDT,NOWDT
//				Watchdog Postscaler - WDT1,WDT2,WDT4,WDT8,WDT16,WDT32,WDT64,WDT128
//				Stack Overflow Reset - NOSTVREN,STVREN
//				Low Voltage Program - NOLVP,LVP
//				Code Protect - PROTECT,NOPROTECT
//				Data EE Protect - CPD,NOCPD
//				Code Protect Boot - CPB,NOCPB
//				Table Write Protect - WRT,NOWRT
//				Data EE Write Protect - NOWRTD,WRTD
//				Table Write Protect Boot - WRTB,NOWRTB
//				Config Write Protect - WRTC,NOWRTC
//				Table Read Protect - EBTR,NOEBTR
//				Table Read Protect Boot - EBTRB,NOEBTRB
//				Debugging - NODEBUG,DEBUG
#DEVICE PIC18F458 ADC=10 *=16
#INCLUDE "18F458.h"
#FUSES H4, NOWDT, PUT, NOBROWNOUT, NOLVP, NOPROTECT
#USE DELAY (CLOCK=40000000)
#USE RS232 (BAUD=38400, XMIT=PIN_C6, RCV=PIN_C7)

// --- Peripheral Initializations Definitions ---

// TIMER0/RTCC Initialization
// TIMER0_INTERRUPT_PERIOD = (4/TIMER0_OSC) * TIMER0_PRESCALAR * (256 - TIMER0_STARTCOUNT)
// TIMER0_OSC			:	RTCC_INTERNAL,RTCC_EXT_L_TO_H,RTCC_EXT_H_TO_L
// TIMER0_PRESCALAR	:	RTCC_DIV_2,RTCC_DIV_4,RTCC_DIV_8,RTCC_DIV_16,RTCC_DIV_32,RTCC_DIV_64,RTCC_DIV_128,RTCC_DIV_256
// TIMER0_STARTCOUNT	:	0-255
#DEFINE	TIMER0_ENABLED		FALSE
#DEFINE	TIMER0_OSC			RTCC_INTERNAL		// 400ns interrupt
#DEFINE	TIMER0_PRESCALAR	RTCC_DIV_2		
#DEFINE	TIMER0_STARTCOUNT	255

// TIMER1 Initialization
// TIMER1_INTERRUPT_PERIOD = (4/TIMER1_OSC) * TIMER1_PRESCALAR * (65536-TIMER1_STARTCOUNT)
// TIMER1_OSC			:	T1_DISABLED,T1_INTERNAL,T1_EXTERNAL,T1_EXTERNAL_SYNC
// TIMER1_PRESCALAR	:	T1_DIV_BY_1,T1_DIV_BY_2,T1_DIV_BY_4,T1_DIV_BY_8
// TIMER1_STARTCOUNT	:	0-65535
#DEFINE	TIMER1_ENABLED		FALSE
#DEFINE	TIMER1_OSC			TIMER1_INTERNAL
#DEFINE	TIMER1_PRESCALAR	T1_DIV_BY_1		
#DEFINE	TIMER1_STARTCOUNT	60536

//	TIMER2 Initialization
//	TIMER2_INTERRUPT_PERIOD = (4/OSC) * TIMER2_PRESCALAR * (TIMER2_RESETCOUNT+1) * TIMER2_POSTSCALAR
//	TIMER2_PRESCALAR	:	T2_DISABLED,T2_DIV_BY_1,T2_DIV_BY_4,T2_DIV_BY_16
//	TIMER2_RESETCOUNT	:	0-255
//	TIMER2_POSTSCALAR	: 1-16
#DEFINE	TIMER2_ENABLED		FALSE
#DEFINE	TIMER2_PRESCALAR	T2_DIV_BY_4	
#DEFINE	TIMER2_RESETCOUNT	62
#DEFINE	TIMER2_POSTSCALAR	1

// Debugging Modes
#DEFINE DEBUG_MODE			DEBUG_DIRECT

#INCLUDE "includes.h"

// Global variables
char dataFile[]="NONAME  TXT";

#IF TIMER0_ENABLED==TRUE
#INT_RTCC
TIMER0_isr() {
	set_timer0(TIMER0_STARTCOUNT);

	// TIMER0 ISR code starts here

}
#ENDIF

#IF TIMER1_ENABLED==TRUE
#INT_TIMER1
TIMER1_isr() {
	set_timer1(TIMER1_STARTCOUNT);		

	// TIMER1 ISR code starts here

}
#ENDIF

#IF TIMER2_ENABLED==TRUE
#INT_TIMER2
TIMER2_isr() {

	// TIMER2 ISR code starts here
	
}
#ENDIF

WORD addCRC(WORD crc,BYTE value) {
   crc  = (int)(crc >> 8) | (crc << 8);
   crc ^= value;
   crc ^= (int)(crc & 0xff) >> 4;
   crc ^= (crc << 8) << 4;
   crc ^= ((crc & 0xff) << 4) << 1;
	return crc;
}

#SEPARATE
void initiateFileRead() {
	int key;
	int16 i;
	BYTE data;
	BYTE packetID;
	int16 packet;
	WORD crc;
	DWORD address;
	DWORD fileSize;
	WORD cluster;
	char fileName[11];

	debug("\n\rInitiating File Read Operation ...\n\r");
	debug("\n\rSearching for \"%S\" ...",dataFile);
	for(i=0;i<512;i++) {
		cluster=fatQueryFile(i,fileName,&fileSize);
		if(!strncmp(fileName,dataFile,11))
			break;
	}
	if(i==512) {
		debug("\n\rFile not found ...\n\r");
		return;
	}
	else {
		debug("\n\r\"%S\" found in file entry %X%X of the root directory ...",fileName,make8(i,1),make8(i,0));
		fatReadDirEntry(i);
		packet=0;
		packetID=0;
		address=fatGetClusFirstByte(cluster);
		fileSize=(fileSize+127)>>7;
		debug("\n\rFirst byte begins from address %X%X%X%X.",make8(address,3),make8(address,2),make8(address,1),make8(address,0));
		debug("\n\rTransfer will require %X%X%X%X 128-byte packets ...\n\r",make8(fileSize,3),make8(fileSize,2),make8(fileSize,1),make8(fileSize,0));
	}

	while(!kbhit());
	key=getc();
	if(key=='X'||key=='x') {
		debug("\n\rFile Read Operation Aborted ...\n\r");
		return;
	}
	else if(key!=0x43) {
		debug("\n\rInvalid response ... Aborting File Read Operation ...\n\r");
		return;
	}
	
	while(fileSize--) {
		packet++;
		packetID++;
		crc=0;

		putc(ASCII_SOH);
		putc(packetID);
		putc(255-packetID);

		mmcStartSingleRead(address,128);
		for(i=0;i<128;i++) {
			data=mmcRead(0xFF);
			crc=addCRC(crc,data);
			putc(data);
		}
		mmcEndSingleRead();
		putc(make8(crc,1));
		putc(make8(crc,0));

		key=getc();
		if(key!=ASCII_ACK) {
			debug("\n\rInvalid acknowledgement ...\n\r");
			return;
		}
		address+=128;

		if(!(packet&0x000F)) {
			cluster=fatReadFAT(cluster);
			if(cluster==0xFFF8||cluster==0xFFFF)
				break;
			else  
				address=fatGetClusFirstByte(cluster);
		}
	}

	putc(ASCII_EOT);
	key=getc();
	if(key!=ASCII_ACK)
		debug("\n\rInvalid acknowledgement ...\n\r");
	else {
		debug("\n\r%LX packets transferred.",packet);
		debug("\n\rFile Download complete ...\n\n\r");
	}
}

void initiateFileWrite() {
	int16 cluster,prevCluster;
	int16 sector;
	int16 fileEntryIndex;
	int32 fileSize;
	int16 packet;
	int16 ptr;
	int16 i;
	char fileName[11];
	BYTE fileEntry[32];

	debug("\n\rInitiating File Write Operation ...\n\r");

	debug("\n\rSearching for \"%S\" ...",dataFile);
	for(i=0;i<512;i++) {
		cluster=fatQueryFile(i,fileName,&fileSize);
		sector=fatGetClusFirstSec(cluster);
		fatWriteFAT(cluster,0xFFFF);
		if(!strncmp(fileName,dataFile,11))
			break;
	}
	if(i==512) {
		debug("\n\rFile not found ...");
		cluster=fatFindEmptyCluster();
		sector=fatGetClusFirstSec(cluster);
		fatWriteFAT(cluster,0xFFFF);
		debug("\n\rNew file to be created at cluster %LX ...",cluster);
		fileEntryIndex=fatNewFileEntry();
		debug("\n\rNew file entry index is %LX ...\n\r",fileEntryIndex);
	}
	else {
		fileEntryIndex=i;
		debug("\n\r\"%S\" found in file entry %LX of the root directory ...\n\r",fileName,fileEntryIndex);
		cluster=fatReadDirEntry(i);
	}
	// Create Directory Entry
	strncpy(fileEntry,dataFile,11);	// DIR_Name
	fileEntry[11]=0x20;					// DIR_Attr
	fileEntry[12]=0x00;					// DIR_NtRes
	fileEntry[13]=0x00;					// DIR_CrtTimeTenth
	fileEntry[14]=fileEntry[15]=0x00;// DIR_CrtTime
	fileEntry[16]=fileEntry[17]=0x00;// DIR_CrtDate
	fileEntry[18]=fileEntry[19]=0x00;// DIR_LstAccDate
	fileEntry[20]=fileEntry[21]=0x00;// DIR_FstClusHI
	fileEntry[22]=fileEntry[23]=0x00;// DIR_WrtTime
	fileEntry[24]=fileEntry[25]=0x00;// DIR_WrtDate
	fileEntry[26]=make8(cluster,0);
	fileEntry[27]=make8(cluster,1);	// DIR_FstClusLO

	ptr=0;
	fileSize=0;
	packet=0;
	debug("\n\rPlease send file within 10 seconds ...");

	delay_ms(10000);
	putc(0x43);

	while(getc()!=ASCII_EOT) {
		packet++;
		getc();	// Ignore packet count
		getc();	// Ignore packet count complement

		for(i=0;i<128;i++) {
			mmcWriteBuffer[ptr]=getc();
			ptr++;
		}
		getc();	// Ignore CRC16
		getc();

		if(!(packet&0x0003)) {
			ptr=0;
			mmcStartSingleWrite(sector,FALSE);
			mmcEndSingleWrite(TRUE);
			sector++;

			if(!(packet&0x000F)) {	// Time to find new cluster
				prevCluster=cluster;
				cluster=fatFindEmptyCluster();
				sector=fatGetClusFirstSec(cluster);
				fatWriteFAT(prevCluster,cluster);
				fatWriteFAT(cluster,0xFFFF);
			}
		}
		
		putc(ASCII_ACK);
	}
	putc(ASCII_ACK);

	debug("\n\rFinalizing FAT updates ...");
	if(packet&0x0003) {
		while(ptr<512)
			mmcWriteBuffer[ptr++]=0x00;
		mmcStartSingleWrite(sector,FALSE);
		mmcEndSingleWrite(TRUE);
	}

	// Write file entry
	fileSize=(DWORD)packet*128;
	fileEntry[28]=make8(fileSize,0);	// DIR_FileSize
	fileEntry[29]=make8(fileSize,1);
	fileEntry[30]=make8(fileSize,2);
	fileEntry[31]=make8(fileSize,3);
	fatWriteDirEntry(fileEntryIndex,fileEntry);
	debug("\n\rFile upload complete.");
	debug("\n\r%LX 128-byte packets received.",packet);
	debug("\n\r%X%X%X%X bytes transferred.\n\r",fileEntry[31],fileEntry[30],fileEntry[29],fileEntry[28]);
	debug("\n\n\rNew File Entry : ");
	fatReadDirEntry(fileEntryIndex);
}

void setFileName() {
	int i;

	debug("\n\rPlease set filename (8+3 characters) ...\n\r");
	for(i=0;i<11;i++) {
		dataFile[i]=getc();
		debug("%C",dataFile[i]);
	}
	debug("\n\rFilename set to \"%S\" ...\n\r",dataFile);
}

void main() {
	// --- Variable declarations ---
	int data;

	// Peripheral Initializations
	// Timer0/RTCC Initializations
	#IF TIMER0_ENABLED==TRUE
	setup_counters(TIMER0_OSC,TIMER0_PRESCALAR);
	enable_interrupts(INT_RTCC);
	#ENDIF

	// Timer1 Initializations
	#IF TIMER1_ENABLED==TRUE
	setup_timer_1(TIMER1_OSC|TIMER1_PRESCALAR);
	enable_interrupts(INT_TIMER1);
	#ENDIF

	// Timer2 Initializations
	#IF TIMER2_ENABLED==TRUE
	setup_timer_2(TIMER2_PRESCALAR,TIMER2_RESETCOUNT,TIMER2_POSTSCALAR);
	enable_interrupts(INT_TIMER2);
	#ENDIF

	enable_interrupts(GLOBAL);
	delay_ms(STARTUP_DELAY); 

	debug("\n\r*** Running Program ***\n\n\r");
	debug("\n\rWaiting for MMC insertion ...");

	while(mmcDetect());
	debug("\n\rMMC insertion detected.\n\r");

	mmcInit();

	//mmcGetStatus();
	mmcDumpCSD();
	//mmcDumpCID();

	debug("\n\rReading First Partition Table Entry ...");
	fatReadPartitionEntry(PARTITION1);
	debug("\n\rReading Boot Sector of Partition 1 ...");
	fatReadBootSector(peStart);

	debug("\n\rEntering idle mode ...\n\n\r");
	while (TRUE) {
		if(kbhit()) {
			data=getc();
			if(data=='r'||data=='R')
				initiateFileRead();
			else if (data=='w'||data=='W')
				initiateFileWrite();
			else if (data=='X'||data=='x')
				setFileName();
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -