找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 325|回复: 14
打印 上一主题 下一主题
收起左侧

关于stc8H的延时函数问题

[复制链接]
跳转到指定楼层
楼主
本人最近在使用STC8H1K08芯片驱动TM1652,晶振是外部 12M
主要核心的驱动逻辑就是使用一根TX发数据给TM1652,不需要有数据回传,一直发就可以。但是由于最初设计时没有使用tx线,所以采用了io模拟tx的方式,19200的波特率用延时换算是52us,52us由stc-isp生成,目前遇到的问题是为什么这个延时不能正常点亮?
#include "main.h"

unsigned char LedSegs[]={63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113};

void Delay52us(void)  //@12.000MHz
{
  unsigned char data i;

  i = 206;
  while (--i);
}

void sd1(unsigned char dat)
{
  unsigned int i=0;
  bit CY = 0,TB = 0;
  ACC = dat;
  if(P)
  {
    TB = 0;
  }
  else
  {
    TB = 1;
  }
  Tm1652_SDA=0;            //将串口发送端口TXD置高
  Delay52us();
  for(i= 0;i<8;i++)
  {
    Tm1652_SDA =  dat & 0x01;
    dat = dat>>1;
    Delay52us();
  }
  Tm1652_SDA = TB;      
  Delay52us();
  Tm1652_SDA=1;            //将串口发送端口TXD置高
  Delay52us();
}
void SendInt1(int ss){
  int qian,bai,shi,ge;
  qian = ss /1000;
  bai = ss / 100;
  shi = ss % 100 / 10;
  ge = ss % 10;

  sd1(LedSegs[qian]);
  sd1(LedSegs[bai]);  
  sd1(LedSegs[shi] | 0x80);
  sd1(LedSegs[ge]);
}
void main()
{
    P1M0 = 0x00;
    P1M1 = 0x00;
    while(1)
    {
      SendInt1(8888);
    }
}#ifndef _MAIN_H_
#define _MAIN_H

#include "STC8H.h"

sbit Tm1652_SDA = P1^3;

#endif



文件STC8H.h也是由stc-isp生成的头文件向各位大佬寻求帮助




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:69038 发表于 2026-7-9 13:46 | 只看该作者
你这代码编译通过了吗?
回复

使用道具 举报

板凳
ID:1133081 发表于 2026-7-9 15:47 | 只看该作者
回复

使用道具 举报

地板
ID:1149881 发表于 2026-7-10 09:32 | 只看该作者
zhuls 发表于 2026-7-9 13:46
你这代码编译通过了吗?

过了()
回复

使用道具 举报

5#
ID:69038 发表于 2026-7-10 14:33 | 只看该作者

那你这个P定义在哪里呢?我咋就没找到?
void sd1(unsigned char dat)
{
  unsigned int i=0;
  bit CY = 0,TB = 0;//CY 没看到被引用
  ACC = dat; //ACC又为什么要=dat?,ACC没看到被引用
  if(P)          //P定义在哪里?
  {
    TB = 0;
  }
  else
  {
    TB = 1;
  }
  Tm1652_SDA=0;            //将串口发送端口TXD置高
  Delay52us();
  for(i= 0;i<8;i++)
  {
    Tm1652_SDA =  dat & 0x01;
    dat = dat>>1;
    Delay52us();
  }
  Tm1652_SDA = TB;      //这个TB是1还是0?你这是启动了校验吗?
  Delay52us();
  Tm1652_SDA=1;            //将串口发送端口TXD置高
  Delay52us();
}
看上去有11个波特率(t)的时间,你启动了校验位?。
正常的TXD是从高到低,并维持一个波特率的时间(t)为起始信号,然后依次8个时间(t)是8bit的数据,最后从低到高再维持一个时间(t)为停止,上述是“波特率,N,8,1”的时序,一共有10个时序波形。
你看一下,你的代码附合不?
回复

使用道具 举报

6#
ID:69038 发表于 2026-7-10 14:38 | 只看该作者
下载了1652的手册看了看,确实要加入校验位,你的校验位是如何得出的?
还是那个(P),是从哪来的?主楼给的代码不完整。
回复

