【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记
1. 引言
因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9),本人之前没有接触过这款单片机,为了维护老产品不得不重新研究研究这款单片机。
10位ADC + LCD的增强型8051微控制器
SH79F9202是一种高速高效率8051可兼容单片机。在同样振荡频率下,较之传统的8051芯片它有着运行更快速的优越特性。
SH79F9202保留了标准8051芯片的大部分特性。这些特性包括内置256字节RAM,2个UART,外部中断0/2/3和外部中断4(8路输入)。此外,SH79F9202还集成了外部1280字节RAM,以及程序存储的最大32K字节Flash,此外还集成了最大4K类EEPROM,用于在系统掉电后保存数据。
SH79F9202不仅集成了如UART等标准通讯模块,此外还集成了LCD驱动器(内建LCD电压稳定电路、电容型偏压电路和电阻型偏压电路),PCA,PWM,10Bit ADC等模块。
为了达到高可靠性和低功耗,SH79F9202内建看门狗定时器,低电压复位功能及系统时钟监控功能。此外SH79F9202还提供了2种低功耗省电模式。
2. 开发环境搭建
- 所需硬件
- SH79F9202U 电路板
- LCD段码液晶屏
- SinoLink Plus 仿真器(见1.文档中的《中颖仿真器使用手册》)
- 所需软件
- Keil C51编译器 C51V961(见2.中颖开发工具包)
- keil插件集成包】Sinowealth_KEIL_Setup_V3.8.13.9.1.7(见2.中颖开发工具包)
- 开发环境安装与配置
- Keil μVision 安装好后要根据需要,代码里面的寄存器初始化和keil里面的代码选项配置保持一致。
- Keil μVision 安装好后要根据需要,代码里面的寄存器初始化和keil里面的代码选项配置保持一致。
3. SH79F9202U单片机资源介绍
基本IO介绍
// Note:配置为输出时,对应的IO上拉需关闭以降低功耗
void IO_Init()
{P0PCR = 0x00; //端口上拉电阻控制寄存器P0CR = 0XFF; // 端口控制寄存器 0:输入模式1:输出模式P0 = 0X00; //端口数据寄存器P0_4 = 1; // P0.4端口输出高电平P1PCR = 0X00;P1CR = 0XFF;P1 = 0X00;P2PCR = 0X00;P2CR = 0XFF;P2 = 0X00;P3PCR = 0X00;P3CR = 0XFE;P3 = 0X00;P4PCR = 0X00;P4CR = 0XFF;P4 = 0X00;P5PCR = 0X04; // 开启上拉P5CR = 0XFB; // P5_2 输入模式P5 = 0X00; //P5_2 input
}
中断
更加详细的中断介绍还是要仔细看芯片手册,这里为了方便查阅放几张截图。
定时器外设
- 注意:定时器的相关寄存器配置和Keil软件上的程序选项配置保持一致
#include "timer2.h"// 20ms
void INT_TIMER2(void) interrupt 5
{ static unsigned char counter = 0;TF2 = 0; // 清除中断标志++counter;if(counter >= 25) // 500ms{Test_Num++;
// P0_4 = !P0_4; // 翻转输出counter = 0;}LCD_Data_OK(Test_Num);// LCD显示内容LCD_Data_Show();
}void Delays(int del)
{while(del--);
}//OSC = 24M
//sysclk OSC / 2 = 12M
void Timer2_Init(void)
{CLKCON = 0x08; //【打开HFON】内部24MHz RC振荡器Delays(2000); //至少等待振荡器预热时间 CLKCON |= 0x04; //【选择FS】24M/8M Hz为OSCSCLKCLKCON |= 0x20; //【分频器CLKS[0:1]】fSYS = fOSCS/2//12M/12 = 1M = 1us(T=1/f) 定时20ms P0PCR = 0x00; // 输出模式 关闭上拉电阻P0CR |= 0X10; // P0_4 GPIO设置为输出模式 T2CON = 0; // 停止定时器2T2MOD = 0x00; // TCK = 12/12 = 1M 系统时钟的1/12|P1.0时钟输入或IO端口|递增计数/*如果EXEN2 = 0,定时器2递增到0FFFFH,在溢出后置起TF2位,同时定时器自动将用户软件写好的寄存器RCAP2H和RCAP2L的16位值装入TH2和TL2寄存器。
*///初始值 45535 2^16=65536 TH2 = 45535 >> 8; // 取高位(177=1011 0001) = 1011 0001 1101 1111 >> 8 TL2 = 45535 & 0x00FF; // 取低位 (223=1101 1111) = 1011 0001 1101 1111 & 0000 0000 1111 1111 // TH2+TL2 = 1011 0001 1101 1111 =45535//重载值 45535RCAP2H = 45535 >> 8;RCAP2L = 45535 & 0x00FF; //重载值// 自动重载值=65536-45535=20001IEN0 |= 0x20; //开中断 定时器2溢出中断T2CON |= 0x04; //开始定时器2 即寄存器0000 0100EA = 1; // 开启总中断
// while(1);
}//IPL1 = 0X01;
//IPH1 = OX01;
4. LCD段码液晶屏参数介绍
- LCD段码液晶屏技术参数
5. 根据LCD液晶屏的真值表写数字译码和驱动程序
根据液晶屏的工作原理和真值表的结构,设计一个数字译码算法,将数字或字符转换为对应的 SEG 和 COM 值。
LCD 真值表
数字译码
基于真值表,编写数字译码表和相应的驱动程序。
源文件 LCD.c
:
#include "LCD.h"xdata unsigned char LCD_SEG[SEGSIZE] _at_ 0x500; // LCD显示地址 指定位置为0x500//时间/频率/电压显示 // 0 1 2 3 4 5 6 7 8 9
const unsigned char Disp_Code[]={0xf5,0x05,0xd3,0x97,0x27,0xb6,0xf6,0x15,0xf7,0xb7,// 不带小数点显示
0xfd,0x0d,0xdb,0x9f,0x2f,0xbe,0xfe,0x1d,0xff,0xbf // 带小数点显示
};//显示数字译码//功率显示 // 0 1 2 3 4 5 6 7 8 9
const unsigned char DispPower_Code[]={0xfd,0x85,0xdb,0x9f,0xa7,0xbe,0xfe,0x95,0xff,0xbf};// 数字译码 "POWER" ":" "."这几个符号常亮//Note:需在(Keil C51)Option中进行选择LCD为电容型
//为更有效的使用电容型LCD驱动器,用户必须先设置PUMPON,LCDON位之外的所有控制位,然后设置PUMPON位,
//在延迟之后(至少50ms)打开LCD,即LCDON位置1,点亮LCD面板;
void LCD_Init(void)
{unsigned char i,j;LCDCON = 0x4F; //0100 1111 LCDON|PUMPON|DUTY(1/4占空比,1/3偏置)|TYPESEL| 1111:VLCD = 1.000VDD 注意:当选择电容型LCD驱动时,此4位无效LCDCON1 = 0x00; // 电阻型LCD驱动控制器寄存器DISPCLK0 = 0x00; // LCD驱动时钟分频寄存器 1/4 128K RC 对应的LCD帧频为256/4=64HzDISPCLK1 = 0x03; // LCD驱动Pump寄存器 4KLCDSEL = 0x00; // 闪烁模式控制寄存器 00 无闪烁功能// 模式选择寄存器P0SS = 0x83 ; // P0_7/1/0 作为SEG13~15P1SS = 0xFF ; // P1_7-P1.0作为SEG5~12P2SS = 0xFF ; // P2_7-P2_4作为COM1~COM4 , P2_3-P2_0 即SEG1~4 P3SS = 0x00 ; // P3_7-P3_0作为I/O,SEG25~32P4SS = 0x00 ; // P4_6-P4_0作为I/0,SEG18~24P5SS = 0x0C ; // P5_3/2 作为SEG16/17for(i=0;i<250;i++) // Delay 50ms 以上再打开LCD 模块{for(j=0;j<250;j++);}LCDCON |= 0X80; // 打开 LCD 模块
}void LCD_Show(unsigned char udata)
{unsigned char i;for(i=0;i<SEGSIZE;i++){LCD_SEG[i] = udata;}}// 数据处理
void LCD_Data_Show(void){// 电压 /频率/时间显示LCD_SEG[0] = Disp_4H; // 千位LCD_SEG[1] = Disp_4L;LCD_SEG[2] = Disp_3H; // 百位LCD_SEG[3] = Disp_3L;LCD_SEG[4] = Disp_2H; // 十位LCD_SEG[5] = Disp_2L;LCD_SEG[6] = Disp_1H; // 个位LCD_SEG[7] = Disp_1L;// V H z 时钟符号显示 LCD_SEG[8] = 0x03;// 功率显示LCD_SEG[14] = DispPower_3H; LCD_SEG[13] = DispPower_3L; // 百位LCD_SEG[12] = DispPower_2H; LCD_SEG[11] = DispPower_2L; // 十位LCD_SEG[10] = DispPower_1H; LCD_SEG[9] = DispPower_1L; // 个位// 油位显示LCD_SEG[15] = 0x0f;LCD_SEG[16] = 0x0f;
//
}void LCD_Data_OK(unsigned long disp_data){//Disp_Data = disp_data;b4 = Disp_Data /1000%10; // 千位b3 = Disp_Data /100%10; // 百位b2 = Disp_Data /10%10; // 十位b1 = Disp_Data %10; // 个位 // 带小数点显示
// b4 = Disp_Data /1000%10 + 10; // 千位
// b3 = Disp_Data /100%10 + 10; // 百位
// b2 = Disp_Data /10%10 + 10; // 十位
// b1 = Disp_Data %10; // 个位 //------------------------------------------------------------------Disp_4H = (Disp_Code[b4])>>4;Disp_4L = (Disp_Code[b4])&0x0F;Disp_3H = (Disp_Code[b3])>>4;Disp_3L = (Disp_Code[b3])&0x0F;Disp_2H = (Disp_Code[b2])>>4;Disp_2L = (Disp_Code[b2])&0x0F;Disp_1H = (Disp_Code[b1])>>4; // 个位Disp_1L = (Disp_Code[b1])&0x0F;//------------------------------------------------------------------ DispPower_3H = (DispPower_Code[b3])>>4;DispPower_3L = (DispPower_Code[b3])&0x0F;DispPower_2H = (DispPower_Code[b2])>>4;DispPower_2L = (DispPower_Code[b2])&0x0F;DispPower_1H = (DispPower_Code[b1])>>4;// 个位DispPower_1L = (DispPower_Code[b1])&0x0F;if(Disp_Data < 1000) // 当显示数值是"0321"时,不显示前面的"0" {Disp_4H = 0;Disp_4L = 0;if(Disp_Data < 100){Disp_3H = 0;Disp_3L = 0;if(Disp_Data < 10){Disp_2H = 0;Disp_2L = 0;}}}
}
头文件LCD.h
#ifndef __LCD_H
#define __LCD_H#include "SH79F9202.h"
#include "cpu.h"#define SEGSIZE 17extern xdata unsigned char LCD_SEG[SEGSIZE]; // LCD显示地址 指定位置为0x500//时间/频率/电压显示
extern const unsigned char Disp_Code[];
//功率显示
extern const unsigned char DispPower_Code[];static volatile unsigned long Disp_Data=0; // 显示数据static volatile unsigned char b1,b2,b3,b4; // 存放 个/十/百/千/万位的数值
static volatile unsigned char Disp_1H,Disp_1L,Disp_2H,Disp_2L,Disp_3H,Disp_3L,Disp_4H,Disp_4L; //显示数据预处理值
static volatile unsigned char DispPower_1H,DispPower_1L,DispPower_2H,DispPower_2L,DispPower_3H,DispPower_3L;//显示数据预处理值(功率)void LCD_Init(void);
void LCD_Show(unsigned char udata);
void LCD_Data_Show(void); // LCD显示内容
void LCD_Data_OK(unsigned long disp_data);#endif
资料下载
- 参考资料和文献
- 示例代码下载链接
参考资料
- 【CSDN】编程圈子-谢厂节的博客
相关文章:

