RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32應(yīng)用案例 基于STM32F103ZE開(kāi)發(fā)的數(shù)碼相冊(cè)

嵌入式技術(shù) ? 來(lái)源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-06-02 09:09 ? 次閱讀

1.硬件平臺(tái)

  • CPUSTM32F103ZE
  • 屏幕:3.5寸TFTLCD屏
  • 觸控:電阻式觸摸屏xpt2046
  • SD卡、外擴(kuò)Sram

2.示例效果

SD卡檢測(cè)和圖片搜索

poYBAGKWuzaAfJxgAAXecAb-MmM388.png

圖片加載與顯示

pYYBAGKWu06Adh3FAAo-vcnwBR8460.png

3.軟件設(shè)計(jì)

3.1 遍歷目錄

??遍歷目錄,搜索所有的bmp格式圖片,以鏈表方式保存圖片名,方便接下來(lái)圖片切換。

typedef struct FILE_info
{
	char file_name[100];
	u16 number;//保存第幾張圖片
	struct FILE_info *next;
	struct FILE_info *pre;
}FILE_INFO;
FILE_INFO *bmp_head=NULL;
/*創(chuàng)建鏈表*/
FILE_INFO *List_CreateHead(FILE_INFO *head)
{
	if(head!=NULL)return head;
	head=malloc(sizeof(FILE_INFO));
	memset(head,0,sizeof(FILE_INFO));
	head->next=NULL;
	head->pre=NULL;
	return head;
}
/*添加節(jié)點(diǎn)*/
FILE_INFO *List_AddNode(FILE_INFO *head)
{
	if(head==NULL)return NULL;//鏈表頭不存在
	FILE_INFO *phead=head;
	while(phead->next!=NULL)
	{
		phead=phead->next;
	}
	FILE_INFO *new_node=malloc(sizeof(FILE_INFO));
	memset(new_node,0,sizeof(FILE_INFO));
	new_node->pre=phead;
	phead->next=new_node;
	new_node->next=NULL;
	return new_node;
}
/*遍歷目錄*/
u8 SDCard_PrintDir(const TCHAR* path)
{
	DIR dp;	
	u8 res;
	u8 stat=0;
	bmp_head=List_CreateHead(bmp_head);//創(chuàng)建鏈表頭	
	res=f_opendir(&dp,path);
  FILINFO file_info;
  if(res)
  {
    printf("打開(kāi)目錄失敗res=%d\r\n",res);
		free(bmp_head);//釋放鏈表頭
    return 1;
  }	
	FILE_INFO *temp=NULL;
	while(1)
	{
		res=f_readdir(&dp,&file_info);
		if(res!=FR_OK || file_info.fname[0]==0)break;
		if(strstr(file_info.fname,".bmp"))//查找bmp圖片
		{
			temp=List_AddNode(bmp_head);//添加節(jié)點(diǎn)
			if(temp==NULL)
			{
				stat=2;//動(dòng)態(tài)分配空間失敗
				goto AA;
			}
			strcpy(temp->file_name,file_info.fname);//文件名
			picture_count++;
			temp->number=picture_count;//第幾張圖片
			//printf("文件名:%s\r\n",temp->file_name);
		}
	}
AA:
	f_closedir(&dp);//關(guān)閉目錄
	return stat;
}

3.2 圖片解析與顯示

??圖片通過(guò)SD卡保存,SD卡采用SDIO驅(qū)動(dòng)。由于STM32F103ZE主頻只有72MHZ,為了提高刷新速度,將主頻超頻至128MHZ。再通過(guò)外擴(kuò)SRAM建立屏幕緩沖區(qū),借助DMA數(shù)據(jù)搬運(yùn),從而提升屏幕刷新效率。

超頻處理后需要注意串口波特率計(jì)算和定時(shí)器工作頻率

