使用单片机FPS122驱动TM1652 LED屏
一:TM1652介绍
TM1652 是一款LED(发光二极管、数码管、点阵屏)驱动控制专用芯片,内部集成了数字通讯电路、 解码电路、数据锁存器、震荡器、LED驱动电路。通讯方式采用异步串口通信(UART)协议,因芯片只 接收单片机发来的数据,仅需要单片机的一个TX端口发送数据给芯片即可,实现单线通讯;在显示驱动 方面,芯片采用动态扫描方式,两种显示模式可选,8级段驱动电流可调,16级位占空比可调;
本芯片采用异步串口通信(UART)协议,工作原理是将传输数据的每个字符以串行方式一位接一位 的传输。下图给出了其工作模式:
TM1652 每一位的时间为:52us
。
//重点
其中每一位(bit)的意义如下:
▲起始位:为由高变低,低电平时间为一位的时间,表示传输字符的开始。
▲数据位:紧跟起始位之后,D0-D7,低位先发。
▲校验位:为一位的时间,如果 8 位数据位中 1 的个数为奇数,该位设为 0(置低电平),否则为 1(置
高电平)。
▲停止位:置高。时间为一位的时间,它是发送完一个字符数据的结束标志。
▲空闲位:置高。如果空闲位置高的时间大于 3ms,TM1652 就认为本次数据帧结束,本次数据从暂存器
打入相应寄存器开始控制芯片输出。如果一帧数据传输没有结束,那么建议设置空闲位时间范围在
0-0.5ms 以内。
TM1652 的一帧数据包括以下两种形式:
⑴ 显示地址命令+显示数据;
⑵ 显示控制命令+显示控制调节命令。
波特率:是衡量数据传输速率的指针。表示为每秒钟传送的二进制位数(bit 数)。例如资料传送速率 为 120 字符/秒,而每一个字符为 11 位,则其传送的波特率为 11×120=1320 bit/秒=1320
波特。TM1652 支持波特率范围为:17500bps~21200bps,这里我们建议用 19200bps 即每位的
时间为:1s(秒)/19200≈52us(微秒)。所以 TM1652 支持的每位的时间范围为:
47us~57us。
二:以下是FPS122 驱动程序 MINI C
#include "extern.h"
UART_Clock => 8000000; //UART时钟,选择1M、2M、4M、8M,其他值默认1M,若使用其他值请咨询FAE
FPPA_Duty => _SYS(INC.FPPA_NUM); // Single FPPA = 1, Mult FPPA = 2 or 4/8/...
Baud_Rate => 19200; //波特率
UART_Out BIT PB.1; //发送端口
/***********************************
* 对应TM1652共阴数码管显示的数字 0~9
* 0 0x77
* 1 0x14
* 2 0x6E
* 3 0x3E
* 4 0x1D
* 5 0x3B
* 6 0x7B
* 7 0x16
* 8 0x7F
* 9 0x3F
* NULL 0x00
***********************************/
BYTE Buffer_Tab[11] = {0x77, 0x14, 0x6E, 0x3E, 0x1D, 0x3B, 0x7B, 0x16, 0x7F, 0x3F};
UART_Delay => ( (UART_Clock / FPPA_Duty) + (Baud_Rate/2) ) / Baud_Rate;
// + (Baud_Rate/2) : to round up or down
Test_V0 => UART_Clock / 1000 * 995;
Test_V1 => UART_Delay * Baud_Rate * FPPA_Duty;
Test_V2 => UART_Clock / 1000 * 1005;
#if (Test_V1 < Test_V0) || (Test_V1 > Test_V2)
.echo %Test_V0 <= %Test_V1 <= %Test_V2
.error Baud_Rate do not match to System Clock
#endif
BYTE cnt_1_buff;
byte SYS_CLKMD;
byte CLKMD_BK;
void Clock_Adjust(void)//时钟调整
{
CLKMD_BK = 0x34;//8M
CLKMD = CLKMD_BK;//将系统时钟修改为设定的UART时钟
nop;//等待
}
//发送程序
void UART_Send (void)
{
BYTE cnt;
BYTE cnt_1; //发送数据 1的个数计数
BYTE UART_Data_Out;
UART_Data_Out = A;
// Start Bit
set0 UART_Out; // 1
// .Delay UART_Delay - 10;
cnt = 8; // 2 ~ 3
cnt_1 = 0;
.Delay 3; // 4 ~ 6
do
{ // Data Bit * 8
.Delay UART_Delay - 10; //延时52us
sr UART_Data_Out; // 7
if (CF)
{
nop; // 10
cnt_1++; //对发送的8位数据中1的位数进行计数 用来奇偶校验
UART_Out = 1; // 1
}
else
{
UART_Out = 0; // 1
.delay 2; // 2 ~ 3
}
} while (--cnt); // 4 ~ 6
.Delay UART_Delay - 5; //延时52us
cnt_1_buff = 0;
cnt_1_buff = (cnt_1 & 0x01); //奇偶校验 当cnt_1_buff & 上1时 为1 则为奇数 否者为偶数
if(cnt_1_buff == 1) //奇数
{
set0 UART_Out; // 0
}
else //偶数
{
set1 UART_Out; // 1
}
.Delay UART_Delay - 2; //延时52us
// Stop Bit
set1 UART_Out; // 1
.Delay 2 * UART_Delay - 2;
}
void UART_HandShake (BYTE SendData) //数据发送
{
Clock_Adjust(); //将系统时钟修改为设定的UART时钟
//发送多组byte
A = SendData;
UART_Send();
.delay 416; //延时52us
CLKMD = SYS_CLKMD; //数据发送结束后,切回原来的系统时钟
nop;//等待
}
void UART_INIT(void)
{
SYS_CLKMD = CLKMD; //初始记录系统时钟,在UART通讯后方便切回系统时钟
$ UART_Out High,Out;//设置UART的通讯脚(发送信号)
.delay 100; //等待
UART_HandShake(0x08);
UART_HandShake(0x7F);
UART_HandShake(0x7F);
UART_HandShake(0x7F);
UART_HandShake(0x7F);
UART_HandShake(0x41);
.delay 1000000; //等待 1s
UART_HandShake(0x18);
UART_HandShake(0xFE); //4F
.delay 1000000; //等待 1s
}
TM1652显示数字格式有两种方式这里只介绍 一种 这种比较常用 为:
Command1:选择显示地址命令(0x08)
Data1~Data n:发送显示数据(最多6bytes)
Time:数据线置高时间(最小时间为3ms)
CommandX:选择显示控制命令(0x18)
CommandY:发送显示控制调节命令(包括位占空比、段驱动电流以及显示模式设置)
UART_HandShake(0x08); 显示地址命令 DATA0
UART_HandShake(0x7F); DATA1 显示第一个数字
UART_HandShake(0x7F); DATA2 显示第二个数字
UART_HandShake(0x7F); DATA3 显示第三个数字
UART_HandShake(0x7F); DATA4 显示第四个数字
UART_HandShake(0x41); DATA5 //这个数据控制图标显示
/**********第DATA5******************
*0x01 第一个 小数点亮
*0x40 第二个 小数点亮
*0x04 电池图标
*0x08 斤图标
*0x10 lb图标
*0x20 kg图标
************************************/