历史上的今天
返回首页

历史上的今天

今天是:2025年04月05日(星期六)

2020年04月05日 | SMS0658B 段式液晶显示例程

2020-04-05 来源:eefocus

头文件:

#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;

}

}

推荐阅读

史海拾趣

BERGQUIST公司的发展小趣事

BERGQUIST公司的故事始于上世纪,当时创始人敏锐地洞察到电子设备热管理的重要性。公司从研发高效热传导材料开始,逐渐在热管理技术领域建立起自己的声誉。初创时期,BERGQUIST面临着资金和技术双重挑战,但团队凭借对技术的执着追求和对市场的深刻洞察,成功开发出了一系列具有创新性的热管理产品,为公司的长远发展奠定了坚实基础。

amcc [applied micro circuits corp]公司的发展小趣事

BERGQUIST公司的故事始于上世纪,当时创始人敏锐地洞察到电子设备热管理的重要性。公司从研发高效热传导材料开始,逐渐在热管理技术领域建立起自己的声誉。初创时期,BERGQUIST面临着资金和技术双重挑战,但团队凭借对技术的执着追求和对市场的深刻洞察,成功开发出了一系列具有创新性的热管理产品,为公司的长远发展奠定了坚实基础。

DESOUTTER公司的发展小趣事

随着全球经济的不断发展,Desoutter公司开始实施国际化战略,积极开拓国际市场。公司通过与全球知名企业的合作,如大众集团、捷豹路虎集团等,成功进入了欧洲、北美等地区的市场。同时,Desoutter公司还在全球范围内建立了多个生产基地和研发中心,以更好地满足不同地区客户的需求。

Custom Connector Corporation公司的发展小趣事

Custom Connector Corporation成立于1969年,当时电子连接器行业正处于快速发展阶段。创始人看到这一市场潜力,决定投身于这一领域。在创业初期,CCC面临着资金紧张、技术瓶颈和市场认可度低等问题。然而,创始人凭借对技术的执着追求和对市场的敏锐洞察,带领团队不断研发新产品,改进生产工艺,逐渐在市场中树立了自己的品牌形象。

EEMB Co Ltd公司的发展小趣事

随着全球电子行业的快速发展和市场竞争的加剧,EEMB集团开始意识到单纯依靠锂电池产品已经难以满足市场的多元化需求。因此,公司开始积极探索新的业务领域和市场机会。通过收购和兼并等方式,公司逐渐将业务扩展到智能家居、可穿戴设备等领域,并成功推出了多款具有创新性和竞争力的新产品。这些新产品的推出不仅丰富了公司的产品线,也为公司带来了新的增长点。

EOZ S.A.S公司的发展小趣事

在电子行业日益关注环保和可持续发展的背景下,EOZ S.A.S公司积极响应号召,致力于绿色电子产品的研发和生产。公司采用环保材料替代传统材料,优化生产工艺降低能耗和废弃物排放。同时,EOZ S.A.S还推出了电子产品回收计划,鼓励消费者将废旧电子产品交给公司进行回收处理。这些举措不仅提升了公司的品牌形象,也为公司赢得了更多消费者的青睐。

问答坊 | AI 解惑

DC-DC转换器 XC6383系列.pdf

DC-DC转换器 XC6383系列该文章很详细的介绍了许多转换器系列的单片机很有收藏价值…

查看全部问答>

求助关于CORDIC算法求反正切

我看了一些关于CORDIC算法的资料,我现在想用CORDIC算法来实现求反正切,我想问一下求反正切时主要考虑一些什么问题?那些要考虑,那些不需要考虑?例如,校正因子K需不需要考虑,旋转方向采用什么方法判断比较有利。希望熟悉的大侠给点意见,非常 ...…

查看全部问答>

最easy的一个问题,VxWorks下怎么控制评估板上的LED ?

VxWorks + ARM7 4510 的评估板, 在ADS下裸机编程调试通过了的一个LED闪灯程序。 把它加入到一个在VxWorks下已经可以运行的程序里面去后。(当然相应的头文件都加上了的) 不能闪灯。 观察到运行到LED闪灯程序处时,闪灯程序直接被跳过。 这是什 ...…

查看全部问答>

稳压管的用法 第二弹

如图,此稳压管作用是什么?求教上面的VCC是24V,图中有错误。 [ 本帖最后由 5137796 于 2011-4-29 11:22 编辑 ]…

查看全部问答>

NEC研制新电池厚度仅0.3毫米

对很多人来说,有机游离基电池可能是个很陌生的名字。有机游离基电池由NEC所开发,和传统的锂电池比起来,有机游离基电池能做到更轻,更薄,更柔软,并且有高输出以及快速充电等特性。而现在,游离基电池的研究到达了一个新的高度:NEC研制出了厚度 ...…

查看全部问答>

Atmaga16学习板上有自带的东西(是二级管吗)来做流水灯吗

Atmaga16学习板上有自带的东西(是二级管吗)来做流水灯吗…

查看全部问答>

2015电子大赛控制类题目预测

欢迎大家一起讨论一下控制类题目的预测 …

查看全部问答>

關於MSP430F2553的IO控制

您好 现在要把2553写成UART to SPI(slave)的一个转换程式,但却碰到了一个问题。 SPI Master端也是用 2553完成的。 状况是Slave端的2553一直没办法读到Master发送过来的SPI data,读出的值都为0x00。 经过一些测试后,发现在slave端读取的SPI m ...…

查看全部问答>

求一款音频切换芯片

前面用过一款音频切换芯片(HEF4051BT)是一款八选一音频选择芯片(但是只能切换单声道音频),现在想找一款都能切换左右声道的的音频切换芯片,希望大家能给点建议。谢谢 …

查看全部问答>

从网上找了一个51开发板PCB 感觉并不怎么样 求高手指点一下它的优点

画板子也有半年了   经常画低频的板子    基本不需要ic元件    想要进一步的学习   所以就想从51开发板画起     从网上找了一个   据说可以直接打板子    & ...…

查看全部问答>