由于工作原因,需要做一个低功耗的红外遥控器。于是接触了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 A b 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的编译器还真是有点问题,对于一些语句的编译很不理想,容易出问题。编程的时候需要尽量简化语句,保证编译成功。否则有些问题真是找的头疼。。。