STM8L052C6 低功耗+LCD显示 经验分享

来源:互联网 发布:java 图片合成框架 编辑:程序博客网 时间:2024/05/01 06:46

由于工作原因,需要做一个低功耗的红外遥控器。于是接触了STM8L这系列低功耗单片机,因为我这个项目要求资源要求不高,所以选了052C6这款。32k flash,2Kbytes的RAM,还有EEPROM。资源很丰富,能满足很多场合的应用了。

这款单片机的低功耗宣称可以小于1uA,不过没什么实际意义,什么都没开的数据。我自己做实验,做一块最小系统版,halt模式下电流为3uA左右。IO口的状态不同,电流相差很大,经过实验发现GPIO_Mode_Out_OD_Low_Slow 模式下功耗最低。实际应用中应该按照IO口外接电路原理分析得到最佳状态。

进入低功耗模式很简单,一句 halt();就解决了。不过根据前人经验来说,最好在执行此语句前先关闭所有用到的外设时钟,设置好所有的中断和IO口状态。对了,halt模式下只能使用外部中断唤醒。halt模式比较简单,多花点时间调下就可以了。不过我在做的过程中也发现了同样的程序有时候功耗降不下来。推测与STVD编译器有关。


接下来说LCD,STM8L052C6这款单片机自带段式LCD驱动,非常方便经济。这个驱动函数刚开始写还真有点懵。仔细读英文的datasheet,加上网上找一些前人的经验贴逐渐明白了,其实还是很有意思的。下图是我的LCD的com和seg的相关参数。

根据上图,我用excel做了下面这张图。有了这张图,编程简单多了。


原因就是STM8L的LCD驱动是通过写LCD_RAM这个寄存器实现的。参考手册介绍如下图:


通过这张图可以清楚的发现LCD的每一个SEG口,COM口都对应着这些寄存器中的一位,只需要置一即可点亮这一段了。

注意:写这个LCD_RAM 寄存器的时候一定要先清0,再写,否则写不进去。



附LCD配置程序:

void LCD_Congfig(void)
{
  CLK_PeripheralClockConfig(CLK_Peripheral_LCD,ENABLE);   //启用或禁用指定的外围时钟
  CLK_RTCClockConfig(CLK_RTCCLKSource_HSI,CLK_RTCCLKDiv_64);      //必须配置RTC时钟源,HSI选为RTC时钟
    /*lcd初始化,*/
  LCD_Init(LCD_Prescaler_8,LCD_Divider_16,LCD_Duty_1_4,LCD_Bias_1_3,LCD_VoltageSource_Internal );//LCD_VoltageSource_External,LCD_VoltageSource_Internal
        /*lcd端口的配置*/  
        LCD_PortMaskConfig(LCD_PortMaskRegister_0,0Xff); // seg 0-7为     seg口
LCD_PortMaskConfig(LCD_PortMaskRegister_1,0X1f); // seg 8,9 12   为seg口
LCD_PortMaskConfig(LCD_PortMaskRegister_2,0X00); // 
LCD_PortMaskConfig(LCD_PortMaskRegister_3,0X00);


LCD_ContrastConfig(LCD_Contrast_Level_7);        //配置LCD的对比度0---7
LCD_DeadTimeConfig(LCD_DeadTime_1);              // 配置LCD液晶的死区时间0--7
LCD_PulseOnDurationConfig(LCD_PulseOnDuration_5);// 配置LCD脉冲持续时间0--7    
LCD_Cmd(ENABLE);    

}      

附LCD显示程序:

__CONST uint8_t  LCM_Num[17]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,0x77,0x1f,0x4e,0x3d,0x4f,0x47,0x00};

//按0abcdefg顺序 /*0    1   2  3   4  5   6  7 8  9   Ab c  d E  F none*/

void LCD_WriteNum1(u8 bNum)
{
   //COM0      
LCD->RAM[LCD_RAMRegister_0] &= (~0x02);
   LCD->RAM[LCD_RAMRegister_0] |= (uint8_t)((LCM_Num[bNum]&0x08)>> 2);// 1D
LCD->RAM[LCD_RAMRegister_0] &= (~0x01);
LCD->RAM[LCD_RAMRegister_0] |= (uint8_t)((LCM_Num[bNum]&0x04)>> 2);// 1E 
   //COM1  
LCD->RAM[LCD_RAMRegister_3] &= (~0x10);
   LCD->RAM[LCD_RAMRegister_3] |= (uint8_t)((LCM_Num[bNum]&0x01)<< 4);// 1G 
LCD->RAM[LCD_RAMRegister_3] &= (~0x20);
   LCD->RAM[LCD_RAMRegister_3] |= (uint8_t)((LCM_Num[bNum]&0x10)<< 1);// 1C  
   //COM2  
LCD->RAM[LCD_RAMRegister_7] &= (~0x02);
   LCD->RAM[LCD_RAMRegister_7] |= (uint8_t)((LCM_Num[bNum]&0x20)>> 4);// 1B
LCD->RAM[LCD_RAMRegister_7] &= (~0x01);
   LCD->RAM[LCD_RAMRegister_7] |= (uint8_t)((LCM_Num[bNum]&0x02)>> 1);// 1F 
   //COM3  
LCD->RAM[LCD_RAMRegister_10]&= (~0x10);
   LCD->RAM[LCD_RAMRegister_10]|= (uint8_t)((LCM_Num[bNum]&0x40)>> 2);// 1A
}

LCM_Num[bNum]根据你的LCD实际情况修改。


先这样吧。吐槽下STVD的编译器还真是有点问题,对于一些语句的编译很不理想,容易出问题。编程的时候需要尽量简化语句,保证编译成功。否则有些问题真是找的头疼。。。


0 2
原创粉丝点击