使用道具 举报

7#
ID:69038 发表于 2026-7-10 14:57 | 只看该作者
还有:
1652要有初始设置,亮度、模式==,但在你的代码中没找到;
sd1(LedSegs[shi] | 0x80);=>这里为什么要“|0x80”,而其它的却没有?
回复

使用道具 举报

8#
ID:624769 发表于 2026-7-10 14:59 | 只看该作者
我说…… 你到底用没用过 TM1652 ?  以及,你看没看过手册,会不会用TM1652?
会用的话…… 初始化呢???
整个代码看了半天,也没看到你初始化 TM1652啊……
回复

使用道具 举报

9#
ID:1133081 发表于 2026-7-10 16:33 | 只看该作者
回复

使用道具 举报

10#
ID:341045 发表于 2026-7-11 09:56 | 只看该作者
  Tm1652_SDA=0;            //将串口发送端口TXD置高

你管这个叫置高?我这边叫置低。Tm1652_SDA=1; 才叫置高。
回复

使用道具 举报

11#
ID:1149881 发表于 2026-7-14 13:10 | 只看该作者
谢谢大家的帮助,我调出来了,为什么问的延时而不是tm1652的使用,是因为之前点亮过,但是因为时序影响,按键按下数码管刷新不流畅,所以又拿出来重写。因为之前重做了一版之后,数码管不亮,然后改用AI生成的52us的延时之后亮了,实际上晶振也没变过,所以就怀疑是延时的问题。这次又重新使用STCISP的延时,成功点亮了,添加别的功能也没有影响。
回复

使用道具 举报

12#
ID:1149881 发表于 2026-7-14 13:10 | 只看该作者
我把代码贴到这里,STC8H.h文件是我在STCISP中下载的头文件,
#include "delay.h"

void Delay52us(void)  //@12.000MHz
{
  unsigned char data i;

  i = 206;
  while (--i);
}

void Delay_ms(unsigned int ms)  //@12.000MHz
{
  unsigned char data i, j;
  unsigned int k = 0;
  for(k = 0;k < ms; k++)
  {
      i = 16;
      j = 147;
      do
      {
        while (--j);
      } while (--i);
  }
}

void Delay_us(unsigned int us)  //@12.000MHz
{
  unsigned char data i;
  unsigned int j = 0;
  for(j = 0; j < us ;j++)
  {
    i = 2;
    while (--i);
  }
}
#include "tm1652.h"

unsigned char code LedSegs[]={63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113};

void sd1(unsigned char dat)
{
  unsigned int i=0;
  bit CY = 0;
  bit TB = 0;
  ACC = dat;
  if(P)
  {
    TB = 0;
  }
  else
  {
    TB = 1;
  }
  Tm1652_SDA = 0;         
  Delay52us();
  for(i= 0;i<8;i++)
  {
    Tm1652_SDA =  dat & 0x01;
    dat = dat>>1;
    Delay52us();
  }
  Tm1652_SDA = TB;      
  Delay52us();
  Tm1652_SDA = 1;            //将串口发送端口TXD置高
  Delay52us();
}

void Tm1652Dispaly(int ss)
{
  int qian,bai,shi,ge;

  qian = ss /1000;
  bai = ss % 1000 / 100;
  shi = ss % 100 / 10;
  ge = ss % 10;
  sd1(0x08);
  sd1(LedSegs[qian] | 0x80);
  sd1(LedSegs[bai] | 0x80);  
  sd1(LedSegs[shi] | 0x80);
  sd1(LedSegs[ge] | 0x80); // 亮小数点
  Tm1652_SDA = 1;
  Delay_ms(3);  //一定要这个延时,否则会不亮,只延时1ms也会不亮
  sd1(0x18);
  sd1(0xb8);  // 调亮度(位驱动占空比和段驱动电流,和位数)

}

#ifndef _TM1652_H_
#define _TM1652_H_

#include "STC8H.h"
#include "delay.h"

sbit Tm1652_SDA = P1^3;

void sd1(unsigned char dat);
void Tm1652Dispaly(int ss);

