打印
[STM32F1]

求好心人帮忙解读下这个程序.拜托了..

[复制链接]
1366|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wzk1017|  楼主 | 2014-5-24 23:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CD, LCD, pi, IO, TE
#include "main.h"

#define LCD_Data_Addr    ((u32)0x60020000)    //A16做RS线
#define LCD_Reg_Addr     ((u32)0x60000000)       

void main(void);
void LCD_IO_Init(void);
void FSMC_LCD_Init(void);
void MyLcd_Reset(void);
void LCD_Configuration(void);
void  SysTickInit (void);
void delay_us(uint16_t DelayTime);
void delay_ms(uint16_t DelayTime);
void MyLcd_WriteReg(u16 index,u16 dat);
void MyLcd_WriteIndex(u16 Index);
void MyLcd_WriteRAM(u16 data);
void LCD_SetPixel(uint16_t x,uint16_t y,uint16_t color);
void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);
void MyLcd_Clear(u16 color);
///////////////////////////////////////////////////////////////////////////////

u32 wCount = 0;

//主函数入口
void main(void)
{
  //使用内部时钟。
  SystemInit();                   //设置STM32工作的时钟方式和工作频率 /
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
                         RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC |
                         RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_GPIOE |
                         RCC_APB2Periph_AFIO, ENABLE);//使用复用功能,必须开启AFIO时钟
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  
  SysTickInit();                //滴答时钟
  
  LCD_Configuration();          //LCD屏配置
  
  while(1)
  {
    wCount++;
    delay_ms(1000);
  }
}


void LCD_IO_Init(void)
{
//GPIO时钟必须使能,已在RCC中使能全部IO和AFIO。
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_LCDRST ;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_LCDRST, &GPIO_InitStructure);

  // LCD背光控制: PA8
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_LCDLAMP;       
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_LCDLAMP, &GPIO_InitStructure);
                        
  /*************LCD  FSMC模式下数据线与控制线配置*******************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 |
                                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 |
                                GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
                                GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
}


/*******************************************************************************
* Function Name  : FSMC_LCD_Init
* Description    : FSMC接口初始化.
* Input          : None
* Output         : None
* Return         : None
* Date           : 30/06/2011
* Other          : FSMC的GPIO必须要先初始化
*******************************************************************************/
void FSMC_LCD_Init(void)
{
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);  //开启FSMC模式,TFT要用到

  p.FSMC_AddressSetupTime = 0x01;//0x00
  p.FSMC_AddressHoldTime = 0x00;
  p.FSMC_DataSetupTime = 0x02;//0x01
  p.FSMC_BusTurnAroundDuration = 0x00;
  p.FSMC_CLKDivision = 0x00;
  p.FSMC_DataLatency = 0x00;
  p.FSMC_AccessMode = FSMC_AccessMode_B;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
//  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;

  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;    //根据网上建议增加,3.5库才有,旧版没有

  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;       

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

  /* Enable FSMC Bank1_SRAM Bank */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}


/****************************************************************************
* 名    称:void MyLcd_Reset()
* 功    能:复位 MyLcd 控制器
* 入口参数:无
* 出口参数:无
* 说    明:复位控制器,内部函数
* 调用方法:MyLcd_Reset()
****************************************************************************/
void MyLcd_Reset(void)
{
  GPIO_SetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
  delay_ms(100);
  GPIO_ResetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
  delay_ms(100);
  GPIO_SetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
  delay_ms(200);
}


