本帖最后由 crazyfool 于 2020-4-5 22:52 编辑
- //************************************************************
- // Copyright (c) 深圳市赛元微电子有限公司
- // 文件名称 : main.c
- // 作者 :
- // 模块功能 : LCD 显示code
- // 局部函数列表:
- // 最后更正日期:
- // 版本 : V1.0
- // 更改记录 : rom前256byte禁止查表,因此在编译的时候,设置keil->option for Target->BL51 Locate->Code Range:0x100
- //*************************************************************
- #include "LCD_INIT.h"
- /*
- 本测试电路使用的LCD与MCU的连接是:
- COM1 C4 P34
- COM2 C5 P35
- COM3 C6 P36
- COM4 C7 P37
- SEG1 S0 P33
- SEG2 S1 P32
- SEG3 S2 P31
- SEG4 S3 P30
- SEG5 S4 P10
- SEG6 S6 P12
- SEG7 S8 P14
- SEG8 S9 P15
- 可见,硬件上,COM注意要么接在COM0-COM3要么接在COM4-COM7,但SEG口随意
- 根据上述接线,要配置对应IO口为LCD输出
- 下面寄存器
- DDRCON
- OTCON
- 要根据LCD的实际参数而配置
- ** LCD规格:1/4 duty 1/3bias 3.3V
- */
- void LCD_Init(void) //DDIC配置为LCD,显示函数和配置需根据LCD屏进行修改
- {
- DDRCON = 0xB0; //-xyy zzzz x:LCD/LED模式 y:占空比 z:LCD电压调节
- P0VO = 0x00;
- P1VO = 0x35;
- P2VO = 0x00;
- P3VO = 0xFF;
- OTCON = 0x04; //---- xxyz x:LCD分压电阻 y:复位管脚选择 z:LCD偏置电压
-
- }
-
- //************************************************************
- // Copyright (c) 深圳市赛元微电子有限公司
- // 文件名称 : LCD_DISPLAY.c
- // 作者 :
- // 模块功能 : LCD 显示
- // 局部函数列表:
- // 最后更正日期:
- // 版本 : V1.0
- // 更改记录 : rom前256byte禁止查表,因此在编译的时候,设置keil->option for Target->BL51 Locate->Code Range:0x100
- //*************************************************************
- #include "lcd_display.h"
- static unsigned char xdata Display_Mode = 0;//0时钟 1NTC温度 2电压值 3DS18B20温度
- //-----------------------LCD编码表---------------------------
- static unsigned char code LcdCodeTab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0xff};
- //-----------------------编码表下标数据-----------------------
- static unsigned char xdata LcdDataTab[4] = {0,0,0,0};//即LCD待显示的数字
- //-----------------------LCD显示RAM配置-----------------------
- static unsigned char xdata LcdDisplay[28] _at_ 0x1000; //注意:不同LCD的RAM起始地址不同
- //-----------------------数据各位缓存变量
- static unsigned char xdata SEGA,SEGB,SEGC,SEGD,SEGE,SEGF,SEGG,SEGDP;//8个段不是有规律分配,需要处理
- /**************************************************
- *函数名称:void LcdSegData(unsigned char LcData,LcdSelCOM COMx)
- *函数功能:LCD显示数据转换
- *入口参数:LcdData LCD显示数据
- COMx COM口选择(取值范围:LCDCOM0~7)
- *出口参数:void
- *功能说明:LcdDisplay[]数组下标值必须根据所选择的SEG口对应
- **特别解读:程序中的COMx == LCDCOM0 等仅仅表示要写第几个位
- 并将数据写入对应的RAM区,仅仅是为了确定RAM地址
- ** LCD规格:1/4 duty 1/3bias 3.3V
- **************************************************/
- static void LcdSegData(unsigned char LcdData,LcdSelCOM COMx)
- {
- switch(Display_Mode)
- {
- case 0://时钟
- if(COMx == LCDCOM0)
- {
- LcdData |= 0x80;//显示冒号
- }
- break;
-
- case 1://NTC
- if(COMx == LCDCOM0)
- {
- LcdData = 0;//不显示
- }
- if(COMx == LCDCOM1)
- {
- LcdData = 0;//不显示
- }
- break;
-
- case 2://电压值
- if(COMx == LCDCOM0)
- {
- LcdData = 0;//不显示
- }
- if(COMx == LCDCOM2)
- {
- LcdData |= 0x80;//显示小数点
- }
- break;
-
- case 3://DS18B20温度
- if(COMx == LCDCOM0)
- {
- LcdData = 0;//不显示
- }
- if(COMx == LCDCOM1)
- {
- LcdData = 0;//不显示
- }
- break;
-
- default:break;
-
- }
- //如下四段,连在一个SEG
- SEGA = ((LcdData >> 0) & 0X01) << 4;
- SEGF = ((LcdData >> 5) & 0X01) << 5;
- SEGE = ((LcdData >> 4) & 0X01) << 6;
- SEGDP = ((LcdData >> 7) & 0X01) << 7;
-
- //如下四段,连在一个SEG
- SEGB = ((LcdData >> 1) & 0X01) << 4;
- SEGG = ((LcdData >> 6) & 0X01) << 5;
- SEGC = ((LcdData >> 2) & 0X01) << 6;
- SEGD = ((LcdData >> 3) & 0X01) << 7;
- //发送第0个字符对应的显示RAM区
- if(COMx == LCDCOM0)
- {
- LcdDisplay[0] = (0x00 |SEGA | SEGF | SEGE | SEGDP);
- LcdDisplay[1] = (0x00 |SEGB | SEGG | SEGC | SEGD);
-
- }
-
- //发送第1个字符对应的显示RAM区
- if(COMx == LCDCOM1)
- {
- LcdDisplay[2] = (0x00 |SEGA | SEGF | SEGE | SEGDP);
- LcdDisplay[3] = (0x00 |SEGB | SEGG | SEGC | SEGD);
- }
-
- //发送第2个字符对应的显示RAM区
- if(COMx == LCDCOM2)
- {
- LcdDisplay[4] = (0x00 |SEGA | SEGF | SEGE | SEGDP);
- LcdDisplay[6] = (0x00 |SEGB | SEGG | SEGC | SEGD);
- }
-
- //发送第3个字符对应的显示RAM区
- if(COMx == LCDCOM3)
- {
- LcdDisplay[8] = (0x00 |SEGA | SEGF | SEGE | SEGDP);
- LcdDisplay[9] = (0x00 |SEGB | SEGG | SEGC | SEGD);
- }
- }
- /**************************************************
- *函数名称:void LcdDisplay(void)
- *函数功能:LCD显示
- *入口参数:无
- *出口参数:void
- *功能说明:COM口必须跟使用的COM相对应
- **************************************************/
- void Lcd_Display(void)
- {
- switch(Display_Mode)
- {
- case 0://RTC 注意SEG1的P1段要点亮
- LcdDataTab[0] = DS1302_Tab[2] >> 4;//时
- LcdDataTab[1] = DS1302_Tab[2] & 0x0f;
- LcdDataTab[2] = DS1302_Tab[1] >> 4;//分
- LcdDataTab[3] = DS1302_Tab[1] & 0x0f;
- break;
-
- case 1://NTC温度
- LcdDataTab[0] = 0;
- LcdDataTab[1] = 0;
- LcdDataTab[2] = NTC_Val / 10;
- LcdDataTab[3] = NTC_Val % 10;
- break;
-
- case 2://电压值
- LcdDataTab[0] = 0;
- LcdDataTab[1] = Voltage_Val / 100;
- LcdDataTab[2] = Voltage_Val % 100 / 10;
- LcdDataTab[3] = Voltage_Val % 10;
- break;
-
- case 3://DS18B20温度值
- LcdDataTab[0] = 0;
- LcdDataTab[1] = 0;
- LcdDataTab[2] = DS18B20_Val / 10;
- LcdDataTab[3] = DS18B20_Val % 10;
- break;
-
- default:
- Display_Mode = 0;
- break;
-
- }
- LcdSegData(LcdCodeTab[LcdDataTab[0]],LCDCOM0);//发送第0个字符对应的RAM
- LcdSegData(LcdCodeTab[LcdDataTab[1]],LCDCOM1);//发送第1个字符对应的RAM
- LcdSegData(LcdCodeTab[LcdDataTab[2]],LCDCOM2);//发送第2个字符对应的RAM
- LcdSegData(LcdCodeTab[LcdDataTab[3]],LCDCOM3);//发送第3个字符对应的RAM
- }
- /**************************************************
- *函数名称:void Dis_Mode_Handle(void)
- *函数功能:LCD显示模式处理
- *入口参数:无
- *出口参数:void
- *功能说明:通过TK24实现改变显示模式
- **************************************************/
- void Dis_Mode_Handle(void)
- {
- Display_Mode ++;
- if(Display_Mode > 3)
- {
- Display_Mode = 0;
- }
- }
一、板载资源
1.电位器 - AIN3(与2实现多通道切换)测试ADC功能
2.NTC - AIN2 (与1实现多通道切换)实现廉价测温,使用乘除法器实现数据计算。这里只简单查表0-40°温度。
3.无源蜂鸣器 - PWM40 测试PWM
4.4个LED灯 - PWM50 - PWM53,可测试PWM、可作为TK指示灯
5.RGB灯珠(5050) - PWM41 -PWM42 ,测试PWM,颜色选择、占空比调节(测试TK长按功能)
6.DS18B20 - 单总线数字温度传感器,时序要求严格,测试定时器、IO口方向动态改变(输入输出快速切换),并与NTC测温做比较
7.4路TK - TK24 - TK27,这是重点之一,熟悉TK调试使用基本流程。
8.DS1302 - RTC,测试LCD,并用UART0实现RTC调整(带后备电池,可断电运行)
9.LCD - 4COM,8SEG,1/4占空比,1/3偏压,3.3V 测试硬件LCD功能。这是重点之二。
二、个人遇到的几个坑
1.PWM的占空比设定值注意不能超过PWM周期,假设周期为2000个数,则占空比应在0-2000之间设定;本人一开始,以12位PWM对应范围0-4095进行设置,以致无法实现预期的占空比调节。
2.TK设计时,对新手或不熟悉的用户来说,应充分阅读学习设计指南。比如走线、线距、敷铜等操作。
3.赛元单片机的GPIO有三种模式(推挽输出、高阻输入(上电默认)、上拉输入),无开漏输出(可程序实现),也不具备准双向功能,当某个IO口同时要作为输入输出时,应注意根据需要改变方向设置。
4.未用IO或封装未引出IO,都要设为推挽输出。
5.TK功能的IO要设为推挽输出,并且直接输出1。
6.使用T1作为串口0的波特率,注意不能启动T1,即TR1不能设为1。
7.官方给的8617Demo程序,定时器初始化部分,应该有误,此型号HRC为32MHz,不是16MHz
8.LCD在硬件设计时,对4COM的LCD而言,COM口只能分配在COM0 - COM3 或 COM4 - COM7,不能随意分配,但分配好COM之余,SEG则可以根据布局需要,随意分配,只需注意对应的型号的单片机的RAM区起始地址。然后根据LCD手册对应段所在位置(接在哪个SEG上,适当处理后,往对应的RAM地址丢数据即可;但这里要注意,如果COM接在COM0-COM3则对应RAM的低4位有效,若是接在COM4-COM7,则是对应RAM的高4位有效。
三、致谢
1.此硬件为第1版,期间多次请教网友、赛元技术支持、康力佳FAE,再次深表感谢!本人能力有限,未能全部领悟,请多包涵。
2.欢迎交流,请勿喷——我这个中年男子。
|