【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记
1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9),本人之前没有接触过这款单片机,为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…...

人工智能初识
🌞欢迎来到人工智能基础的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2024年5月1…...
【算法刷题day60】Leetcode:84. 柱状图中最大的矩形
文章目录 Leetcode 84. 柱状图中最大的矩形解题思路代码总结 草稿图网站 java的Deque Leetcode 84. 柱状图中最大的矩形 题目:84. 柱状图中最大的矩形 解析:代码随想录解析 解题思路 反方向接雨水。见上一篇文章 代码 class Solution {public int la…...

ThingsBoard物联网网关在智慧城市数据采集中的应用
智慧城市由监控中心、采集网关、前端采集设备、前端感应执行器组成。 为何选用ThingsBoard作为平台 监控中心为物联网平台,该平台包含云计算、大数据、人工智能、物联网、GIS、云安全等主要模块,具备数据采集、数据交换、超大规模计算、数据分析、数据应…...
Java中的打印流PrintStream 和 PrintWriter
PrintStream和PrintWriter在Java中都是用于打印输出的类,但它们之间存在一些明显的区别。以下是关于这两个类的详细解释和比较: PrintStream 基本特性 PrintStream是一个字节打印流,它继承自FilterOutputStream。 主要操作byte流࿰…...

【MATLAB源码-第217期】基于matlab的16QAM系统相位偏移估计HOS算法仿真,对比补偿前后的星座图误码率。
操作环境: MATLAB 2022a 1、算法描述 高阶统计量(HOS)频偏估计算法 高阶统计量(Higher Order Statistics, HOS)频偏估计算法是一种先进的信号处理技术,广泛应用于现代数字通信系统中,以应对…...
C# CryptoStream流的详解与示例
在当今数字时代,数据安全变得越来越重要。保护敏感信息免受未授权访问是每个开发者的责任。在C#中,使用CryptoStream流可以方便地对数据进行加密和解密。本文将详细介绍C# CryptoStream库的用法、功能以及它如何对数据进行加密和解密。 一、CryptoStrea…...
Kubernetes 之 ReplicaSet
Kubernetes 之 ReplicaSet ReplicaSet 定义 ReplicaSet 是 Kubernetes 中的一种副本控制器,其主要作用是控制其管理的 Pod 的预设副本数量。它会持续监听这些 Pod 的运行状态,在Pod发生故障时执行重启策略,当 Pod 数量减少时会重新启动新的…...

转发和重定向
目录 是什么 转发(Forwarding) 概念 特点 实现方式 重定向(Redirecting) 概念 特点 实现方式 转发和重定向区别整理 转发和重定向的适用场景 转发(Forwarding) 重定向(Redirect&am…...

源码部署ELK
目录 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 单节点 集群(3台节点集群为例) 启动 二、部署logstash 部署logstash 添加配置文件 启动 三、部署kiban…...

构造+模拟,CF1148C. Crazy Diamond
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1148C - Codeforces 二、解题报告 1、思路分析 题目提示O(5n)的解法了,事实上我们O(3n)就能解决,关键在于1,n的处理 我们读入数据a[],代表初始数组…...

CAD二次开发(2)-将直线对象添加到CAD图形文件
1. 准备工作 创建一个类库项目,如下: 2. 分析Line对象 Line类的初始化方法和参数 using Autodesk.AutoCAD.DatabaseServices; Line line new Line();Line 继承Curve 继承Entity 继承DBObject 继承Drawable 继承RXObject 初始化方法有两个…...
代码随想录二刷 Day05 | 242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和,454.四数相加II,383. 赎金信
题目与题解 参考资料:哈希表理论基础 Tips: 一般哈希表都是用来快速判断一个元素是否出现集合里哈希表生成原理:先通过哈希函数将变量映射为hashcode,如果二者hashcode相同,再通过哈希碰撞方法(拉链法&…...

2024年四川省三支一扶报名流程图解✅
2024年四川省三支一扶报名流程图解✅ 🔴时间安排 1、报名时间:5月31日—6月4日17:00 2、资格初审时间:5月31日—6月5日17:00 3、准考证打印时间:6月25日—6月29日 4、笔试时间:6月30日 5、笔试成绩:7…...
js Dom基础
获取元素 1、getElementById() 通过id属性获取一个元素节点对象 <div id"div1"></div> <script> var div1 document.getElementById(div1) </script> 2、 getElementsByTagName()可以根据标签名来获取一组元素节点对象 这个方法会给我们返…...
pytest识别测试用例的机制以及和unittest的区别
pytest识别测试用例的机制 文件 以test_开头或以_test结尾的python文件,即test_xxx.py或xxx_test.py类,在第一点识别到的文件中的类,且满足一下任一条件: 1)以Test_开头,且没有__init__()初始化函数的类&a…...

民国漫画杂志《时代漫画》第17期.PDF
时代漫画17.PDF: https://url03.ctfile.com/f/1779803-1248612629-85326d?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络!...
[AIGC] Spring Boot 2 自定义 Starter 指南
Spring Boot 包含一系列的 “Starter POMs”,它们都是一些方便的依赖描述符,你可以在你的应用中导入。在一些情况下,你可能想创建自己的自定义 starter。以下是创建自己的 Spring Boot Starter 的步骤。 文章目录 1. 创建基本的 Maven 项目2.…...
HCIP综合实验命令
目录 一、配置IP地址 二、配置DHCP 三、配置静态路由(内网通) 四、配置缺省路由 (外网通) 五、配置缺省 (全网通) 六、防环配置 七、配置远程登录 八、修改优先级 九、配置MP-GROUP 十、配置ppp进…...
JS移动端设置mouseover,mouseleave有效么
在移动设备的浏览器环境中,mouseover 和 mouseleave 事件的行为与桌面浏览器有所不同,主要是因为移动设备的交互方式主要是基于触摸的,而不是基于鼠标的。 在移动设备上,当用户触摸屏幕时,通常会触发 touchstart 事件…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...