最丐条形时钟

2个月前

简介:用查理复用法驱动数码管,外接ds1302时钟芯片, 无源蜂鸣器播音乐,热敏电阻测量温度,中规中矩的时钟, 兼容HK32F030M,STM8S003,n76e003at20

开源协议: GPL 3.0

  • 1.3k
  • 9
  • 22

描述

前言

数码管驱动电路:查理复用法

8个io驱动8位7段数码管,而且电路和最丐机械键盘的无按键冲突电路非常类似。所以取名一致。

数码管集成在PCB上,通过3D打印部件进行透光柔和,外壳显示一体化更加美观。

后期尝试做脚对脚兼容芯片的程序移植,当前先开发这次活动的金主:航顺HK32F030M。

吐槽一下烧写口位置和硬件I2C复用,不能边debug边用I2C。

电路原理说明

这是用查理复用法3个io驱动6个LED的原理图,

image.png

假设此时P1高,P3低,P2高阻,此时LED6亮,虽然LED1和LED3串联有正向电压,但由于LED6钳位,使得电压不足以同时导通。

image.png

若P1高,P2、P3都为低,此时LED1和LED6都亮,都亮度不及上面的状态,因为两个LED的电流都流过P3电阻,P3电阻分压加大。

image.png

所以每个限流电阻上并联一个二极管,利用单向导通性,使得电阻在特定电流方向下,两端分压一致,使得同时亮的LED亮度一致。

image.png

核心算法说明

不是说我代码不开源,而是代码放出来了,即使有100个人下载。然而有80个人看不懂。

那我不如只列出特别的算法,图文并茂地讲解,让更多人能看懂。

大家可以看我GD32杯的电源工程, 虽然最后功能并不成功,但经常隔三差五就被人收藏克隆慢慢吃透,但唯独没什么人点赞【PS:你们倒是把三个都点上啊。你们的支持就是我更新的动力】。 你们有什么想看的算法评论区里提。有空我会后续更新。

ADC超采样:

由技术文档可知HK32F030M的ADC有效精度是8bit,如果温度要显示到小数点后1位起码要12bit的ADC,

这怎么办呢?

这时就可以用超采样技术。

第一步,ADC设置成连续转换,EOC转换完成中断

