打着雨伞请教,关于万利板的LCDDEMO程序的疑问

千面魔军   2009-1-14 17:42 楼主

下面这段程序是从万利板的DEMO程序中抠出来的,看了半天,也只看到主程序循环中似乎只干了一件事,就是把那几个字母“STM32 LCD DEMO”,翻来覆去颠来倒去颠鸾倒凤地显示。
没有看到按键处理程序(不过好像看到了按键初始化代码),估计是在中断中?
更没有看到ADC处理程序,以及显示ADC结果的代码。
但是DEMO板上,通电后再按KEY2 后却可以看到,LCD显示内容被切换成了ADC结果。明明有这个功能,怎么程序里没有找到对应的代码呢?
 
(来源于C:ManleyEKBoardEKSTM32FLCDDemo(lcd+led+buttom)LCDDemo。。。)


/*******************************************************************************
* Function Name  : main
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{

#ifdef DEBUG
  debug();
#endif

  /* System Clocks Configuration */
  RCC_Configuration();

  /* GPIO ports pins Configuration */
  GPIO_Configuration();

  /* NVIC Configuration */
  NVIC_Configuration();

  /* Configure the systick */
  SysTick_Config();

  LcdShow_Init();
  Led_Config();
  Button_Config();

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource3);
  /* Configure EXTI Line9 to generate an interrupt on falling edge */
  EXTI_InitStructure.EXTI_Line = EXTI_Line3;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource4);
  /* Configure EXTI Line9 to generate an interrupt on falling edge */
  EXTI_InitStructure.EXTI_Line = EXTI_Line4;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  while(1)
  {
      write_string("STM3");  /*STM32 LCD demo*/
      delay();
      write_string("TM32");
      delay();
      write_string("M32 ");
      delay();
      write_string("32 L");
      delay();
      write_string("2 LC");
      delay();
      write_string(" LCD");
      delay();
      write_string("LCD ");
      delay();
      write_string("CD D");
      delay();
      write_string("D DE");
      delay();
      write_string(" DEM");
      delay();
      write_string("DEMO");
      delay();

  }
}

回复评论 (27)

呵呵,匠人也开始玩STM32了...

                                 可能都在中断程序中....
点赞  2009-1-14 17:49

有进步~~~比呼啦圈肯定好玩~~~

                                  
点赞  2009-1-14 17:53

是的,所有LCD的扫描都在中断程序中

                                 记得圈圈有一篇博客专门是分析这个LCD程序的,匠人可以找找看。
点赞  2009-1-14 18:06

哈哈~~~可以来这里看看拉...俺的是放在主程序中的,很直观..


没有放在定时器中哦...,方便分析时序。

