
(1)控制2个LED,1个LED亮,1个LED熄灭;
(2)使用定时器控制(1)中2个LED亮灭状态翻转,间隔1秒;
(3)使用串口接收数字0-9,并用以控制PWM模块输出频率为1K-10K启动及停止,并用示波器检测;
(4)使用中断按键启动控制ADC转换;
(5)使用ADC测量光敏电阻LDR阻值,并使用串口显示。
用STM32F103R6实现上述这些功能,用的Proteus仿真,麻烦大家帮忙看看代码和电路连接有没有什么问题
#include "stm32f10x.h"
#include "stdio.h"
// LED 相关定义
#define LED1_GPIO_PORT GPIOB
#define LED1_GPIO_PIN GPIO_Pin_0
#define LED2_GPIO_PORT GPIOB
#define LED2_GPIO_PIN GPIO_Pin_1
// PWM 相关定义
#define PWM_TIMER TIM2
#define PWM_CHANNEL TIM_Channel_1
#define PWM_GPIO_PORT GPIOA
#define PWM_GPIO_PIN GPIO_Pin_0
// 串口相关定义
#define USARTx USART1
#define USART_RX_PIN GPIO_Pin_10
#define USART_TX_PIN GPIO_Pin_9
#define USART_GPIO_PORT GPIOA
// 频率范围
#define MIN_FREQUENCY 1000
#define MAX_FREQUENCY 10000
// 当前频率变量
volatile uint32_t currentFrequency = MIN_FREQUENCY;
// 标志位,表示 PWM 是否正在运行
volatile uint8_t pwmRunning = 1;
// ADC 相关定义
#define ADC_CHANNEL ADC_Channel_1
#define ADC_GPIO_PORT GPIOA
#define ADC_GPIO_PIN GPIO_Pin_1
// 中断按键相关定义
#define KEY_GPIO_PORT GPIOC
#define KEY_PIN GPIO_Pin_0
#define KEY_EXTI_LINE EXTI_Line0
#define KEY_IRQn EXTI0_IRQn
// 光敏电阻相关参数
#define REFERENCE_RESISTANCE 10000.0 // 参考电阻值,单位欧姆
void GPIO_Config(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIOMode_TypeDef GPIO_Mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOx, &GPIO_InitStructure);
}
void USART1_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
GPIO_Config(USART_GPIO_PORT, USART_TX_PIN | USART_RX_PIN, GPIO_Mode_AF_PP);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USARTx, &USART_InitStructure);
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USARTx, ENABLE);
}
void USART_SendChar(char ch)
{
while (!(USARTx->SR & USART_FLAG_TXE));
USART_SendData(USARTx, ch);
}
void USART_SendString(const char* str)
{
while (*str)
{
USART_SendChar(*str++);
}
}
int fputc(int ch, FILE *f)
{
USART_SendChar((char)ch);
return ch;
}
void LED_Toggle(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
GPIOx->ODR ^= GPIO_Pin;
USART_SendString("LED toggled.\n");
}
void LED_Init(void)
{
GPIO_Config(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_Mode_Out_PP);
GPIO_Config(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_Mode_Out_PP);
// 初始状态 LED1 亮,LED2 灭
GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
USART_SendString("LED_Init\n");
}
void Timer3_Init(void)
{
USART_SendString("Starting Timer3 initialization...\n");
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 9999;
TIM_TimeBaseStructure.TIM_Prescaler = 7199;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
USART_SendString("Timer3_Init\n");
USART_SendString("Timer3 initialization completed.\n");
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update)!= RESET)
{
USART_SendString("Timer3 counter value before LED toggle: ");
char buffer[64];
snprintf(buffer, sizeof(buffer), "%d\n", TIM3->CNT);
USART_SendString(buffer);
LED_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);
LED_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
USART_SendString("Timer3 counter value after LED toggle: ");
snprintf(buffer, sizeof(buffer), "%d\n", TIM3->CNT);
USART_SendString(buffer);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
USART_SendString("Timer3 interrupt occurred.\n");
}
}
void PWM_Init(void)
{
USART_SendString("Starting PWM initialization...\n");
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_Config(PWM_GPIO_PORT, PWM_GPIO_PIN, GPIO_Mode_AF_PP);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / currentFrequency - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(PWM_TIMER, &TIM_TimeBaseStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(PWM_TIMER, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(PWM_TIMER, TIM_OCPreload_Enable);
TIM_Cmd(PWM_TIMER, ENABLE);
USART_SendString("PWM_Init\n");
USART_SendString("PWM initialization completed. Period: ");
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d\n", TIM_TimeBaseStructure.TIM_Period);
USART_SendString(buffer);
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USARTx, USART_IT_RXNE)!= RESET)
{
char receivedChar = USART_ReceiveData(USARTx);
uint8_t receivedNumber = receivedChar - '0';
if (receivedNumber >= 0 && receivedNumber <= 9)
{
currentFrequency = MIN_FREQUENCY + receivedNumber * (MAX_FREQUENCY - MIN_FREQUENCY) / 9;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / currentFrequency - 1;
TIM_TimeBaseInit(PWM_TIMER, &TIM_TimeBaseStructure);
TIM_SetAutoreload(PWM_TIMER, TIM_TimeBaseStructure.TIM_Period);
USART_SendString("Updated PWM frequency.\n");
}
else if (receivedChar == 's')
{
pwmRunning =!pwmRunning;
if (pwmRunning)
{
TIM_Cmd(PWM_TIMER, ENABLE);
USART_SendString("PWM started.\n");
}
else
{
TIM_Cmd(PWM_TIMER, DISABLE);
USART_SendString("PWM stopped.\n");
}
}
USART_ClearITPendingBit(USARTx, USART_IT_RXNE);
}
}
// 中断按键中断处理函数
void KEY_IRQHandler(void)
{
if (EXTI_GetITStatus(KEY_EXTI_LINE)!= RESET)
{
// 启动 ADC 转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
USART_SendString("Key pressed, starting ADC conversion.\n");
EXTI_ClearITPendingBit(KEY_EXTI_LINE);
}
}
// 读取 ADC 值函数
uint16_t readADCValue(ADC_TypeDef* ADCx)
{
ADC_SoftwareStartConvCmd(ADCx, ENABLE);
while (!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC));
return ADC_GetConversionValue(ADCx);
}
// 计算光敏电阻阻值函数
float calculateLDRResistance(uint16_t adcValue)
{
// 假设 ADC 参考电压为 3.3V
float adcVoltage = adcValue * 3.3 / 4095.0;
float ldrVoltage = 3.3 - adcVoltage;
return REFERENCE_RESISTANCE * adcVoltage / ldrVoltage;
}
int main(void)
{
USART1_Init();
LED_Init();
Timer3_Init();
PWM_Init();
ADC_InitTypeDef adcInitStruct;
adcInitStruct.ADC_Mode = ADC_Mode_Independent;
adcInitStruct.ADC_ScanConvMode = DISABLE;
adcInitStruct.ADC_ContinuousConvMode = DISABLE;
adcInitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adcInitStruct.ADC_DataAlign = ADC_DataAlign_Right;
adcInitStruct.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &adcInitStruct);
// 配置中断按键
GPIO_Config(KEY_GPIO_PORT, KEY_PIN, GPIO_Mode_IPU);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = KEY_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructureKey;
NVIC_InitStructureKey.NVIC_IRQChannel = KEY_IRQn;
NVIC_InitStructureKey.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructureKey.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructureKey.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructureKey);
while (1)
{
uint16_t adcValue = readADCValue(ADC1);
float ldrResistance = calculateLDRResistance(adcValue);
char buffer[64];
snprintf(buffer, sizeof(buffer), "LDR Resistance: %.2f ohms\n", ldrResistance);
USART_SendString(buffer);
}
}