【将测量结果通过串口发送到电脑上,方便复制】 #include <stm32f10x.h> #include <string.h>
const uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; char str[] = "Total: x.xxxxs High Level: x.xxxxs\r\n";
void delay(void) { uint16_t i; for (i = 0; i < 20000; i++); }
void ser_in(uint8_t data) { uint8_t i; for (i = 0; i < 8; i++) { GPIO_ResetBits(GPIOB, GPIO_Pin_9); // SCLK=>PB9 if (data & 0x80) GPIO_SetBits(GPIOB, GPIO_Pin_7); // DIO=>PB7 else GPIO_ResetBits(GPIOB, GPIO_Pin_7); data <<= 1; GPIO_SetBits(GPIOB, GPIO_Pin_9); } }
void par_out(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_8); // RCLK=>PB8 GPIO_SetBits(GPIOB, GPIO_Pin_8); }
void seg_scan(void) { uint16_t numbuf; uint8_t i; if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1) == SET) numbuf = TIM_GetCapture1(TIM2); // 按键松开时显示上次脉冲的总长度(单位: 秒) else numbuf = TIM_GetCapture2(TIM2); // 按键按下时显示高电平的长度(单位: 秒) for (i = 0; i < 5; i++) { __disable_irq(); if (i == 4) ser_in(seg8[numbuf % 10] & 0x7f); // 显示小数点 else ser_in(seg8[numbuf % 10]); ser_in(1 << i); par_out(); __enable_irq(); delay(); numbuf /= 10; } }
int main(void) { DMA_InitTypeDef dma; GPIO_InitTypeDef gpio; NVIC_InitTypeDef nvic; TIM_ICInitTypeDef timic; TIM_TimeBaseInitTypeDef tim; USART_InitTypeDef usart; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_USART1, ENABLE); // 时钟输入引脚和串口接收引脚配置 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10; GPIO_Init(GPIOA, &gpio); // 串口发送引脚配置 gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Pin = GPIO_Pin_9; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio); // 数码管扫描管脚配置 gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio); // 按键管脚PC1配置 gpio.GPIO_Mode = GPIO_Mode_IPU; gpio.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOC, &gpio); // 配置定时器的计数范围 TIM_TimeBaseStructInit(&tim); tim.TIM_CounterMode = TIM_CounterMode_Up; tim.TIM_Period = 0xffff; // 最大计数值 tim.TIM_Prescaler = 7199; // 7200分频, 得到基准时钟0.1ms TIM_TimeBaseInit(TIM2, &tim); // 配置定时器2的通道1 timic.TIM_Channel = TIM_Channel_1; timic.TIM_ICFilter = 0; // 不消抖 timic.TIM_ICPolarity = TIM_ICPolarity_Rising; // 通道1捕获上升沿 timic.TIM_ICPrescaler = TIM_ICPSC_DIV1; timic.TIM_ICSelection = TIM_ICSelection_DirectTI; // TI1->IC1=PA0 TIM_ICInit(TIM2, &timic); // 配置定时器2的通道2 timic.TIM_Channel = TIM_Channel_2; timic.TIM_ICFilter = 0; timic.TIM_ICPolarity = TIM_ICPolarity_Falling; // 通道2捕获下降沿 timic.TIM_ICPrescaler = TIM_ICPSC_DIV1; timic.TIM_ICSelection = TIM_ICSelection_IndirectTI; // TI2->IC1=PA0 TIM_ICInit(TIM2, &timic); TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1); // TRGI=TI1 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); // 上升沿使定时器归0 TIM_Cmd(TIM2, ENABLE); // 配置串口 USART_StructInit(&usart); usart.USART_BaudRate = 115200; usart.USART_Mode = USART_Mode_Tx; USART_Init(USART1, &usart); USART_Cmd(USART1, ENABLE); // 配置串口DMA USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); dma.DMA_BufferSize = 0; dma.DMA_DIR = DMA_DIR_PeripheralDST; dma.DMA_M2M = DMA_M2M_Disable; dma.DMA_MemoryBaseAddr = (uint32_t)str; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_Priority = DMA_Priority_Low; DMA_Init(DMA1_Channel4, &dma); // 配置定时器中断 TIM_ITConfig(TIM2, TIM_IT_Trigger, ENABLE); nvic.NVIC_IRQChannel = TIM2_IRQn; nvic.NVIC_IRQChannelCmd = ENABLE; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&nvic); while (1) seg_scan(); }
void TIM2_IRQHandler(void) { uint8_t i, j; uint16_t numbuf; TIM_ClearITPendingBit(TIM2, TIM_IT_Trigger); for (i = 7; i < 30; i += 21) { if (i == 7) numbuf = TIM_GetCapture1(TIM2); else numbuf = TIM_GetCapture2(TIM2); for (j = 5; j <= 5; j--) { if (j == 1) continue; str[i + j] = '0' + numbuf % 10; numbuf /= 10; } } DMA_Cmd(DMA1_Channel4, DISABLE); DMA_SetCurrDataCounter(DMA1_Channel4, strlen(str)); DMA_Cmd(DMA1_Channel4, ENABLE); }
|