我在做把rs485的数据存入到sd卡中,有两个数据缓冲区,每个缓冲区的大小是6400,然后会交换使用缓冲区存储数据,每存够6400个数就写入新建的txt中,一共存10次,然后关掉当前txt,新建文件再次存数。现在的问题是两个缓冲区交换的时候会有数据遗漏,我发的数据是1到150,下面的word是存好的一个txt的数据,其中黑 {MOD}的是正常数据,红 {MOD}的数据是为了表示出两句红 {MOD}数据中间有遗漏的数据,蓝 {MOD}的数据是被遗漏的数据。
rs485的程序如下:
[mw_shl_code=c,true]#if EN_USART2_RX //如果使能了接收,.h一直为1
//u8 RS485_RX_BUF[5000]; //中间传递缓冲区
//u32 RS485_RX_CNT; //中间传递计数值
u32 QueueIdx = 0; // 当前使用队列下标
CQueue CommQueue[2]; // 串口数据接收队列
CQueue *QueueFullWithData = NULL; // 已写满数据的队列
u8 Data;
int i = 1;
void USART2_IRQHandler(void)
{
CQueue *CurQueue = CommQueue + QueueIdx;
while(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)//接收到数据
{
//判断溢出
if(USART_GetFlagStatus(USART2, USART_FLAG_ORE) == SET)
{
USART_ClearFlag(USART2, USART_FLAG_ORE);//读SR就是清除标志位
USART_ReceiveData(USART2);
}
// 读取接收到的数据USART2->DR
Data = USART_ReceiveData(USART2);
// 将接收到的数据写入当前队列中
QueuePushBack(CurQueue, Data);
// 如果队列写满,则下次使用另一个队列
if(QueueFull(CurQueue))
{
QueueFullWithData = CurQueue;
QueueIdx = ++QueueIdx % 2;
CurQueue = CommQueue + QueueIdx;
InitQueue(CurQueue);
}
}
}
#endif
//初始化IO 串口2
//bound:波特率
void RS485_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
//串口2引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2复用为USART2
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3复用为USART2
//USART2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //GPIOA2与GPIOA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA2,PA3
//PG8推挽输出,485模式控制
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOG8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOG,&GPIO_InitStructure); //初始化PG8
//USART2 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口 2
USART_ClearFlag(USART2, USART_FLAG_TC);
#if EN_USART2_RX
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启接受中断
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
#endif
RS485_TX_EN=0; //默认为接收模式
InitQueue(&CommQueue[0]); // 初始化第一个接收队列
}
[/mw_shl_code]
main函数的程序如下:
[mw_shl_code=c,true]#define __SHOW_SD_PROCEDURE__
static int i = 0;
char FileName[16];
char CntBuf[64];
u8 res_open = 1;
int open = 0;
int file_name;
FIL File;
FIL* CreateNewFile(void)
{
__align(8) RTC_TimeTypeDef RTC_TimeStruct; //__align(8) 8字节对其
__align(8) RTC_DateTypeDef RTC_DateStruct;
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct);
file_name = changetime(&RTC_TimeStruct, &RTC_DateStruct);
sprintf(FileName, "%08d.txt",file_name);
while(res_open!=0)
{
res_open = f_open(&File, FileName, FA_OPEN_ALWAYS | FA_WRITE);
if(++open > 2)
{
sprintf(CntBuf, "f_open = %d", res_open);
LCD_ShowString(60, 80, 210, 16, 16, CntBuf);
}
}
res_open = 1; open = 0;
f_lseek(&File, 0);
#ifdef __SHOW_SD_PROCEDURE__
LCD_ShowString(60, 140, 210, 16, 16, FileName);
#endif
LCD_ShowString(60, 170, 210, 16, 16, " CreateNewFile = ");
LCD_ShowNum(200, 170, ++i, 8, 16);
return &File;
}
#define FILE_BLOCK_CNT 10
int FileBlockCnt = 0;
int FileCnt = 0;
int main(void)
{
char CntBuf[64];
FIL *SDFile = NULL;
//-------------------------------
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
//-------------------------------
delay_init(168); // 初始化延时函数
uart_init(115200); // 初始化串口波特率为115200
LED_Init(); // 初始化LED
LCD_Init(); // LCD初始化
RS485_Init(115200); // 初始化RS485串口2
RTC_Set_WakeUp(RTC_WakeUpClock_CK_SPRE_16bits, 0); // 配置WAKE UP中断,1秒钟中断一次
exfuns_init(); //为fatfs相关变量申请内存
usmart_dev.init(72);
my_mem_init(SRAMIN); //初始化内部内存池
SD_InitializeCards();
f_mount(fs[0], "0:", 1); //注册工作区
// //-----------------------------
while(1)
{
if(QueueFullWithData)
{
if(FileBlockCnt == 0)
{
SDFile = CreateNewFile();
}
f_write(SDFile, QueueFullWithData, QUEUE_SIZE, (UINT*)&bw);
//delay_ms(1);
QueueFullWithData = NULL;
LCD_ShowString(60, 200, 210, 16, 16, "Saved File Block = ");
LCD_ShowNum(200, 200, ++FileBlockCnt, 8, 16);
if(FileBlockCnt == FILE_BLOCK_CNT)
{
f_close(SDFile);
FileBlockCnt = 0;
LCD_ShowString(60, 260, 210, 16, 16, "Saved File Cnt = ");
LCD_ShowNum(200, 260, ++FileCnt, 8, 16);
}
}
}
}
[/mw_shl_code]
可以看一下是什么问题吗?
---------------------------------
你的 sd卡有没有使用 dma 功能啊,建议使用dma 功能试试看
一周热门 更多>