stm32编程初始化设备步骤

1.使用LED

使用GPIO 、锁存器

步骤:

1.开启时钟
2.初始化GPIO结构体(包括8个LED和锁存器)PC8~PC15、PD2

(模式:GPIO_Mode_Out_PP 推挽输出

3.写一个控制LED的函数

因为LED和LCD公用GPIO,因此如果每次写入的是某一个GPIO的位,其他LED可能会在锁存器打开时因改变了LCD的值使LED也发生改变,因此,每一次改变LED的亮灭,应设置所有的GPIO。通过调用函数 LED_Lit(uint8_t led) 实现。

void LED_Lit(uint8_t led)
{
	GPIO_Write(GPIOC,led<<8);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
4.定义一个LED的全局变量

因此控制LED的应该是一个全局变量,在改变LED时改变这个全局变量的相应位即可。

2.使用按键

控制按键一般是使用轮询或中断,由于轮询需要写按键扫描函数,所以这里介绍中断方式

使用GPIO 、EXTI、NVIC

步骤:

1.开启时钟(GPIOA、GPIOB、AFIO)
2.初始化GPIO结构体(4个按键)PA0、PA8、PB、PB2

(模式:GPIO_Mode_IPU 上拉输入)

3.初始化NVIC结构体

初始化NVIC就是在配置优先级

4.初始化EXTI结构体

需要使用"stm32f10x_gpio.h"中的函数GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource8);来配置每一个EXTI对应的GPIO引脚。

5.写中断服务函数

一般步骤是先判断是否有EXTI_Linex的中断发生;如果有,先延时20ms,然后进行操作,一般中断服务函数里不做太多的操作,都是修改相应的标志,然后在主函数里根据标志位进行操作;最后清除标志位。

3.使用UART

串行输入输出使用的是uart2(PA3–RXD,PA2–TXD),且最好也是使用中断方式进行判断。

使用GPIO 、NVIC、

步骤:

1.开启时钟(GPIOA)
2.初始化GPIO结构体PA2、PA3

(PA3模式:GPIO_Mode_IN_FLOATING 浮空输入)因为这里是接受字符,字符是0、1序列,所以应该是输入什么就接受什么,所以是浮空输入。
(PA2模式:GPIO_Mode_AF_PP 复用推挽输出)

3.初始化NVIC结构体

初始化NVIC就是在配置优先级

4.其他函数的调用
USART_Cmd(USART2,ENABLE);//打开uart
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//配置中断是 接受队列不为空时产生中断

(显然,当发送数据时是不需要中断的,直接发送出去即可。
只有在接受数据时,当计算机发送数据到开发板,开发板需要检测是否有数据接受。)
发送数据到计算机需要使用函数printf();将printf中调用的fputc()进行修改,则每次调用printf()即向计算机发送一次数据。

int fputc(int ch,FILE* file)
{
	USART_SendData(USART2,ch);
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
	return ch;
}
5.中断处理函数(应该是接受数据时中断)

同样的,首先判断标志位USART_IT_RXNE是否发生;如果是,那么调用固件库函数USART_ReceiveData(USART2);接受一个字符,然后进行相应操作即可;最后清除标志位

4.使用EEPROM存储

使用GPIO 、I²C

(需要使用的函数考试时已经给出,直接调用即可,只需要写出俩个函数:写入EEPROM、读取EEPROM)
步骤:

写入EEPROM、读取EEPROM的函数
uint8_t EEPROM_Read(uint8_t adds)
{
	uint8_t data;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(adds);
	I2CWaitAck();

	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	data=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	return data;

}
void EEPROM_Write(uint8_t adds,uint8_t data)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(adds);
	I2CWaitAck();
	I2CSendByte(data);
	I2CWaitAck();
	I2CStop();
}

5.使用模拟输入ADC

(R37是PB0引脚 ,属于ADC,因此是模拟信号(模拟输入),且R37使用的是ADC1)

使用GPIO 、ADC、NVIC

步骤:

1.开启时钟(GPIOB、ADC1)
2.初始化GPIO结构体 PB0

(PA2模式:GPIO_Mode_AIN 模拟输入)

3.初始化NVIC结构体

即配置中断优先级

4.初始化ADC结构体
需要注意的有:
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent; //独立ADC
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//不使用外部触发
5.其他函数调用
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC时钟(只有这一个需要去"stm32f10x_rcc.h"里面找)

ADC_Cmd(ADC1,ENABLE);//打开ADC
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //中断配置

ADC_ResetCalibration(ADC1);//校准ADC
ADC_StartCalibration(ADC1);//校准ADC
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校准完毕

ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_13Cycles5);//规则通道配置
6.写中断服务函数

同样的,首先判断标志位ADC_IT_EOC是否发生;如果是,那么调用固件库函数ADC_GetConversionValue(ADC_TypeDef* ADCx);
接受ADC的值,然后进行相应操作即可;最后清除标志位

6.使用PWM输出

(PWM输出是TIM的一种使用。STM32S103RBT6开发板只有TIM1/2/3/4。其中,TIM1是高级定时器,其他是通用定时器。通过查stm32f103rbt6.pdf手册,找出题目中对应GPIO引脚使用的是哪一个TIM
每一个TIM有4个通道,根据GPIO判断使用的是哪一个通道
如:PA4使用的是TIM3——CN1)

使用GPIO 、TIM

步骤:

1.开启时钟(GPIOA、AFIO、TIM1/2/3/4)
2.初始化GPIO结构体

(模式:GPIO_Mode_AF_PP 复用推挽输出)

3.初始化时基结构体(TIM_TimeBaseInitTypeDef)
TIM_TimeBaseInitStruct.TIM_Prescaler=71;//分频系数,使定时器频率为72/(71+1)=1MHz。
TIM_TimeBaseInitStruct.TIM_Period=999;//周期,即重装载值设置为1000,则可以定时1ms
4.初始化输出比较结构体(TIM_OCInitTypeDef)
特别的:
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
5.其他的函数调用
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);//TIM预分频配置
TIM_Cmd(TIM3,ENABLE);  //打开相应的TIM           

7.使用LCD

同IIC,直接使用比赛时提供的函数进行调用。

8.系统时钟Systick

调用函数SysTick_Config(SystemCoreClock/1000);配置系统时钟为1ms中断一次
然后写相应的延时函数即可

9.蜂鸣器

使用GPIO

步骤:

1.开启时钟(GPIOB、AFIO)
2.初始化GPIO结构体 PB4

(模式 :GPIO_Mode_Out_PP 推挽输出)

3.其他函数调用
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE);//配置引脚映射(禁止JTRST)
上一篇:STM32复习笔记(四) —— 按键翻转LED


下一篇:第2期ARM裸机篇:【12】蜂鸣器实验