打印
[MM32硬件]

【EV Board (MM32L0136C7P)测评】+倒计时计时器

[复制链接]
820|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 suncat0504 于 2022-12-8 12:15 编辑

#申请原创# @21小跑堂
本次测试完成了键盘输入、OLED显示的测试,实现任意时间(最大99小时99分钟99秒的)倒计时测试。
键盘使用TTP229构成的模块,它的适用电压支持3.3V和5.5V,使用IIC接口。OLED使用128X32点阵的,接口也是IIC的。这两个部件需要用到四个GPIO。在使用了SLCD的场合,开饭很难再另外规划出多余的GPIO,也已就是用了四个LED所在的GPIO口,刚好数据通讯也可以通过LED显示出来。

按键处理部分的代码:
#define TTP229_Port_SDA  GPIOB
#define TTP229_Pin_SDA   GPIO_Pin_11
#define TTP229_Port_SCL  GPIOB
#define TTP229_Pin_SCL   GPIO_Pin_10

#define TTP229_SDA_0()  GPIO_ResetBits(TTP229_Port_SDA,TTP229_Pin_SDA)
#define TTP229_SDA_1()  GPIO_SetBits(TTP229_Port_SDA,TTP229_Pin_SDA)
#define TTP229_SDA_TOGGLE()  (GPIO_ReadOutputDataBit(TTP229_Port_SDA,TTP229_Pin_SDA))?(GPIO_ResetBits(TTP229_Port_SDA,TTP229_Pin_SDA)):(GPIO_SetBits(TTP229_Port_SDA,TTP229_Pin_SDA))

#define TTP229_SCL_0()  GPIO_ResetBits(TTP229_Port_SCL,TTP229_Pin_SCL)
#define TTP229_SCL_1()  GPIO_SetBits(TTP229_Port_SCL,TTP229_Pin_SCL)
#define TTP229_SCL_TOGGLE()  (GPIO_ReadOutputDataBit(TTP229_Port_SCL,TTP229_Pin_SCL))?(GPIO_ResetBits(TTP229_Port_SCL,TTP229_Pin_SCL)):(GPIO_SetBits(TTP229_Port_SCL,TTP229_Pin_SCL))


#define TTP229_KEYCODE_1 1
#define TTP229_KEYCODE_2 2
#define TTP229_KEYCODE_3 3
#define TTP229_KEYCODE_4 4
#define TTP229_KEYCODE_5 5
#define TTP229_KEYCODE_6 6
#define TTP229_KEYCODE_7 7
#define TTP229_KEYCODE_8 8
#define TTP229_KEYCODE_9 9
#define TTP229_KEYCODE_0 10
#define TTP229_KEYCODE_Cancel 11    // 取消
#define TTP229_KEYCODE_OK 12        // 确认
//#define TTP229_KEYCODE_Left 13      // 左移
//#define TTP229_KEYCODE_Right 14     // 右移
//#define TTP229_KEYCODE_Set 15       // 设置
//#define TTP229_KEYCODE_Mode 16      // 定时器模式切换
#define TTP229_KEYCODE_T1 13      // 定时1
#define TTP229_KEYCODE_T2 14      // 定时2
#define TTP229_KEYCODE_T3 15      // 定时3
#define TTP229_KEYCODE_DT 16      // 设置日期时间

/********************************************************************
* 名称 : TTP229_ReadKey()
* 功能 : 扫描TTP229电容键盘(16按键)函数
* 触摸结果直接输出只有8个,平时输出低电平,触摸按键键后,对应输出脚为高电平
* 同时触摸按键,只有第一个生效
* 输入 : 无
* 输出 : 按键编号
***********************************************************************/
u8 TTP229_ReadKey(void) {
        u8 key=0;
    u8 val=0;
        u8 i;
    unsigned int temp=0x0000;

    set_tm1638_sda_out();
        TTP229_SDA_0();
    delayUs(100);
    TTP229_SDA_1();
        delayUs(100);

    set_tm1638_sda_in();
           for(i=0;i<16;i++) {
                  TTP229_SCL_0();
                delayUs(100);
                TTP229_SCL_1();
        delayUs(100);
                if(GPIO_ReadInputDataBit(TTP229_Port_SDA, TTP229_Pin_SDA) == Bit_RESET) {
                        temp|=(1<<i);
                }
               
        }
           for (i=0;i<16;i++) {
           if ((temp & (1<<i)) > 0) {
                      key=i+1;
           }
        }
        DELAY_Ms(30);
           return key;
}
OLE处理中接口部分的代码:
//定义IIC从设备地址:OLED上设置的访问地址为0x78
#define IIC_SLAVE_ADDR 0x78

//--------------IIC总线引脚定义-----------------------
#define OLED_SCL_PORT                      GPIOC
#define OLED_SCL_PIN                       GPIO_Pin_0    //OLED屏IIC时钟信号
#define OLED_SDA_PORT                      GPIOB
#define OLED_SDA_PIN                       GPIO_Pin_9    //OLED屏IIC数据信号