#endif



回复

使用道具 举报

13#
ID:1149881 发表于 2026-7-14 13:17 | 只看该作者
谢谢大家的评论,是有帮助的。
之所以发这个帖,帖题目问时序问题是因为之前使用tm1652成功点亮过,但是后面换了一个板子烧录,就发现没办法点亮了,判断是52us延时的问题,原先的52us是STCISP生成,后来AI生成了一个52us延时之后,可以点亮,但是时序很乱,按键按下数码管刷新不了或者会卡顿。最后又掏出来重新写,确实是没注意到之前写这个的时候,没加芯片驱动开始的地址,亮度等参数,所以没办法正确点亮,现在我把成功的贴到下面,希望可以帮助到别人
STC8H.h是STCISP生成的头文件。

#include "tm1652.h"

unsigned char code LedSegs[]={63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113};

void sd1(unsigned char dat)
{
        unsigned int i=0;
        bit CY = 0;
  bit TB = 0;
        ACC = dat;
        if(P)
        {
                TB = 0;
        }
        else
        {
                TB = 1;
        }
        Tm1652_SDA = 0;            //将串口发送端口TXD置高
        Delay52us();
        for(i= 0;i<8;i++)
        {
                Tm1652_SDA =  dat & 0x01;
                dat = dat>>1;
                Delay52us();
        }
        Tm1652_SDA = TB;                  
        Delay52us();
        Tm1652_SDA = 1;            //将串口发送端口TXD置高
        Delay52us();
}

void Tm1652Dispaly(int ss)
{
        int qian,bai,shi,ge;

  qian = ss /1000;
        bai = ss % 1000 / 100;
        shi = ss % 100 / 10;
        ge = ss % 10;
        sd1(0x08);
  sd1(LedSegs[qian] | 0x80);
        sd1(LedSegs[bai] | 0x80);  
        sd1(LedSegs[shi] | 0x80);
        sd1(LedSegs[ge] | 0x80); // 亮小数点
        Tm1652_SDA = 1;
        Delay_ms(3);  //一定要这个延时,否则会不亮,只延时1ms也会不亮
        sd1(0x18);
        sd1(0xb8);  // 调亮度(位驱动占空比和段驱动电流,和位数)

}
#ifndef _TM1652_H_
#define _TM1652_H_

#include "STC8H.h"
#include "delay.h"

sbit Tm1652_SDA = P1^3;

void sd1(unsigned char dat);
void Tm1652Dispaly(int ss);

#endif

#include "delay.h"

void Delay52us(void)        //@12.000MHz
{
        unsigned char data i;

        i = 206;
        while (--i);
}

void Delay_ms(unsigned int ms)        //@12.000MHz
{
        unsigned char data i, j;
        unsigned int k = 0;
        for(k = 0;k < ms; k++)
        {
                        i = 16;
                        j = 147;
                        do
                        {
                                while (--j);
                        } while (--i);
        }
}

void Delay_us(unsigned int us)        //@12.000MHz
{
        unsigned char data i;
        unsigned int j = 0;
        for(j = 0; j < us ;j++)
        {
                i = 2;
                while (--i);
        }
}
delay也均由STCISP生成。
回复

使用道具 举报

14#
ID:1149881 发表于 2026-7-14 13:19 | 只看该作者
zhuls 发表于 2026-7-10 14:33
那你这个P定义在哪里呢?我咋就没找到?
void sd1(unsigned char dat)
{

多谢审读我的代码,是的,芯片驱动主要的初始化和亮度等参数没写入,所以导致没办法点亮,补全之后就可以了
但是P这些校验,应该是STC本身的寄存器,调用头文件就可以正常使用了,应该是不需要定义的
回复

使用道具 举报

15#
ID:1149881 发表于 2026-7-14 13:19 | 只看该作者
188610329 发表于 2026-7-10 14:59
我说…… 你到底用没用过 TM1652 ?  以及,你看没看过手册,会不会用TM1652?
会用的话…… 初始化呢?? ...

是的,是因为这个问题,谢谢,已经纠正了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表