一,自己觉得此题需要注意的
1、
在这里插入图片描述
本题需用到PA2的串口发送和TIM2_CH3的捕获功能,如果不加处理,会发生冲突,这里我选择把PA2串口部分初始化注销掉

	//RXD-PA3 设置为浮空模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//TXD-PA2 设置为推挽输出
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);

实验效果能够达到,然而串口助手却疯狂打印乱码,仍然没有解决!
2.
PWM捕获时,捕获5000HZ以下频率,捕获值较准确,超过5000Hz,捕获值会不准确,需要继续优化代码!
3.

要避免长数据对短数据的覆盖,应在数据后面加空格
	sprintf((char*)string," Channel(1):%dHz     ",FRE1);
	LCD_DisplayStringLine(Line1,string);

	sprintf((char*)string," N(1)      :%d ",Chan1_N);//要避免长数据对短数据的覆盖,应在数据后面加空格!!!!!!
	LCD_DisplayStringLine(Line3,string);

4.
PWM输出比较模式:复用推挽输出 GPIO_Mode_AF_PP
5.
CAPTURE:中断函数中:
HL=TIM_GetCounter(TIM2);
而非HL=TIM_GetCapture2(TIM2);
二,代码
由于初始化没有什么不同,这里只呈现主函数

#include"stm32f10x.h"
#include"capture.h"
#include"pwm_oc.h"
#include"stdio.h"
#include"lcd.h"
#include"timer.h"
#include"key.h"
#include"i2c.h"
#include"e2prom.h"
#include"led.h"
#include"usart2.h"
//如何解决PA2为USART和捕获共用????
/**   注意   **/
//要避免长数据对短数据的覆盖,应在数据后面加空格!!!!!!

u32 LED_MODE=0xffff;//LED变量
u32 FRE1;
u32 FRE2;
extern u32 TIM2_CH2_CAPTURE_HL;
extern u32 TIM2_CH3_CAPTURE_HL;
extern u8 TIM2_CH2_MODE;
extern u8 TIM2_CH3_MODE;
u8 Chan1_En=0;//TIM3_CH1使能
u8 Chan2_En=0;//TIM3_CH2使能
u8 string[20];

//按键部分
u8 SetFlag=0;//0代表本地设定,1代表串口设定
u8 ChanFlag=0;//0代表通道一,1代表通道二
u8 Chan1_N=1;//通道一的倍频
u8 Chan2_N=1;//通道二的倍频

//串口//
extern u8 RxdCnt;
extern u8 RxdOver;
extern u8 RxdBuf[20];

extern u32 delaytime;
extern u8 flag200ms	;
extern u8 flag1s;

