头文件:
#ifndef _SMS0658B_LCD_H_
#define _SMS0658B_LCD_H_
/*
=========================================================================================================
SMS0658B 段式液晶结构图:
___A___
| |
F B
| |
---G---
| |
E C
|___D___| . --> H
例如: 如果要显示 '8', 则是 0xFE(从最高位到最低位一次是 FGEDABCH, 最低位表示小数点是 H).
再如: 显示 '4.', 则是 0xC6 | 0x01. 所以可根据上面的段序来组合意中的数字
=========================================================================================================
*/
//=========================================================================================================
// LCD 工作的配置信息常量
#define NOP10() {_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();}
#define NOP() {NOP10(); NOP10(); NOP10(); NOP10(); NOP10(); NOP10(); NOP10(); NOP10(); NOP10(); NOP10();}
// 显示小说点的掩码, H 位
#define DOT_MASK 0x01
// 空白显示
#define SPACE table[10]
// 下面是针对每个 LCD 的段选地址进行常量化
#define SEG_1 0
#define SEG_2 2
#define SEG_3 4
#define SEG_4 6
#define SEG_5 8
#define SEG_6 10
// LCD 序号
#define LCD_1 1
#define LCD_2 2
#define LCD_3 3
#define LCD_4 4
//=========================================================================================================
// 接口声明
// 液晶显示控制器进入睡眠模式以减少功耗
void LCD_Sleep(unsigned char n);
// LCD 初始化, 复位
void LCD_Reset(unsigned char n);
// LCD 频率显示函数
void LCD_Display_FRQ(unsigned int num, unsigned char n);
#endif
C文件:
#include #include #include "SMS0658B_LCD.h" //========================================================================================================= // 控制命令字 #define CMDOFF 0x00 #define CMDON 0x01 #define CMDLCDOFF 0x02 #define CMDLCDON 0x03 #define CMDB3C4 0x29 //SMS0658B 引脚说明 //PIN1: CS [片选信号输入] //PIN2: CLK [串行移位脉冲输入] //PIN3: DI [串行数据输入] //PIN4: VSS [电源地] //PIN5: VDD [电源正极] // 1 <= n <= 4 #define CS_SET(n) (P4 |= 1 << n) // 设置某位置高 #define CS_CLR(n) (P4 &= ~(1 << n)) // 清零某位置低 #define CS_FALLING_EDGE(n) {CS_SET(n); NOP(); NOP(); CS_CLR(n); NOP(); NOP(); } // 第 n 位引脚下降沿产生 // 数据和串行时钟引脚 sbit DIPIN = P0^5; sbit CLKPIN = P0^6; // 0 1 2 3 4 5 6 7 8 9 空白 - unsigned char code table[] = {0xBE, 0x06, 0x7C, 0x5E, 0xC6, 0xDA, 0xFA, 0x0E, 0xFE, 0xCE, 0xBE, 0x40}; //========================================================================================================= // 送入 1 位数据到 LCD 显示控制器 static void Trans_Bit(bit bit_data) { DIPIN = bit_data; // 送入数据到串行输入口 DI NOP(); CLKPIN = 1; // 时钟端口发送一个负脉冲 NOP(); CLKPIN = 0; NOP(); // 延时一会儿 CLKPIN = 1; } //========================================================================================================= // 送控制字到液晶显示控制器 // 参数: n表示选中的 LCD 序号 static void LCD_WC(unsigned char cmd, unsigned char n) { unsigned char i = 0; // 参数检查 if (n > 4 || n < 1) { return ; // LCD 序号错误 } CS_FALLING_EDGE(n); // CS 先产生下降沿 Trans_Bit(1); // 连续送入数据 100b 后再送入控制命令 NOP(); Trans_Bit(0); NOP(); Trans_Bit(0); NOP(); for (i = 0; i < 8; i++) { if((cmd & 0x80) == 0x80) { Trans_Bit(1); } else { Trans_Bit(0); } cmd <<= 1; NOP(); } Trans_Bit(0); NOP(); DIPIN = 1; CS_SET(n); // 送完后将对应的 LCD 片选端置高 } //========================================================================================================= void LCD_Reset(unsigned char n) { // 参数检查 if (n > 4 || n < 1) { return ; // LCD 序号错误 } LCD_WC(CMDOFF, n); // 掉电 LCD_WC(CMDLCDOFF, n); // 关闭 LCD_WC(CMDON, n); // 上电 LCD_WC(CMDLCDON, n); // 显示 LCD_WC(CMDB3C4, n); // 模式设置 } //========================================================================================================= // 液晶显示控制器进入睡眠模式减少功耗 // 参数: n 表示将对应的 LCD 设为睡眠状态 void LCD_Sleep(unsigned char n) { // 参数检查 if (n > 4 || n < 1) { return ; // LCD 序号错误 } LCD_WC(CMDLCDOFF, n); // 关闭液晶显示 LCD_WC(CMDOFF, n); // 进入睡眠状态, 此时 LCD 控制器电流小于 1uA } //========================================================================================================= // 发送 1 字节数据到液晶显示控制器 static void Trans_data(unsigned char address, unsigned char Byte_data, unsigned char n) { unsigned char i; // 参数检查 if (n > 4 || n < 1) { return ; // LCD 序号错误 } CS_SET(n); NOP(); CS_CLR(n); Trans_Bit(1); NOP(); Trans_Bit(0); NOP(); Trans_Bit(1); NOP(); // 地址处理 address <<= 2; for (i = 0; i < 6; i++) { if ((address & 0x80) == 0x80) { Trans_Bit(1); } else { Trans_Bit(0); } address <<= 1; NOP(); } // 送数据 for (i = 0; i < 8; i++) { if ((Byte_data & 0x01) == 0x01) { Trans_Bit(1); } else { Trans_Bit(0); } Byte_data >>= 1; NOP(); } DIPIN = 1; CS_SET(n); } //========================================================================================================= // LCD 频率显示函数, 高位为零时显示空白, 其余正常显示 0 // 参数: freq 表示将要显示的频率值, n 表示送入第几个 LCD 显示. // 输出: 无 // 注意: 如果, 将此函数放到定时中断内进行处理, 可能需要点时间, 影响其他操作的实时性. 所以, 尽量将 // 定时器中断频率降低, 不影响 void LCD_Display_FRQ(unsigned int freq, unsigned char n) { // 参数检查 if (n > 4 || n < 1) { return ; // LCD 序号错误 } if (freq > 137 || freq < 118) { return ; // 频率超出界限, 根据设置而定 } switch (n) { case 1: Trans_data(SEG_1, table[0], LCD_1); // 最低三位为精度根据情况, 暂时定为 0 Trans_data(SEG_2, table[0], LCD_1); Trans_data(SEG_3, table[0], LCD_1); Trans_data(SEG_4, table[freq % 10] | DOT_MASK, LCD_1); // 取个位显示, 后缀小数点 Trans_data(SEG_5, table[freq / 10 % 10], LCD_1); // 取十位显示 Trans_data(SEG_6, table[freq / 100], LCD_1); break; case 2: Trans_data(SEG_1, table[0], LCD_2); // 最低三位为精度根据情况, 暂时定为 0 Trans_data(SEG_2, table[0], LCD_2); Trans_data(SEG_3, table[0], LCD_2); Trans_data(SEG_4, table[freq % 10] | DOT_MASK, LCD_2); // 取个位显示, 后缀小数点 Trans_data(SEG_5, table[freq / 10 % 10], LCD_2); // 取十位显示 Trans_data(SEG_6, table[freq / 100], LCD_2); break; case 3: Trans_data(SEG_1, table[0], LCD_3); // 最低三位为精度根据情况, 暂时定为 0 Trans_data(SEG_2, table[0], LCD_3); Trans_data(SEG_3, table[0], LCD_3); Trans_data(SEG_4, table[freq % 10] | DOT_MASK, LCD_3); // 取个位显示, 后缀小数点 Trans_data(SEG_5, table[freq / 10 % 10], LCD_3); // 取十位显示 Trans_data(SEG_6, table[freq / 100], LCD_3); break; case 4: Trans_data(SEG_1, table[0], LCD_4); // 最低三位为精度根据情况, 暂时定为 0 Trans_data(SEG_2, table[0], LCD_4); Trans_data(SEG_3, table[0], LCD_4); Trans_data(SEG_4, table[freq % 10] | DOT_MASK, LCD_4); // 取个位显示, 后缀小数点 Trans_data(SEG_5, table[freq / 10 % 10], LCD_4); // 取十位显示 Trans_data(SEG_6, table[freq / 100], LCD_4); break; default: return; } }
设计资源 培训 开发板 精华推荐
- AD5347 并行接口、八路电压输出、10 位 DAC 的典型应用
- LTC1266,高精度微处理器电源
- RSO-1209DZ ±9V、56mA输出DC/DC转换器的典型应用电路
- 使用 Analog Devices 的 LTC1771EMS8 的参考设计
- LT6656AIS6-1.25、1.25V 扩展电源范围电压基准的典型应用
- MIC4826 EL 驱动器,用于 180VPP 电压的 2in/2 灯
- LT3467,单节锂离子电池至 5V 升压转换器
- LT1086IT 用于遥感的低压差正稳压器的典型应用
- AD8601ARTZ-R2 高端运算放大器电流监视器的典型应用
- 5.8V 直流转直流单路输出电源
- ADI有奖下载活动之17:变频驱动及电源设计中的隔离技术
- 逛村田在线云展厅,看干货,闯关赢好礼!
- 感谢有你,感恩龙年,EEWORLD陪你一起“闹”龙年!
- 瑞萨电子颠覆传统理念的嵌入式开发平台 Renesas Synergy™ 评估套件震撼来袭!答题即可免费申请!
- ADI & 世健 新基建系列第一期——工业以太网 答题赢好礼!
- 【泰有聊】第三期:参与泰克揭秘探头行动,瓜分2019元新年红包
- 有奖直播|TI 新一代Sitara™ AM62处理器革新人机交互——产品介绍和相关资源
- 下载送好礼|人工智能物联网时代即将来临,您准备好了吗?
- 拆招有礼:洞悉电子产品中的大数据,招招解决测量难题!Keysight DAQ970系列活动