stm32 检测相位差 并简单实现两个单片机的通信

stm32 检测相位差 并简单实现两个单片机的通信,第1张

红叶何时落水

校赛第二部分

详见

http://t.csdn.cn/50yJu

利用定时器的输入捕获模式来测量相位差

通过 (两路波形上升沿的时间差 / 波形周期)* 360°来实现相位差的测量

deg = (360 - (((TIM2CH1_CAPTURE_VAL3 * 360)  / (TIM2CH1_CAPTURE_VAL)) + chart)) % 180;

其中chart为线性补偿,可以通过按键改变其值,以此实现不同电路的测量

可以利用相位差来计算相应的频率与峰峰值

难点在于C语言中int 类型 (2 / 3)* 3 = 0;

解决,((2 * 10 / 3) * 3) / 10 = 1;尽量吧

vpp = (((((deg * 1000000)/56 - 285714) / 33) * 4096)/ 88) / 100000 ;
tim4 = 1000000 / (35 * deg - 600);		

再一个功能,第二个单片机需要实现扫描功能,而第三个需要检测它。

那么我们如何保证输出与检测同时进行呢?

方案一

难点,需要极快的手速,两个单片机的按键同时按下。

结局方案,多多练习手速

方案二

因为两个单片机只允许用一根线连接,所以我们只能用电压作为启动信号。

将第二个单片机的前五秒输出设置为3.3V输出,之后再扫描。

而第三个单片机再检测到小于3.3V的电压后,在进行数据的采集。

不足,由于启动信号为直流,所以在经过放大与衰减电路后会失真,导致启动信号失效。

解决,将启动信号改成峰峰值为3.3V的正弦波,后续电路检测峰峰值是否小于3.3V

主函数

int main(void)
 { 

	u16 adcx;
	int i = 0, t = 0;
	Init();
	while(1)
	{	
		deg = (360 - (((TIM2CH1_CAPTURE_VAL3 * 360)  / (TIM2CH1_CAPTURE_VAL)) + chart)) % 180;
		delay_ms(50);
		change();
		t=KEY_Scan(0);		//µÃµ½¼üÖµ
		switch(t)
		{				 
			case KEY0_PRES:
				pint_deg = (pint_deg + 1) % 5;
				LCD_ShowxNum(120,50, pint_deg,3,16,0X80);
				break;
			case KEY1_PRES:
				deg2 = deg2 + 10;
				if(pint_deg == 3) 
				{chart++;}
				break;
			case WKUP_PRES:		
				deg2 = deg2 - 10;
				if(pint_deg == 3) 
				{chart--;}
				break;
			default:
				delay_ms(10);
		} 
			
		

			
			
	}											    
}	

void Init(void) {

	uart_init(9600);
	delay_init();
 	LCD_Init();
	KEY_Init();		
		
	TIM5_Int_Init(0XFFFF,0);
	TIM3_Int_Init(0XFFFF,0);	

	Dac3_Init();
	MYDMA1_Config( (u32) & (DAC->DHR12R1), (u32)SIN, 72);
	TIM2_Config(tim4, 1);


	POINT_COLOR=BLUE;	
	LCD_ShowString(80,50,50,16,16,"deg");
	LCD_ShowString(80,70,50,16,16,"deg2");
	LCD_ShowxNum(120,50, pint_deg,3,16,0X80);
}

void change(void) {
	int n = 0;
	if(pint_deg == 0) {
		if(old_deg != deg) {
						old_deg = deg;
						vpp = (((((deg * 1000000)/56 - 285714) / 33) * 4096)/ 88) / 100000 ;
						tim4 = 1000000 / (35 * deg - 600);			
						LCD_ShowxNum(50,50, deg,3,16,0X80);
						for(i = 0; i < 72; i++) {
							SIN[i] = old_SIN[i] * vpp;
						}			
						TIM2->ARR = tim4;
						delay_ms(500);
					}
	} else if(pint_deg == 1) {
			if(old_deg2 != deg2) {
			old_deg2 = deg2;
						vpp = (((((deg2 * 1000000)/56 - 285714) / 33) * 4096)/ 88) / 100000 ;
						tim4 = 1000000 / (35 * deg2 - 600);			
						LCD_ShowxNum(50,70, deg2,3,16,0X80);
						LCD_ShowString(80,100,200,16,16,"V = 1/28P - 4/7        ");
						LCD_ShowString(80,120,200,16,16,"F = 35P - 600");
						for(i = 0; i < 72; i++) {
							SIN[i] = old_SIN[i] * vpp;
						}			
						TIM2->ARR = tim4;
						delay_ms(50);
			}
	} else if(pint_deg == 4) {
			for(i = 0; i < 72; i++) {
				SIN[i] = 4000;
			}		
			delay_ms(10000);
			for(i = 0; i < 70; i++) {
				tim4 = 1000000 / (35 * (20 + 2 * i) - 600);	
				vpp = ((((((20 + 2 * i) * 1000000)/56 - 285714) / 33) * 4096)/ 88) / 100000 ;	
				LCD_ShowxNum(50,70, (20 + 2 * i),3,16,0X80);
				for(n = 0; n < 72; n++) {
					SIN[n] = old_SIN[n] * vpp;
				}		
				TIM2->ARR = tim4;
				delay_ms(20);
			}
			pint_deg = 0;
			LCD_ShowxNum(120,50, pint_deg,3,16,0X80);
	} else if(pint_deg == 2) {
		if(old_deg2 != deg2) {
						old_deg2 = deg2;
						tim4 = 1000000 / (35 * deg2 - 600);	
						vpp = ((((((35 * deg2 - 600) * 100000 / 2000)) / 33) * 4096)/ 88) / 10000 ;
						LCD_ShowString(80,100,200,16,16,"V = F / 2000             ");
						LCD_ShowString(80,120,200,16,16,"                      ");
						LCD_ShowxNum(50,70, deg2,3,16,0X80);
						for(i = 0; i < 72; i++) {
							SIN[i] = old_SIN[i] * vpp;
						}			
						TIM2->ARR = tim4;
						delay_ms(50);
			}
	} 
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1295824.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存