【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写

文章目录

  • 1、硬件资源一览
  • 2、硬件资源功能
    • 2.1、3 位 7 段共阴数码管
    • 2.2、8 个 ADC 按键
    • 2.3、DS18B20
    • 2.4、DHT11
    • 2.5、LIS302DL
    • 2.6、光敏电阻DO
    • 2.7、光敏电阻AO
    • 2.8、ADC*2
    • 2.9、脉冲测量(PWM输入捕获)


1、硬件资源一览

1、装配 3 位 7 段共阴数码管
2、装配 8 个 ADC 按键
3、装配 DS18B20 温度传感器
4、装配 DHT11 温湿度传感器
5、装配 LIS302DL 三轴传感器
  装配光敏电阻模拟量及开关量信号输出:
6、模拟量输出为光敏电阻和定值
电阻的分压值
7、开关量信号输出为光敏电阻分压和电位器分压值后通过
比较器输出的高低电平值
8、装配两路模拟信号输出,为电位器与定值电阻分压。
9、装配四路脉冲信号输出,其中 PWM1、PWM2 为占空比可调,频率不同可微调,PULS1、PULS2 为频率可调方波信号。

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第1张图片

▲布局图

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第2张图片

▲实物图

2、硬件资源功能

2.1、3 位 7 段共阴数码管

跳线帽接线:

排针行索引 排针列索引
P3 1、2、3(SER RCK SCK)
P4 1、2、3

  这三位数码管通过三个带输出锁存的8位移位寄存器获取SER端口发送的24位数据。
  下图为74LS595真值表,其中板子上的SER、RCK、SCK分别对应这里的SCLR、RCK、SCK
【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第3张图片

▲74LS595真值表

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第4张图片

▲74LS595在CT117E_EXA上

示例驱动:

#define RCLK_H			GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define RCLK_L			GPIO_ResetBits(GPIOA,GPIO_Pin_2)

#define SER_H			GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define SER_L			GPIO_ResetBits(GPIOA,GPIO_Pin_1)

#define SCK_H			GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define SCK_L			GPIO_ResetBits(GPIOA,GPIO_Pin_3)

uc8 Seg7[17] = { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x4f,0x79,0x78,0x00}; 


void SEG_DisplayValue(u8 Bit1,  u8 Bit2, u8 Bit3)//DS1 DS2 DS3
{
	u8 i = 0;	//
	u8 code_tmp = 0;

	code_tmp = Seg7[Bit3];//先传输第三位数码管段码
	for(i=0;i<8;i++){

		if(code_tmp & 0x80){//由高位至低位传输
			SER_H;
		}else{
			SER_L;
		}
		SCK_H;//上升沿(数据移位)
		code_tmp = code_tmp << 1; 
		SCK_L;//电平拉低
	}
	
	code_tmp = Seg7[Bit2];
	for(i=0;i<8;i++){

		if(code_tmp & 0x80){
			SER_H;
		}else{
			SER_L;
		}
		SCK_H;
		code_tmp = code_tmp << 1;   
		SCK_L;
	}	
	
	code_tmp = Seg7[Bit1];
	for(i=0;i<8;i++){

		if(code_tmp & 0x80){
			SER_H;
		}else{
			SER_L;
		}
		SCK_H;
		code_tmp = code_tmp << 1;   
		SCK_L;
	}		
	RCLK_H;//上升沿(输出锁存)
	RCLK_L;//电平拉低
}

2.2、8 个 ADC 按键

跳线帽接线:

排针行索引 排针列索引
P4 5
P5 5(AKEY)

  PA5对应的ADC通道为ADC_IN5,配置ADC读取相关操作在之前的文章中有说明,在此不再赘述,这里默认ADC已经配置完成。
  从下图可以看出采用分压法使得按下不同按键的ADC测量回路上所加电压也就不同。

按键索引 分压电阻阻值/总电阻阻值 理论ADC读数
S1 0/10 0
S2 0.51/10.51 198~199
S3 1.71/11.71 598~599
S4 3.31/13.31 1018~1019
S5 5.11/15.11 1385~1386
S6 8.1/18.1 1833~1834
S7 12.81/28.81 2300~2301
S8 22.81/32.81 2847~2848

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第5张图片

▲ADCKEY在CT117E_EXA上

  买板子给的代码中给出了中值滤波算法对ADC读取值进行滤波,实测没啥用…,推荐在比赛的时候直接读取ADC的值就行。

#define BTN_BUFF_LEN	50

static u16 btn_buff[BTN_BUFF_LEN];