//--------------IIC端口操作定义---------------------
#define        OLED_SDA_1()          GPIO_SetBits(OLED_SDA_PORT,  OLED_SDA_PIN)
#define        OLED_SDA_0()          GPIO_ResetBits(OLED_SDA_PORT,OLED_SDA_PIN)
  
#define        OLED_SCL_1()          GPIO_SetBits(OLED_SCL_PORT,  OLED_SCL_PIN)
#define        OLED_SCL_0()          GPIO_ResetBits(OLED_SCL_PORT,OLED_SCL_PIN)
其他处理相关代码太多,详见后面附件中工程。为了实现字符的显示(包括汉字)的显示,需要另外的工具,把用到的字符转换为点阵数据保存到文件中。为了能让OLED多显示字符,我把汉字转换为16X12的点阵点阵数据文件格式:



计时处理中使用定时器16,通过参数设置,实现秒单位的定时中断。根据芯片资料介绍,TIM16 由一个 16 位可实时编程预分频器和一个 16 位自动重装载计数器组成,可以为用户提供便捷的计数定时功能,计数器时钟由预分频器分频得到。

// TIM16中断处理函数

void TIM16_IRQHandler(void)

{

TIM_ClearITPendingBit(TIM16, TIM_IT_Update);

ucTim16Flag++;

// 测试用代码

printf("*");

if (djsVal>0) {

// 秒数减1

djsVal--;

}

// 测试用代码

TTP229_SCL_TOGGLE(); // PB10电平翻转

}

从结构图中可以看到,计算出合理的PSC和ARR,可以从TIM16获得自己需要的信号。
为了测试精度,利用TIM16的中断处理和LED中的一个GPIO,输出一个秒信号,并用示波器测量结果。使用下面的语句:
TIM16_Init(APP_TIM_UPDATE_PERIOD - 1, SystemCoreClock / 500000);

PB10上得到的测试波形:

脉冲的周期为20ms。说明定时时长为10ms。因此如果把TIM16的时钟周期放大100倍,
TIM16_Init(APP_TIM_UPDATE_PERIOD - 1, SystemCoreClock / 5000);

定时周期将变为1秒,可以作为倒计时用的计数信号。
在主程序中周期检测键盘输入情况,按键盘上1-9的按键时,进入倒计时程序处理。此时LCD上显示00:00:00,分别对应时:分:秒,可以通过13、14调整要修改的定时时间的位置,通过1-10按键,修改数值。最大范围为99小时99分钟99秒。运行时,SLCD屏幕显示小时、分钟、秒的变化,OLED屏显示剩余的秒数。




附上测试代码: 倒计时测试.zip (1.13 MB)




使用特权

评论回复
沙发
tpgf| | 2023-1-4 08:50 | 只看该作者
倒计时计时器可以直接使用定时器的减计数模式吗

使用特权

评论回复
评论
suncat0504 2023-1-4 09:02 回复TA
可以啊。 
板凳
nawu| | 2023-1-4 09:41 | 只看该作者
时间上的进位借位是如何保证可靠计算的呢

使用特权

评论回复
评论
suncat0504 2023-1-4 15:36 回复TA
根据数值,小时、分、秒分开计算。减一处理。分秒低于60后,正常0-59范围。 
地板
drer| | 2023-1-4 10:01 | 只看该作者
一般这种计时用的数据我们使用的是无符号数据还是有符号数据呢

使用特权

评论回复
评论
suncat0504 2023-1-4 15:37 回复TA
倒计时,数值>0,全都用无符号数据即可。 
5
zljiu| | 2023-1-4 10:09 | 只看该作者
如何通过外部按钮进行时钟的设置呢

使用特权

评论回复
评论
suncat0504 2023-1-4 15:38 回复TA
参考代码。键盘返回值为1-16,可以根据自己需要,自由定义键值对应的操作指令。 
6
kxsi| | 2023-1-4 10:21 | 只看该作者
小板上的按键功能是如何确定或者是如何定义的呢

使用特权

评论回复
评论
suncat0504 2023-1-4 15:39 回复TA
参考代码。键盘返回值为1-16,可以根据自己需要,自由定义键值对应的操作指令。 
7
tfqi| | 2023-1-4 10:38 | 只看该作者
功能不错啊  有手动设置时间的功能吗

使用特权

评论回复
评论
suncat0504 2023-1-4 15:35 回复TA
有啊,最大可以设置为99小时99分99秒 
8
Jacquetry| | 2023-1-5 17:10 | 只看该作者
drer 发表于 2023-1-4 10:01
一般这种计时用的数据我们使用的是无符号数据还是有符号数据呢

全都用无符号数据即可

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

151

主题

4002

帖子

5

粉丝