/* TIM6 init function */
void MX_TIM6_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
//72M 就是72000000 HZ 分7200*10 就是1000HZ 那么周期是10-3s也就是1MS
htim6.Instance = TIM6;
htim6.Init.Prescaler = 7200-1;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 10-1;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
然后中断呢?
不看IT直接用回调
HAL_TIM_Base_Start_IT(&htim6);
也就是3步搞定
static int cnt=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6)
{
if(++cnt == 1000)
{
cnt=0;
printf("1S\r\n");
}
}
}
可以看1S出书一次
+++++++++继续+++++++++
上面3步很基础 开始高级的 增加一个模块GTIMER.C
操作链表
第一步 timer_isr 放到上面1S执行一次
第二部可以用了
char timerid=0;
void timerpaly(void)
{
printf("%s\r\n",__FUNCTION__);
}
void stop_timer_callback( void ) {timer.stop(timerid);}
void start_timer_callback( void ){timer.start(timerid);}
void creat_timer_paly( void )
{
static time_type T;
timerid = timer.creat(&T,3000 , 1 ,timerpaly );
//3000代表多少个时基现在1MS一次那就是3S执行一次
//1代表立刻开启 0就是只是创建 现在是关闭的 需要后面再开启
}
static int cnt=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6)
{
timer_isr();
if(++cnt == 10000)
{
printf("10S\r\n");stop_timer_callback();
}
}
}
每3S执行一次 后面被定时器关闭掉!
也就是————————1——————1————————这样的在瞬间执行一次函数
++++++++++++++++继续++++++++++++++
做一个AAAAAAAAAAABBBBBBBBBBBBBB
这样样子的闪烁函数 它是一次性的 做完就结束
第一步 需要包含模块
#ifndef _BASETwinkle_H_
#define _BASETwinkle_H_
#include <stdio.h>//printf
#include <string.h>//stpcpy
#include <stdint.h>//typedef signed char int8_t;
#include <ctype.h> //toupper
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>//负责#define NULL 0
typedef void (*fc)(void);
//节点的结构体
typedef struct
{
volatile uint8_t openFlag;//节点功能开关-
int setcnt;//设定的次数
int realCnt;//实际的次数
uint32_t RTime;//实际的计数值
uint32_t ATime;//设定的A计数值
uint32_t BTime;//设定的B计数值
fc funA;//[0-A之间的函数]
fc funB;//[A-B之间的函数]
}twinkleType;
//操作节点的函数的结构体
typedef struct
{
void (*set)( void *pnode,uint8_t enable,uint8_t Cnt , uint32_t ATime ,uint32_t BTime,fc Afun,fc Bfun);
void (*isr)( void *pnode );
}twinklefunctionType;
extern twinklefunctionType twfunc;
//给上层的接口
typedef struct
{
void (*write) (uint8_t id,uint8_t cnt);
}twapp_type;
#endif
#include "basetwinkle.h"
//使用说明:本模块在最底层 仅仅给LED BEEP这样的APP对接 上面的LED BEEP在网上对接
//这里放置了twinkleType twled;在上层中初始化
//不需要调用任何
//对节点的实例化 也就是赋值
void twinkle_set(void *pp ,uint8_t enable,uint8_t Cnt , uint32_t ATime ,uint32_t BTime,fc Afun,fc Bfun)
{
twinkleType* p=(twinkleType *)pp;
if(p==NULL)return;
p->setcnt = Cnt;
p->realCnt = 0;
p->RTime = 0;
p->ATime = ATime;
p->BTime = BTime;
p->funA = Afun;
p->funB = Bfun;
p->openFlag = enable;
}
void twinkle_timer_isr( void *pp )
{
twinkleType * p=(twinkleType *)pp;
if(p==NULL)
return;
if(p->openFlag)
{
if( p->RTime ++ < p->ATime)
{
if( *p->funA )p->funA() ;
}
else
{
if( *p->funB )p->funB() ;
}
if( p->RTime > p->ATime+p->BTime)
{
p->RTime = 0;
if( ++p->realCnt >= p->setcnt)
{
p->openFlag = 0;
}
}
}
else//无意义
{
p->openFlag = 0;
}
}
twinklefunctionType twfunc=
{
twinkle_set,
twinkle_timer_isr,
};
因为结构体比较复杂 再上面在接口一层比如BEEP
#ifndef _twbeep_H_
#define _twbeep_H_
#include "basetwinkle.h"
void beepon(void) ;
void beepoff(void);
extern twapp_type beep;//前台方便调用
extern twinkleType twbeep;//后台定时器轮训
#endif
#include "main.h"
#include "twbeep.h"
twinkleType twbeep={0};
void beepon(void) {HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, GPIO_PIN_SET);}
void beepoff(void){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, GPIO_PIN_RESET);}
void TWBEEP_write(uint8_t id,uint8_t num)
{
twfunc.set(&twbeep,1,num,200,200,beepon,beepoff);
}
twapp_type beep=
{
.write = TWBEEP_write,
};
现在就好了 去调用吧 底层的可以不要了 .H文件在BEEP里面再次包含了
在main
#include "twbeep.h"
static int cnt=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6)
{
twfunc.isr(&twbeep);
}
}
这样就后台好了 前台自己试试
beep.write(2);
注意:ONENET 麒麟座 晶振不是8M是12M