最近兩天由於之前研究的GPS+BD定位信息不只需要獲取信息並顯示,還需要對當時的信息進行存儲,比如說我們在一個地方進行測量,測量人員記錄了測量數值和位置,但是不免會出現錯誤,當然GPS出現錯誤也有可能,所以我們需要把每次測試的信息和位置同時記錄一份,以便工作結束後數據比對校正。我的處理方式就是使用SD卡和FATFS搞定
首先要講一點小知識
【SD卡根據其使用的系統規範】
系統規範版本 | 時鐘 |
---|---|
V3.31 | 1-20MHz |
V4.2和V4.4 | 1-48MHz |
這一點浪費了我一整天的時間在找問題(也怪我是個菜雞,沒有看完模塊的說明就來幹活,希望大家不要和我犯一樣的錯誤)
今日目標
- 實現通過文件系統在SD卡根目錄下創建一個名爲“GPSSave.txt”的文本文檔
- 在“GPSSave.txt”內寫上“我就是那張SD卡,8G那張!!”
- 讀取“GPSSave.txt”,將其內容寫到串口上。
一、基本思路
- 需要接入SD卡,所以需要使能SDMMC
- 需要通過串口顯示,需要使能UART
- 需要用文件系統管理,需要使能FATFS
二、操作步驟
1、根據自己的stm32的芯片型號來選擇,我這裏是STM32F767IGTx
2、選好芯片之後照舊設置RCC爲外部時鐘
3、使能串口1(usart1)
模式設爲異步(Asynchronous)其他默認,波特率可以自己改,USART1爲115200Bits/s,如圖
4、使能SDMMC
模式設爲SD 4 Bits Wide bus ,設置DMA,如圖
使能SDMMC1中斷
此處必須使得SDMMC的中斷優先級高於DMA,纔可正常工作,所以在中斷設置中設置中斷優先級
設備 | 優先級 |
---|---|
SDMMC | 5 |
DMA | 6 |
5、使能FATFS
勾選SD Card,修改紅框相應參數如圖
6、時鐘樹設置
由於本人使用的SD卡系統規範的版本爲V3.31所以需要保證SDMMC的時鐘小於20MHz,如圖:
之後下拉時鐘樹,找到SDMMC1的頻率,修改時鐘源爲PLL48CLK,如圖:
7、項目設置
有文件系統,堆棧改大一點0x1000
生成代碼右上角GENERATE CODE
8、代碼修改
- 爲保證我們方便的使用串口打印信息,所以找到uart.c,並在/* USER CODE BEGIN 0 */後添加如下代碼:
#include <stdio.h>
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->ISR&0X40)==0);
USART1->TDR=(uint8_t)ch;
return ch;
}
用於重定義printf函數的輸出口
- 在main.c函數中的/* USER CODE BEGIN PV */後添加如下定義
FATFS fs; //工作空間
FIL fil; // 文件項目
uint32_t byteswritten; // 寫文件計數
uint32_t bytesread; // 讀文件計數
uint8_t wtext[] = "我就是那張SD卡,8G那張!!"; // 寫的內容
uint8_t rtext[1024]; // 讀取的buff
char filename[] = "GPSSave.txt"; // 文件名
- 在main.c函數中的/* USER CODE BEGIN 2 */後添加如下代碼:
printf("\r\n ****** 文件系統 ******\r\n\r\n");
/*-1- 掛載文件系統*/
retSD = f_mount(&fs, "", 0);
if(retSD)
{
printf(" mount error : %d \r\n",retSD);
Error_Handler();
}
else
printf(" mount sucess!!! \r\n");
/*-2-創建新的文件並寫入數據*/
retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); //打開文件,權限包括創建、寫(如果沒有該文件,會創建該文件)
if(retSD) //返回值不爲0(出現問題)
printf(" open file error : %d\r\n",retSD); //打印問題代碼
else
printf(" open file sucess!!! \r\n");
/*-3- 在txt文件中寫入數據*/
retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten); //在文件內寫入wtext內的內容
if(retSD) //返回值不爲0(出現問題)
printf(" write file error : %d\r\n",retSD); //打印問題代碼
else
{
printf(" write file sucess!!! \r\n");
printf(" write Data : %s\r\n",wtext); //打印寫入的內容
}
/*-4- 關閉txt文件*/
retSD = f_close(&fil); //關閉該文件
if(retSD) //返回值不爲0(出現問題)
printf(" close error : %d\r\n",retSD); //打印問題代碼
else
printf(" close sucess!!! \r\n");
/*-5- 打開文件讀取數據*/
retSD = f_open(&fil, filename, FA_READ); //打開文件,權限爲只讀
if(retSD) //返回值不爲0(出現問題)
printf(" open file error : %d\r\n",retSD); //打印問題代碼
else
printf(" open file sucess!!! \r\n");
/*-6- 讀取txt文件數據*/
retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread); //讀取文件內容放到rtext中
if(retSD) //返回值不爲0(出現問題)
printf(" read error!!! %d\r\n",retSD); //打印問題代碼
else
{
printf(" read sucess!!! \r\n");
printf(" read Data : %s\r\n",rtext); //打印讀取到的數據
}
/*-7- 關閉文件*/
retSD = f_close(&fil); //關閉該文件
if(retSD) //返回值不爲0(出現問題)
printf(" close error!!! %d\r\n",retSD); //打印問題代碼
else
printf(" close sucess!!! \r\n");
/*##-8- 讀寫一致性檢測 ############*/
if(bytesread == byteswritten) //如果讀寫位數一致
{
printf(" FatFs is working well!!!\r\n"); //打印文件系統工作正常
}
編譯、下載
三、結果驗證
插上SD卡,打開串口調試助手並設置比特率等參數與串口1一致,上電
得到如下結果:
爲保證我不是瞎搞的,現在來看看SD卡里的內容
文件名爲:GPSSave.txt
打開後內容爲:我就是那張SD卡,8G那張!!
到此試驗成功。
Good Game!!!!!!
接下來會推出一系列的關於串口外設使用的分享,有需要的猿們敬請關注!!!!!
以上內容歡迎大家轉載引用,標明出處即可!!!!!