http://blog.ednchina.com/computer00/142101/message.aspx
 
    LCD的驱动不像LED那样,加上电压(LED实际上是电流驱动)就可以长期显示的。LCD驱动必须使用交流电压驱动才能保持稳定的显示,如果在LCD上加上稳定的直流电压,不但不能正常显示,时间久了还会损坏LCD。一段LCD由背电极和段电极组成,需要显示时,在背电极和段电极之间加上合适的交流电压(通常使用方波)。为了调节对比度,可以调节方波中每半个周期中显示的时间(即占空比)来实现。
    通常,为了节约驱动口,将多个背电极连在一起,形成公共背电极端:COM。另外,再将属于不同COM的段电极连接在一起,形成公共段电极端:SEG。当在某个COM和某个SEG之间加了足够的交流电压之后,就会将对应的段点亮(实际上是变黑)。
    像万利的板子上使用的这种LCD,有4个COM,还有16个SEG。要想某一SEG显示时,需要在对应的SEG和COM之间加上足够的交流电压。在万利的板子上,COM驱动使用了两个电阻分压,输出电压为1/2Vcc,当不想让某位显示时,就将它的电压设置为1/2Vcc(通过设置IO口为高阻态来完成),这样加在对应的SEG和COM之间的电压只有1/2Vcc,不足以点亮对应的SEG。需要显示的,就将COM电压设置为0或者1,这样SEG电压跟COM电压相反的段就被点亮了(变黑),因为它们之间的电压为Vcc。通过定期扫描每个COM,即可稳定的在LCD上显示需要的图形了。需要显示字符或者数字时,自己先将对应的图案设计好,在显示时,发送到相应的SEG和COM上即可。但是如果使用100%的时间都驱动的话,会造成对比度太高,甚至出现不该显示的地方也显示了。因此在显示一段时间后,就将COM和SEG都设置为低,以关闭它的显示,降低对比度。通过调节关闭时间的长短(PWM),可以调节对比度。在下面的测试程序中,为了简化程序,使用了50%固定的占空比。
    为了方便描述,我们把COM为低电平时点亮叫做正亮,COM为高电平时点亮叫做负亮。扫描每个COM分成4个阶段:正亮,关闭,负亮,关闭。因此对于本板子上的LCD驱动,总共有16个状态,每个COM都有上面所说的4个状态。我们每隔2ms就切换一次状态,这样整个扫描周期就是2*16=32ms,基本上感觉不到闪烁。
    但是需要注意的是,这个LCD中的每个COM并不是刚好对应着显示图案中的一个字符的位置。每个COM都对应着每个显示字符中的相同4段!换句话说,要显示第一个字符位置的字符,每个COM都要被用到。因此,要改变某个字符位置的显示,就需要改变每次COM输出时对应的SEG中的4段。为此,建立一个缓冲区,当需要修改显示字符时,就修改缓冲区中的内容。这个缓冲区有4行,每行中有16个SEG,对应着一个COM。需要修改显示时,把每行中对应的4个SEG设置为需要的值,这样就实现了某个显示位置图案的修改。
    为了显示字符,需要事先把需要显示的字符按照SEG和COM的分布,制作成数据保存起来,需要显示时,就把它复制到显示缓冲区中对应的位置去。另外,由于输入的参数是字符的ASCII码,因此还需要将ASCII码转换为对应的字符图案的索引值。使用一个专门的函数来完成这些转换和填充缓冲区,在需要修改显示数据时,就调用该函数。
    为了方便大家对这个LCD的驱动方式和编程,下面简单的画一下驱动的波形图。

    这里只画出2个SEG波形图,实际有16个SEG,只要你理解了2个SEG的,那么16个的也是一样的意思。如图所示,所有偶数阶段都是关闭显示阶段,这时COM和SEG都是0,将不会有段被点亮,通过调节关闭显示阶段所占的时间百分比,即可调节总体显示的对比度。SEG和COM之间电平相差1格的显示不出来或者浓度不够,而SEG和COM之间电平相差2格的则可以显示出来或者浓度较深。例如第一阶段中的SEG1和COM1之间相差2格,第三阶段中COM1和SEG1相差2格,因而SEG1和COM1之间的交叉点(即点1)被显示。又如第九阶段的SEG1和COM3之间相差2格,第十一阶段中的COM3和SEG1之间相差2格,因而SEG1和COM3之间的交叉点(即点5)被显示出来。其它点以此类推。
    最后,再来看看万利板子上的LCD的COM和SEG之间的关系图,如下图所示。

    图中显示,S0、S1、S2、S3属于第一个字符,在显示第一个字符时,只要在对应的COM选中时,将需要显示的SEG放在上面即可。其余几个字符类似。例如要显示一个数字3,则应该将A段、B段、C段、D段、G段、K段显示。某段显示,用1表示,不显示用0表示,得到的各段值如下:
X=0 I="0" A="1" DP="0"
F=0 H="0" J="0" B="1"
E=0 G="1" K="1" C="1"
L=0 M="0" N="0" D="1"
注意是低位在先的,把每行用十六进制来表示(高位在先),就是0x4,0x8,0xE,0x8。它们分别对应着COM1~COM3选中时S3~S0的输出值。为了方便管理,将这4个十六进制值合并为一个2字节的值0x48E8保存。其它各字符的构造方式相同。显示时,分别取出各段的值写入到对应的缓冲区去。
扫描LCD的程序流程如下:
①、COM1设置为低电平,其余COM为1/2高电平,设置PE口为需要的电平(16个段码),延时2ms;
②、4个COM、PE口均设置为低电平,关闭显示,延时2ms;
③、COM1设置为高电平,其余COM为1/2高电平,设置PE口为需要的电平(第一步16个段码的取反),延时2ms。
④、4个COM、PE口均设置为低电平,关闭显示,延时2ms;
然后对剩下的3个COM重复前面4个步骤,这样一个完整的扫描就完成了。
具体的实现代码比较长,这里就不再贴出了,在工程包中的LCD.C中可以查看。该测试工程包使用软件延时的方法来实现LCD的扫描,实际使用时,可以将扫描代码放在定时器中断中处理。该测试程序使用一个时钟功能来演示LCD的显示,显示为xx分xx秒。从这里下载整个测试的工程包:

点赞  2009-1-14 18:11

哈哈,答非所问,答非所问。


谢谢,我的主要问题是在该DEMO程序中,没有找到ADC结果送显处理部分的程序代码。而不是问LCD驱动的原理。
另:打伞的目的是担心问题太菜,被人喷哈喇子,挡口水用的。
点赞  2009-1-14 20:03

呵呵,这雨伞打得很有些先见之明。

                                  
点赞  2009-1-14 20:14

