历史上的今天
今天是: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; } }
史海拾趣
|
我看了一些关于CORDIC算法的资料,我现在想用CORDIC算法来实现求反正切,我想问一下求反正切时主要考虑一些什么问题?那些要考虑,那些不需要考虑?例如,校正因子K需不需要考虑,旋转方向采用什么方法判断比较有利。希望熟悉的大侠给点意见,非常 ...… 查看全部问答> |
|
最easy的一个问题,VxWorks下怎么控制评估板上的LED ? VxWorks + ARM7 4510 的评估板, 在ADS下裸机编程调试通过了的一个LED闪灯程序。 把它加入到一个在VxWorks下已经可以运行的程序里面去后。(当然相应的头文件都加上了的) 不能闪灯。 观察到运行到LED闪灯程序处时,闪灯程序直接被跳过。 这是什 ...… 查看全部问答> |
|
对很多人来说,有机游离基电池可能是个很陌生的名字。有机游离基电池由NEC所开发,和传统的锂电池比起来,有机游离基电池能做到更轻,更薄,更柔软,并且有高输出以及快速充电等特性。而现在,游离基电池的研究到达了一个新的高度:NEC研制出了厚度 ...… 查看全部问答> |
|
您好 现在要把2553写成UART to SPI(slave)的一个转换程式,但却碰到了一个问题。 SPI Master端也是用 2553完成的。 状况是Slave端的2553一直没办法读到Master发送过来的SPI data,读出的值都为0x00。 经过一些测试后,发现在slave端读取的SPI m ...… 查看全部问答> |
|
从网上找了一个51开发板PCB 感觉并不怎么样 求高手指点一下它的优点 画板子也有半年了 经常画低频的板子 基本不需要ic元件 想要进一步的学习 所以就想从51开发板画起 从网上找了一个 据说可以直接打板子 & ...… 查看全部问答> |




