suncat0504 发表于 2022-12-8 11:45

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

本帖最后由 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_SDAGPIOB
#define TTP229_Pin_SDA   GPIO_Pin_11
#define TTP229_Port_SCLGPIOB
#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屏显示剩余的秒数。




附上测试代码:




tpgf 发表于 2023-1-4 08:50

倒计时计时器可以直接使用定时器的减计数模式吗

nawu 发表于 2023-1-4 09:41

时间上的进位借位是如何保证可靠计算的呢

drer 发表于 2023-1-4 10:01

一般这种计时用的数据我们使用的是无符号数据还是有符号数据呢

zljiu 发表于 2023-1-4 10:09

如何通过外部按钮进行时钟的设置呢

kxsi 发表于 2023-1-4 10:21

小板上的按键功能是如何确定或者是如何定义的呢

tfqi 发表于 2023-1-4 10:38

功能不错啊有手动设置时间的功能吗

Jacquetry 发表于 2023-1-5 17:10

drer 发表于 2023-1-4 10:01
一般这种计时用的数据我们使用的是无符号数据还是有符号数据呢

全都用无符号数据即可
页: [1]
查看完整版本: 【EV Board (MM32L0136C7P)测评】+倒计时计时器