void STM32_Clock_Init(u8 PLL)
{
	u8 temp;
	RCC->CFGR&=0XFFFFFFFC;	//修改時(shí)鐘頻率為內(nèi)部8M	   
	RCC->CR&=~0x01000000;  	//PLLOFF 
 	RCC->CFGR&=~(0XF<<18);	//清空原來(lái)的設(shè)置  
	RCC->CR|=1<<16;//開(kāi)啟HSE時(shí)鐘
	while(!(RCC->CR>>17));//等待外部時(shí)鐘就緒
	RCC->CFGR|=0x4<<8;//APB1時(shí)鐘由系統(tǒng)時(shí)鐘2分頻
	PLL-=2;//實(shí)際倍頻數(shù)和填入?yún)?shù)差2,9倍頻寫(xiě)入的數(shù)值為7
	RCC->CFGR|=PLL<<18;//PLL時(shí)鐘9倍頻
	RCC->CFGR|=1<<16;	  //HSE作為PLL時(shí)鐘輸入源
	FLASH->ACR|=0x32;	  //FLASH 2個(gè)延時(shí)周期
	RCC->CR|=1<<24;//PLL時(shí)鐘使能
	while(!(RCC->CR>>25));//等待PLL鎖定
	RCC->CFGR|=0x2<<0;//PLL輸出作為系統(tǒng)時(shí)鐘
	while(1)
	{
		temp=(RCC->CFGR>>2)&0x3;
		if(temp==0x2)break;
	}	
}

3.3 DMA配置

??直接存儲(chǔ)器存取(DMA)用來(lái)提供在外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器和存儲(chǔ)器之間的高速數(shù)據(jù)傳輸。無(wú)須CPU干預(yù),數(shù)據(jù)可以通過(guò)DMA快速地移動(dòng),這就節(jié)省了CPU的資源來(lái)做其他操作。

/******DMA_CH1從存儲(chǔ)器到存儲(chǔ)器************
**形參:u32 cpar -- 外設(shè)地址
**			u32 cmar -- 存儲(chǔ)器地址
**
**************************************/
void DMA_CH1_Init(void)
{
	RCC->AHBENR|=1<<0;//dma1時(shí)鐘使能
	DMA1_Channel1->CCR|=1<<14;//存儲(chǔ)器到存儲(chǔ)器模式
	DMA1_Channel1->CCR|=0x3<<12;//設(shè)置CH1優(yōu)先級(jí)為最高
	DMA1_Channel1->CCR|=0x1<<10;//存儲(chǔ)器數(shù)據(jù)寬度16位
	DMA1_Channel1->CCR|=0x1<<8;//外設(shè)數(shù)據(jù)寬度16位	
	DMA1_Channel1->CCR|=1<<7;//存儲(chǔ)器地址增量
	DMA1_Channel1->CCR&=~(1<<6);//外設(shè)地址不增量
	DMA1_Channel1->CCR&=~(1<<5);//不執(zhí)行循環(huán)操作
	//DMA1_Channel1->CCR|=1<<5;//執(zhí)行循環(huán)操作
	DMA1_Channel1->CCR&=~(1<<4);//從外設(shè)讀
}
/**********開(kāi)啟DMA1_CH1數(shù)據(jù)傳輸*************
***
***形參:u16 data_len -- DMA要傳輸數(shù)目
***********************************************/
void DMA_CH1_Start(u32 cpar,u32 cmar,u16 data_len)
{
	DMA1_Channel1->CPAR=cpar;//外設(shè)地址
	DMA1_Channel1->CMAR=cmar;//存儲(chǔ)器地址
	DMA1_Channel1->CCR&=~(1<<0);//關(guān)閉通道傳輸
	DMA1_Channel1->CNDTR=data_len;//設(shè)置傳輸數(shù)量
	DMA1_Channel1->CCR|=1<<0;//開(kāi)啟通道傳輸
}

3.4 圖片解析與顯示

本示例主要以BMP圖片為例,其他格式圖形需要移植第三方庫(kù)才可實(shí)現(xiàn)。
由于我們常規(guī)BMP圖片多為24位真彩色,即RGB888;而本次使用的LCD屏是16位真彩色RGB565,因而需要進(jìn)行顏色格式轉(zhuǎn)換。