void LCD_Configuration(void)
{
  LCD_IO_Init();                //IO口初始化
  
  FSMC_LCD_Init();              //FSMC初始化
  
  Lcd_BackLightOn();
  Lcd_BackLightOff();
  Lcd_BackLightOn();
  MyLcd_Reset();
  
  MyLcd_WriteReg(0x0083,0x0002);
  MyLcd_WriteReg(0x0085,0x0003);
  MyLcd_WriteReg(0x008B,0x0000);
  MyLcd_WriteReg(0x008C,0x0093);
MyLcd_WriteReg(0x0091,0x0001);
MyLcd_WriteReg(0x0083,0x0000);


MyLcd_WriteReg(0x003E,0x00B0);
MyLcd_WriteReg(0x003F,0x0003);
MyLcd_WriteReg(0x0040,0x0010);
MyLcd_WriteReg(0x0041,0x0056);
MyLcd_WriteReg(0x0042,0x0013);
MyLcd_WriteReg(0x0043,0x0046);
MyLcd_WriteReg(0x0044,0x0023);
MyLcd_WriteReg(0x0045,0x0076);
MyLcd_WriteReg(0x0046,0x0000);
MyLcd_WriteReg(0x0047,0x005E);
MyLcd_WriteReg(0x0048,0x004F);
MyLcd_WriteReg(0x0049,0x0040);


MyLcd_WriteReg(0x0017,0x0091);
MyLcd_WriteReg(0x002B,0x00F9);
delay_ms(10);
MyLcd_WriteReg(0x001B,0x0014);
MyLcd_WriteReg(0x001A,0x0011);
MyLcd_WriteReg(0x001C,0x0006);
MyLcd_WriteReg(0x001F,0x0042);
delay_ms(20);
MyLcd_WriteReg(0x0019,0x000A);
MyLcd_WriteReg(0x0019,0x000A);
delay_ms(40);
MyLcd_WriteReg(0x0019,0x0012);
delay_ms(40);
MyLcd_WriteReg(0x001E,0x0027);
delay_ms(100);

MyLcd_WriteReg(0x0024,0x0060);
MyLcd_WriteReg(0x003D,0x0040);
MyLcd_WriteReg(0x0034,0x0038);
MyLcd_WriteReg(0x0035,0x0038);
MyLcd_WriteReg(0x0024,0x0038);
delay_ms(10);
MyLcd_WriteReg(0x0024,0x003C);
MyLcd_WriteReg(0x0016,0x001C);
MyLcd_WriteReg(0x0001,0x0006);
MyLcd_WriteReg(0x0055,0x0000);
MyLcd_WriteReg(0x0002,0x0000);
MyLcd_WriteReg(0x0003,0x0000);
MyLcd_WriteReg(0x0004,0x0000);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteReg(0x0006,0x0000);
MyLcd_WriteReg(0x0007,0x0000);
MyLcd_WriteReg(0x0008,0x0001);
MyLcd_WriteReg(0x0009,0x008f);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteIndex(0x0202);


//MyLcd_Clear(YELLOW);

MyLcd_Clear(0xFFE0);



}

#define OS_TICKS_PER_SEC 100
void  SysTickInit (void)
{
      //嘀嗒时钟配置为10ms中断, 自动重装载,使能中断
      //嘀嗒时钟源来自HCLK = 72MHz(为0则来自HCLK/8)
        if (SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC))
          {
            /* Capture error */
            while (1);
          }
}

/*******************************************************************************
* Function Name  : delay_us
* Description    : 利用嘀嗒定时器实现的精确延时函数.
* Input          : DelayTime延时微妙数,范围:范围:嘀嗒定时器中断时间即0-10000.
* Output         : None
* Return         : None
* Date           : 30/06/2011
* Other          : 原理:嘀嗒时钟为72MHz,所以1us计数值为72M/1000000,当需要延时DelayTime
                   时,计数个数为DelayTime*72
*******************************************************************************/
void delay_us(uint16_t DelayTime)
{
  u32 start,total,diff = 0;
  u32 count = 0;
  u32 temp;
  temp  = SystemCoreClock / OS_TICKS_PER_SEC; //定时器最大脉冲数
  start = SysTick->VAL;                       //定时器寄存器当前值记下
  total = 1000000/OS_TICKS_PER_SEC;           //延时最大微妙值
  if(DelayTime > total) DelayTime = total;    //输入超过最大值,则只执行最大值
  total = DelayTime *(SystemCoreClock/1000000); //需要计算的脉冲个数
   while(diff < total)
  {
    count = SysTick->VAL;                     //
    if(start < count)
      diff = temp - (count - start);          //定时器溢出时
    else
      diff  = start -count;                   //定时器未溢出时
  }
}
//------------------------------------------------------------------