//
u16 Read_Btn(void)//中值滤波算法
{
	u16 tmp;
	u8 i = 0,j = 0;
	
	for(i=0; i<BTN_BUFF_LEN; i++){
		btn_buff[i] = Read_ADC();//获取BTN_BUFF_LEN次ADC原始值
	}

	for(i=0; i<=BTN_BUFF_LEN - 1; i++){//冒泡排序
		for(j=0; j<	BTN_BUFF_LEN-i-1; j++){
			if(btn_buff[j+1] < btn_buff[j]){
				tmp = btn_buff[j+1];
				btn_buff[j+1] = btn_buff[j];
				btn_buff[j] = tmp;
			}
		}
	}

	if(BTN_BUFF_LEN % 2 == 0){//如果数据数量为偶数个取ADC数值缓冲区中中间两个数的平均值返回
		return(btn_buff[BTN_BUFF_LEN/2-1] + btn_buff[BTN_BUFF_LEN/2])/2;
	}else{//如果数据数量为奇数个取ADC数值缓冲区中中间值返回
		return(btn_buff[BTN_BUFF_LEN/2]);
	}
}

//
u8 Scan_Btn(void)
{
	u16 btn_tmp = 0;

	btn_tmp = Read_Btn();//Read_ADC();

	if(btn_tmp <= 0x0020){//32
		return 1;
	}else if((btn_tmp >= 0x00B0) && (btn_tmp <= 0x0100)){//176-256
		return 2;
	}else if((btn_tmp >= 0x0240) && (btn_tmp <= 0x0300)){//576-768
		return 3;
	}else if((btn_tmp >= 0x03B0) && (btn_tmp <= 0x0450)){//944-1104
		return 4; 
	}else if((btn_tmp >= 0x0500) && (btn_tmp <= 0x0600)){//1280-1536
		return 5;
	}else if((btn_tmp >= 0x0700) && (btn_tmp <= 0x0800)){//1792-2048
		return 6;
	}else if((btn_tmp >= 0x0840) && (btn_tmp <= 0x0940)){//2112-2368
		return 7;
	}else if(btn_tmp <= 0x0B50){//2896
		return 8;
	}else{
		return 0;	//error status & no key
	}
}


2.3、DS18B20

跳线帽接线:

排针行索引 排针列索引
P4 6
P3 6(TDQ)

  在官方驱动的基础上注意在读取数据的时候将总中断关闭,在读取数据完毕之后将总中断开启。

s16 ds18b20_read(void)
{
	u8 val[2];
	u8 i = 0;

	s16 x = 0;	
	
	//
	__disable_irq(); 	//关闭总中断

	ow_reset();
	ow_byte_wr(OW_SKIP_ROM);
	ow_byte_wr(DS18B20_CONVERT);
	delay_us(750000);

	ow_reset();
	ow_byte_wr( OW_SKIP_ROM );
	ow_byte_wr ( DS18B20_READ );

	for ( i=0 ;i<2; i++) {
		val[i] = ow_byte_rd();
	}
	//
	__enable_irq(); 	//打开总中断
	
	x = val[1];
	x <<= 8;   
	x |= val[0];

	return x;
}
...
	float DS_TemVal = 0;
...
	ds18b20_init_x();
...
	//
	DS_TemVal = ds18b20_read()*0.0625;
	sprintf((char *)Str,"Tem:%.2f            ",DS_TemVal);
	LCD_DisplayStringLine(Line3,Str);

2.4、DHT11

跳线帽接线:

排针行索引 排针列索引
P4 7
P3 7(HDQ)

  DHT11数据读取最好以两秒为时间间隔否则数据容易读取出错使显示跳变为0。

	unsigned int DHT_Val = 0;
	...
	dht11_init();
	...
	DHT_Val = dht11_read();
	sprintf((char *)Str, " Humidity: %2d%%", DHT_Val>>24); 
	LCD_DisplayStringLine(Line4, Str); 
	sprintf((char *)Str, " Temperature: %2dC", (DHT_Val>>8)&0xff); 
	LCD_DisplayStringLine(Line5, Str);
	
	Delay_Ms(2000);

2.5、LIS302DL

跳线帽接线:
  P2全部短接且保证PA4、5、6、7未被使用。
  LIS302DL是意法半导体公司生产的I2C协议驱动的三轴加速度计,对于简单操作LIS302DL只需要写CTRL_REG1寄存器中的值,然后读取OUT_X、OUT_Y、OUT_Z中的值即可。
【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第6张图片

▲CTRL_REG1于LIS302DL官方数据手册

在这里插入图片描述