ST的网站上有LCD的使用说明。

有时间可以下载看看。
看看这个链接的【STM32入门】,就是为初学STM32的朋友写的。
相关链接:http://blog.ednchina.com/netjob/152468/message.aspx
点赞  2009-1-14 22:08

无语中

                                  
点赞  2009-1-14 22:21

哈哈~

                                  
点赞  2009-1-14 22:44

没看过源程序

猜的,ADC结果送显处理部分的程序代码是不是这样?
   ADC的结果是通过DMA通道,传到显示部分的!你看看,有没有启动ADC的DMA?
点赞  2009-1-15 00:23

在中断中....有个SYSTICK和TIME2吧...

                                  
点赞  2009-1-15 08:40

请教 怎样可以补偿扭矩

在低速度下,电机如何补偿转矩,增加扭力。
三相无刷电机。

点赞  2009-1-15 09:01

应该是万历CD中的这个项目和灌在片子里运行的项目不是同一

你自己把这个项目灌进去,看看。应该没有ADC转换值的显示吧。

上传烧到板子里的demo
demo如下:
板子上电并且插上USB电缆后,
1.实现USB鼠标的功能,用Joystick可以控制四个方向键
2.通过KEY2可以切换LCD上显示"STM32 LCD DEMO"字样,还是当前ADC转换值。
(1)从ADC值到文字的切换,实时。
(2)从文字到ADC值的切换,不是实时,要等到完整的一串文字都显示完了,再开始显示ADC值。
3.切换的同时,四个LED亮/灭变化。

板子里的demo
点赞  2009-1-15 09:28

像匠人这种偶像级别的

                                  不能问问题,一问问题就显露出平常人的一面,影响形象和在FANS心目中的地位
点赞  2009-1-15 11:52

所以嘛,要带着雨伞来问问题

                                  
点赞  2009-1-15 12:15

呵呵,都是平常人...

都是平常人,何来影响形象和在FANS心目中的地位之说?
牛人就什么都会?
牛人就不用问问题?
技术领域无边无际,谁感说什么都会?
点赞  2009-1-15 12:20

上传万利板子里烧的demo

demo如下:
板子上电并且插上USB电缆后,
1.实现USB鼠标的功能,用Joystick可以控制四个方向键
2.通过KEY2可以切换LCD上显示"STM32 LCD DEMO"字样,还是当前ADC转换值。
(1)从ADC值到文字的切换,实时。
(2)从文字到ADC值的切换,不是实时,要等到完整的一串文字都显示完了,再开始显示ADC值。
3.切换的同时,四个LED亮/灭变化。
相关链接:https://bbs.eeworld.com.cn/upfiles/img/20091/2009115121230452.zip
点赞  2009-1-15 12:20

谢谢lut1lut

看了一下,这个差不多,至少看到程序里确实有了ADC送显的内容。这个程序与光盘里的内容确实不一样。

这样匠人就踏实了,否则还以为是自己弱智,连个代码都看不懂,差点晚节不保,呵呵。

再次感谢。


  while(1)
  {
    if (flag) 
    {
    // show adc value on lcd
    vu16 value = ADC_ConvertedValue;

    u8 num1 = value&0xf;
    u8 num2 = (value&0xff)>>4;
    u8 num3= (value&0xfff)>>8;
    u8 num4 = value>>12;
    if (num1>9)
      display[3]=num1+(65-10);
    else
      display[3]=num1+(48-0);
    
    if (num2>9)
      display[2]=num2+(65-10);
    else
      display[2]=num2+(48-0);
    
    if (num3>9)
      display[1]=num3+(65-10);
    else
      display[1]=num3+(48-0);
    
    if (num4>9)
      display[0]=num4+(65-10);
    else
      display[0]=num4+(48-0);
    
    write_string(display);  
    while(!flag_delay_500ms); // delay 0.5 second
      flag_delay_500ms = FALSE;
    }
    else
    {
      // show logo on lcd
      write_string("STM3");  
      while(!flag_delay_500ms); // delay 0.5 second
      flag_delay_500ms = FALSE;
      
      write_string("TM32");
      while(!flag_delay_500ms); // delay
      flag_delay_500ms = FALSE;
      
      write_string("M32 ");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("32 L");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("2 LC");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string(" LCD");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("LCD ");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("CD D");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("D DE");  
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string(" DEM");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
      
      write_string("DEMO");
      while(!flag_delay_500ms);
      flag_delay_500ms = FALSE;
    }
 }
}
点赞  2009-1-15 12:37

哈哈,不是弱智,据他们说叫 老年痴呆...呵呵~

                                  
点赞  2009-1-15 12:41
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复