你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C0评测】数码时钟

[复制链接]
lugl 发布时间:2025-5-3 15:35

1、创建基础工程,使用PA0与PA1为TM1637的时钟与数据IO

2、打开LSE、UART,配置RTC的闹钟为1秒周期

image.png

3、生成mdk工程。

4、添加TM1637的驱动:

#include "tm1637.h"
#include "NimaLTD.NimaLTD-TM1637_conf.h"
#include "stm32c092xx.h"
#include "main.h"
#include "systick_delay.h"

void _tm1637Start(void);
void _tm1637Stop(void);
void _tm1637ReadResult(void);
void _tm1637WriteByte(unsigned char b);
void _tm1637DelayUsec(unsigned int i);
void _tm1637ClkHigh(void);
void _tm1637ClkLow(void);
void _tm1637DioHigh(void);
void _tm1637DioLow(void);
void tm1637SetBrightness(char brightness);


#define CLK_PORT GPIOA
#define DIO_PORT GPIOA
#define CLK_PIN GPIO_PIN_0
#define DIO_PIN GPIO_PIN_1
#define CLK_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE
#define DIO_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE


const char segmentMap[] = {
    0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, // 0-7
    0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, // 8-9, A-F
    0x00
};


void tm1637Init(void)
{
    CLK_PORT_CLK_ENABLE();
    DIO_PORT_CLK_ENABLE();
    GPIO_InitTypeDef g = {0};
    g.Pull = GPIO_PULLUP;
    g.Mode = GPIO_MODE_OUTPUT_OD; // OD = open drain
    g.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    g.Pin = CLK_PIN;
    HAL_GPIO_Init(CLK_PORT, &g);
    g.Pin = DIO_PIN;
    HAL_GPIO_Init(DIO_PORT, &g);

    tm1637SetBrightness(8);
}

void tm1637DisplayDecimal(int v, int displaySeparator)
{
    unsigned char digitArr[4];
    for (int i = 0; i < 4; ++i) {
        digitArr[i] = segmentMap[v % 10];
        if (i == 2 && displaySeparator) {
            digitArr[i] |= 1 << 7;
        }
        v /= 10;
    }

    _tm1637Start();
    _tm1637WriteByte(0x40);
    _tm1637ReadResult();
    _tm1637Stop();

    _tm1637Start();
    _tm1637WriteByte(0xc0);
    _tm1637ReadResult();

    for (int i = 0; i < 4; ++i) {
        _tm1637WriteByte(digitArr[3 - i]);
        _tm1637ReadResult();
    }

    _tm1637Stop();
}
void TM1637_DisplayTime(RTC_TimeTypeDef sTime, int displaySeparator)
{
    unsigned char digitArr[4];

    digitArr[0] = segmentMap[sTime.Minutes / 10];
      digitArr[1] = segmentMap[sTime.Minutes % 10];
    digitArr[2] = segmentMap[sTime.Seconds / 10];
      digitArr[3] = segmentMap[sTime.Seconds % 10];

    _tm1637Start();
    _tm1637WriteByte(0x40);
    _tm1637ReadResult();
    _tm1637Stop();

    _tm1637Start();
    _tm1637WriteByte(0xc0);
    _tm1637ReadResult();

    for (int i = 0; i < 4; ++i) {
        _tm1637WriteByte(digitArr[3 - i]);
        _tm1637ReadResult();
    }

    _tm1637Stop();
}

// Valid brightness values: 0 - 8.
// 0 = display off.
void tm1637SetBrightness(char brightness)
{
    _tm1637Start();
    _tm1637WriteByte(0x87 + brightness);
    _tm1637ReadResult();
    _tm1637Stop();
}

void _tm1637Start(void)
{
    _tm1637ClkHigh();
    _tm1637DioHigh();
    _tm1637DelayUsec(2);
    _tm1637DioLow();
}

void _tm1637Stop(void)
{
    _tm1637ClkLow();
    _tm1637DelayUsec(2);
    _tm1637DioLow();
    _tm1637DelayUsec(2);
    _tm1637ClkHigh();
    _tm1637DelayUsec(2);
    _tm1637DioHigh();
}

void _tm1637ReadResult(void)
{
    _tm1637ClkLow();
    _tm1637DelayUsec(5);
    // while (dio); // We're cheating here and not actually reading back the response.
    _tm1637ClkHigh();
    _tm1637DelayUsec(2);
    _tm1637ClkLow();
}

void _tm1637WriteByte(unsigned char b)
{
    for (int i = 0; i < 8; ++i) {
        _tm1637ClkLow();
        if (b & 0x01) {
            _tm1637DioHigh();
        }
        else {
            _tm1637DioLow();
        }
        _tm1637DelayUsec(3);
        b >>= 1;
        _tm1637ClkHigh();
        _tm1637DelayUsec(3);
    }
}

void _tm1637DelayUsec(unsigned int i)
{
    delay_us(i);
}

void _tm1637ClkHigh(void)
{
    HAL_GPIO_WritePin(CLK_PORT, CLK_PIN, GPIO_PIN_SET);
}

void _tm1637ClkLow(void)
{
    HAL_GPIO_WritePin(CLK_PORT, CLK_PIN, GPIO_PIN_RESET);
}

void _tm1637DioHigh(void)
{
    HAL_GPIO_WritePin(DIO_PORT, DIO_PIN, GPIO_PIN_SET);
}

void _tm1637DioLow(void)
{
    HAL_GPIO_WritePin(DIO_PORT, DIO_PIN, GPIO_PIN_RESET);
}

在主函数中周期进行显示时间,显示完后关闭一次TM1637显示,再开启显示。这样就可以达到降低功耗:

  /* USER CODE BEGIN 2 */
    SysTick_Init();
  tm1637Init();
    // Optionally set brightness. 0 is off. By default, initialized to full brightness.
  tm1637SetBrightness(1);
    // Display the value "1234" and turn on the `:` that is between digits 2 and 3.

  RTC_TimeTypeDef sTime = {0};
    RTC_DateTypeDef sDate = {0};
//  RTC_AlarmConfig(1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  if(flag)
    {
        flag = !flag;
        tm1637SetBrightness(1);
        HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
        /* Get the RTC current Date */
        HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
        shownum = (sTime.Minutes*100) + sTime.Seconds;
        tm1637DisplayDecimal(shownum, 1);
    }
    else
    {
        flag = !flag;
        tm1637SetBrightness(0);
    }


    HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);

【测试效果】

在关闭显示时,整个系统可以隆到0.7毫安,在打开数码管显示时,电流为1.5MA。感觉整体的电流都是给数码管用去了。

通过JP5来测试STM32C092的工作电流是只有0.08mA的工作电流,因此如果有LCD的显示器,那做为低功耗的时钟是非常好的。

收藏 评论0 发布时间:2025-5-3 15:35

举报

0个回答

所属标签

ST中文论坛活动

即日起开启活动话题入口,之后的活动统一都放在此处,欢迎大家的加入!


最新内容

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版