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)