用FPGA在SD卡上新建一个TXT文件,并定义一个大小500的数组,并将数组里的数写入文件的时候,会出现几种如下错误然后一直不往下工作:
当把数组大小设为400,可运行成功:
AD采的数是我在前面产生的,0到99循环输入。
用FPGA在SD卡上新建一个TXT文件,并定义一个大小500的数组,并将数组里的数写入文件的时候,会出现几种如下错误然后一直不往下工作:
当把数组大小设为400,可运行成功:
AD采的数是我在前面产生的,0到99循环输入。
代码如下(可能表达方法跟论坛提供的例程不一样,但内容应该差不多):
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
#include "system.h"
#include
#include
#include
#include "sys/unistd.h"
//函数申明
void init_usb(void); //CH376初始化
void init_Udisk(void); //U盘初始化
void set_usb_mode(alt_u8 mode); //设置USB工作模式
void send_string_to_usb(alt_8 *str,alt_8 str_len); //向USB写入数据块
void write_command_to_usb(alt_u8 command); //写命令到CH376
void write_data_to_usb(alt_u8 data); //写数据到CH376
alt_u8 read_data_from_usb(void); //从CH376读出数据
void delayus(alt_u32 cnt); //短延时函数
alt_u8 ch376_intflag; //CH376中断标志位,1表示产生中断
alt_u8 ch376_status; //CH376中断状态数据
//////////////////////////////////////////////////////////////////////
//函数名:handle_usbirq_interrupts
//功 能:ch376中断函数
//输 入:无
//返 回:无
//////////////////////////////////////////////////////////////////////
static void handle_usbirq_interrupts(void* nirq_isr_context)
{
//获取中断状态并取消请求
write_command_to_usb(GET_STATUS); //发送命令
ch376_status = read_data_from_usb(); //读取当前状态
ch376_intflag = 1; //中断标志位置位
}
//////////////////////////////////////////////////////////////////////
//函数名:main
//功 能:主函数
//输 入:无
//返 回:alt_u8
//////////////////////////////////////////////////////////////////////
alt_u8 main()
{
alt_u16 ad_dis[400]; //给500的时候不行,只有小于等于400的时候程序可以运行成功
alt_u8 num1;
alt_u8 num2;
alt_u8 num3;
alt_u8 num4;
alt_u16 cnt;
cnt=0;
init_usb(); //CH376初始化
init_Udisk(); //U盘初始化
while(IORD_ALTERA_AVALON_PIO_DATA(PIO_BASE)==0);
printf("开始数据采集\n");
for(cnt=0;cnt<400;cnt++)
{
ad_dis[cnt]=IORD_16DIRECT(DATA_BASE,0);
}
cnt=0;
printf("数据采集完成\n");
//新建一个名为TEST.TXT的文件
printf("\n创建一个TXT文件……%d",cnt1);
write_command_to_usb(SET_FILE_NAME);//送“设置文件名”命令
send_string_to_usb("/",1);
write_data_to_usb(cnt1+0x30);
send_string_to_usb(".TXT\0",6); //送文件名“TEST.TXT”
write_command_to_usb(FILE_CREATE); //送“新建文件”命令
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH376中断标志位
if(ch376_status == USB_INT_SUCCESS) //请求继续写入
{
printf("成功!\n");
}
else
{
printf("失败--%d\n",ch376_status);
while(1);
}
write_command_to_usb(FILE_CLOSE); //关闭当前已经打开的文件或目录
write_data_to_usb(1); //允许自动更新文件长度
printf("TXT文本创建完成!\n");
write_command_to_usb(SET_FILE_NAME);//送“设置文件名”命令
send_string_to_usb("/",1);
write_data_to_usb(cnt1+0x30);
send_string_to_usb(".TXT\0",8); //送文件名“TEST.TXT”
write_command_to_usb(FILE_OPEN); //送“打开文件或目录,枚举文件和目录”命令
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH376中断标志位
if(ch376_status == USB_INT_SUCCESS) //请求继续写入
{
printf("文件打开成功!\n");
}
else
{
printf("文件打开失败--%d\n",ch376_status);
while(1);
}
while(cnt<400)
{
//往已有文件添加一串数据
write_command_to_usb(BYTE_WRITE); //以字节为单位从当前位置写入数据块
write_data_to_usb(8); //头两个字节是以低字节在前的16bit指示后续写入的数据个数
write_data_to_usb(0);
ch376_intflag = 0; //清除CH375中断标志位
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH375中断标志位
if(ch376_status == USB_INT_DISK_WRITE) //请求继续写入
{
write_command_to_usb(WR_REQ_DATA); //向内部指定缓冲区写入请求的数据块
read_data_from_usb();
printf("需要写入TXT的数据量为:%d\n",cnt);
}
else
{
printf("\nTXT文本数据写入失败--%d\n",ch376_status);
while(1);
}
printf("ad_dis=%d\n",ad_dis[cnt] );
num1=ad_dis[cnt]/4096;
num2=ad_dis[cnt]%4096/256;
num3=ad_dis[cnt]%4096%256/16;
num4=ad_dis[cnt]%4096%256%16;
if(num1<10)
{
write_data_to_usb(num1+0x30);
}
else
{
num1=num1%10;
write_data_to_usb(num1+0x61);
}
if(num2<10)
{
write_data_to_usb(num2+0x30);
}
else
{
num2=num2%10;
write_data_to_usb(num2+0x61);
}
if(num3<10)
{
write_data_to_usb(num3+0x30);
}
else
{
num3=num3%10;
write_data_to_usb(num3+0x61);
}
if(num4<10)
{
write_data_to_usb(num4+0x30);
}
else
{
num4=num4%10;
write_data_to_usb(num4+0x61);
}
send_string_to_usb("\r\n",4); //回车换行
write_command_to_usb(BYTE_WR_GO); //继续字节写
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH375中断标志位
if(ch376_status == USB_INT_SUCCESS) //请求继续写入
{
printf("TXT文本数据写入成功!\n");
}
else
{
printf("TXT文本数据写入失败--%d\n",ch376_status);
while(1);
}
cnt++;
}
write_command_to_usb(FILE_CLOSE); //关闭当前已经打开的文件或目录
write_data_to_usb(1); //允许自动更新文件长度
printf("TXT文本创建并写入完成!\n");
cnt=0;
while(1);
return 0;
}
//////////////////////////////////////////////////////////////////////
//函数名:init_usb
//功 能:CH376初始化
//输 入:无
//返 回:无
//////////////////////////////////////////////////////////////////////
void init_usb(void)
{
alt_u8 temp = 0; //临时变量
//初始化全局变量
ch376_intflag = 0; //清除CH376中断标志位
ch376_status = 0; //清除 CH376中断寄存器
//注册中断函数
alt_ic_isr_register(CH376_CONTROLLER_0_IRQ_INTERRUPT_CONTROLLER_ID,
CH376_CONTROLLER_0_IRQ,
handle_usbirq_interrupts,
NULL,
NULL);
//设置USB工作模式
write_command_to_usb(SET_USB_MODE); //送命令
write_data_to_usb(0x03); //切换到SD卡主机模式,管理和存取SD卡中的文件
/*
模式代码为04H时切换到未启用的USB主机方式;
模式代码为05H时切换到已启用的USB主机方式,不产生SOF包;
模式代码为06H时切换到已启用的USB主机方式,自动产生SOF包;
模式代码为07H时切换到已启用的USB主机方式,复位USB总线;
*/
ch376_intflag = 0; //清除CH376中断标志位
delayus(100);
//CH376芯片工作状态测试
write_command_to_usb(CHECK_EXIST); //发送命令
write_data_to_usb(0xaa); //写入数据0xaa
temp = read_data_from_usb(); //读取写入数据取反结果,即0xaa取反应为0x55
if(temp == 0x55) printf("CH376芯片工作正常\n"); //打印测试结果
else
{
printf("CH376芯片初始化失败\n");
while(1);
}
}
//////////////////////////////////////////////////////////////////////
//函数名:init_Udisk
//功 能:U盘初始化
//输 入:无
//返 回:无
//////////////////////////////////////////////////////////////////////
void init_Udisk(void)
{
alt_u8 i;
// alt_u8 temp = 0; //临时变量
alt_u8 mem[9]; //U盘存储量
//初始化USB存储设备
printf("初始化USB存储设备……"); //打印事件
ch376_intflag = 0; //清除CH376中断标志位
write_command_to_usb(DISK_MOUNT); //发送命令
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH376中断标志位
if(ch376_status == USB_INT_SUCCESS) printf("成功\n");
else
{
printf("失败——0x%x\n",ch376_status);
while(1);
}
//获取USB存储设备的磁盘物理容量
printf("获取USB存储设备的磁盘物理容量……"); //打印事件
write_command_to_usb(DISK_CAPACITY); //发送命令
while(ch376_intflag != 1); //等待中断产生
ch376_intflag = 0; //清除CH376中断标志位
if(ch376_status == USB_INT_SUCCESS)
{
printf("成功\n");
write_command_to_usb(RD_USB_DATA0); //发送命令
//读取并打印USB存储设备容量
read_data_from_usb();//读取第一个字节,即后续数据长度,为8
for(i=0;i<4;i++) //连续读取8个字节数据
{
mem[i] = read_data_from_usb();
}
printf("\t总扇区数为:%d\n",((mem[3]<<24)+(mem[2]<<16)+(mem[1]<<8)+mem[0]));
printf("\t每个扇区字节数为:%d\n",512);
printf("\t总存储量为:%dMB\n",((mem[3]<<24)+(mem[2]<<16)+(mem[1]<<8)+mem[0])*512/1024/1024);
}
else
{
printf("失败——0x%x\n",ch376_status);
while(1);
}
}
//////////////////////////////////////////////////////////////////////
//函数名:send_string_to_usb
//功 能:向USB主机端点的输出缓冲区写入数据块
//输 入:alt_8 *str----写入字符串,alt_8 str_len----字符串长度
//返 回:无
//////////////////////////////////////////////////////////////////////
void send_string_to_usb(alt_8 *str,alt_8 str_len)
{
alt_u8 i;
//写入固定长度数据字节
for(i=0;i
{
//写入数据
write_data_to_usb(str[i]);
}
}
//////////////////////////////////////////////////////////////////////
//函数名:write_command_to_usb
//功 能:写命令到CH376
//输 入:alt_u8 command----写入命令
//返 回:无
//////////////////////////////////////////////////////////////////////
void write_command_to_usb(alt_u8 command)
{
//延时>1.5us
delayus(1);
IOWR_8DIRECT(CH376_CONTROLLER_0_BASE,1,command);
//命令操作 A0=1
}
//////////////////////////////////////////////////////////////////////
//函数名:write_data_to_usb
//功 能:写数据到CH376
//输 入:alt_u8 data----写入数据
//返 回:无
//////////////////////////////////////////////////////////////////////
void write_data_to_usb(alt_u8 data)
{
//延时>1.5us
delayus(1);
IOWR_8DIRECT(CH376_CONTROLLER_0_BASE,0,data);
}
//////////////////////////////////////////////////////////////////////
//函数名:read_data_from_usb
//功 能:从CH376读出数据
//输 入:无
//返 回:alt_u8----读出数据
//////////////////////////////////////////////////////////////////////
alt_u8 read_data_from_usb(void)
{
//延时>1.5us
delayus(1);
return IORD_8DIRECT(CH376_CONTROLLER_0_BASE,0);
}
//////////////////////////////////////////////////////////////////////
//函数名:delayus
//功 能:短延时函数
//输 入:alt_u32 cnt----延时值
//返 回:void
//////////////////////////////////////////////////////////////////////
void delayus(alt_u32 cnt)
{
int i;
for(i=0;i
}
用的芯片是CH376