void UsartAction(void);
void delay_ms(u32 time);
void KeyAction(int code);
void Display(void);
void LED_Warn(void);
int main()
{
	SysTick_Config(SystemCoreClock/1000);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);	
	LCD_SetTextColor(White);
    Pwm_oc_Init(1000,50,1,1,1);
	TIM4_Init(2000,72);//2ms
	Capture_Init();
	Key_Init();
	i2c_init();
	LED_Init();
	USART2_Init();

	Chan1_N=E2Read(0x00);
	delay_ms(5);
	Chan2_N=E2Read(0x01);//读取倍频
	delay_ms(5);
	while(1)
	{
		KeyDriver();
	 	if(TIM2_CH2_MODE==2)
		{
			FRE1=1000000/TIM2_CH2_CAPTURE_HL;
			if(FRE1<50||FRE1>50000)
			{
				Chan1_En=0;	
			}
			else
			{
				Chan1_En=1;
			}
			TIM2_CH2_MODE=0;
		}
		if(TIM2_CH3_MODE==2)
		{
			FRE2=1000000/TIM2_CH3_CAPTURE_HL;
			if(FRE2<50||FRE2>50000)
			{
				Chan2_En=0;
			}
			else
			{
				Chan2_En=1;
			}
			TIM2_CH3_MODE=0;
		}

		if(flag200ms)
		{
			Display();
			LED_Warn();
			flag200ms=0;
		}
		if(flag1s)//1s输出
		{
			Pwm_oc_Init(FRE1*Chan1_N,FRE2*Chan2_N,0,Chan1_En,Chan2_En);	//不需要再初始化
			flag1s=0;	
		}
		if(SetFlag)//处于串口设定
		{
			if(RxdOver)
			{
				UsartAction();
				RxdOver=0;
			}
	    }
	}

}
void UsartAction() //串口识别的是字符,判断时注意
{
	u8 i=0;
	if(RxdBuf[4]=='1')//通道一
	{
		switch(RxdBuf[7])
		{
			case '2':Chan1_N=2;break;
			case '3':Chan1_N=3;break;
			case '4':Chan1_N=4;break;
			case '5':Chan1_N=5;break;
			case '6':Chan1_N=6;break;
			case '7':Chan1_N=7;break;
			case '8':Chan1_N=8;break;
			case '9':Chan1_N=9;break;
			case '0':Chan1_N=10;break;
			default : break;
		}
//		if(RxdBuf[6]=='1'&&RxdBuf[7]=='0')
//		{
//			Chan1_N=10;
//		}
//		else
//		{
//			Chan1_N=RxdBuf[6]-'0';
//		}
	}
	else//通道二
	{
			switch(RxdBuf[7])
		{
			case '2':Chan2_N=2;break;
			case '3':Chan2_N=3;break;
			case '4':Chan2_N=4;break;
			case '5':Chan2_N=5;break;
			case '6':Chan2_N=6;break;
			case '7':Chan2_N=7;break;
			case '8':Chan2_N=8;break;
			case '9':Chan2_N=9;break;
			case '0':Chan2_N=10;break;
			default : break;
		}
	}

	//!!!
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启中断
	for(i=0;i<20;i++)//清除缓冲数组内容
	{
		RxdBuf[i]=0;	
	}	
}
void delay_ms(u32 time)
{
	delaytime=time;
	while(delaytime!=0);
}
void LED_Warn()
{
	if(Chan1_En)
	{
		LED_MODE&=~(1<<8);
	}
	else
	{
		LED_MODE|=(1<<8);
	}
	if(Chan2_En)
	{
		LED_MODE&=~(1<<9);
	}
	else
	{
		LED_MODE|=(1<<9);
	}
	if(SetFlag)//处于串口设定
	{
		LED_MODE&=~(1<<10);
	}
	else
	{
		LED_MODE|=(1<<10);
	}
	 GPIOC->ODR=LED_MODE;
	 GPIOD->ODR|=(1<<2);
	 GPIOD->ODR&=~(1<<2);
}
void Display(void)
{
	sprintf((char*)string," Channel(1):%dHz     ",FRE1);
	LCD_DisplayStringLine(Line1,string);

	sprintf((char*)string," N(1)      :%d ",Chan1_N);//要避免长数据对短数据的覆盖,应在数据后面加空格!!!!!!
	LCD_DisplayStringLine(Line3,string);

	sprintf((char*)string," Channel(2):%dHz   ",FRE2);
	LCD_DisplayStringLine(Line5,string);

	sprintf((char*)string," N(2)      :%d ",Chan2_N);
	LCD_DisplayStringLine(Line7,string);

	sprintf((char*)string,"               %d",ChanFlag+1);
	LCD_DisplayStringLine(Line9,string);

}
void KeyAction(int code)
{
	if(code==1)
	{
		SetFlag^=1;
	}
	else if(code==2)
	{
		if(SetFlag==0)//本地设定
		{
			ChanFlag^=1;//改变通道	
		}	
	}
	else if(code==3)
	{
		if(SetFlag==0) //本地设定
		{
			if(ChanFlag==0)	//通道一
			{
			   Chan1_N--;
			   if(Chan1_N<1)
			   {
			   		Chan1_N=1;
			   }
			}
			else//通道二
			{
				Chan2_N--;
				if(Chan2_N<1)
				{
					Chan2_N=1;
				}
			}
			E2Write(0x00,Chan1_N);
			delay_ms(5);
			E2Write(0x01,Chan2_N);
			delay_ms(5);
		}
	}
	else if(code==4)
	{
		if(SetFlag==0)//处于本地设定
		{
			if(ChanFlag==0)//通道一
			{
				Chan1_N++;
				if(Chan1_N>=10)
				{
					Chan1_N=10;
				}	
			}
			else //通道二
			{
				Chan2_N++;
				if(Chan2_N>=10)
				{
					Chan2_N=10;
				}
			}
			E2Write(0x00,Chan1_N);
			delay_ms(5);
			E2Write(0x01,Chan2_N);
			delay_ms(5);	
		}
	}	
}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