嵌入式实验报告宗子轩.docx
《嵌入式实验报告宗子轩.docx》由会员分享,可在线阅读,更多相关《嵌入式实验报告宗子轩.docx(21页珍藏版)》请在冰豆网上搜索。
嵌入式实验报告宗子轩
嵌入式实验报告-宗子轩
中南民族大学
学生实验报告
院系:
计算机科学学院
专业:
自动化__
年级:
2008级
课程名称:
嵌入式技术与应用
指导教师:
张志俊
组号:
组员:
覃静
2011年11月1日
实验题目:
USB接口实验
一、设计要求
利用EduKit-M3实验平台的五个按键实现标准的USB接口游戏杆功能。
二、硬件电路实现
在EduKit-M3实验平台上已有一个简易的游戏杆,其SELECTION、DOWN、RIGHT、LEFT和UP键分别与处理器的PD12、PD14、PE1、PE0、PD8引脚相连;处理器的USB接口已经转换电路连接到CN1连接器。
三、软件程序设计
该程序的结构比较复杂,除了库文件以及USB函数库文件之外,还包含8个源文件,其中STM32F10x.s是启动代码。
下面分别为其他7个函数:
1、main.c——该函数中主要包含2个函数,其中main函数初始化系统以及USB接口,之后不断查询游戏杆是否有动作,如果有动作则根据动作向USB缓冲器发出相关数据;Delay函数用于延迟。
intmain(void)
{#ifdefDEBUG
debug();
#endif
Set_System();
USB_Interrupts_Config();
Set_USBClock();
USB_Init();
while
(1)
{if(JoyState()!
=0)
{Joystick_Send(JoyState());}
}
}
voidDelay(vu32nCount)
{for(;nCount!
=0;nCount--);}
#ifdefDEBUG
2、usb_desc.c——该文件中没有任何函数,只是包含一些定义USB设备的描述符常数,由于游戏杆是标准USB设备,因此比较容易得到相关的参数。
若要开发非标准的USB设备,则还需要开发PC上运行的非标准设备的驱动程序。
3、stm32f10x_it.c——该文件中包含USB中断服务程序,由于USB中断有很多情况,这里的中断服务程序只是调用usb_Istr.c文件中的USB_Istr函数,由USB_Istr函数再做轮询处理。
4、usb_Istr.c——该文件中只有一个函数,即USB中断的USB_Istr函数,该函数对各类引起USB中断的事件作轮询处理。
voidUSB_Istr(void)
{wIstr=_GetISTR();
#if(IMR_MSK&ISTR_RESET)
if(wIstr&ISTR_RESET&wInterrupt_Mask)
{_SetISTR((u16)CLR_RESET);
Device_Property.Reset();
#ifdefRESET_CALLBACK
RESET_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_DOVR)
if(wIstr&ISTR_DOVR&wInterrupt_Mask)
{_SetISTR((u16)CLR_DOVR);
#ifdefDOVR_CALLBACK
DOVR_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_ERR)
if(wIstr&ISTR_ERR&wInterrupt_Mask)
{_SetISTR((u16)CLR_ERR);
#ifdefERR_CALLBACK
ERR_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_WKUP)
if(wIstr&ISTR_WKUP&wInterrupt_Mask)
{_SetISTR((u16)CLR_WKUP);
Resume(RESUME_EXTERNAL);
#ifdefWKUP_CALLBACKWKUP_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_SUSP)
if(wIstr&ISTR_SUSP&wInterrupt_Mask)
{
if(fSuspendEnabled)
{Suspend();}
else
{Resume(RESUME_LATER);}
_SetISTR((u16)CLR_SUSP);
#ifdefSUSP_CALLBACK
SUSP_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_SOF)
if(wIstr&ISTR_SOF&wInterrupt_Mask)
{_SetISTR((u16)CLR_SOF);
bIntPackSOF++;
#ifdefSOF_CALLBACK
SOF_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_ESOF)
if(wIstr&ISTR_ESOF&wInterrupt_Mask)
{_SetISTR((u16)CLR_ESOF);
#ifdefESOF_CALLBACK
ESOF_Callback();
#endif
}
#endif
#if(IMR_MSK&ISTR_CTR)
if(wIstr&ISTR_CTR&wInterrupt_Mask)
{CTR_LP();
#ifdefCTR_CALLBACK
CTR_Callback();
#endif
}
#endif
}/*USB_Istr*/
5、usb_prop.c——该文件用于实现相关设备的USB协议,例如初始化、SETUP包、IN包、OUT包等等。
6、usb_pwr.c——该文件中包含处理上电、调电、挂起和恢复事件的函数,
7、——该文件中包含系统配置的函数,和处理游戏杆动作的函数。
其中,Set_System函数用于配置时钟、通用端口;Set_USBClock函数用于配置USB端口时钟;USB_Interrupts_Config函数用于配置USB中断;USB_Cable_Config函数配置USB电缆状态;JoyState函数用于获取游戏杆的状态;Joystick_Send用于向USB端口传送游戏杆的事件。
voidSet_System(void)
{GPIO_InitTypeDefGPIO_InitStructure;
RCC_DeInit();
/*EnableHSE*/
RCC_HSEConfig(RCC_HSE_ON);
/*WaittillHSEisready*/
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)
{
/*EnablePrefetchBuffer*/
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/*Flash2waitstate*/
FLASH_SetLatency(FLASH_Latency_2);
/*HCLK=SYSCLK*/
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/*PCLK2=HCLK*/
RCC_PCLK2Config(RCC_HCLK_Div1);
/*PCLK1=HCLK/2*/
RCC_PCLK1Config(RCC_HCLK_Div2);
/*ADCCLK=PCLK2/6*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/*PLLCLK=8MHz*9=72MHz*/
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
/*EnablePLL*/
RCC_PLLCmd(ENABLE);
/*WaittillPLLisready*/
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
{
}
/*SelectPLLassystemclocksource*/
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/*WaittillPLLisusedassystemclocksource*/
while(RCC_GetSYSCLKSource()!
=0x08)
{
}
}
/*EnableGPIODandGPIOEclock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOC,ENABLE);
/*PD.09usedasUSBpull-up*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*ConfiguretheJoyStickIOs*/
/*Keyup+Keydown*/
GPIO_InitStructure.GPIO_Pin=JOY_UP|JOY_DOWN|JOY_SEL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*Keyleft+Keyright*/
GPIO_InitStructure.GPIO_Pin=JOY_LEFT|JOY_RIGHT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_InitStructure);
/*Right_button+Left_button*/
GPIO_InitStructure.GPIO_Pin=JOY_LEFT_BUTTON|JOY_RIGHT_BUTTON;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
voidSet_USBClock(void)
{/*SelectUSBCLKsource*/
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
/*EnableUSBclock*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB,ENABLE);
}
voidUSB_Interrupts_Config(void)
{NVIC_InitTypeDefNVIC_InitStructure;
#ifdefVECT_TAB_RAM
/*SettheVectorTablebaselocationat0x20000000*/
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else/*VECT_TAB_FLASH*/
/*SettheVectorTablebaselocationat0x08000000*/
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN_RX0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
voidUSB_Cable_Config(FunctionalStateNewState)
{
if(NewState!
=DISABLE)
{GPIO_ResetBits(GPIOD,GPIO_Pin_9);}
else
{GPIO_SetBits(GPIOD,GPIO_Pin_9);}
}
u8JoyState(void)
{/*"right"keyispressed*/
if(!
GPIO_ReadInputDataBit(GPIOE,JOY_RIGHT))
{returnRIGHT;}
/*"left"keyispressed*/
if(!
GPIO_ReadInputDataBit(GPIOE,JOY_LEFT))
{returnLEFT;}
/*"up"keyispressed*/
if(!
GPIO_ReadInputDataBit(GPIOD,JOY_UP))
{returnUP;}
/*"down"keyispressed*/
if(!
GPIO_ReadInputDataBit(GPIOD,JOY_DOWN))
{returnDOWN;}
/*"sel"keyispressed*/
if(!
GPIO_ReadInputDataBit(GPIOD,JOY_SEL))
{returnSEL;}
if(!
GPIO_ReadInputDataBit(GPIOC,JOY_LEFT_BUTTON))
{returnLEFT_BUTTON;}
if(!
GPIO_ReadInputDataBit(GPIOC,JOY_RIGHT_BUTTON))
{returnRIGHT_BUTTON;}
/*Nokeyispressed*/
else
{return0;}
}
voidJoystick_Send(u8Keys)
{u8Mouse_Buffer[4]={0,0,0,0};
s8X=0,Y=0,BUTTON=0;
switch(Keys)
{caseLEFT:
X+=CURSOR_STEP;
break;
caseRIGHT:
X-=CURSOR_STEP;
break;
caseUP:
Y-=CURSOR_STEP;
break;
caseDOWN:
Y+=CURSOR_STEP;
break;
caseSEL:
BUTTON=BUTTON|0x01;
break;
caseLEFT_BUTTON:
BUTTON=BUTTON|0x01;
break;
caseRIGHT_BUTTON:
BUTTON=BUTTON|0x02;
break;
default:
return;
}
/*preparebuffertosend*/
Mouse_Buffer[0]=BUTTON;
Mouse_Buffer[1]=X;
Mouse_Buffer[2]=Y;
/*copymousepositioninfoinENDP1TxPacketMemoryArea*/
UserToPMABufferCopy(Mouse_Buffer,GetEPTxAddr(ENDP1),4);
if(Mouse_Buffer[0]!
=0)
{Mouse_Buffer[0]=0;
UserToPMABufferCopy(Mouse_Buffer,GetEPTxAddr(ENDP1),4);
}
/*enableendpointfortransmission*/
SetEPTxValid(ENDP1);
}
四、运行过程
(1)使用KeiluVision3,通过一根USB电缆连接EduKit-M3实验平台的CN1;
(2)打开实验例程目录USB_TEST子目录下的USB.Uv2例程,编译链接工程;
(3)点击MDK的Debug菜单,点击Start/StopDebugSession;或者将程序烧写到EduKit-M3实验平台上,重启EduKit-M3实验平台;
(4)分别使用EduKit-M3实验平台上的Joystick的5个键,观察PC机屏幕的鼠标,如果鼠标跟随Joystick的按键动作而移动,则表明程序运行成功。
注意:
运行程序前请确保跳线JP1的2-3连接。
五、实验心得
对嵌入式利用EduKit-M3实验平台的五个按键实现标准的USB接口游戏杆功能。
实验题目:
TFT-LCD实验(扩展LCD显示)
一、设计要求
1、在液晶屏幕上显示自己的名字;
2、在液晶屏幕上显示直线;
3、在液晶屏幕上显示圆
4、将16*16点阵改为24*24的,并在液晶屏幕上显示。
二、硬件电路设计
图10-1-2LCD驱动电路连接图
三、实验原理
液晶屏(LCD:
LiquidCrystalDisplay)主要用于显示文本及图形信息。
液晶显示屏具有轻薄、体积小、低耗电量、无辐射危险、平面直角显示以及影像稳定不闪烁等特点,因此在许多电子应用系统中,常使用液晶屏作为人机界面。
液晶显示屏按显示原理分为STN和TFT两种:
STN(SuperTwistedNematic,超扭曲向列)液晶屏
STN液晶显示器与液晶材料、光线的干涉现象有关,因此显示的色调以淡绿色与橘色为主。
STN液晶显示器中,使用X、Y轴交叉的单纯电极驱动方式,即X、Y轴由垂直与水平方向的驱动电极构成,水平方向驱动电压控制显示部分为亮或暗,垂直方向的电极则负责驱动液晶分子的显示。
STN液晶显示屏加上彩色滤光片,并将单色显示矩阵中的每一像素分成三个子像素,分别通过彩色滤光片显示红、绿、蓝三原色,也可以显示出色彩。
单色液晶屏及灰度液晶屏都是STN液晶屏。
TFT(ThinFilmTransistor,薄膜晶体管)彩色液晶屏
随着液晶显示技术的不断发展和进步,TFT液晶显示屏被广泛用于制作成电脑中的液晶显示设备。
TFT液晶显示屏既可在笔记本电脑上应用(现在大多数笔记本电脑都使用TFT显示屏),也常用于主流台式显示器。
分65536色及26万色,1600万色三种,其显示效果非常出色。
TFT的显示采用“背透式”照射方式——假想的光源路径不是像STN液晶那样从上至下,而是从下向上。
这样的作法是在液晶的背部设置特殊光管,光源照射时通过下偏光板向上透出。
由于上下夹层的电极改成FET电极和共通电极,在FET电极导通时,液晶分子的表现也会发生改变,可以通过遮光和透光来达到显示的目的,响应时间大大提高到80ms左右。
本系统采用的液晶屏为SPI接口的TFT屏幕,像素为128×160。
图10-1-1TFT液晶屏外形
四、软件程序设计
1、显示自己的名字
intmain(void)
{#ifdefDEBUG
debug();
#endif
Demo_Init();
LCD_Display_Color(0x0000);//RAD
LCD_Display_Color(0xffff);
Lcd_DspHz16(6,0,"覃静");
while
(1)
{
}
}
2、画线
修改画线的函数LCD_DrawLine,之后再main函数中直接调用即可。
voidLCD_DrawLine(u8Xpos,u16Ypos,u16Length,u8Direction)
{
u32i=0;
//LCD_Display_Color(BackColor);
if(Direction==Horizontal)
{
for(i=0;i{LCD_DisplayPoint(Xpos+i,Ypos,TextColor);}
}
else
{for(i=0;i{LCD_DisplayPoint(Xpos+i,Ypos+(i*160/250),TextColor);}
}
}
3、画圆
在main函数中调用画圆函数LCD_DrawCircle,可随意输入圆的横纵坐标和半径值。
voidLCD_DrawCircle(u8Xpos,u8Ypos,u8Radius)
{
s32D;/*DecisionVariable*/
u32CurX;/*CurrentXValue*/
u32CurY;/*CurrentYValue*/
D=3-(Radius<<1);
CurX=0;
CurY=Radius;
//LCD_Display_Color(BackColor);
while(CurX<=CurY)
{
LCD_DisplayPoint(Xpos+CurX,Ypos+CurY,TextColor);
LCD_DisplayPoint(Xpos+CurX,Ypos-CurY,TextColor);
LCD_DisplayPoint(Xpos-CurX,Ypos+CurY,TextColor);
LCD_DisplayPoint(Xpos-CurX,Ypos-CurY,TextColor);
LCD_DisplayPoint(Xpos+CurY,Ypos+CurX,TextColor);
LCD_DisplayPoint(Xpos+CurY,Ypos-CurX,TextColor);
LCD_DisplayPoint(Xpos-CurY,Ypos+CurX,TextColor);
LCD_DisplayPoint(Xpos-CurY,Ypos-CurX,TextColor);
if(D<0)
{D+=(CurX<<2