基于keil编写stm32f103ze代码:利用定时中断对程序八次AD采样进行计时,并在TFTLCD上显示计时的时间
时间: 2023-06-16 12:08:00 浏览: 111
以下是一个简单的基于Keil编写STM32F103ZE代码的示例,利用定时中断对程序八次AD采样进行计时,并在TFTLCD上显示计时的时间:
```c
#include "stm32f10x.h"
#include "TFTLCD.h"
#define ADC_CHANNEL 0 // ADC通道
#define ADC_SAMPLE_TIMES 8 // ADC采样次数
#define TIMER_PERIOD 100000 // 定时器计数周期
#define TIMER_PRESCALER 72 // 定时器分频系数
volatile uint32_t timer_count = 0; // 定时器计数
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除定时器更新中断标志位
timer_count++; // 定时器计数加1
}
}
void ADC_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // 使能ADC1和GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PA0连接到ADC通道0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); // 复位ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 无触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; // 转换通道数
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); // 使能ADC1
}
uint16_t ADC_Sample(void)
{
uint8_t i;
uint16_t adc_value = 0;
for (i = 0; i < ADC_SAMPLE_TIMES; i++)
{
ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5); // 配置ADC通道和采样时间
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动ADC转换
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // 等待转换完成
adc_value += ADC_GetConversionValue(ADC1); // 获取转换结果
}
adc_value /= ADC_SAMPLE_TIMES; // 取平均值
return adc_value;
}
int main(void)
{
SysTick_Config(SystemCoreClock / 1000); // 初始化系统滴答定时器,1ms中断一次
TFTLCD_Init(); // 初始化TFTLCD
ADC_Init(); // 初始化ADC
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD - 1; // 计数周期
TIM_TimeBaseStructure.TIM_Prescaler = TIMER_PRESCALER - 1; // 分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能定时器更新中断
TIM_Cmd(TIM2, ENABLE); // 启动定时器
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 定时器2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure);
uint16_t adc_value;
uint32_t start_time, end_time, total_time;
while (1)
{
start_time = timer_count; // 记录开始时间
adc_value = ADC_Sample(); // 进行ADC采样
end_time = timer_count; // 记录结束时间
total_time = (end_time - start_time) * TIMER_PERIOD / SystemCoreClock; // 计算采样时间
TFTLCD_ShowNum(0, 0, total_time, 5, 16); // 在TFTLCD上显示采样时间
}
}
```
在这个示例中,我们使用了TIM2定时器来进行计时,每当定时器的计数器溢出时,就会触发TIM2_IRQHandler中断处理函数。在主函数中,我们不断进行ADC采样,并在每次采样结束后计算出采样时间,并在TFTLCD上显示出来。需要注意的是,在进行ADC采样的过程中,需要等待ADC转换完成,并且需要进行多次采样并取平均值,以提高采样精度。
阅读全文