▲OUT_X、OUT_Y、OUT_Z于LIS302DL官方数据手册

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第7张图片

▲I2C引脚于CT117E_EXA

  值得注意的是这里要将I2C.c文件中的i2c_init()函数做以下修改。

/** I2C 总线接口 */
/** I2C 总线接口 */
#define I2C_PORT GPIOA    //GPIOA
#define SDA_Pin	GPIO_Pin_5//GPIO_Pin_5
#define SCL_Pin GPIO_Pin_4//GPIO_Pin_4
...

void i2c_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//RCC_APB2Periph_GPIOA

	GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);

}

LIS302DL.c:

#include "Headfile.h"

u8 LIS302DL_X = 0;
u8 LIS302DL_Y = 0;
u8 LIS302DL_Z = 0;


void LIS302DL_Write(u8 Addr,u8 Val)
{
	I2CStart();
	I2CSendByte(0x38);//器件地址+写
	I2CWaitAck();
	I2CSendByte(Addr);//寄存器地址
	I2CWaitAck();
	I2CSendByte(Val);
	I2CWaitAck();
	I2CStop();
}

u8 LIS302DL_Read(u8 Addr)
{
	u8 Dat = 0;
	I2CStart();
	I2CSendByte(0x38);//器件地址+写
	I2CWaitAck();
	I2CSendByte(Addr);
	I2CWaitAck();

	I2CStart();
	I2CSendByte(0x39);//器件地址+读
	I2CWaitAck();
	Dat = I2CReceiveByte();
	I2CSendNotAck();
	I2CStop();

	return Dat;
}


void LIS302DL_Init()
{
	LIS302DL_Write(0x20,0x47);//使工作在正常模式,x、y、z寄存器输出使能
}

void LIS302DL_DataRead()
{
	LIS302DL_X = LIS302DL_Read(0x29);
	LIS302DL_Y = LIS302DL_Read(0x2B);
	LIS302DL_Z = LIS302DL_Read(0x2D);

}





2.6、光敏电阻DO

跳线帽接线:

排针行索引 排针列索引
P4 3
P5 3(TRDO)

  TRDOLM393D的输出端口,在这里LM339的输入两个输入端口分别是来自于光敏电阻的分压值(接同相输入)和电位器RP7的分压值(接反相输入),从电路图上可以看出当光敏电阻接收到的光照减小也就是光敏电阻阻值升高从而使得同相输入端口的电压升高当大于反相输入端的电压时TRDO端口输出高电平。
  换而言之,我们可以通过调节RP7设定光照阈值来使得LM339的输出电压和光强产生映射关系。

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第8张图片

▲Tr_DO在CT117E_EXA上

  这部分的代码较为简单只要初始化PA3,读取PA3端口的电平值即可。

void DO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
...
while(1){
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == Bit_SET){
				LCD_DisplayStringLine(Line7, (u8*)"       DO:High     ");
			}else{
				LCD_DisplayStringLine(Line7, (u8*)"       DO:Low      ");
	}

2.7、光敏电阻AO

跳线帽接线:

排针行索引 排针列索引
P4 4
P5 4(TRAO)

  ADC相关介绍戳这里。
  TRAO的部分也就是通过PA4(ADCIN4)来测量光敏电阻上的分压来估计光敏电阻此时的阻值。
【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第9张图片

▲Tr_AO在CT117E_EXA上
void ADC_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 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 = 4;
	ADC_Init(ADC1, &ADC_InitStructure);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_13Cycles5);    

	ADC_Cmd(ADC1, ENABLE);   
	ADC_ResetCalibration(ADC1);
	/* Check the end of ADC1 reset calibration register */
	while(ADC_GetResetCalibrationStatus(ADC1));
	ADC_StartCalibration(ADC1);
	/* Check the end of ADC1 calibration */
	while(ADC_GetCalibrationStatus(ADC1));
}
...
u16 Read_ADC(void)
{
	u16 ADC_VALUE = 0;
	
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	ADC_VALUE = ADC_GetConversionValue(ADC1);
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_VALUE;
}
...
	while(1){
		
		tmp = Read_ADC();
		snprintf((char *)str, sizeof(str), " R-P:%.2fK  ", tmp/(4096.-tmp)*10);//(U2/U1)*R1=R2
		LCD_DisplayStringLine(Line6, str);
		Delay_Ms(200);
	}

2.8、ADC*2

跳线帽接线:

