蓝桥杯嵌入式-双通道方波频率检测与倍频输出
一,自己觉得此题需要注意的1、本题需用到PA2的串口发送和TIM2_CH3的捕获功能,如果不加处理,会发生冲突,这里我选择把PA2串口部分初始化注销掉//RXD-PA3 设置为浮空模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPI...
·
一,自己觉得此题需要注意的
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);
}
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)