bstimer:通用定时器,有两个例子,一个是dma:直接存储器访问,一个是onepulse:单脉冲模式
1、dma:全称Direct Memory Access,即直接存储器访问。
DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。
参考:(2条消息) 【STM32】 DMA原理,步骤超细详解,一文看懂DMA_Z小旋的博客-CSDN博客_dma stm32
开很多时钟,SYSCFG【系统控制器】:主要管理内存空间的映射、与EXTI中断源有关的IO配置以及其它配置等事务,因为要进行数据转移操作,内存空间重映射。只用了一个定时器,做一次转移操作
时钟计算:24M/(0+1)=2400000Hz,计时器时间=(187+1)*(1/2400000)=0.0000783s=0.783ms;是不是随便写的数字?
void bstimer_dma()
{
bstimer_init_t bstimer_init_config;
dma_dev_t dma_dev = { 0 };
bstimer_init_config.bstimer_mms = BSTIMER_MMS_ENABLE;
bstimer_init_config.period = 0xbb;
bstimer_init_config.prescaler = 0;
bstimer_init_config.autoreload_preload = false;// 不重复的定时器
bstimer_init(BSTIMER0, &bstimer_init_config);
bstimer_config_overflow_update(BSTIMER0, DISABLE);
bstimer_config_update_disable(BSTIMER0, DISABLE);
bstimer_config_dma(BSTIMER0, ENABLE);
bstimer_data = 0xaa;
dma_dev.dma_num = 0;
dma_dev.ch = 0;
dma_dev.mode = M2P_MODE;
dma_dev.src = (uint32_t)(&bstimer_data);
dma_dev.dest = (uint32_t)(&(BSTIMER0->ARR));
dma_dev.priv = write_bstimer_dma_irq_handle;
dma_dev.src_msize = 0;
dma_dev.dest_msize = 0;
dma_dev.data_width = 1;
dma_dev.block_size = 1;
dma_dev.handshake = DMA_HANDSHAKE_BSTIMER_0_UP;
dma_init(&dma_dev);
dma_ch_enable(dma_dev.dma_num, dma_dev.ch);
bstimer_cmd(BSTIMER0, true);
while (is_write_bstimer_dma_done == 0) {
;
}
dma_finalize(&dma_dev);
}
2、onepulse 单脉冲模式,好像可以实现精准延时,单脉冲模式(OPM)允许计数器在受到一个激励时启动,在一个可编程的延时后产生一个宽度可编程的脉冲。
可参考:https://blog.csdn.net/u013407012/article/details/84191666
只开了两个定时器的时钟,用到了第一个时钟,时钟计算:24M/(9999+1)=2400Hz,计时器时间=(2399+1)*(1/2400)=1s;
void bstimer_onepulse()
{
bstimer_init_t bstimer_init_config;
bstimer_init_config.bstimer_mms = BSTIMER_MMS_ENABLE;
bstimer_init_config.period = 2399; //time period is ((1 / 2.4k) * (2399 + 1))
bstimer_init_config.prescaler = 9999; //sysclock defaults to 24M, is divided by (prescaler + 1) to 2.4k
bstimer_init_config.autoreload_preload = false;
bstimer_init(BSTIMER0, &bstimer_init_config);
bstimer_config_one_pulse(BSTIMER0, ENABLE);
bstimer_config_overflow_update(BSTIMER0, ENABLE);
bstimer_generate_event(BSTIMER0, BSTIMER_EGR_UG, ENABLE); //in order to make prescaler work in the first time period
bstimer_config_interrupt(BSTIMER0, ENABLE);
bstimer_cmd(BSTIMER0, true);
NVIC_EnableIRQ(BSTIMER0_IRQn);
NVIC_SetPriority(BSTIMER0_IRQn, 2);
}
NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器,IRQHandler是中断处理函数,所以最后两句是使能中断,设置中断优先级。