/*顏色轉(zhuǎn)換RGB888轉(zhuǎn)RGB565*/
u16 RGB888_Transform_RGB565(u32 rgb)
{
	u8 r,g,b;
	u16 rgb565;
	r=(rgb>>16)>>3;
	g=(rgb>>8)>>2;
	b=(rgb&0xff)>>3;
	rgb565=(r<<11)|(g<<5)|(b<<0);
	return rgb565;
}
u16 picture_count=0;//圖片總數(shù)量
/*BMP圖片顯示*/
static u8 buff_rgb888[320*3];//用來(lái)保存讀取到的原始數(shù)據(jù)
static u16 buff_rgb565[320*480];//用來(lái)保存轉(zhuǎn)換完成的RGB565數(shù)據(jù)
u8 BMP_Display(const char *file,u16 number)
{
	FIL fp;
	FRESULT res;
	UINT br;
	u16 w,h;
	char buff[100];
	snprintf(buff,sizeof(buff),"0:/photo/%s",file);
	res=f_open(&fp,buff,FA_READ);
	if(res!=FR_OK)return 1;
	BMP_HEADER bmphead;
	BMP_INFO bmpinfo;
	memset(&bmphead,0,sizeof(BMP_HEADER));
	memset(&bmpinfo,0,sizeof(BMP_INFO));
	res=f_read(&fp,&bmphead,sizeof(BMP_HEADER),&br);
	if(res!=FR_OK)return 2;
	res=f_read(&fp,&bmpinfo,sizeof(BMP_INFO),&br);
	if(res!=FR_OK)return 2;
//	printf("圖片類(lèi)型:%c%c\r\n",bmphead.bfType>>8,bmphead.bfType);
//	printf("圖片尺寸:%d*%d\r\n",bmpinfo.biWidth,bmpinfo.biHeight);
//	printf("顏色位數(shù):%d\r\n",bmpinfo.biBitCount);
	w=bmpinfo.biWidth;
	h=bmpinfo.biHeight;
	u32 oneline_size=bmpinfo.biWidth*3;//一行的字節(jié)數(shù)
	u32 read_oneline_size=oneline_size;//要讀取的一行字節(jié)數(shù)
	/*取出有效的rgb顏色值的一行字節(jié)數(shù)*/
  while(oneline_size%4)oneline_size++;/*保存一行字節(jié)數(shù)為4的倍數(shù)*/
	u32 addr=bmphead.bfOffBits+(bmpinfo.biHeight-1)*oneline_size;
	/*將指針偏移到最后一行*/
	u32 i=0,j=0;;
	u32 rgb888;
	u32 cnt=0;
	for(i=0;i

3.5 主函數(shù)main.c

??在主函數(shù)main.c中主要完成各個(gè)外設(shè)初始化、SD卡掛載、圖片獲取、觸摸屏坐標(biāo)和按鍵值獲取,最終實(shí)現(xiàn)通過(guò)觸摸屏滑動(dòng)或者按下切換圖片。

FATFS fs;
int main()
{

	u8 key;
	STM32_Clock_Init(16);
	Beep_Init();
	Led_Init();
	Key_Init();
	Usartx_Init(USART1,115200,128);
	TIMx_Init(TIM2,128,20*1000);
	W25Q64_Init();//W25Q64初始化
	IIC_Init();//IIC初始化
	NT35310_Init();//LCD初始化
	XPT2046_Init();
	TOUCH_Calibration();//觸摸屏校準(zhǔn)
	printf("觸摸屏校準(zhǔn)完成\r\n");
	SRAM_Init();
	u8 res;
AA:
	res=f_mount(&fs,"0",1);
	if(res)
	{
		LCD_Clear(LIGHTBLUE);
		LCD_Display_Str(LCD_WIDTH/2-strlen("請(qǐng)檢查SD卡是否插好!")*12/2,210,24,(u8 *)"請(qǐng)檢查SD卡是否插好!",RED);
		LCD_Display_Str(LCD_WIDTH/2-strlen("注意文件系統(tǒng)格式須為FAT32!")*12/2,240,24,(u8 *)"注意文件系統(tǒng)格式須為FAT32!",RED);
		LCD_Refresh();//更新顯示
		Delay_Ms(1000);
		goto AA;
	}
BB:
	LCD_Clear(LIGHTBLUE);
	res=SDCard_PrintDir("photo");//遍歷目錄
	if(res)
	{
		LCD_Refresh();//更新顯示
		LCD_Display_Str(LCD_WIDTH/2-strlen("BMP圖片不存在!")*12/2,210,24,(u8 *)"BMP圖片不存在!",RED);
		LCD_Display_Str(LCD_WIDTH/2-strlen("請(qǐng)將圖片存儲(chǔ)在/photo下")*12/2,240,24,(u8 *)"請(qǐng)將圖片存儲(chǔ)在/photo下",RED);
		LCD_Refresh();//更新顯示
		Delay_Ms(1000);
		goto BB;
	}
	LCD_Clear(LIGHTBLUE);
	LCD_Display_Str(LCD_WIDTH/2-strlen("正在加載圖片。。")*12/2,210,24,(u8 *)"正在加載圖片。。",RED);
	LCD_Refresh();//更新顯示
	Delay_Ms(1000);
	FILE_INFO *bmp_temp=bmp_head;
	if(bmp_temp->next!=NULL)
	{
		bmp_temp=bmp_temp->next;
		BMP_Display(bmp_temp->file_name,bmp_temp->number);
	}
	u16 x1,x2;
	int stat=0;
	while(1)
	{
		res=XPT2046_ReadXY();
		if(res)
		{
			x1=touch_info.x;
			while(T_PEN==0)//等待松開(kāi)
			{
				XPT2046_ReadXY();
				x2=touch_info.x;
			}
			if(x1-x2>50)stat=1;
			else if(x2-x1>50)stat=2;
		}
		key=Key_Scan();
		if(key==1 || stat==1)
		{
			stat=0;
			BEEP=1;
			Delay_Ms(50);
			BEEP=0;
			if(bmp_temp->next!=NULL)
			{
				bmp_temp=bmp_temp->next;
				BMP_Display(bmp_temp->file_name,bmp_temp->number);
			}
		}
		else if(key==2 || stat==2)
		{
			stat=0;
			BEEP=1;
			Delay_Ms(50);
			BEEP=0;
			if(bmp_temp->pre!=NULL && bmp_temp->pre->file_name[0]!=0)
			{
				bmp_temp=bmp_temp->pre;
				BMP_Display(bmp_temp->file_name,bmp_temp->number);
			}
			//printf("%s\r\n",bmp_temp->file_name);
		}
	}
}

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • lcd
    lcd
    +關(guān)注

    關(guān)注

    34

    文章

    4424

    瀏覽量

    167396
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10895

    瀏覽量

    355728
  • TFT
    TFT
    +關(guān)注

    關(guān)注

    10

    文章

    385

    瀏覽量

    111061
  • STM32F103ZE
    +關(guān)注

    關(guān)注

    2

    文章

    14

    瀏覽量

    10886
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于STM32設(shè)計(jì)的數(shù)碼相冊(cè)

    項(xiàng)目是基于STM32設(shè)計(jì)的數(shù)碼相冊(cè),能夠通過(guò)LCD顯示屏解碼顯示主流的圖片,支持bmp、jpg、gif等格式。用戶(hù)可以通過(guò)按鍵或者觸摸屏來(lái)切換圖片,同時(shí)還可以旋轉(zhuǎn)顯示,并能夠自適應(yīng)居中顯示,小尺寸圖片居中顯示,大尺寸圖片自動(dòng)縮小顯示(超出屏幕范圍)。圖片從SD卡中獲取。
    的頭像 發(fā)表于 06-24 21:14 ?12.2w次閱讀
    基于<b class='flag-5'>STM32</b>設(shè)計(jì)的<b class='flag-5'>數(shù)碼相冊(cè)</b>

    STM32F103ZE最小系統(tǒng)版

    1.單片機(jī):STM32F103ZE最小系統(tǒng)版6.0?N1RVcKX0SpK?回????/寶或點(diǎn)***擊***鏈節(jié)至瑬覽器【STM32F103ZET6小系統(tǒng)板 STM32開(kāi)發(fā)
    發(fā)表于 08-06 07:51

    怎樣將uTenux移植到STM32F103ZE開(kāi)發(fā)板上去呢

    uTenux是什么?怎樣將uTenux移植到STM32F103ZE開(kāi)發(fā)板上去呢?
    發(fā)表于 11-02 06:42

    STM32F103ze簡(jiǎn)介

    一、STM32F103ze 簡(jiǎn)介本文中,采用的 MCU 具體型號(hào)為 STM32F103ZET6,其擁有豐富的外設(shè)資源(USB,IIC,USART,TIMER)等,大容量的RAM和ROM,以及上百
    發(fā)表于 02-11 06:04

    【技術(shù)精選】嵌入式STM32原創(chuàng)征文活動(dòng)精選文章

    應(yīng)用案例基于PAJ7620和STM32手勢(shì)識(shí)別應(yīng)用案例STM32應(yīng)用案例 基于STM32F103ZE開(kāi)發(fā)數(shù)碼相冊(cè)基于
    發(fā)表于 07-27 18:26

    STM32F103ZE最小系統(tǒng)原理圖

    STM32F103ZE最小系統(tǒng)原理圖
    發(fā)表于 09-20 11:07 ?196次下載
    <b class='flag-5'>STM32F103ZE</b>最小系統(tǒng)原理圖

    基于stm32f103ze的四軸飛控代碼

    基于stm32f103ze的四軸飛控代碼
    發(fā)表于 01-13 10:21 ?30次下載

    嵌入式 STM32F103ZE主要特性

    Embest公司的STM32F103ZE ARM Cortex-M3嵌入式評(píng)估板采用ST公司的STM32F103ZE處理器,工作頻率72MHz.評(píng)估板集成了USB, CAN, SD卡接口
    發(fā)表于 05-08 11:17 ?1.5w次閱讀
    嵌入式 <b class='flag-5'>STM32F103ZE</b>主要特性

    基于STM32F103ZE的USART2 端口時(shí)鐘

    STM32F103ZE默認(rèn)的USART2就是PA03PA02,如果配置映射,USART2端口是PD05PD06了。
    發(fā)表于 06-04 07:26 ?6356次閱讀
    基于<b class='flag-5'>STM32F103ZE</b>的USART2 端口時(shí)鐘

    新版STM32F103ZE核心板原理圖詳細(xì)資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是新版STM32F103ZE核心板原理圖詳細(xì)資料免費(fèi)下載。
    發(fā)表于 08-29 08:00 ?0次下載
    新版<b class='flag-5'>STM32F103ZE</b>核心板原理圖詳細(xì)資料免費(fèi)下載

    STM32F103ZE核心板電路原理圖和PCB圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32F103ZE核心板電路原理圖和PCB圖免費(fèi)下載。
    發(fā)表于 04-01 08:00 ?0次下載
    <b class='flag-5'>STM32F103ZE</b>核心板電路原理圖和PCB圖免費(fèi)下載

    新版STM32F103ZE核心板原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是新版STM32F103ZE核心板原理圖免費(fèi)下載。
    發(fā)表于 02-26 11:46 ?0次下載
    新版<b class='flag-5'>STM32F103ZE</b>核心板原理圖免費(fèi)下載

    新版STM32F103ZE核心板原理圖

    新版STM32F103ZE核心板原理圖免費(fèi)下載。
    發(fā)表于 06-18 11:14 ?0次下載

    STM32F103ZE構(gòu)建固件庫(kù)模板

    STM32F103ZE構(gòu)建固件庫(kù)模板
    發(fā)表于 12-08 18:51 ?13次下載
    <b class='flag-5'>STM32F103ZE</b>構(gòu)建固件庫(kù)模板

    STM32F103ZE最小系統(tǒng)板

    STM32F103ZE最小系統(tǒng)板,可能帶有一些不足
    發(fā)表于 03-30 18:18 ?0次下載
    RM新时代网站-首页