void ADC_init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_ADC_PIN ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GOIO_ADC_PORT, &GPIO_InitStructure);
    GPIO_PinAFConfig(GOIO_ADC_PORT,GPIO_PinSource6,GPIO_AF_7);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC ,ENABLE);

    ADC_DeInit(ADC1);
    ADC_StructInit(&ADC_InitStructure);

    ADC_ClockModeConfig(ADC1,ADC_ClockMode_SynClkDiv4);//系统时钟4分频,8M

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
    ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;//向后扫描
    ADC_Init(ADC1,&ADC_InitStructure);
    /* ADC1 regular channels configuration */ 
    ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_239_5Cycles);

    /* Enable EOC interrupt */
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);//转换结束中断使能

    /* Configure and enable ADC1 interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    ADC_GetCalibrationFactor(ADC1);//ADC校准

    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); 
    ADC_StartOfConversion(ADC1);
}

第二步,在中断里累加ADC读回来的值(反正后面都要求平均数,不如先加起来)。

这里由于按键与热敏电阻共用同一路ADC,为了按键扫描正常,刷新率取比1000Hz稍大的数。

extern uint16_t ntc_data_13b[2];
void ADC1_COMP_IRQHandler(void)
{
    static uint8_t i=0;
    if(ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET)
    {
        ntc_data_13b[0]+=ADC_GetConversionValue(ADC1)>>4;//读取后自动清除EOC标志位
        i++;
        if(i>=32)//32分频,1041.6Hz
        {
            i=0;
            ntc_data_13b[1]=ntc_data_13b[0];//存入二缓
            ntc_data_13b[0]=0;//一缓清零
        }
    }
}

数码管上下移动动画:

动画特效一大堆,这里举一个简单一点的,用下移做例子

image.png

上图展示的是下移的过程,提取重复的部分,只有一个步骤(上移同理)

#define digital_a 0x01
#define digital_b 0x02
#define digital_c 0x04
#define digital_d 0x08
#define digital_e 0x10
#define digital_f 0x20
#define digital_g 0x40

uint8_t digital_putdown(uint8_t dat)
{
    uint8_t temp=0;
    temp|=(dat&digital_g)?digital_d:0;//G赋值到D
    temp|=(dat&digital_a)?digital_g:0;//A赋值到G
    temp|=(dat&digital_b)?digital_c:0;//B赋值到C
    temp|=(dat&digital_f)?digital_e:0;//F赋值到E
    return temp;//其余没赋值的数据丢弃
}

走时误差校准:

首先这个DS1302很多人都反馈不准,其实是有诀窍的:

这个网址可以参考下:http://www.51hei.com/bbs/dpj-177015-1.html

下面的代码调时间的。

//输入最小数值-86400
void time_adjust(int32_t sec)
{
    uint8_t time_temp[7];
    uint8_t i;
    for(i=0;i<7;i++)
        time_temp[i]=bcd2hex(*((uint8_t *)&time_data+i));

    if(sec<0)//直接借一天做减法
    {
        sec+=86400;
        time_temp[5]--;//星期是从1到7,不担心溢出
    }

    time_temp[0]+=sec%60;
    if(time_temp[0]>=60)
    { 
        time_temp[1]+=time_temp[0]/60;
        time_temp[0]%=60;
    }
    time_temp[1]+=sec%3600/60;
    if(time_temp[1]>=60)
    {
        time_temp[2]+=time_temp[1]/60;
        time_temp[1]%=60;
    }
    time_temp[2]+=sec/3600; 
    if(time_temp[2]>=24)
    {
        time_temp[5]+=time_temp[2]/24;
        time_temp[2]%=24;

        time_temp[5]%=7;
        time_temp[5]=time_temp[5]?time_temp[5]:7;//将零偏移到7
    }

    for(i=0;i<7;i++)
        *((uint8_t *)&time_data+i)=hex2bcd(time_temp[i]);
}

由于我这里没有年月日,只有星期,所以轻松一点。不用考虑更多的进制。

和上面网址里的一样,挑一个夜深人静的时候校准。当然校准时有概率会跳过闹钟。但谁会设置午夜凶铃呢?🤣

加一点补充,怕有人不理解自动校准。

比如你的手表一天快了1分钟。当我只观察这个手表时,这个手表走了1天多1分钟时,调慢1分钟,就能和标准时间对上。

当然在校准前一刻快了的59秒。但每天的累计误差被压缩了。

现在经过我这套算法。设置好后,一个星期最大相差1秒以内。一年下来,误差也就一分钟。

时间校准方法:

每天在同一个固定的时间段来调整时间,先根据第一天的观察来决定要每天偏移多少秒。

输入到AC_DAY的设置里。然后再重新设置时间。

同理,一个星期后再调节AC_WEEK。这样就完成了。

由于校准数据是存在DS1302的内存里的。如果电池没电数据就清空的,建议在PCB上写上校准参数。

PCB成品展示

IMG_20210313_075408.jpg

IMG_20210313_075425.jpg

组装成品展示

IMG_20210324_200043.jpg

IMG_20210324_200051.jpg

IMG_20210324_200108.jpg

时钟动画演示

时钟下都带错位延迟更新效果。

凑巧格式转换成GIF后,速度变慢了,拿来展示效果刚刚好。

无过渡动画:

1.无动画 00_00_00-00_00_30 \[640i\].gif

切换后闪烁:

2.闪烁 00_00_00-00_00_30 \[640i\].gif

上移出上移入:

3.上移移出移入 00_00_00-00_00_30 \[640i\].gif

亮度渐变:

4.渐变 00_00_00-00_00_30 \[640i\].gif

笔划移位:

5.笔划移位 00_00_00-00_00_30 \[640i\].gif

逐位更新:

6.逐位更新 00_00_00-00_00_30 \[640i\].gif

操作逻辑及流程图

按键逻辑:

动作时间 提示音 功能
0.5s内松开 松开后有动作提示音 加数值或者切换界面
0.5s~1s松开 提示音滴一声后 确认或进入
1s~1.5s松开 提示音滴两声后 重新设置该数值
1.5s以上松开 提示音滴三声后 放弃设置并返回

菜单设置流程:

条形时钟流程图.png

条形时钟流程图2.png

外壳说明

不得不夸赞下立创的光敏打印,价格没比PLA贵,关键是壁厚能做到1mm。

但是最后做出来的均匀光效果不理想,颜色发散,导致晚上看的时候有点糊。

能在里面塞入亚克力导光就可以改善。

下面放3d模型渲染图

前面板

正方字体:

image.png

VFD字体

image.png

福禄克字体

image.png

后面板

image.png

打印文件后续我重新设计一些加强结构并且验证过后会再上传到附件,

条形时钟.JPG

来自工具人的外壳制作过程

通过数字的槽内壁喷上一层黑漆,再倒入不同颜色的树脂的方法:

黑漆防止泛光, 白色树脂将led的光线匀开, 透明树脂将光投射到上层。

示意图.png

遮盖

示意图2.jpg

喷漆+倒胶+擦拭油漆

喷漆前一天熬夜上头忘记拍喷漆和倒胶了,就只留个倒胶图吧。加上滴胶凝固大约1天 关于滴胶之前尝试过按1/3比例配置但比例没控制好,重新试了下发现树脂混合时比较稀的时候效果最好。 示意图3.jpg

成品

滴胶挺硬的,两侧泛光的现象几乎没有,但led的光晕开效果不明显,而且正面效果确实不咋地,

数字面板几乎是全黑的,等想做2.0看先灌白色树脂再喷漆效果如何吧。 示意图4.jpg示意图5.jpg

程序细节

音乐清单:

开机音乐:《全家开门铃声》

下面音乐可设置为闹钟铃声:

  1. 《天空之城》
  2. 《永远同在》
  3. 《华为主题曲》
  4. 《电磁炮》op1
  5. 《紫色激情》开头循环
  6. 《克罗地亚狂想曲》
  7. 《this game》
  8. 《next to you》
  9. 《柯南主题曲》
  10. 《青鸟》

V05的歌曲数组已经占用了6k的ROM,总共16K的ROM空间已经吃干抹净了,

后续可能会用MIDI乐谱来转换,可能歌曲数量就更少了。看情况,咕咕咕。

程序更新日志:

V00
  1. 时钟+温度功能,暂时没有闹钟功能
  2. 设置界面下,短按松开是加,滴一声后松开确认
  3. 运行界面下,短按换界面,滴一声后松开进入设置
  4. 星期温度界面下,等待10秒后自动返回时间界面,短按松开切换时钟特效并返回走时界面
  5. 上电自检DS1302内存,若数据丢失,则进入星期时间设置,并关闭充电模式
V01
  1. 完善闹钟功能,闹钟时间保存在DS1302内,电池没电后一起复位
  2. 显示时间时按住1.5秒后松开切换数码管过渡动画
  3. 温度显示精确到小数点后一位
  4. 加入移位刷新与移位移出移入动画
  5. 闹钟音乐加入《电磁炮》op1
  6. 杂项设置菜单未完成,无法进入选项
V02
  1. 音乐添加《紫色激情》,《克罗地亚》,《this game》,《next to you》,《柯南主题曲》,《青鸟》
  2. 开机音乐替换为《头文字D》开头
  3. 音调输出改为pwm模式,减少中断次数
V03
  1. 开机音乐替换为《帝国进行曲》开头
  2. 音乐完善《紫色激情》,《头文字D》,添加《学猫叫》,《记忆》,《愤怒的小鸟》
  3. 占空比下调到25%,以降低音质来换功耗
V04
  1. 音乐添加《命运石之门》,并无损压缩部分音乐
  2. 部分GPIO配置改为操作寄存器
  3. 修复闹钟设置的回退层级问题
V05
  1. 每日/每周走秒误差补偿
  2. 若在一周内重新上电,校正这一周的累计误差
  3. 音量/音色,过渡动画可调,且掉电保存
  4. 存储格式改为结构体,提高代码阅读性
  5. 若开机发现为掉电状态,闹钟,设置,重置为默认值
  6. 更换音乐《紫色激情》来换取代码空间

已知硬件问题:

  1. 上电冲击可能导致DS1302时间复位,可能是个别芯片现象,更换DS1302或者加大滤波电容或者将DS1302供电改3.3V可解决
  2. 蜂鸣器长时间运行导致电路板升温会影响温度检测
  3. 3.3V单片机因为导通压降的原因,只能用红黄橙的LED,更换宽电压单片机和去掉稳压块可解决,等待后续其他单片机支持。

感谢引用:

原理说明图片来源:https://blog.csdn.net/m0_38106923/article/details/83242204

流程图绘制工具:腾讯文档

BOM

ID Name Designator Footprint Quantity BOM_Manufacturer Part BOM_Manufacturer BOM_Supplier BOM_Supplier Part
1 C70373 BT1 BAT-SMD_CR2032-3V 1 C70373 Q&J LCSC C70373
2 MLT-7525 BUZZER1 BUZ-SMD_4P-L7.5-W7.5-P7.59-BR 1 MLT-7525 Jiangsu Huaneng Elec LCSC C95299
3 105 C3 C0603 1 0603B331K251CT Walsin Tech Corp LCSC C458879
4 106 C2,C4,C5 C0603 3 0603B331K251CT Walsin Tech Corp LCSC C458879
5 22 C7,C8 C0603 2 0603B331K251CT Walsin Tech Corp LCSC C458879
6 104 C1,C6,C9 C0603 3 0603B331K251CT Walsin Tech Corp LCSC C458879
7 4148 D1,D2,D3,D4,D5,D6,D7,D8,D9 LL-34_L3.5-W1.5-RD 9 TCLL4148 Tak Cheong LCSC C127077
8 BURN J1 HDR-TH_8P-P2.54-V-F-R2-C4-S2.54 1 220S-2*4P H=8.5MM Ytype Gold-plated Ckmtw LCSC C124422
9 RED LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8,LED9,LED10,LED11,LED12,LED13,LED14,LED15,LED16,LED17,LED18,LED19,LED20,LED21,LED22,LED23,LED24,LED25,LED26,LED27,LED28,LED29,LED30,LED31,LED32,LED33,LED34,LED35,LED36,LED37,LED38,LED39,LED40,LED41,LED42,LED43,LED44,LED45,LED46,LED47,LED48,LED49,LED50,LED51,LED52,LED53,LED54,LED55,LED56 LED0805-R-RD 56 17-21SURC/S530-A3/TR8 EVERLIGHT LCSC C72037
10 10k NTC1 RES-TH_L2.5-W2.5-P1.70-D0.3 1 MF52A1 103J3435 Nanjing Shiheng Elec LCSC C123373
11 S8050 Q1 SOT-23_L2.9-W1.3-P0.95-LS2.4-BR 1 S8050 Slkor(SLKORMICRO Elec.) LCSC C444723
12 10K R1 R0603 1 AC0603FR-07210KL YAGEO LCSC C227705
13 5.1K R3,R4 R0603 2 AC0603FR-07210KL YAGEO LCSC C227705
14 1K R5 R0603 1 AC0603FR-07210KL YAGEO LCSC C227705
15 471 RN1,RN2 RES-ARRAY-SMD_0603-8P-L3.2-W1.6-BL 2 RTA03-4D103JTP RALEC LCSC C102646
16 TSA356 S1 SW-SMD_TSA356G00-250 1 TSA356G00-250 BRIGHT LCSC C354961
17 LM1117-33 U1 SOT-223_L6.7-W3.5-P2.30-BR 1 AMS1117-3.3 Youtai Semiconductor Co., Ltd. LCSC C347222
18 HK32F030MF4P6 U2 TSSOP-20_L6.5-W4.4-P0.65-LS6.4-BL 1 HK32F030MF4P6 HK LCSC C707444
19 DS1302 U3 SOP-8_L5.0-W4.0-P1.27-LS6.0-BL 1 GC1302 Gcore LCSC C504377
20 TYPE-C 6P USB1 TYPE-C-SMD_TYPE-C-6P 1 TYPE-C 6P SHOU HAN LCSC C456012
21 32.768KHz X1 OSC-TH_BD3.1-P0.8-D0.3 1 X308032768KGB2SC YXC LCSC C52082

展开

工程成员

服务时间

周一至周五 9:00~18:00
  • 153 6159 2675

服务时间

周一至周五 9:00~18:00
  • 立创EDA微信号

    easyeda

  • QQ交流群

    664186054

  • 立创EDA公众号

    lceda-cn