/*******************************************************************************
* Function Name  : delay_ms
* Description    : 利用嘀嗒定时器实现的精确延时函数.
* Input          : DelayTime延时毫秒数.
* Output         : None
* Return         : None
* Date           : 30/06/2011
* Other          :
*******************************************************************************/
void delay_ms(uint16_t DelayTime)
{
    uint16_t i;
    for(i = 0; i < DelayTime; i++)
      delay_us(1000);
}
////////////////////////////////////////////////////////////////////////////////

//往RAM中写入数据。RS=1,表示写数据,RS= 0表示写寄存器
void MyLcd_WriteRAM(u16 data)
{
  *(volatile u16 *) (LCD_Data_Addr) = data;
}

//往某个地址的寄存器中写数据
void MyLcd_WriteReg(u16 index,u16 dat)
{
  *(volatile u16 *) (LCD_Reg_Addr) = index;
  *(volatile u16 *) (LCD_Data_Addr) = dat;
}

//往寄存器中写数据
void MyLcd_WriteIndex(u16 Index)
{
  *(volatile u16 *) (LCD_Reg_Addr) = Index;
}

//设置某个点的颜色
void LCD_SetPixel(uint16_t x,uint16_t y,uint16_t color)
{
  MyLcd_WriteReg(0x0003,x);
  MyLcd_WriteReg(0x0007,y);
  MyLcd_WriteIndex(0x0022);       
  MyLcd_WriteRAM(color);
}

void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
  MyLcd_WriteReg(0x0003,x1);
  MyLcd_WriteReg(0x0006,y1>>8);
  MyLcd_WriteReg(0x0007,y1);
  MyLcd_WriteReg(0x0005,x2);
  MyLcd_WriteReg(0x0008,y2>>8);
  MyLcd_WriteReg(0x0008,y2);
  MyLcd_WriteIndex(0x0022);
}

void MyLcd_Clear(u16 color)
{
  u32 temp,end;;
  LCD_SetWindow(0,0,LCD_XSIZE-1,LCD_YSIZE-1);
  end = LCD_XSIZE * LCD_YSIZE;
  for (temp = 0; temp < end; temp++)
  {
    MyLcd_WriteRAM(color);
  }
}
求好心人稍微详细点解读下这个程序.....最好一步步对应来...拜托了....
沙发
mmuuss586| | 2014-5-25 09:43 | 只看该作者

晕,程序都已经有注释了

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
wzk1017 + 1 赞一个!
板凳
mmuuss586| | 2014-5-25 09:44 | 只看该作者
有一段,FSMC初始化部分,未注释,你网上查下就知道了

使用特权

评论回复
地板
wzk1017|  楼主 | 2014-5-25 09:58 | 只看该作者
mmuuss586 发表于 2014-5-25 09:44
有一段,FSMC初始化部分,未注释,你网上查下就知道了

高手..能加下QQ  1063955636不..求帮助.拜托了

使用特权

评论回复
5
wzk1017|  楼主 | 2014-5-25 10:04 | 只看该作者
mmuuss586 发表于 2014-5-25 09:43
晕,程序都已经有注释了

高手~求帮忙啊~关乎能不能毕业啊~~求好心人加扣扣1063955636...麻烦了~~~~

使用特权

评论回复
6
mmuuss586| | 2014-5-25 10:08 | 只看该作者
wzk1017 发表于 2014-5-25 10:04
高手~求帮忙啊~关乎能不能毕业啊~~求好心人加扣扣1063955636...麻烦了~~~~

自己对照着看下吧
FSMC.rar (3.21 MB)

使用特权

评论回复
7
wzk1017|  楼主 | 2014-5-25 15:00 | 只看该作者
mmuuss586 发表于 2014-5-25 10:08
自己对照着看下吧

完完全全的小白....老师让参考这个做毕业设计........死翘翘了..还是希望大神有空能帮下- -万分感谢..

使用特权

评论回复
8
dingsujie| | 2014-5-25 16:20 | 只看该作者
FSMC你可以看看STM32的规格书讲得比较详细;也可以看看刘火良的《STM32库开发实践指南》

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