排针行索引 排针列索引
P4 4、5
P3 4(AO1)、5(AO2)

  ADC相关介绍戳这里。
  AO1AO2分别对应着PA4PA5也就是ADCIN4ADCIN5,这里是在更改ADC模式为混合的同步规则+注入同步模式的前提下在ADC规则组通道设置时将通道设为变量。即:
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
其中channel是一个变量,从以下宏定义中选出。
  驱动参考:
赛点资源数据包_嵌入式_2019\6-STM32固件库代码V3.5版\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\ADC\RegSimul_DualMode

#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \
                                 ((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \
                                 ((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \
                                 ((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \
                                 ((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \
                                 ((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \
                                 ((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \
                                 ((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \
                                 ((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17))

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第10张图片

▲AO1、AO2在CT117E_EXA上
void ADC_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
	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 = 2;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	/* ADC1 regular channels configuration */ 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5);
	ADC_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1));
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1));
}
...
u16 Get_ADCs(u8 channel)
{
	
	u16 ADC_Val = 0;
	
	ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	ADC_Val = ADC_GetConversionValue(ADC1);
	ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
	
	ADC_SoftwareStartConvCmd(ADC1, DISABLE);
	
	return ADC_Val;
}

...
	while(1){
		
		x = Get_ADCs(ADC_Channel_4);
		y = Get_ADCs(ADC_Channel_5);
		
		snprintf((char *)str, sizeof(str), " VRp5:%3.2fV", x/4096.*3.3);
		LCD_DisplayStringLine(Line6, str);
		snprintf((char *)str, sizeof(str), " VRp6:%3.2fV", y/4096.*3.3);
		LCD_DisplayStringLine(Line7, str);
		
		Delay_Ms(200);
	}


2.9、脉冲测量(PWM输入捕获)

跳线帽接线:

排针行索引 排针列索引
P4 1、2、6、7
P5 1(PULS1)、2(PULS2)、6(PWM1)、7(PWM2)

【蓝桥杯嵌入式】【STM32】14_CT117E_EXA蓝桥杯嵌入式扩展板硬件资源一览及其驱动编写_第11张图片

▲脉冲发生在CT117E_EXA上

  有关PWM输入模式相关参考这里。程序源码参考ST官方固件库实例:...赛点资源数据包_嵌入式_2019\6-STM32固件库代码V3.5版\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\PWM_Input

PA7_PWM捕获:

__IO uint16_t IC2Value = 0;
__IO uint16_t DutyCycle = 0;
__IO uint32_t Frequency = 0;

void RCC_Configuration(void)
{
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM3 channel 2 pin (PA.07) configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


void TIM3_CC2Config()
{
	TIM_ICInitTypeDef  TIM_ICInitStructure;


	/* System Clocks Configuration */
  RCC_Configuration();

  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* TIM3 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH2 pin (PA.01), 
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value 
     The TIM3 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

  /* Select the TIM3 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

}

//定时器3中断---输入捕获
void TIM3_IRQHandler(void)
{
  /* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM3);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = SystemCoreClock / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}
...
while(1)
	{
		snprintf((char *)str, sizeof(str), " DTY:%d%%   ", DutyCycle);
		LCD_DisplayStringLine(Line6, str);
		
		snprintf((char *)str, sizeof(str), " FRQ:%dHz  ",Frequency);
		LCD_DisplayStringLine(Line7, str);
		
		Delay_Ms(200);
	}

PA1_PWM输入捕获:

#include "Headfile.h"

__IO uint16_t IC2Value = 0;
__IO uint16_t DutyCycle = 0;
__IO uint32_t Frequency = 0;

void RCC_Configuration(void)
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


void TIM2_CC2Config()
{
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;


  RCC_Configuration();

  NVIC_Configuration();

  GPIO_Configuration();

  /* TIM2 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH2 pin (PA.01), 
     The Rising edge is used as active edge,
     The TIM2 CCR2 is used to compute the frequency value 
     The TIM2 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */
	TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 72;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
	TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);

	 //选择输入捕获的触发信号
  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);


  // PWM输入模式时,从模式须工作在复位模式,当捕获开始时,计数器CNT被复位清零
  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
	
	TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

}

void TIM2_IRQHandler(void)
{
  /* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM2);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = (SystemCoreClock/72) / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}


...
	while(1)
	{
		snprintf((char *)str, sizeof(str), " DTY:%d%%   ", DutyCycle);
		LCD_DisplayStringLine(Line6, str);
		
		snprintf((char *)str, sizeof(str), " FRQ:%dHz  ",Frequency);
		LCD_DisplayStringLine(Line7, str);
		
		Delay_Ms(200);
	}


你可能感兴趣的:(#,蓝桥杯嵌入式,STM32,CT117E-EXA,蓝桥杯嵌入式)