TM1650显示问题
今天看到别人在用TM1650驱动数码管,太简单了,也想学来试试,但一直不成功,需要请教各位老师。代码如下,帮忙分析。单片机8H1K08主函数
#include <STC8.h>
#include "includes.h"
#include "TM1650.h"
void main()
{
//unsigned intTempData = 223;
P_SW2 |= 0x80;
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
TM1650_Init(); //数码管驱动芯片初始化
while (1)
{
Display_Value(1234);
delay_ms(500);
}
}
TM1650函数
#include "includes.h"
#include "TM1650.h"
uchar CODE = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9显示代码
/**************************************************************************
* 函数名称 :I2C_Start_TM1650()
* 函数功能 :开始信号
***************************************************************************/
void I2C_Start_TM1650()
{
TM1650_SDA = 1;
//时钟信号保持高电平
//Delay5us();
TM1650_SCL = 1;//数据线拉高
Delay5us();
//Delay5us();
//delay_us(5);
TM1650_SDA = 0; //
Delay5us();
//Delay5us();
//delay_us(5);
TM1650_SCL = 0; //
//Delay5us();
//Delay5us();
}
/**************************************************************************
* 函数名称 :I2C_Stop_TM1650()
* 函数功能 :停止信号
***************************************************************************/
void I2C_Stop_TM1650()
{
TM1650_SCL = 0;
TM1650_SDA = 0;
//Delay5us();
Delay1us();Delay1us();
//保证数据线为低电平
//delay_us(5);
TM1650_SCL = 1;
Delay1us();Delay1us();
//Delay5us();
// delay_us(5);
TM1650_SDA = 1; //数据线出现上升沿
Delay1us();Delay1us();
}
/**************************************************************************
* 函数名称 :I2C_Wait_Ack_TM1650()
* 函数功能 :等待应答信号
* 返回参数 : = 0,有应答
= 1,无应答
***************************************************************************/
uchar I2C_Wait_Ack_TM1650()
{
uchar ackTime = 0;//应答等待计数
TM1650_SCL = 1;
Delay5us();
//delay_us(5);
TM1650_SCL = 1;
while(TM1650_SDA)
{
ackTime++;
if(ackTime > 250)
{
I2C_Stop_TM1650();
return 1;
}
}
TM1650_SCL = 0;
return 0;
}
/**************************************************************************
* 函数名称 :I2C_Wait_Ack_TM1650()
* 函数功能 :等待应答信号
* 函数参数 : -- 需要写的数据
***************************************************************************/
void I2C_WriteByte_TM1650(uchar txd)
{
uchar i;
TM1650_SCL = 0;
Delay1us();
//delay_us(1);
for(i = 0;i < 8;i++)
{
if(txd & 0x80)
TM1650_SDA = 1;
else
TM1650_SDA = 0;
txd <<= 1;
//TM1650_SCL = 0;
//Delay5us();
Delay1us();Delay1us();
TM1650_SCL = 1;
Delay1us();Delay1us();
//delay_us(5);
TM1650_SCL = 0;
Delay1us();Delay1us();
}
}
/**************************************************************************
* 函数名称 :TM1650_WriteDat()
* 函数功能 :
* 函数参数 :
***************************************************************************/
void TM1650_WriteDat(uchar add,uchar dat)
{
I2C_Start_TM1650();
I2C_WriteByte_TM1650(add); //第一个显存地址
I2C_Wait_Ack_TM1650();
I2C_WriteByte_TM1650(dat);
I2C_Wait_Ack_TM1650();
I2C_Stop_TM1650();
}
/**************************************************************************
* 函数名称 :TM1650_WriteCmd()
* 函数功能 :
* 函数参数 :
***************************************************************************/
void TM1650_WriteCmd(uchar cmd)
{
I2C_Start_TM1650();
I2C_WriteByte_TM1650(0x48);//显示模式
I2C_Wait_Ack_TM1650();
I2C_WriteByte_TM1650(cmd);
I2C_Wait_Ack_TM1650();
I2C_Stop_TM1650();
}
void Display(uchar add,uchar dat)
{
switch(add)
{
case 0: //第1位数码管显示
TM1650_WriteDat(0x68,CODE); //DIG1
break;
case 1: //第2位数码管显示
TM1650_WriteDat(0x6A,CODE); //DIG1
break;
case 2: //第3位数码管显示
TM1650_WriteDat(0x6C,CODE | 0x80); //DIG1
break;
case 3: //第4位数码管显示
TM1650_WriteDat(0x6E,CODE); //DIG1
break;
default:
break;
}
}
void Display_Value( unsigned intdat)
{
unsigned char buf={1,2,3,4};
unsigned char i;
buf = dat/1000;
buf = dat%1000/100;
buf = dat%100/10;
buf = dat%10;
for(i=0;i<4;i++)
{
Display(i,buf);
}
}
/**************************************************************************
* 函数名称 :TM1650_Init()
* 函数功能 :1650初始化
***************************************************************************/
void TM1650_Init()
{
TM1650_WriteCmd(0x11); //1级亮度 8段显示 开显示
TM1650_WriteDat(0x68,0x00); //DIG1
TM1650_WriteDat(0x6a,0x00); //DIG2
TM1650_WriteDat(0x6c,0x00); //DIG3
TM1650_WriteDat(0x6e,0x00); //DIG4
}
延时函数
#include "includes.h"
/*****************************************************************************
* 函数原型:delay_us(uint us)
* 功能 :微秒延时函数
* 参数 1:延时时间
* 返回值:无
*****************************************************************************/
void Delay5us(void) //@22.1184MHz
{
unsigned char data i;
_nop_();
i = 25;
while (--i);
}
void Delay1us(void) //@22.1184MHz
{
unsigned char data i;
i = 3;
while (--i);
}
void delay_us(uint us) //@22.1184MHz
{
uchar i;
while(us--)
{
_nop_();
i = 5;
while (--i);
}
}
/*****************************************************************************
* 函数原型:delay_ms(uint ms)
* 功能 :毫秒延时函数
* 参数 1:延时时间
* 返回值:无
*****************************************************************************/
void delay_ms(uint ms)
{
uchar i, j;
while(ms--)
{
_nop_();
_nop_();
_nop_();
i = 29;
j = 183;
do
{
while (--j);
} while (--i);
}
}
专业分析:STM1650驱动数码管运行异常问题
1. 驱动流程概述
STM1650是一种高性能的无源数字电路芯片,主要用于驱动各种数字设备,包括数码管、LED灯管等。其驱动流程主要包括以下几个关键步骤:
初始化:设置时钟信号、地址信号等。
开始I2C通信:为后续的I2C通信奠定基础。
读取数据:通过SPI或I2C接口读取数据。
关闭I2C通信:完成I2C通信的结束。
2. 问题分析
用户使用STM1650驱动数码管时,运行异常,且代码如下:
void main() {
unsigned int TempData = 223;
PSW2 |= 0x80;
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
TM1650Init(); // 数码管驱动芯片初始化
while (1) {
DisplayValue(1234);
delayms(500);
}
}
3. 常见问题及原因分析
1. 初始化错误:
原因:在初始化过程中,可能没有正确设置时钟信号(SMA)或地址信号(SMA)为高电平。
解决方案:在启动I2C前,确保SMA和SCL信号为高电平,以确保I2C通信的正常进行。
2. I2C通信开始设置错误:
原因:在开始I2C通信时,可能没有正确设置TM1650SDA和TMA1650SMA信号的值。
解决方案:在启动I2C前,确保TM1650SDA置为1,TMA1650SMA置为1。在I2C通信开始时,设置TM1650SMA和TMA1650SMA为0。
3. 读取数据的设置问题:
原因:缺少读取数据的步骤,导致无法读取数码管的响应。
解决方案:在读取数据时,需要使用SPI或I2C接口的读取函数,例如SPIMouseRead()或I2CRead()。
4. 建议步骤
1. 参考STM1650文档:
检查和学习STM1650的驱动文档,了解完整的I2C通信流程和相关设置。
注意时钟信号、地址信号等关键信号的正确设置。
2. 设置I2C通信参数:
在启动I2C前,确保TM1650SMA和TMA1650SMA为0。
在I2C通信开始时,设置TM1650SMA和TMA1650SMA为1。
3. 读取数据的实现:
在代码中,添加读取数据的步骤,例如:
c
// 读取数据的实现
while (true) {
int value = SPIMouseRead();
// 将值转换为数码管的响应
// 根据value的范围(0-9)显示相应的数码管响应
}
4. 调试工具的使用:
使用调试工具(如IDE的调试模式)尝试读取数据,确保数据读取正常。
如果读取数据失败,检查I2C通信的连接情况,确保SPI或I2C接口的正常工作。
5. 常见错误及解决方法
错误1:时钟信号未设置为高电平:
原因:在初始化或开始I2C通信时,时钟信号(SMA或SMA1650)未设置为高电平。
解决方法:在启动I2C前,确保SMA和SMA1650信号为高电平(1)。在I2C通信开始时,设置SMA和SMA1650信号为0。
错误2:地址信号未设置为高电平:
原因:在初始化或开始I2C通信时,地址信号(SMA或SMA1650)未设置为高电平。
解决方法:在启动I2C前,确保SMA和SMA1650信号为高电平。在I2C通信开始时,设置SMA和SMA1650信号为0。
错误3:读取数据时数据范围错误:
原因:在读取数据时,值范围不在0-9之间,导致数码管无法正确显示响应。
解决方法:根据读取到的值(0-9)来控制数码管的响应,确保读取值的范围正确。
6. 总结
使用STM1650驱动数码管时,需要严格按照驱动流程操作,包括初始化、开始I2C通信、读取数据等关键步骤。同时,确保时钟信号、地址信号等信号的正确设置,以及读取数据的正确实现。如果运行异常,建议检查代码中的设置是否正确,以及是否使用了正确的接口进行读取。
[本文内容由国芯人工智能辅助生成,仅供参考] 端口设置为推挽输出,时钟频率调低,延时加大,看看 haiyang201 发表于 2025-5-18 17:21
端口设置为推挽输出,时钟频率调低,延时加大,看看
好的,我试试 人在江南 发表于 2025-5-18 17:27
好的,我试试
改为11.0593,延时6us,推挽,还是不行。P1M0 = 0x41; P1M1 = 0x00;
void Delay5us(void) //@11.0592MHz
{
unsigned char data i;
_nop_();
i = 11;
while (--i);
} 你再看看通讯协议吧,我感觉时序有问题 时序参数 C_wolf 发表于 2025-5-18 23:32
你再看看通讯协议吧,我感觉时序有问题
谢谢 stc32G驱动数码,其他客户测试的分享:https://www.stcaimcu.com/forum.p ... amp;extra=#pid44151
其实建议 用 STC8H4K32TL-40I-LQFP48/32 来驱动,一个芯片搞定
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)
AI-32位8051 发表于 2025-5-19 09:08
stc32G驱动数码,其他客户测试的分享:https://www.stcaimcu.com/forum.p ... amp;extra=#pid44151
其实建 ...
谢谢,这个芯片好,省去不少数码管驱动电路
页:
[1]
2