我在用扇区读写的时候每次执行写操作的时候好像要花很长时间,这样的话就会有数据丢失,程序如下: SIGNAL(SIG_INTERRUPT2) { UINT8 i; WriteToReg_ADC(0X38); CS_0; FILE_DATA_BUF[h]=Read_Byte_SPI(); FILE_DATA_BUF[h+1]=Read_Byte_SPI(); CS_1; CS_A; FILE_DATA_BUF[h+2]=Read_Byte_SPI(); FILE_DATA_BUF[h+3]=Read_Byte_SPI(); CS_B; h+=4; if(h==512) { h=0; mCmdParam.Write.mSectorCount=1; i = CH375FileWrite( ); /* 向文件写入数据 */ mStopIfError( i ); mCmdParam.Write.mSectorCount=0; i = CH375FileWrite( ); /* 向文件写入数据 */ mStopIfError( i ); } }
这是用labview回放的数据。
请问哪个例子是用双缓冲写的?
请问怎么应用CH375FileWriteX这个函数,能否告知一个用双缓冲写的例子?
375没有双缓冲的例子,你可以使用374芯片,这个芯片有128字节的缓冲区,可以用来做双缓冲使用,速度比375要快
那么我应该怎样应用CH375FileWriteX()这个函数呢?怎样将数据先放到(例如0x40位起始地址)的缓冲区呢,有没有用CH375FileWriteX()写的例子呢?
使用双缓冲区交替读写,那么不要定义FILE_DATA_BUF_LEN,而是在参数中指定缓冲区起址,用CH375FileReadX代替CH375FileRead,用CH375FileWriteX代替CH375FileWrite。 在调用之前指定缓冲区mCmdParam.WriteX.mDataBuffer的位子。CH375EVT\PUB\MCS51C\FILELIB4\EXAM1中的注释掉的地方有使用说明。
那就是说FILE_DATA_BUF在这里就没有用了是吗?那我采集的数据怎样放到缓冲区呢?
FILE_DATA_BUF在这里就没有用了
将你的数据缓冲区的地址赋给mCmdParam.WriteX.mDataBuffer
我可不可以这样: data[i]=get_adc(); mCmdParam.WriteX.mDataBuffer=&data[0];
我用了CH375FileWriteX之后,为什么会有下面的错误啊? libCH375HFD.A(CH375SEC.o)(.text+0x166): In function `CH375ReadBlock': : undefined reference to `xWriteToExtBuf' libCH375HFD.A(CH375SEC.o)(.text+0x1be): In function `CH375ReadBlock': : undefined reference to `xWriteToExtBuf' libCH375HFD.A(CH375SEC.o)(.text+0x2d4): In function `CH375WriteBlock': : undefined reference to `xReadFromExtBuf' libCH375HFD.A(CH375SEC.o)(.text+0x32c): In function `CH375WriteBlock': : undefined reference to `xReadFromExtBuf' make.exe: *** [ch375.elf] Error 1
象你这样功能的程序对时间要求比较高的不适合用这种结构,需要改成实时系统结构。即你不可能等待优盘写完再继续处理,应该写入命令和64字节数据后就继续去采集数据,有中断后继续传输下一个64字节。
to Skunk { M }: 你有qq吗?想和你探讨一下!
你可以将你的程序帖出来看下,这个更象程序的问题
/* 2004.06.05 **************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB Host File Interface for CH375 ** ** TC2.0@PC, ICCAVR_6.31@AVR ** **************************************** */ /* CH375 主机文件系统接口 */ /* 支持: FAT12/FAT16/FAT32 */
/* AVR单片机C语言的U盘文件读写示例程序 */ /* 该程序将U盘中的/C51/CH375HFT.C文件中的小写字母转成大写字母后, 写到新建的文件NEWFILE.TXT中, 如果找不到原文件CH375HFT.C, 那么该程序将显示C51子目录下所有以CH375开头的文件名, 并新建NEWFILE.TXT文件并写入提示信息, 如果找不到C51子目录, 那么该程序将显示根目录下的所有文件名, 并新建NEWFILE.TXT文件并写入提示信息 */ /* CH375的INT#引脚采用查询方式处理, 数据复制方式为"内部复制", 本程序适用于ATmega128单片机, 串口0输出监控信息,9600bps */
/* ICCAVR -v -Wp -I\ICC\INCLUDE -Wf -Mavr_enhanced -Wl -L\ICC\LIB -m -bfunc_lit:0x8C.0x20000 -bdata:0x0100.0x0FFF -dram_end:0x0FFF -dhwstk_size:40 -ucrtatmega.o CH375HFB.C CH375HFB.A */
#include #include #include #include #include #include #define uchar unsigned char #define uint unsigned int #define ulonglong unsigned long long #define has_volatile 1 #if has_volatile volatile unsigned int h=0; //全局变量,会在中断服务程序中被修改,须加volatile限定 #else unsigned int h=0; //全局变量. #endif
/* 以下定义的详细说明请看CH375HF9.H文件 */ #define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */
/* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */ #define FILE_DATA_BUF_LEN 0x0200 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */ /* 如果准备使用双缓冲区交替读写,那么不要定义FILE_DATA_BUF_LEN,而是在参数中指定缓冲区起址,用CH375FileReadX代替CH375FileRead,用CH375FileWriteX代替CH375FileWrite */
#define CH375_INT_WIRE ( PIND & 0x04 ) /* PINB.4, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未调用CH375FileEnumer程序故禁止以节约代码 */ #define NO_DEFAULT_CH375_F_QUERY 1 /* 未调用CH375FileQuery程序故禁止以节约代码 */
#include "CH375HFB.H" #define CS_1 (PORTB|= 0X08) #define CS_0 (PORTB&= 0XF7)
/* 有些AVR单片机提供开放系统总线,那么直接将CH375挂在其系统总线上,以8位I/O方式进行读写 */ /* 虽然Atmega128提供系统总线,不过本例假定不开放系统总线,所以用I/O引脚模拟产生CH375的并口读写时序 */ /* 本例中的硬件连接方式如下(实际应用电路可以参照修改下述3个并口读写子程序) */ /* 单片机的引脚 CH375芯片的引脚 PIND.2 INT# PORTD.7 A0 PORTD.6 CS# PORTD.5 WR# PORTD.4 RD# PORTA(8位端口) D7-D0 */
void mDelay1uS(void ) /* 至少延时1uS,根据单片机主频调整 */ { UINT8 i; for ( i = 5; i != 0; i -- ); }
void CH375_PORT_INIT(void ) /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */ { DDRA = 0x00; /* 设置8位并口为输入 */ PORTD = 0x70; /* 设置CS,WR,RD默认为高电平 */ DDRD = 0xF0; /* 设置CS,WR,RD,A0为输出,设置INT#为输入 */ }
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */ { mDelay1uS( ); mDelay1uS( ); /* 至少延时1uS */ /* *(volatile unsigned char *)CH375_CMD_PORT_ADDR = mCmd; 通过并口直接读写CH375而非普通I/O模拟 */ PORTD |= 0x80; /* 输出A0=1 */ PORTA = mCmd; /* 向CH375的并口输出数据 */ DDRA = 0xFF; /* 并口D0-D7输出 */ PORTD &= 0x9F; /* 输出有效写控制信号, 写CH375芯片的命令端口, A0=1; CS=0; WR=0; RD=1; */ DDRA = 0xFF; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ PORTD |= 0xF0; /* 输出无效的控制信号, 完成操作CH375芯片, A0=1; CS=1; WR=1; RD=1; */ DDRA = 0x00; /* 禁止数据输出 */ PORTD &= 0x7F; /* 输出A0=0; 可选操作 */ mDelay1uS( ); mDelay1uS( ); /* 至少延时2uS */ }
void xWriteCH375Data( UINT8 mData ) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */ { /* *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData; 通过并口直接读写CH375而非普通I/O模拟 */ PORTA = mData; /* 向CH375的并口输出数据 */ DDRA = 0xFF; /* 并口D0-D7输出 */ PORTD &= 0x1F; /* 输出有效写控制信号, 写CH375芯片的数据端口, A0=0; CS=0; WR=0; RD=1; */ DDRA = 0xFF; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ PORTD |= 0x70; /* 输出无效的控制信号, 完成操作CH375芯片, A0=0; CS=1; WR=1; RD=1; */ DDRA = 0x00; /* 禁止数据输出 */ mDelay1uS( ); /* 至少延时1.2uS */ }
UINT8 xReadCH375Data( void ) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */ { UINT8 mData; /* mData = *(volatile unsigned char *)CH375_DAT_PORT_ADDR; 通过并口直接读写CH375而非普通I/O模拟 */ mDelay1uS( ); /* 至少延时1.2uS */ DDRA = 0x00; /* 数据输入 */ PORTD &= 0x2F; /* 输出有效读控制信号, 读CH375芯片的数据端口, A0=0; CS=0; WR=1; RD=0; */ DDRA = 0x00; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */ mData = PINA; /* 从CH375的并口PA输入数据 */ PORTD |= 0x70; /* 输出无效的控制信号, 完成操作CH375芯片, A0=0; CS=1; WR=1; RD=1; */ return( mData ); }
/* 在P0.2连接一个LED用于监控演示程序的进度,低电平LED亮 */ //#define LED_OUT_INIT( ) { PORTB |= 0x80; DDRB |= 0x80; } /* PORTB.7 高电平为输出方向 */ //#define LED_OUT_ACT( ) { PORTB &= 0x7F; } /* PORTB.7 低电平驱动LED显示 */ //#define LED_OUT_INACT( ) { PORTB |= 0x80; } /* PORTB.7 低电平驱动LED显示 */
/* 延时指定毫秒时间,根据单片机主频调整,不精确 */ void mDelaymS( UINT8 ms ) { UINT16 i; while ( ms -- ) for ( i = 2600; i != 0; i -- ); }
/* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ while ( 1 ) { //LED_OUT_ACT( ); /* LED闪烁 */ //mDelaymS( 100 ); //LED_OUT_INACT( ); //mDelaymS( 100 ); } }
/* 为printf和getkey输入输出初始化串口 */ //extern int _textmode; //void mInitSTDIO( ) //{ // UBRR0H = 0; // UBRR0L = 103; /* 9600bps@16MHz */ // UCSR0B = 0x18; /* BIT(RXEN) | BIT(TXEN); */ // UCSR0C = 0x06; /* BIT(UCSZ1) | BIT(UCSZ0); */ // _textmode = 1; //} //**********************短延时程序50us**************************// void delay50us(uint t) { uint j; for(;t>0;t--) for(j=0;j<70;j++) ; } //**********************短延时程序5us**************************// void delay5us(uint t) { uint j; for(;t>0;t--) for(j=0;j<7;j++) ; }
void spi_init(void) { DDRB=0XBB; //0b10111011; //PB3\PB6输入 PORTB=0X67;//0b01100111; //MISO输入加上拉电阻 SPCR=0X5F;//SPI 设置//SPCR = (1< SPSR = 0X00; //setup SPI,主机倍频 //CS_0; //使能SPI器件 }
//******************SPI写寄存器函数 8BIT*******************************// void WriteToReg_ADC(uint byteword) { CS_0;//PORTB&= 0XFB; //使能SPI器件 //SPE_1; SPDR=byteword; //发送数据 while(!(SPSR & (1< CS_1;//PORTB|= 0X04; //禁止SPI器件 delay5us(10); } //******************SPI读函数 8BIT*******************************// unsigned char Read_Byte_SPI(void) { SPDR = 0Xff; //发送数据,给AD7705提供脉冲 while (!(SPSR &(1< return SPDR; } //******************SPI读数据寄存器函数 16BIT****************************// uint Read_ADC16BitValue(void) { uchar temp1=0; uint temp=0; CS_0;//PORTB&= 0XFB; //使能SPI器件 temp=Read_Byte_SPI(); temp=temp<<8; temp1=Read_Byte_SPI(); temp=temp|temp1; CS_1;//PORTB|= 0X04; //禁止SPI器件 return temp; } //**************************AD初始化*************************//
在主函数里面只有许多器件的初始化和打开文件,然后进入中断。