您尚未登录。

#2 Re: 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » Cadence Virtuoso 一些工艺库 » 2022-05-08 13:19:43

顺便问一下,楼主有没有支持20-60v,可以做电源的pdk

#7 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » BLDC开发板开车——02.小马达动起来!! » 2020-06-05 20:45:03

精简一下代码

#include <NUC029xAN.h>
#include <stdio.h>
#include <stdint.h>

void sys_init(void) {
	SYS_UnlockReg();
	CLK_EnableModuleClock(CLK_PWRCON_XTL12M_EN_Msk);
	CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
	CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HXT, FREQ_100MHZ);
	CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
	CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(2));
	SystemCoreClockUpdate();
}

void led_init(void) {
	SYS->P3_MFP &= ~(SYS_MFP_P32_Msk | SYS_MFP_P33_Msk | SYS_MFP_P34_Msk | SYS_MFP_P35_Msk);
	SYS->P3_MFP |= SYS_MFP_P32_GPIO | SYS_MFP_P33_GPIO | SYS_MFP_P34_GPIO | SYS_MFP_P35_GPIO;
	GPIO_SetMode(P3, BIT2 | BIT3 | BIT4 | BIT5, GPIO_PMD_OUTPUT);
}

void acmp_init(void) {
	SYS->P1_MFP &= ~(SYS_MFP_P14_Msk | SYS_MFP_P15_Msk | SYS_MFP_P16_Msk | SYS_MFP_P17_Msk);
	SYS->P1_MFP |= SYS_MFP_P14_ACMP0_N | SYS_MFP_P15_ACMP0_P | SYS_MFP_P16_ACMP2_N | SYS_MFP_P17_ACMP2_P;
	SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
	SYS->P3_MFP |= SYS_MFP_P30_ACMP1_N | SYS_MFP_P31_ACMP1_P;
	GPIO_DISABLE_DIGITAL_PATH(P1, BIT4 | BIT5 | BIT6 | BIT7);
	GPIO_DISABLE_DIGITAL_PATH(P3, BIT0 | BIT1);
	CLK_EnableModuleClock(ACMP01_MODULE);
	CLK_EnableModuleClock(ACMP23_MODULE);
	ACMP_Open(ACMP01, 0, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
	ACMP_Open(ACMP01, 1, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
	ACMP_Open(ACMP23, 2, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
}

void pwm_init(void) {
	SYS->P2_MFP &= ~(SYS_MFP_P20_Msk | SYS_MFP_P21_Msk | SYS_MFP_P22_Msk | SYS_MFP_P23_Msk | SYS_MFP_P24_Msk | SYS_MFP_P25_Msk);
	SYS->P2_MFP |= SYS_MFP_P20_PWM0 | SYS_MFP_P21_PWM1 | SYS_MFP_P22_PWM2 | SYS_MFP_P23_PWM3 | SYS_MFP_P24_PWM4 | SYS_MFP_P25_PWM5;
	GPIO_SetMode(P2, BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5, GPIO_PMD_OUTPUT);
	P20 = 0; P21 = 0; P22 = 0; P23 = 0; P24 = 0; P25 = 0;
	CLK_EnableModuleClock(PWM01_MODULE);
	CLK_EnableModuleClock(PWM23_MODULE);
	CLK_EnableModuleClock(PWM45_MODULE);
	CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK, 0);
	CLK_SetModuleClock(PWM23_MODULE, CLK_CLKSEL1_PWM23_S_HCLK, 0);
	CLK_SetModuleClock(PWM45_MODULE, CLK_CLKSEL2_PWM45_S_HCLK, 0);
	PWMA->PPR = (10 << PWM_PPR_DZI23_Pos) | (10 << PWM_PPR_DZI01_Pos) | (1 << PWM_PPR_CP23_Pos) | (1 << PWM_PPR_CP01_Pos);
	PWMB->PPR = (10 << PWM_PPR_DZI01_Pos) | (1 << PWM_PPR_CP01_Pos);
	PWMA->CSR = (4 << PWM_CSR_CSR2_Pos) | (4 << PWM_CSR_CSR0_Pos);
	PWMB->CSR = (4 << PWM_CSR_CSR0_Pos);
	PWMA->PCR = PWM_PCR_PWM23TYPE_Msk | PWM_PCR_PWM01TYPE_Msk | PWM_PCR_CH2MOD_Msk | PWM_PCR_CH0MOD_Msk | PWM_PCR_DZEN23_Msk | PWM_PCR_DZEN01_Msk;
	PWMB->PCR = PWM_PCR_PWM01TYPE_Msk | PWM_PCR_CH0MOD_Msk | PWM_PCR_DZEN01_Msk;
	PWMA->CMR0 = 250;
	PWMA->CMR2 = 250;
	PWMB->CMR0 = 250;
	PWMA->CNR0 = 500;
	PWMA->CNR2 = 500;
	PWMB->CNR0 = 500;
	PWMA->POE = PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk | PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->POE = PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->PSCR = PWM_PSCR_PSSEN2_Msk | PWM_PSCR_PSSEN0_Msk;
	PWMB->PSCR = PWM_PSCR_PSSEN0_Msk;
	PWMA->PCR |= PWM_PCR_CH0EN_Msk;
}

void ah(int32_t duty) {
	PWMB->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->CMR0 = 250 - duty;
}

void al(int32_t duty) {
	PWMB->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->CMR0 = 250 + duty;
}

void az(void) {
	PWMB->POE &= ~(PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk);
}

void bh(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk;
	PWMA->CMR2 = 250 - duty;
}

void bl(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk;
	PWMA->CMR2 = 250 + duty;
}

void bz(void) {
	PWMA->POE &= ~(PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk);
}

void ch(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->CMR0 = 250 - duty;
}

void cl(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->CMR0 = 250 + duty;
}

void cz(void) {
	PWMA->POE &= ~(PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk);
}

int32_t wait_a_pn(volatile int32_t t, int32_t pn) {
	int32_t i;
	P32 = 0;
	for ( ; t; t--) {
		if (pn != ACMP_GET_OUTPUT(ACMP01, 1)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (pn != ACMP_GET_OUTPUT(ACMP01, 1)) {
				break;
			}
		}
		if (0 == i) {
			P32 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_b_pn(volatile int32_t t, int32_t pn) {
	int32_t i;
	P33 = 0;
	for ( ; t; t--) {
		if (pn != ACMP_GET_OUTPUT(ACMP23, 2)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (pn != ACMP_GET_OUTPUT(ACMP23, 2)) {
				break;
			}
		}
		if (0 == i) {
			P33 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_c_pn(volatile int32_t t, int32_t pn) {
	int32_t i;
	P34 = 0;
	for ( ; t; t--) {
		if (pn != ACMP_GET_OUTPUT(ACMP01, 0)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (pn != ACMP_GET_OUTPUT(ACMP01, 0)) {
				break;
			}
		}
		if (0 == i) {
			P34 = 1;
			break;
		}
	}
	return t;
}

void bldc_run(void) {
	int32_t t = 50000, duty = 10;
	for ( ;  ;  ) {
		cz();
		bl(duty);
		wait_c_pn(t, 1); // 1 0 z
		t -= (t >> 12);
		az();
		ch(duty);
		wait_a_pn(t, 0); // z 0 1
		t -= (t >> 12);
		bz();
		al(duty);
		wait_b_pn(t, 1); // 0 z 1
		t -= (t >> 12);
		cz();
		bh(duty);
		wait_c_pn(t, 0); // 0 1 z
		t -= (t >> 12);
		az();
		cl(duty);
		wait_a_pn(t, 1); // z 1 0
		t -= (t >> 12);
		bz();
		ah(duty);
		wait_b_pn(t, 0); // 1 z 0
		t -= (t >> 12);
		if (duty < 60) {
			duty++;
		}
	}
}

int main(void) {
	sys_init();
	led_init();
	acmp_init();
	pwm_init();
	bldc_run();
	return 0;
}

#10 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » BLDC开发板开车——02.小马达动起来!! » 2020-06-05 20:10:41

bunny
回复: 6
#include <NUC029xAN.h>
#include <stdio.h>
#include <stdint.h>

void sys_init(void) {
	SYS_UnlockReg();
	CLK_EnableModuleClock(CLK_PWRCON_XTL12M_EN_Msk);
	CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
	CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HXT, FREQ_100MHZ);
	CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
	CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(2));
	SystemCoreClockUpdate();
}

void led_init(void) {
	SYS->P3_MFP &= ~(SYS_MFP_P32_Msk | SYS_MFP_P33_Msk | SYS_MFP_P34_Msk | SYS_MFP_P35_Msk);
	SYS->P3_MFP |= SYS_MFP_P32_GPIO | SYS_MFP_P33_GPIO | SYS_MFP_P34_GPIO | SYS_MFP_P35_GPIO;
	GPIO_SetMode(P3, BIT2 | BIT3 | BIT4 | BIT5, GPIO_PMD_OUTPUT);
}

void acmp_init(void) {
	SYS->P1_MFP &= ~(SYS_MFP_P14_Msk | SYS_MFP_P15_Msk | SYS_MFP_P16_Msk | SYS_MFP_P17_Msk);
	SYS->P1_MFP |= SYS_MFP_P14_ACMP0_N | SYS_MFP_P15_ACMP0_P | SYS_MFP_P16_ACMP2_N | SYS_MFP_P17_ACMP2_P;
	SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
	SYS->P3_MFP |= SYS_MFP_P30_ACMP1_N | SYS_MFP_P31_ACMP1_P;
	GPIO_DISABLE_DIGITAL_PATH(P1, BIT4 | BIT5 | BIT6 | BIT7);
	GPIO_DISABLE_DIGITAL_PATH(P3, BIT0 | BIT1);
	CLK_EnableModuleClock(ACMP01_MODULE);
	CLK_EnableModuleClock(ACMP23_MODULE);
	ACMP_Open(ACMP01, 0, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
	ACMP_Open(ACMP01, 1, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
	ACMP_Open(ACMP23, 2, ACMP_CR_VNEG_PIN, ACMP_CR_HYSTERESIS_ENABLE);
}

void pwm_init(void) {
	SYS->P2_MFP &= ~(SYS_MFP_P20_Msk | SYS_MFP_P21_Msk | SYS_MFP_P22_Msk | SYS_MFP_P23_Msk | SYS_MFP_P24_Msk | SYS_MFP_P25_Msk);
	SYS->P2_MFP |= SYS_MFP_P20_PWM0 | SYS_MFP_P21_PWM1 | SYS_MFP_P22_PWM2 | SYS_MFP_P23_PWM3 | SYS_MFP_P24_PWM4 | SYS_MFP_P25_PWM5;
	GPIO_SetMode(P2, BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5, GPIO_PMD_OUTPUT);
	P20 = 0; P21 = 0; P22 = 0; P23 = 0; P24 = 0; P25 = 0;
	CLK_EnableModuleClock(PWM01_MODULE);
	CLK_EnableModuleClock(PWM23_MODULE);
	CLK_EnableModuleClock(PWM45_MODULE);
	CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK, 0);
	CLK_SetModuleClock(PWM23_MODULE, CLK_CLKSEL1_PWM23_S_HCLK, 0);
	CLK_SetModuleClock(PWM45_MODULE, CLK_CLKSEL2_PWM45_S_HCLK, 0);
	PWMA->PPR = (10 << PWM_PPR_DZI23_Pos) | (10 << PWM_PPR_DZI01_Pos) | (1 << PWM_PPR_CP23_Pos) | (1 << PWM_PPR_CP01_Pos);
	PWMB->PPR = (10 << PWM_PPR_DZI01_Pos) | (1 << PWM_PPR_CP01_Pos);
	PWMA->CSR = (4 << PWM_CSR_CSR2_Pos) | (4 << PWM_CSR_CSR0_Pos);
	PWMB->CSR = (4 << PWM_CSR_CSR0_Pos);
	PWMA->PCR = PWM_PCR_PWM23TYPE_Msk | PWM_PCR_PWM01TYPE_Msk | PWM_PCR_CH2MOD_Msk | PWM_PCR_CH0MOD_Msk | PWM_PCR_DZEN23_Msk | PWM_PCR_DZEN01_Msk;
	PWMB->PCR = PWM_PCR_PWM01TYPE_Msk | PWM_PCR_CH0MOD_Msk | PWM_PCR_DZEN01_Msk;
	PWMA->CMR0 = 250;
	PWMA->CMR2 = 250;
	PWMB->CMR0 = 250;
	PWMA->CNR0 = 500;
	PWMA->CNR2 = 500;
	PWMB->CNR0 = 500;
	PWMA->POE = PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk | PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->POE = PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->PSCR = PWM_PSCR_PSSEN2_Msk | PWM_PSCR_PSSEN0_Msk;
	PWMB->PSCR = PWM_PSCR_PSSEN0_Msk;
	PWMA->PCR |= PWM_PCR_CH0EN_Msk;
}

void ah(int32_t duty) {
	PWMB->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->CMR0 = 250 - duty;
}

void al(int32_t duty) {
	PWMB->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMB->CMR0 = 250 + duty;
}

void az(void) {
	PWMB->POE &= ~(PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk);
}

void bh(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk;
	PWMA->CMR2 = 250 - duty;
}

void bl(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk;
	PWMA->CMR2 = 250 + duty;
}

void bz(void) {
	PWMA->POE &= ~(PWM_POE_PWM3_Msk | PWM_POE_PWM2_Msk);
}

void ch(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->CMR0 = 250 - duty;
}

void cl(int32_t duty) {
	PWMA->POE |= PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk;
	PWMA->CMR0 = 250 + duty;
}

void cz(void) {
	PWMA->POE &= ~(PWM_POE_PWM1_Msk | PWM_POE_PWM0_Msk);
}

int32_t wait_ap(volatile int32_t t) {
	int32_t i;
	P32 = 0;
	for ( ; t; t--) {
		if (0 == ACMP_GET_OUTPUT(ACMP01, 1)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (0 == ACMP_GET_OUTPUT(ACMP01, 1)) {
				break;
			}
		}
		if (0 == i) {
			P32 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_an(volatile int32_t t) {
	int32_t i;
	P32 = 0;
	for ( ; t; t--) {
		if (1 == ACMP_GET_OUTPUT(ACMP01, 1)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (1 == ACMP_GET_OUTPUT(ACMP01, 1)) {
				break;
			}
		}
		if (0 == i) {
			P32 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_bp(volatile int32_t t) {
	int32_t i;
	P33 = 0;
	for ( ; t; t--) {
		if (0 == ACMP_GET_OUTPUT(ACMP23, 2)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (0 == ACMP_GET_OUTPUT(ACMP23, 2)) {
				break;
			}
		}
		if (0 == i) {
			P33 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_bn(volatile int32_t t) {
	int32_t i;
	P33 = 0;
	for ( ; t; t--) {
		if (1 == ACMP_GET_OUTPUT(ACMP23, 2)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (1 == ACMP_GET_OUTPUT(ACMP23, 2)) {
				break;
			}
		}
		if (0 == i) {
			P33 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_cp(volatile int32_t t) {
	int32_t i;
	P34 = 0;
	for ( ; t; t--) {
		if (0 == ACMP_GET_OUTPUT(ACMP01, 0)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (0 == ACMP_GET_OUTPUT(ACMP01, 0)) {
				break;
			}
		}
		if (0 == i) {
			P34 = 1;
			break;
		}
	}
	return t;
}

int32_t wait_cn(volatile int32_t t) {
	int32_t i;
	P34 = 0;
	for ( ; t; t--) {
		if (1 == ACMP_GET_OUTPUT(ACMP01, 0)) {
			continue;
		}
		for (i = 100; i; i--) {
			if (1 == ACMP_GET_OUTPUT(ACMP01, 0)) {
				break;
			}
		}
		if (0 == i) {
			P34 = 1;
			break;
		}
	}
	return t;
}

void bldc_run(void) {
	int32_t t = 50000, duty = 10;
	for ( ;  ;  ) {
		cz();
		bl(duty);
		wait_cp(t); // 1 0 z
		t -= (t >> 12);
		az();
		ch(duty);
		wait_an(t); // z 0 1
		t -= (t >> 12);
		bz();
		al(duty);
		wait_bp(t); // 0 z 1
		t -= (t >> 12);
		cz();
		bh(duty);
		wait_cn(t); // 0 1 z
		t -= (t >> 12);
		az();
		cl(duty);
		wait_ap(t); // z 1 0
		t -= (t >> 12);
		bz();
		ah(duty);
		wait_bn(t); // 1 z 0
		t -= (t >> 12);
		if (duty < 60) {
			duty++;
		}
	}
}

int main(void) {
	sys_init();
	led_init();
	acmp_init();
	pwm_init();
	bldc_run();
	return 0;
}

#12 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » BLDC开发板开车——01.流水灯入门 » 2020-06-04 14:58:33

bunny
回复: 0
#include <NUC029xAN.h>
#include <stdio.h>

void sys_init(void) {
	SYS_UnlockReg();
	CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
	CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
	CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HXT, FREQ_100MHZ);
	CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
	CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(2));
	SystemCoreClockUpdate();
}

void led_init(void) {
	SYS->P3_MFP &= ~(SYS_MFP_P32_Msk | SYS_MFP_P33_Msk | SYS_MFP_P34_Msk | SYS_MFP_P35_Msk);
	SYS->P3_MFP |= SYS_MFP_P32_GPIO | SYS_MFP_P33_GPIO | SYS_MFP_P34_GPIO | SYS_MFP_P35_GPIO;
	GPIO_SetMode(P3, BIT2 | BIT3 | BIT4 | BIT5, GPIO_PMD_OUTPUT);
}

void delay(volatile uint32_t t) {
	for ( ; t; t--) {
	}
}

int main(void) {
	sys_init();
	led_init();
	for ( ; ; ) {
		P35 = 0;
		P32 = 1;
		delay(1000000);
		P32 = 0;
		P33 = 1;
		delay(1000000);
		P33 = 0;
		P34 = 1;
		delay(1000000);
		P34 = 0;
		P35 = 1;
		delay(1000000);
	}
	return 0;
}

#14 Re: 华芯微特 » 【问答环节】关于(BLDC)直流无刷电机的问题 » 2020-05-22 10:20:57

华芯微特 说:

所以想要多咨询一些信息哦~,肯定是会出的呢

袜裤网的BLDC在开车,快去勾引晕哥

#15 Re: 华芯微特 » 【问答环节】关于(BLDC)直流无刷电机的问题 » 2020-05-20 09:24:28

你想推广的话,就出个华芯微特的bldc的开发板噻

#17 Re: 华芯微特 » 【问答环节】关于(BLDC)直流无刷电机的问题 » 2020-05-15 16:08:11

基本上有三路互补PWM和几路ADC或者模拟比较器的M0 M3 M4都可以搞BLDC,当然有些厂家还有集成度更高性价比更高的片子

#24 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » fft又来了,这次更简单,代码才30行 » 2020-03-31 22:57:34

flex-A 说:

请问有大佬测试过这个代码吗,我自己写的的计算出来全是0

int main()
{
	double x[16],y[16];
	int i=0;
	for(i=0;i<16;i++)
	{
		y[i]=0;
		x[i]=0;
	}
	x[0]=1.0;
	x[1]=1.0;
	double dx[16]={0},dy[16]={0};

	fft(x,y,dx,dy,4);
	for (i = 0; i < 16; i++) {
        printf((const char*)"dat[%d] = %f + %f * i\n", i, dx[i], dy[i]);
    }
	return 0;
}

你的测试是没问题的,是我代码的疏漏,出现了内存区域的覆盖,第一版本中使用malloc free,没有这个问题,后来改成静态内存的时候逻辑没理顺,出现的内存覆盖的BUG,由于未经严格测试,没有发现这个BUG,经你提醒才抓出来
上传最早的版本(引用了malloc free函数)

void fft(const double* src_x, const double* src_y, double* dst_x, double* dst_y, int k) {
    int i, n;
    double temp, temp_x, temp_y;
    double* buffer;
    if (0 == k) {
        *dst_x = *src_x;
        *dst_y = *src_y;
        return;
    }
    n = 1 << (k - 1);
    buffer = (double*)malloc(4 * n * sizeof(double));
    for (i = 0; i < n; i++) {
        buffer[i] = src_x[i * 2];
        buffer[i + n] = src_y[i * 2];
        buffer[i + 2 * n] = src_x[i * 2 + 1];
        buffer[i + 3 * n] = src_y[i * 2 + 1];
    }
    fft((const double*)buffer + 2 * n, (const double*)buffer + 3 * n, dst_x, dst_y, k - 1);
    fft((const double*)buffer, (const double*)buffer + n, (double*)buffer + 2 * n, (double*)buffer + 3 * n, k - 1);
    for (i = 0; i < n; i++) {
        temp = i * M_PI / n;
        temp_x = cos(temp);
        temp_y = sin(temp);
        buffer[i] = dst_y[i] * temp_y + dst_x[i] * temp_x;
        buffer[i + n] = dst_y[i] * temp_x - dst_x[i] * temp_y;
        dst_x[i] = buffer[i + 2 * n] + buffer[i];
        dst_y[i] = buffer[i + 3 * n] + buffer[i + n];
        dst_x[i + n] = buffer[i + 2 * n] - buffer[i];
        dst_y[i + n] = buffer[i + 3 * n] - buffer[i + n];
    }
    free(buffer);
}

#28 Re: DSP » 公司急需DSP数字电源大牛 » 2020-03-05 19:25:12

达克罗德 说:

在长沙还可以。要是我在上海能赚到房价我要笑死

你可以上海赚钱,来长沙买别墅

#29 Re: 华芯微特 » 画了一个带sram的swm320的板子 » 2020-03-01 19:07:00

外接sram性价比太低了,要支持sdram就好了

#31 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 请问Qt如何判断一个点是否在多边形内部呢? » 2020-02-23 09:04:17

daydayup 说:

牛批6666,还能判断多边形非法,有项目需求的朋友买了不吃亏不上当,

顺便再请教楼上的大神,是不是matlab是不是直接可以输出c语言代码?

这次代码用c撸的,编译成exe,用matlab调用做测试
matlab代码是可以编译成c/c++代码的,但我没这么用过

写代码扒漏洞,历时四小时,你猜代码多少行?

#32 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 请问Qt如何判断一个点是否在多边形内部呢? » 2020-02-23 03:50:39

代码写出来了,函数支持三个返回值,点在多边形内(多边形合法),点在多边形外(多边形合法),多边形非法

#34 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 请问Qt如何判断一个点是否在多边形内部呢? » 2020-02-22 22:56:45

有偿编写,有兴趣吗?价格2k,带注释,可众筹,交期一个晚上

#36 Re: 全志 SOC » F1C100S 为什么要这么多路电压 » 2020-02-16 22:58:35

Freeboy 说:

少量封装费用大概要多少?好奇

qfn的不清楚,wb bga的小尺寸芯片大概七七八八估计要100k左右

#37 Re: 全志 SOC » F1C100S 为什么要这么多路电压 » 2020-02-16 13:12:53

还有一点很重要,全志卖不卖wafer,即使是卖wafer,单个晶片的价格很可能比你买单个成品芯片的价格贵

#38 Re: 全志 SOC » F1C100S 为什么要这么多路电压 » 2020-02-16 13:10:48

还有,sip把ldo做进去的话,热源就大很多了,温度这关可能过不了

#39 Re: 全志 SOC » F1C100S 为什么要这么多路电压 » 2020-02-16 13:07:57

另外,晶振 电感本身都不适合sip,体积大了

#42 Re: 全志 SOC » 数组赋值效率问题? » 2019-12-18 22:21:04

开cathe吧,连续访问效率高太多

#43 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » Qt 安装目录下的 modbus RTU DEMO 程序大家用过吗? » 2019-11-21 21:41:10

你最好跑个一天试试(改一下源码,定时一秒读写一次),我以前测试的结果是几个小时就会死机,后来自己撸的

#44 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 一步一步写一个超级简陋的C编译器——小小翻译 » 2019-11-18 22:19:45

kekemuyu 说:

是按照编译原理做的吗?还是用的lex和yacc工具

没有正统地学过编译原理,但是应该思路是比较相似的
确实是用lex yacc 做的,结构树自己写的

#45 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 一步一步写一个超级简陋的C编译器——小小翻译 » 2019-11-18 21:07:44

bunny
回复: 5

晒图,代码等语法树全部做完再贴吧,目前支持运算和if else和?:,for while还没做进来
_20191118210429.png

#46 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 大数运算之乘法篇——计算20000的阶乘 » 2019-11-18 20:46:04

凿子树 说:

------------------------
错不在这!
而是这里
https://whycan.cn/files/members/334/1.png
改为这样:

char* order(int n)
{
    char temp[16];
    char* res = (char*)"1";    //删除
    char* res = (char*)malloc(32);    //改正后
    for ( ; n > 1; n--)
    {
        sprintf((char*)temp, "%d", n);
        res = mult1(res, (const char*)temp);
    }
    return res;
}

就可以了。

确实是这个BUG,疏忽了

#49 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 坑网独家骚操作——环形振荡器之纯硬件流水灯 » 2019-09-14 17:03:11

Gentlepig 说:
xxzouzhichao 说:
Gentlepig 说:

正在学习qt5,能否分享下源码?

作为一个QT应用程序而言,其实本身没啥亮点,无非就是对话框拖几个控件进来,简单到不能再简单了,可以说毫无参考价值,百度一下比比皆是
这个程序的核心是一段不涉及Qt界面的计算代码,这部分代码不方便开源,请谅解

理解。

我把核心计算代码删掉了,改成了一个简单的Qt例程,你可以参考参考
led_loop1.zip

#50 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 应广单片机PMS150C有人有仿真器吗? » 2019-09-11 09:51:07

如果你有需求,我可以给你写一个653的汇编框架,或者做一个傻瓜式代码生成器,不过不是免费的

#51 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 应广单片机PMS150C有人有仿真器吗? » 2019-09-11 09:48:01

量不大的情况下选用653合适,毕竟烧录器便宜,这个级别的mcu开发基本就是汇编得了,虽然好像两家都支持C

#52 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 坑网独家骚操作——环形振荡器之纯硬件流水灯 » 2019-09-09 20:02:29

Gentlepig 说:

正在学习qt5,能否分享下源码?

作为一个QT应用程序而言,其实本身没啥亮点,无非就是对话框拖几个控件进来,简单到不能再简单了,可以说毫无参考价值,百度一下比比皆是
这个程序的核心是一段不涉及Qt界面的计算代码,这部分代码不方便开源,请谅解

#54 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 坑网独家骚操作——环形振荡器之纯硬件流水灯 » 2019-09-07 11:27:06

bunny
回复: 13

奇数个非门加RC延迟首尾串联做的振荡器,估计不少人并不陌生,用它做个流水灯不错
非门用NMOS做,9节串联电路图如下:
TIM20190907110433.jpg

图中圈出的四项参数决定振荡频率,分别是R阻值,C容值,MOS阈值电压,电源电压;
LTSpice仿真结果:
TIM20190907110641.jpg

再贴一个45节串联的PCB布线图:
TIM20190903231137.jpg

那么问题来了,到底选用一个什么样的参数,让流水灯的效果看起来舒服点(毕竟在嘉力创贴片的话,下单的时候就得把RC参数定下来,自己一种种去试验太费劲),LTSpice虽然能仿真波形,但是看波形并不能很直观地想象出显示效果,于是做了个模拟器

9节串联的仿真

45节串联的仿真

#56 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » fft又来了,这次更简单,代码才30行 » 2019-08-25 21:25:31

超级萌新 说:

牛叉, 递归调用, 路过学习

不优雅的代码也不敢往晕哥的坑网里塞啊

#57 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » fft又来了,这次更简单,代码才30行 » 2019-08-25 20:09:26

bunny
回复: 17
static double buffer[N]; // N = 2^(k+1)
void fft(const double* src_x, const double* src_y, double* dst_x, double* dst_y, int k) {
    int i, n;
    double temp, temp_x, temp_y;
    if (0 == k) {
        *dst_x = *src_x;
        *dst_y = *src_y;
        return;
    }
    n = 1 << (k - 1);
    for (i = 0; i < n; i++) {
        buffer[i] = src_x[i * 2];
        buffer[i + n] = src_y[i * 2];
        buffer[i + 2 * n] = src_x[i * 2 + 1];
        buffer[i + 3 * n] = src_y[i * 2 + 1];
    }
    fft((const double*)buffer + 2 * n, (const double*)buffer + 3 * n, dst_x, dst_y, k - 1);
    fft((const double*)buffer, (const double*)buffer + n, (double*)buffer + 2 * n, (double*)buffer + 3 * n, k - 1);
    for (i = 0; i < n; i++) {
        temp = i * M_PI / n;
        temp_x = cos(temp);
        temp_y = sin(temp);
        buffer[i] = dst_y[i] * temp_y + dst_x[i] * temp_x;
        buffer[i + n] = dst_y[i] * temp_x - dst_x[i] * temp_y;
        dst_x[i] = buffer[i + 2 * n] + buffer[i];
        dst_y[i] = buffer[i + 3 * n] + buffer[i + n];
        dst_x[i + n] = buffer[i + 2 * n] - buffer[i];
        dst_y[i + n] = buffer[i + 3 * n] - buffer[i + n];
    }
}

函数使用说明:
void fft(const double* src_x, const double* src_y, double* dst_x, double* dst_y, int k)
src_x:输入数据实部
src_y:输入数据虚部
dst_x:输出数据实部
dst_y:输出数据虚部
k:表征fft点数为2^k,比如1024点的fft,k=10;4096点的fft,k=12;

#58 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 热乎乎的!2019年电赛F题纸张计数的同学看过来!拟合算法源码出售 » 2019-08-10 03:13:51

bunny
回复: 1

昨天突然QQ上好些人加我,搞半天才知道是做电赛F题纸张计数来找数据拟合算法的,由于以前发布过最小二乘法的帖子,他们顺着百度扒过来的,废话少说,先上题目:
TIM20190810024436.jpg

F_.pdf

原理:电容法,自己百度平板电容计算公式
推导:
TIM20190810024727.jpg
TIM20190810024730.jpg

问题来了,电容量x与纸张数量y的关系满足(x + a) * (y + b) = c的关系,自校准需要得到a b c的值,当然首选最小二乘法拟合,然而非线性的拟合还是有点复杂的,熬夜折腾几小时终于搞定了这个算法源码!

先是用matlab脚本实现了功能,效果还不错
TIM20190810025537.jpg

然后用C重写,算出来结果与matlab一致
TIM20190810025613.jpg

提供一个exe程序供验证用,把数据放到data.txt里面,然后双击xy_fit.exe即可
TIM20190810025935.jpg

2019F.zip

源码出售,绝对原创,有意请联系,有效时间1天

#59 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 写字机一根皮带搞定 X, Y轴移动, 请问是什么原理? » 2019-05-13 18:43:46

晕哥 说:
arychen 说:

会不会像汽车上那种皮带   内层是带齿的

对的,工业缝纫机是这样,我买的写字机也是。

这个叫同步带

#60 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 闲鱼淘宝性价比电子产品推荐 (一) » 2019-05-12 00:24:48

smartcar 说:

33 包邮, 还送外壳, 看起来挺不错, 可是还没想到双目摄像头可以用来做什么应用呢

33的不带外壳,带外壳的贵点

#62 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真——0~5V的脉冲转+-12V的脉冲 » 2019-05-09 21:55:50

bunny
回复: 1

频率高,负载重就用右图
频率低,负载轻就用左图

TIM20190509214630.png
TIM20190509214618.png
TIM20190509215143.png
TIM20190509215132.png

#66 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 学习fpga的妈妈cpld » 2019-04-22 12:55:13

需要门多点可以用ep4ce6,性价比不错,二十几块,核心板五六十左右,一般学习够用了

#70 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真——模拟数据采集之adc前端抗混叠滤波器 » 2019-04-04 23:00:00

bunny
回复: 1

1,搭建滤波器,并进行AC扫描
TIM20190404224155.png

2,幅频特性曲线,截止频率约27MHz
TIM20190404224236.png

3,时域波形仿真,先输入5MHz方波
TIM20190404224559.png

4,5MHz输入滤波后波形:
TIM20190404224705.png

5,时域波形仿真,先输入20MHz方波
TIM20190404225252.png

6,20MHz输入滤波后波形:
TIM20190404225303.png

#73 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真——分立器件搭建积分ADC应用之NTC测温 » 2019-03-02 23:06:56

bunny
回复: 2

原理:自己算吧,方波占空比等于NTC阻值与参考电阻之比
缺点:比起单片机自带ADC,成本当然增加了
优点:比单片机ADC分辨率高,器件不算多(一个参考电阻,运放可选GS8551,一个74HC14,一个模拟开关BL1551,积分阻容),方便隔离,一个6N137搞定
TIM20190302225309.pngTIM20190302225349.png
TIM20190302225426.png
TIM20190302225520.png
TIM20190302225612.png
TIM20190302225628.png

#77 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 小玩意也有大学问——扬声器 » 2019-01-19 12:52:42

预先透露一点,R1代表的是扬声器的直流阻抗,L2代表扬声器线圈的电感,L1和C1是扬声器质量,弹性系数,磁场强度,线圈匝数共同作用得到的一个虚拟参数,R2代表的是振荡阻尼参数

#78 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 小玩意也有大学问——扬声器 » 2019-01-19 12:46:56

bunny
回复: 4

首先,摘一段别处的科普文章http://www.av010.com/zixun/news_info_16082.html/

截取其中一段贴图:
TIM20190119123645.png

用RLC搭建其等效模型:
TIM20190119124032.png

扫频结果:
TIM20190119124058.png

为什么会是这样一个等效模型?模型的参数是如何确定的?
这个问题问得好,这个问题其实是一个中等难度的物理建模,以后再用simulink写另一个帖子吧

#79 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真——文氏桥振荡电路朝花夕拾(原创内容) » 2019-01-19 11:24:04

bunny
回复: 1

首先,文氏桥振荡电路大多数工程师都熟悉
TIM20190119110301.png

按照惯例,先做RC网络的扫频分析,看看选频特性:
TIM20190119105435.png
TIM20190119105620.png

搭建仿真电路:
TIM20190119103610.png
TIM20190119103659.png

变体结构的文氏桥振荡电路,用了两个运放(原创内容):
TIM20190119104131.png
TIM20190119104206.png

既然文氏桥利用了RC网络的选频特性,那么能否用LC选频特性来搭建另类文氏桥呢?
答案当然是可以,先看看LC并联选频:
TIM20190119105446.png
TIM20190119105703.png
搭建LC并联振荡电路:
TIM20190119104611.png
TIM20190119104627.png

再看看LC串联选频:
TIM20190119105455.png
TIM20190119105734.png
搭建LC串联振荡电路:
TIM20190119104901.png
TIM20190119105017.png

调整一下LC串联Q值:
TIM20190119111924.png
TIM20190119111940.png
重新仿真:
TIM20190119112044.png
TIM20190119112111_20190118-2224.png

选频特性尖了以后,更接近正弦波,谐波成分少多了

#81 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真——振荡电路仿真集锦 » 2019-01-18 22:11:39

bunny
回复: 2

单片机最常见的晶振应用电路:
TIM20190118211910.png

这个电路内部结构相信大部分人都知道,仿真一下:
TIM20190118210958.png

波形图:
TIM20190118211202.png

把74HC04换成74HC14(斯密特反相器):
TIM20190118211250.png

波形图:
TIM20190118211312.png

74HC14(斯密特反相器)还可以搭建更简单的RC振荡器:
TIM20190118211421.png

波形图:
TIM20190118211443.png

用NPN三极管做的反相器代替74HC04:
TIM20190118213232.png

波形图:
TIM20190118213250.png

此外,还有一类不多见的晶振接法,以下摘自PT4330数据手册:
TIM20190118220349.png

以下摘自SA626/SA625/SA605数据手册:
TIM20190118220420.png

如此看来,这种接法也不算少见,以下摘自SA626内部结构图
TIM20190118220518.png

搭建电路仿真:
TIM20190118213346.png

这个电路有一个特殊用途,可以通过LC选频,输出晶振的倍频,比如下图10Mhz晶振就可以出来20MHz正弦波:
TIM20190118215134.png

波形图:
TIM20190118215203.png

192pF 330nH的谐振频率为20MHz

#82 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2019-01-11 22:07:58

xxzouzhichao 说:

更正一段代码:

static uint32_t bits_reverse(uint32_t index, uint32_t bits) {
    uint32_t left, right;
    left = index << 16;
    right = index >> 16;
    index = left | right;
    left = (index << 8) & 0xff00ff00;
    right = (index >> 8) & 0x00ff00ff;
    index = left | right;
    left = (index << 4) & 0xf0f0f0f0;
    right = (index >> 4) & 0x0f0f0f0f;
    index = left | right;
    left = (index << 2) & 0xc3c3c3c3;
    right = (index >> 2) & 0x3c3c3c3c;
    index = left | right;
    left = (index << 1) & 0xa5a5a5a5;
    right = (index >> 1) & 0x5a5a5a5a;
    index = left | right;
    return index >> (32 - bits);
}

更正后:

static uint32_t bits_reverse(uint32_t index, uint32_t bits) {
    uint32_t left, right;
    left = index << 16;
    right = index >> 16;
    index = left | right;
    left = (index << 8) & 0xff00ff00;
    right = (index >> 8) & 0x00ff00ff;
    index = left | right;
    left = (index << 4) & 0xf0f0f0f0;
    right = (index >> 4) & 0x0f0f0f0f;
    index = left | right;
    left = (index << 2) & 0xcccccccc;
    right = (index >> 2) & 0x33333333;
    index = left | right;
    left = (index << 1) & 0xaaaaaaaa;
    right = (index >> 1) & 0x55555555;
    index = left | right;
    return index >> (32 - bits);
}

#83 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2019-01-11 20:58:57

更正一段代码:

static uint32_t bits_reverse(uint32_t index, uint32_t bits) {
    uint32_t left, right;
    left = index << 16;
    right = index >> 16;
    index = left | right;
    left = (index << 8) & 0xff00ff00;
    right = (index >> 8) & 0x00ff00ff;
    index = left | right;
    left = (index << 4) & 0xf0f0f0f0;
    right = (index >> 4) & 0x0f0f0f0f;
    index = left | right;
    left = (index << 2) & 0xc3c3c3c3;
    right = (index >> 2) & 0x3c3c3c3c;
    index = left | right;
    left = (index << 1) & 0xa5a5a5a5;
    right = (index >> 1) & 0x5a5a5a5a;
    index = left | right;
    return index >> (32 - bits);
}

更正后:

static uint32_t bits_reverse(uint32_t index, uint32_t bits) {
    uint32_t left, right;
    left = index << 16;
    right = index >> 16;
    index = left | right;
    left = (index << 8) & 0xff00ff00;
    right = (index >> 8) & 0x00ff00ff;
    index = left | right;
    left = (index << 4) & 0xf0f0f0f0;
    right = (index >> 4) & 0x0f0f0f0f;
    index = left | right;
    left = (index << 2) & 0xc3c3c3c3;
    right = (index >> 2) & 0x3c3c3c3c;
    index = left | right;
    left = (index << 1) & 0xaaaaaaaa;
    right = (index >> 1) & 0x55555555;
    index = left | right;
    return index >> (32 - bits);
}

#84 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-18 21:11:34

晕哥 说:


恭喜恭喜,用 video 标签可以播放视频.

坐等楼主卖成品

搭建原型容易,做成品还有点距离

#86 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-11 12:18:59

smartcar 说:
xxzouzhichao 说:
lilo 说:

有钱人果然时间比较值钱.

真谈不上有钱人,纯纯的穷人

弱弱问下大佬,在家里创做SMT,除了要提供 PCB文件,还要提供什么文件, 我用 AD14, 直接提供 PcbDoc 文件

我用allegro出的geber,另外提供了bom表和元件坐标,方向,有格式模板的

#87 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-11 10:17:34

lilo 说:

有钱人果然时间比较值钱.

真谈不上有钱人,纯纯的穷人

#88 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-10 22:54:57

basicdev 说:
xxzouzhichao 说:

嘉力创下了单,花了182块,希望能顺利调试出来~~

看原理图很简单啊,怎么会那么贵,说好的30块包顺丰呢,笑哭

最近比较忙,没工夫焊接,就顺手下的smt单,50工程费 50器件费 40扩展库费 30的板费

#91 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-08 16:06:01

上图紫色是包络检波后波形
绿色是满曼彻斯特原码的方波,红色是最终解调出来的满曼彻斯特码波形

#93 Re: PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-08 15:56:15

4,先跳过二极管包络检波电路(这是非线性电路,分析比较复杂,以后再慢慢研究),着手搞后面的带通滤波
TIM20181208155106.png
曼彻斯特码脉冲宽度256us,512us,频谱范围在1.8kHz-20kHz内,主要干扰是125khz 250khz
TIM20181208155115.png
上图带通范围在500hz-20kHz之间,还是不错的

#94 PN532/MFRC522/MFRC523/MFRC500/ » 理论指导设计——廉价125kHZ RFID读卡器之电路计算与仿真 » 2018-12-08 15:12:56

bunny
回复: 34

七八年前用atmega48搞过,以前的硬件是抄的,那时候学识浅薄,一知半解,如今朝花夕拾,当然要有所长进了

1,低压方波是如何变成高压正弦波的?
_20181208150234.jpg

2,pspise仿真:
TIM20181208150451.png
TIM20181208150729.png
TIM20181208150622.png

3,RFID卡靠近时,相当于L线圈多个负载,用下图来模拟RFID调制波形:
TIM20181208150948.png
TIM20181208151021.png

4,未完待续

#96 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 大数运算之乘法篇——计算20000的阶乘 » 2018-12-01 09:12:41

bunny
回复: 8

直接上源码:

#include <stdio.h>
#include <stdlib.h>

char* real_mult(const char* a, const char* b) {
	int i, j, k, m, n, len_a, len_b;
	len_a = strlen(a);
	len_b = strlen(b);
	int* res_p;
	char* c;
	res_p = (int*)malloc((len_a + len_b) * sizeof(int));
	if (!res_p) {
        printf((const char*)"malloc int[%d] fail!\n", len_a + len_b);
        for ( ; ; );
	}
	for (i = len_a + len_b - 1; i >= 0; i--) {
		res_p[i] = 0;
	}
	for (i = 0; i < len_a; i++) {
		for (j = 0; j < len_b; j++) {
			k = i + j + 1;
			res_p[k] += (a[i] - '0') * (b[j] - '0');
		}
	}
	res_p[0] = 0;
	for ( ; k > 0; k--) {
		res_p[k - 1] += res_p[k] / 10;
		res_p[k] %= 10;
	}
	for (j = 0; j < len_a + len_b; j++) {
        if (res_p[j] != 0) {
            break;
        }
	}
	c = (char*)malloc((len_a + len_b + 1 - j) * sizeof(char));
	if (!c) {
        printf((const char*)"malloc char[%d] fail!\n", len_a + len_b + 1 - j);
        for ( ; ; );
	}
	for (i = 0; i < len_a + len_b - j; i++) {
		c[i] = (char)(res_p[i + j] + '0');
	}
	free(res_p);
	c[i] = '\0';
	return c;
}

char* mult1(char* a, const char* b) {
    char* c = real_mult((const char*)a, b);
    free(a);
    return c;
}

char* order(int n) {
    char temp[16];
    char* res = (char*)"1";
    for ( ; n > 1; n--) {
        sprintf((char*)temp, "%d", n);
        res = mult1(res, (const char*)temp);
    }
    return res;
}

int main(int argc, const char* argv[]) {
    char* c;
    c = order(20000);
    printf("%s\n", c);
    free(c);
    return 0;
}

测试结果比对:
TIM20181201091200.png

#97 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 攒垃圾续——matlab simulink应用之FM调制与解调仿真 » 2018-11-24 20:29:33

bunny
回复: 2

调频信号公式:
y = A * sin(2*pi*(f0+k*x)*t)
其中A是载波幅值,f0是载波中心频率,x为被调制信号,k为频偏系数,t为实时时刻

首先,用simulink搭建调频模块:
TIM20181124201628.png

解调原理:将调制后信号延时0.25/f0,与延时前信号相乘,过低通滤波器,输出即可:
TIM20181124201936_20181124-0724.png

待调制波形:100Hz与350Hz叠加
TIM20181124202513.png

调制后波形:10kHz的载波,1k的频偏系数
TIM20181124202642.png

解调后波形:
TIM20181124202723.png

解调后波形与输入对比:
TIM20181124202848.png

#99 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 穷电工又攒垃圾了 » 2018-11-10 14:28:23

bunny
回复: 3

新换了一工作,要学的东西太多了,自己旧电脑(N3150的无风扇小盒子)不堪重负,遂有了新买电脑的想法,奈何银子紧张,本来琢磨着上amd的锐龙2600/2700,搞下来一个主机估计要四千多(intel更贵啦),最后一咬牙,还是上了假货宝的贼船,去捡了志强E5的破烂

E5-2420 6核12线程,1.9GHz(志强都这尿性),32G内存(做电源/信号完整性仿真不得不上大内存,可惜不支持64G),2200块,性价比一般,不推荐购买

电脑拿到手,先装了cadence和sigrity,先试试sigrity吧,以前画的一个imx6ul的板子,仿一下ddr的插损回损吧
先上allegro的layout:
TIM20181110142012.png
转换成sigrity spd文件后:
TIM20181110142258.png
DDR3 DQ AC的插损回损:
TIM20181110142418.png
DDR3 DQS CLK差分对的插损回损:
TIM20181110142459.png

#105 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2018-08-20 11:56:19

达克罗德 说:

st的库能不需移植直接给别的CPU跑吗?

我没用过stm的库,我用的mdk自带的dsp库对比的,128点比mdk的库慢了2500us

#106 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2018-08-20 11:54:34

晕哥 说:

大神这是软硬通吃,我等望尘莫及.

2013年毕业前夕照着数字信号处理的书写的,在amobbs上开源了,如今朝花夕拾,优化了一下代码风格,在挖坑网开源

#107 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2018-08-20 11:49:59

演技担当黄晓明 说:

运算速度如何?  和ST的库比较一下哪个快点

mdk的库128点fft约6300us

#108 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2018-08-20 11:40:24

演技担当黄晓明 说:

运算速度如何?  和ST的库比较一下哪个快点

stm32f030 16点fft 400us
stm32f030 64点fft 3900us
stm32f030 128点fft 9200us

开优化后128点fft 8800us

#109 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 代码超级精简的fft源码,无需移植,代码才80行 » 2018-08-20 11:17:43

bunny
回复: 27

先上源代码!

#include <stdio.h>
#include <stdint.h>
#include <math.h>

typedef struct {
    float r;
    float i;
}complex;

static void butter_fly(complex* a, complex* b, const complex* c) {
    complex bc;
    bc.r = b->r * c->r - b->i * c->i;
    bc.i = b->r * c->i + b->i * c->r;
    b->r = a->r - bc.r;
    b->i = a->i - bc.i;
    a->r += bc.r;
    a->i += bc.i;
}

static uint32_t bits_reverse(uint32_t index, uint32_t bits) {
    uint32_t left, right;
    left = index << 16;
    right = index >> 16;
    index = left | right;
    left = (index << 8) & 0xff00ff00;
    right = (index >> 8) & 0x00ff00ff;
    index = left | right;
    left = (index << 4) & 0xf0f0f0f0;
    right = (index >> 4) & 0x0f0f0f0f;
    index = left | right;
    left = (index << 2) & 0xc3c3c3c3;
    right = (index >> 2) & 0x3c3c3c3c;
    index = left | right;
    left = (index << 1) & 0xa5a5a5a5;
    right = (index >> 1) & 0x5a5a5a5a;
    index = left | right;
    return index >> (32 - bits);
}

static void fft_k(complex* dat, const complex* w, uint32_t k, uint32_t k_all) {
    uint32_t i, j;
    complex* dat1;
    k_all = 1 << (k_all - k - 1);
    k = 1 << k;
    dat1 = dat + k;
    for (i = 0; i < k_all; i++) {
        for (j = 0; j < k; j++) {
            butter_fly(dat++, dat1++, w + j * k_all);
        }
        dat += k;
        dat1 += k;
    }
}

void fft_init(complex* w, uint32_t k) {
    float beta = 0.0f, dbeta = 3.1415926535f / k ;
    for ( ; k; k--) {
        w->r = cosf(beta);
        w->i = sinf(beta);
        beta += dbeta;
        w++;
    }
}

void fft(complex* dat, const complex* w, uint32_t k) {
    uint32_t i, j, n;
    complex temp;
    n = 1 << k;
    for (i = 0; i < n; i++) {
        j = bits_reverse(i, k);
        if (i <= j) {
            continue;
        }
        temp = dat[i];
        dat[i] = dat[j];
        dat[j] = temp;
    }
    for (i = 0; i < k; i++) {
        fft_k(dat, w, i, k);
    }
}

再上代码的使用方法:

#define K 4
#define N (1 << K)
static complex w[N / 2];
static complex dat[N];

int main() {
    uint32_t i;
    for (i = 0; i < N; i++) {
        dat[i].r = 0.0f;
        dat[i].i = 0.0f;
    }
    dat[0].r = 1.0f;
    dat[1].r = 1.0f;
    fft_init((complex*)w, N / 2);
    fft((complex*)dat, (const complex*)w, K);
    for (i = 0; i < N; i++) {
        printf((const char*)"dat[%d] = %f + %f * i\n", i, dat[i].r, dat[i].i);
    }
    return 0;
}

输出结果:
TIM20180820111332_20180819-2323.jpg

对比matlab输出结果:
none.jpg

#110 Re: 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » 有没有哪位知道 NTC的上拉电阻如何选取合适 求指导一下 » 2018-08-13 16:11:32

假设测温范围内,NTC的最大阻值为Rmax,最小阻值为Rmin,那么最佳的分压电阻为sqrt(Rmax * Rmin),这个是经过严格的数学证明的

#111 Re: DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 有大神玩过BLDCM吗?,里面那个过零检测的部分,我想不明白为什么要搞那么复杂啊,不可以直接把电源分压一半来做基准电压吗? » 2018-07-29 08:33:27

参考Y型接法,三相四线,原则上是每根相线与中线做电压比较判断转子位置,但是通常中线没有引出来,中线电压近似等于三根相线电压平均值,因此通过Y型接法的电阻网络(做均值运算),构建出来虚拟的中线电压,送入比较器判断转子位置

三角形接法可以等效变换到Y型接法,这点不解释

#119 Re: 8051/STC8/AT89C51/N76E003 » 新唐的那款1块多,我打开看了,晶圆好大,感觉赚到了,这么大的晶圆,拿来做稳压管,最少可以做到20个 » 2018-05-10 16:33:36

单片机晶片出现大块区域的空白,几乎只有一种情况,那就是单片机逻辑非常简单而扇出的引脚比较多,为了封测,特意把晶片做大

#121 Re: 8051/STC8/AT89C51/N76E003 » 新唐的那款1块多,我打开看了,晶圆好大,感觉赚到了,这么大的晶圆,拿来做稳压管,最少可以做到20个 » 2018-05-10 16:14:19

首先,抛开研发成本不说,单从生产角度,工艺制程,晶片面积是影响成本的大头
工艺先进,意味着面积可以做得更小,数字电路电压可以做得更低,比如当今的cpu核电压0.x伏特,而stc核电压却是几伏特
面积小意味着数字电路时序会好做一些,通常频率可以跑更高,当然价格也是更高了
所以,面积的选择是基于成本,速度等因素平衡
面积一方面决定了单wafer产出芯片量,另一方面曝光窗和掩膜成本也受影响

单片机里面除了arm核以外,很少见到大尺寸固化ip,做物理设计的时候很少出现大块空白区域,毕竟那是钱啊,更何况是新唐这种经验丰富,出货量巨大的公司

#122 Re: 8051/STC8/AT89C51/N76E003 » 新唐的那款1块多,我打开看了,晶圆好大,感觉赚到了,这么大的晶圆,拿来做稳压管,最少可以做到20个 » 2018-05-10 06:13:56

arphone 说:

不是不想利用,是利用不起来

利用不起来?你以为新唐做了这么多年芯片,是白痴么?

#123 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 一步一步写一个超级简陋的C编译器——flex&yacc运算化简 » 2018-05-09 21:22:47

bunny
回复: 5

先上flex文件:

%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "simple_compiler.tab.h"
#define YY_SKIP_YYWRAP
extern int yylval;
int yylex(void);

static int var_save(char* v) {
	char* p = (char*)malloc(32);
	sprintf(p, "%s", v);
	return (int)p;
}

static int new_var(void) {
	static int index = 0;
	char* p = (char*)malloc(16);
	sprintf(p, "r_%d", index++);
	return (int)p;
}

static int function_paras(int para0, int para1) {
	char* p = (char*)malloc(128);
	sprintf(p, "%s, %s",  (const char*)para0, (const char*)para1);
	free((char*)para0);
	free((char*)para1);
	return (int)p;
}

static int function_call(int func) {
	char* p = (char*)malloc(256);
	sprintf(p, "%s()",  (const char*)func);
	free((char*)func);
	return (int)p;
}

static int function_callp(int func, int paras) {
	char* p = (char*)malloc(256);
	sprintf(p, "%s(%s)",  (const char*)func, (const char*)paras);
	free((char*)func);
	free((char*)paras);
	return (int)p;
}

%}

num [0-9]+
hex "0x"[0-9a-fA-F]+
bin "0b"[01]+
_var [_a-zA-z]+[_a-zA-z0-9]*

_equal "="
_lp_s "("
_rp_s ")"
_split1 ","
_split2 ";"

_plus "+"
_minus "-"
_mul "*"
_divide "/"
_mod "%%"
_shift_r ">>"
_shift_l "<<"
_not "~"
_more ">"
_less "<"
_more_equal ">="
_less_equal "<="
_equal_equal "=="
_not_equal "!="

_next_line [\n]+
space [ \t]+

%%
{num} {
	yylval = var_save(yytext);
	return var;
}
{hex} {
	yylval = var_save(yytext);
	return var;
}
{bin} {
	yylval = var_save(yytext);
	return var;
}
{_var} {
	yylval = var_save(yytext);
	return var;
}

{_lp_s} {
	return lp_s;
}
{_rp_s} {
	return rp_s;
}

{_split1} {
	return split1;
}
{_split2} {
	return split2;
}

{_plus} {
	return plus;
}
{_minus} {
	return minus;
}
{_mul} {
	return mul;
}
{_divide} {
	return divide;
}
{_mod} {
	return mod;
}
{_shift_r} {
	return shift_r;
}
{_shift_l} {
	return shift_l;
}
{_not} {
	return not;
}
{_more} {
	return more;
}
{_less} {
	return less;
}
{_more_equal} {
	return more_equal;
}
{_less_equal} {
	return less_equal;
}
{_equal_equal} {
	return equal_equal;
}
{_not_equal} {
	return not_equal;
}

{_equal} {
	return equal;
}

{_next_line} {
	return next_line;
}
{space} {
}
. {
}

%%

再上yacc文件:

%{
#include <stdio.h>
#define YYSTYPE int
#include "lex.yy.c"
int yyparse(void);
void yyerror(char* s);
%}

%token dig var lp_s rp_s plus minus mul divide mod shift_r shift_l not more less more_equal less_equal equal_equal not_equal equal split1 split2 next_line

%%

code_lines: code_lines code_line next_line {}
	| code_line next_line {}
	;
code_line: code split2 {}
	;
code: var_set {}
	| var_level5 {}
	;
var_set: var equal var_level5 {printf("%s = %s;\n", (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	;
var_level5: var_level5 more var_level4 {$$ = new_var(); printf("%s = %s > %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level5 less var_level4 {$$ = new_var(); printf("%s = %s < %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level5 more_equal var_level4 {$$ = new_var(); printf("%s = %s >= %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level5 less_equal var_level4 {$$ = new_var(); printf("%s = %s <= %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level5 equal_equal var_level4 {$$ = new_var(); printf("%s = %s == %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level5 not_equal var_level4 {$$ = new_var(); printf("%s = %s != %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level4 {$$ = $1;}
	;
var_level4: var_level4 shift_r var_level3 {$$ = new_var(); printf("%s = %s >> %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level4 shift_l var_level3 {$$ = new_var(); printf("%s = %s << %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level3 {$$ = $1;}
	;
var_level3: var_level3 plus var_level2 {$$ = new_var(); printf("%s = %s + %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level3 minus var_level2 {$$ = new_var(); printf("%s = %s - %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level2 {$$ = $1;}
	;
var_level2: var_level2 mul var_level1 {$$ = new_var(); printf("%s = %s * %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
    | var_level2 divide var_level1 {$$ = new_var(); printf("%s = %s / %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
	| var_level2 mod var_level1 {$$ = new_var(); printf("%s = %s %% %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
    | var_level1 {$$ = $1;}
	;
var_level1: var {$$ = $1;}
	| not var {$$ = new_var(); printf("%s = ~%s;\n", (char*)$$, (char*)$1); free((char*)$1);}
	| func_call {$$ = $1;}
	| not func_call {$$ = new_var(); printf("%s = ~%s;\n", (char*)$$, (char*)$1); free((char*)$1);}
	| lp_s var_level5 rp_s {$$ = $2;}
	;
func_call: var lp_s rp_s {$$ = new_var(); printf("%s = %s;\n", (char*)$$, (char*)function_call($1));}
	| var lp_s func_para rp_s {$$ = new_var(); printf("%s = %s;\n", (char*)$$, (char*)function_callp($1, $3));}
	;
func_para: var_level5 {$$ = $1;}
	| func_para split1 var_level5 {$$ = function_paras($1, $3);}
	;
%%
int main(int argc, char *argv[]) {
	return yyparse();
}

int yywrap(void) {
	return 1;
}

void yyerror(char* s) {
	printf("error: %s\n", s);
}

转换成c文件
bison.exe -d simple_compiler.y
flex simple_compiler.l

编译成exe,测试:
输入文件:
TIM20180509212140.png
输出文件:
TIM20180509212150.png

#124 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 一步一步写一个超级简陋的C编译器——开篇通过一个计算器demo初识flex&yacc » 2018-05-09 21:01:00

bunny
回复: 0

先上cal.l代码:

%{
#include <string.h>
#include "cal.tab.h"

#define YY_SKIP_YYWRAP

extern int yylval;
int yylex(void);
%}

numbers ([0-9])+
plus "+"
minus "-"
times "*"
divide "/"
lp "("
rp ")"
delim [ \n\t]
ws {delim}*

%%
{numbers} {
	sscanf(yytext, "%d", &yylval);
	return INTEGER;
}

{plus} {
	return PLUS;
}

{minus} {
	return MINUS;
}

{times} {
	return TIMES;
}

{divide} {
	return DIVIDE;
}

{lp} {
	return LP;
}

{rp} {
	return RP;
}

{ws} {
}

. {
}
%%

再上cal.y代码:

%{
#include <stdio.h>
#include "lex.yy.c"
#define YYSTYPE int
int yyparse(void);
void yyerror(char* s);
%}

%token PLUS MINUS TIMES DIVIDE INTEGER LP RP

%%
command: exp {printf("%d\n", $1);}

exp: exp PLUS term {$$ = $1 + $3;}
   | exp MINUS term {$$ = $1 - $3;}
   | term {$$ = $1;}
   ;

term: term TIMES factor {$$ = $1 * $3;}
    | term DIVIDE factor {$$ = $1 / $3;}
    | factor {$$ = $1;}
	;

factor: INTEGER {$$ = $1;}
      | LP exp RP {$$ = $2;}
	  ;
%%

int main(int argc, char *argv[]) {
	return yyparse();
}

int yywrap() {
	return 1;
}

void yyerror(char* s) {
	printf("error: %s\n", s);
}

编译出c代码:
bison.exe -d cal.y
flex cal.l

再编译cal.tab.c得到exe文件,测试:
TIM20180509205944.png

#126 Re: 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真系列:MOSFET驱动G极驱动为什么串个几欧姆的电阻? » 2018-05-06 15:49:11

演技担当黄晓明 说:

上次看了一片文章,云山雾罩说了一大通,最后的结论就是100欧姆是最优解

硬件设计极少有最优解,都是各项指标均衡的结果

#127 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » pspise仿真系列:MOSFET驱动G极驱动为什么串个几欧姆的电阻? » 2018-05-06 14:18:04

bunny
回复: 3

答案:驱动导线有等效电感,MOS管有Cgs,会构成LC谐振,表现为驱动沿振铃&过冲,串入R可以抑制振铃
如下图,L模拟驱动导线电感,0.01R电阻模拟导线电阻,10R电阻模拟串联电阻
TIM20180506135534.png
TIM20180506135610.png
不难看出,绿线有振铃,红线振铃抑制得很好
不过话又说回来,不串电阻真的就不能工作吗?显然不是,很多时候没有这个电阻照样跑。
大概你又要问我是不是脱了裤子放屁?哈哈,硬件设计就是这样的啦,慢慢习惯就好

#130 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 22:02:16

超级萌新 说:

请教一下,能不能用gcc, 把 lex.yy.c   pre_compiler.tab.c    pre_compiler.tab.h 生成 pre_compiler.exe ?

肯定能啊,我就是用的codeblock做的,它就是GCC啊
附个工程截图:
TIM20180504220206.png

#131 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 21:35:34

晕哥 说:

请教大神,怎么使用?

详细使用教程已经发上来了

#134 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 21:23:51

flex&yacc转换出来的c文件:
TIM20180504211430.png

将c文件编译成exe文件:
TIM20180504211512.png

exe文件调用方法:
TIM20180504212029.png

汇编例程源文件demo.asm:
TIM20180504211537.png

pre_compiler.exe将汇编文件demo.asm编译,输出中间文件temp.asm:
TIM20180504211559.png

输出最终文件out.asm:
TIM20180504211630.png

#135 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 21:12:06

3,将上述文件用flex&yacc工具生成c源码文件,codeblock编译成pre_compiler.exe,一个编译器就做好了

#136 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 21:10:15

2,pre_compiler.y

%{
#include <stdio.h>
#define YYSTYPE int
#include "lex.yy.c"
int yyparse(void);
void yyerror(char* s);

static FILE* file_temp = NULL;
static int code_addr = 0;
%}

%token VAR NUM PLUS MINUS TIMES DIVIDE LP RP SPLIT SUBWF DECF ADDWF COMF INCF SUBLW ADDLW ADCWF SBCWF DAA DAS CLRF CLRW IORWF ANDWF XORWF RRF RLF SWAPF BCF BSF ANDLW XORLW IORLW DECFSZ INCFSZ BTFSC BTFSS GOTO CALL RETURN RETFIE RETLW MOVWF MOVF MOVLW NOP OPTION TRIS SLEEP CLRWDT INT EQU ORG END LABEL NEXT_LINE

%%
file: file NEXT_LINE {}
	| codes END {fprintf(file_temp, (const char*)"end\n");}
	;
codes: codes code {}
	| codes pre_code {}
	| codes NEXT_LINE {}
	| code {}
	| pre_code {}
	;
code: code2 exp_var SPLIT exp_var NEXT_LINE {$$ = exp_store3("%s %s, %s", $1, $2, $4); exp_store_print(file_temp, $$);}
	| code1 exp_var NEXT_LINE {$$ = exp_store2("%s %s", $1, $2); exp_store_print(file_temp, $$);}
	| code0 NEXT_LINE {$$ = $1; exp_store_print(file_temp, $$);}
	;
pre_code: VAR EQU exp NEXT_LINE {var_store_write($1, $3);}
	| ORG exp NEXT_LINE {code_addr = $2; fprintf(file_temp, (const char*)"org %d\n", $2);}
	| VAR LABEL NEXT_LINE {var_store_write($1, code_addr);}
	;
code0: DAA {$$ = $1;}
	| DAS {$$ = $1;}
	| CLRW {$$ = $1;}
	| RETURN {$$ = $1;}
	| RETFIE {$$ = $1;}
	| NOP {$$ = $1;}
	| OPTION {$$ = $1;}
	| SLEEP {$$ = $1;}
	| CLRWDT {$$ = $1;}
	| INT {$$ = $1;}
	;
code1: SUBLW {$$ = $1;}
	| ADDLW {$$ = $1;}
	| CLRF {$$ = $1;}
	| ANDLW {$$ = $1;}
	| XORLW {$$ = $1;}
	| IORLW {$$ = $1;}
	| GOTO {$$ = $1;}
	| CALL {$$ = $1;}
	| RETLW {$$ = $1;}
	| MOVWF {$$ = $1;}
	| MOVLW {$$ = $1;}
	| TRIS {$$ = $1;}
	;
code2: SUBWF {$$ = $1;}
	| DECF {$$ = $1;}
	| ADDWF {$$ = $1;}
	| COMF {$$ = $1;}
	| INCF {$$ = $1;}
	| ADCWF {$$ = $1;}
	| SBCWF {$$ = $1;}
	| IORWF {$$ = $1;}
	| ANDWF {$$ = $1;}
	| XORWF {$$ = $1;}
	| RRF {$$ = $1;}
	| RLF {$$ = $1;}
	| SWAPF {$$ = $1;}
	| BCF {$$ = $1;}
	| BSF {$$ = $1;}
	| DECFSZ {$$ = $1;}
	| INCFSZ {$$ = $1;}
	| BTFSC {$$ = $1;}
	| BTFSS {$$ = $1;}
	| MOVF {$$ = $1;}
	;
exp_var: exp_var PLUS term_var {$$ = exp_store2("%s + %s", $1, $3);}
	| exp_var MINUS term_var {$$ = exp_store2("%s - %s", $1, $3);}
	| term_var {$$ = $1;}
	;
term_var: term_var TIMES factor_var {$$ = exp_store2("%s * %s", $1, $3);}
    | term_var DIVIDE factor_var {$$ = exp_store2("%s / %s", $1, $3);}
    | factor_var {$$ = $1;}
	;
factor_var: VAR {$$ = $1;}
	| LP exp_var RP {$$ = exp_store1("(%s)", $2);}
	| exp {$$ = exp_store0($1);}
	;
exp: exp PLUS term {$$ = $1 + $3;}
	| exp MINUS term {$$ = $1 - $3;}
	| term {$$ = $1;}
term: term TIMES factor {$$ = $1 * $3;}
    | term DIVIDE factor {$$ = $1 / $3;}
    | factor {$$ = $1;}
factor: NUM {$$ = $1;}
	| LP exp RP {$$ = $2;}
	;
%%
int main(int argc, char *argv[]) {
	file_temp = fopen((const char*)"temp.asm", "w");
	if (NULL == file_temp) {
		return 0;
	}
	var_store_init();
	yyparse();
	fclose(file_temp);
	yyin = fopen((const char*)"temp.asm", "r");
	if (NULL == yyin) {
		return 0;
	}
	file_temp = stdout;
	return yyparse();
}

int yywrap(void) {
	return 1;
}

void yyerror(char* s) {
	printf("error: %s\n", s);
}

#137 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 写一个简单的编译器-flex&yacc » 2018-05-04 21:09:04

bunny
回复: 9

先贴代码吧:
1,pre_compiler.l

%{
#include <stdio.h>
#include <string.h>
#include "pre_compiler.tab.h"
#define YY_SKIP_YYWRAP
extern int yylval;

int yylex(void);

typedef struct {
	char name[128];
	int init;
	int value;
}var_store;
static var_store var_store_buf[8192];
static int var_store_cnt = 0;

static void exp_store_print(FILE* file, int index) {
	fprintf(file, (const char*)"%s\n", (const char*)var_store_buf[index].name);
}

static int exp_store0(int num) {
	sprintf((char*)var_store_buf[var_store_cnt].name, (const char*)"%d", num);
	var_store_buf[var_store_cnt].init = 0;
	var_store_buf[var_store_cnt++].value = 0;
	return var_store_cnt - 1;
}

static int exp_store1(const char* str, int a) {
	char* p_a;
	if ((a < 0) || (a >= var_store_cnt)) {
		return -1;
	}
	p_a = (char*)var_store_buf[a].name;
	sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a);
	var_store_buf[var_store_cnt].init = 0;
	var_store_buf[var_store_cnt++].value = 0;
	return var_store_cnt - 1;
}

static int exp_store2(const char* str, int a, int b) {
	char* p_a;
	char* p_b;
	if ((a < 0) || (a >= var_store_cnt) || (b < 0) || (b >= var_store_cnt)) {
		return -1;
	}
	p_a = (char*)var_store_buf[a].name;
	p_b = (char*)var_store_buf[b].name;
	sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a, p_b);
	var_store_buf[var_store_cnt].init = 0;
	var_store_buf[var_store_cnt++].value = 0;
	return var_store_cnt - 1;
}

static int exp_store3(const char* str, int a, int b, int c) {
	char* p_a;
	char* p_b;
	char* p_c;
	if ((a < 0) || (a >= var_store_cnt) || (b < 0) || (b >= var_store_cnt) || (c < 0) || (c >= var_store_cnt)) {
		return -1;
	}
	p_a = (char*)var_store_buf[a].name;
	p_b = (char*)var_store_buf[b].name;
	p_c = (char*)var_store_buf[c].name;
	sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a, p_b, p_c);
	var_store_buf[var_store_cnt].init = 0;
	var_store_buf[var_store_cnt++].value = 0;
	return var_store_cnt - 1;
}

static void var_store_init(void) {
	for (var_store_cnt = 4095; ; var_store_cnt--) {
		strcpy((char*)var_store_buf[var_store_cnt].name, (const char*)"");
		var_store_buf[var_store_cnt].value = 0;
		var_store_buf[var_store_cnt].init = 0;
		if (0 == var_store_cnt) {
			break;
		}
	}
}

static int var_store_read(int index) {
	if ((index >= 0) && (index < var_store_cnt) && var_store_buf[index].init) {
		return var_store_buf[index].value;
	}
	return 0;
}

static void var_store_write(int index, int value) {
	if ((index >= 0) && (index < var_store_cnt)) {
		var_store_buf[index].value = value;
		var_store_buf[index].init = -1;
	}
}

static int var_store_find(const char* name) {
	int i;
	for (i = 0; i < var_store_cnt; i++) {
		if (0 == strcmp((const char*)var_store_buf[i].name, name)) {
			return i;
		}
	}
	strcpy((char*)var_store_buf[var_store_cnt].name, name);
	var_store_buf[var_store_cnt].init = 0;
	var_store_buf[var_store_cnt++].value = 0;
	return var_store_cnt - 1;
}

static int is_var_inited(int index) {
	return var_store_buf[index].init;
}

static int bin2num(const char* bin) {
	int num;
	if ('0' != *bin++) {
		return 0;
	}
	if ('b' != *bin++) {
		return 0;
	}
	for (num = 0; *bin; bin++) {
		num <<= 1;
		if ('1' == *bin) {
			num |= 1;
		}
	}
	return num;
}

%}

subwf "subwf"
decf "decf"
addwf "addwf"
comf "comf"
incf "incf"
sublw "sublw"
addlw "addlw"
adcwf "adcwf"
sbcwf "sbcwf"
daa "daa"
das "das"
clrf "clrf"
clrw "clrw"
iorwf "iorwf"
andwf "andwf"
xorwf "xorwf"
rrf "rrf"
rlf "rlf"
swapf "swapf"
bcf "bcf"
bsf "bsf"
andlw "andlw"
xorlw "xorlw"
iorlw "iorlw"
decfsz "decfsz"
incfsz "incfsz"
btfsc "btfsc"
btfss "btfss"
goto "goto"
call "call"
return "return"
retfie "retfie"
retlw "retlw"
movwf "movwf"
movf "movf"
movlw "movlw"
nop "nop"
option "option"
tris "tris"
sleep "sleep"
clrwdt "clrwdt"
int "int"

equ "equ"
org "org"
end "end"
label ":"
split ","
note ";"[^\n]*
next_line [\n]
space [ \t]+

plus "+"
minus "-"
times "*"
divide "/"
lp "("
rp ")"

num [0-9]+
hex1 "0x"[0-9a-fA-F]+
hex2 [0-9]+[0-9a-fA-F]*[hH]
bin "0b"[01]+
var [_a-zA-z]+[_a-zA-z0-9]*

%%
{subwf} {
	yylval = var_store_find(yytext);
	return SUBWF;
}
{decf} {
	yylval = var_store_find(yytext);
	return DECF;
}
{addwf} {
	yylval = var_store_find(yytext);
	return ADDWF;
}
{comf} {
	yylval = var_store_find(yytext);
	return COMF;
}
{incf} {
	yylval = var_store_find(yytext);
	return INCF;
}
{sublw} {
	yylval = var_store_find(yytext);
	return SUBLW;
}
{addlw} {
	yylval = var_store_find(yytext);
	return ADDLW;
}
{adcwf} {
	yylval = var_store_find(yytext);
	return ADCWF;
}
{sbcwf} {
	yylval = var_store_find(yytext);
	return SBCWF;
}
{daa} {
	yylval = var_store_find(yytext);
	return DAA;
}
{das} {
	yylval = var_store_find(yytext);
	return DAS;
}
{clrf} {
	yylval = var_store_find(yytext);
	return CLRF;
}
{clrw} {
	yylval = var_store_find(yytext);
	return CLRW;
}
{iorwf} {
	yylval = var_store_find(yytext);
	return IORWF;
}
{andwf} {
	yylval = var_store_find(yytext);
	return ANDWF;
}
{xorwf} {
	yylval = var_store_find(yytext);
	return XORWF;
}
{rrf} {
	yylval = var_store_find(yytext);
	return RRF;
}
{rlf} {
	yylval = var_store_find(yytext);
	return RLF;
}
{swapf} {
	yylval = var_store_find(yytext);
	return SWAPF;
}
{bcf} {
	yylval = var_store_find(yytext);
	return BCF;
}
{bsf} {
	yylval = var_store_find(yytext);
	return BSF;
}
{andlw} {
	yylval = var_store_find(yytext);
	return ANDLW;
}
{xorlw} {
	yylval = var_store_find(yytext);
	return XORLW;
}
{iorlw} {
	yylval = var_store_find(yytext);
	return IORLW;
}
{decfsz} {
	yylval = var_store_find(yytext);
	return DECFSZ;
}
{incfsz} {
	yylval = var_store_find(yytext);
	return INCFSZ;
}
{btfsc} {
	yylval = var_store_find(yytext);
	return BTFSC;
}
{btfss} {
	yylval = var_store_find(yytext);
	return BTFSS;
}
{goto} {
	yylval = var_store_find(yytext);
	return GOTO;
}
{call} {
	yylval = var_store_find(yytext);
	return CALL;
}
{return} {
	yylval = var_store_find(yytext);
	return RETURN;
}
{retfie} {
	yylval = var_store_find(yytext);
	return RETFIE;
}
{retlw} {
	yylval = var_store_find(yytext);
	return RETLW;
}
{movwf} {
	yylval = var_store_find(yytext);
	return MOVWF;
}
{movf} {
	yylval = var_store_find(yytext);
	return MOVF;
}
{movlw} {
	yylval = var_store_find(yytext);
	return MOVLW;
}
{nop} {
	yylval = var_store_find(yytext);
	return NOP;
}
{option} {
	yylval = var_store_find(yytext);
	return OPTION;
}
{tris} {
	yylval = var_store_find(yytext);
	return TRIS;
}
{sleep} {
	yylval = var_store_find(yytext);
	return SLEEP;
}
{clrwdt} {
	yylval = var_store_find(yytext);
	return CLRWDT;
}
{int} {
	yylval = var_store_find(yytext);
	return INT;
}

{equ} {
	yylval = var_store_find(yytext);
	return EQU;
}
{org} {
	yylval = var_store_find(yytext);
	return ORG;
}
{end} {
	yylval = var_store_find(yytext);
	return END;
}
{label} {
	return LABEL;
}
{split} {
	return SPLIT;
}
{next_line} {
	return NEXT_LINE;
}
{space} {
}
{note} {
}

{num} {
	sscanf(yytext, "%d", &yylval);
	return NUM;
}
{hex1} {
	sscanf(yytext, "0x%x", &yylval);
	return NUM;
}
{hex2} {
	sscanf(yytext, "%x", &yylval);
	return NUM;
}
{bin} {
	yylval = bin2num(yytext);
	return NUM;
}
{plus} {
	return PLUS;
}
{minus} {
	return MINUS;
}
{times} {
	return TIMES;
}
{divide} {
	return DIVIDE;
}
{lp} {
	return LP;
}
{rp} {
	return RP;
}
{var} {
	yylval = var_store_find(yytext);
	if (is_var_inited(yylval)) {
		yylval = var_store_read(yylval);
		return NUM;
	}
	else {
		return VAR;
	}
}

. {
}

%%

#138 Re: ST/STM8/STM8S/STM8L » STM8 写的 433Mhz 解码器 » 2018-05-01 08:07:41

晕哥 说:

啥是COB ?

封装的一种,直接把裸芯封装在电路板上,留一个牛屎坨

#139 Re: 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » 再发一个小工具,用淘宝二十几块的白菜逻辑分析仪抓IIC通讯数据 » 2018-04-25 22:13:35

晕哥 说:

不错,
不过 Sea-Logic 不是已经可以直观图形显示了吗?选择I2C协议分析。
为什么还要这样导出?不太明白,请指教。

图一就是选择IIC协议,然后导出数据啊,图二更加简洁而已
之前有一款数字电源芯片,接口是IIC的,需要分析调电压的寄存器地址和数据,从一堆数据里找,工作量比较大
图一的地址和数据没有分离出来,图二的设备地址,寄存器地址,读写数据都分离出来了

#140 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » 再发一个小工具,用淘宝二十几块的白菜逻辑分析仪抓IIC通讯数据 » 2018-04-25 22:04:12

bunny
回复: 5

穷人一个,买不起高端仪器,调数字电路只好用淘宝二十几块的逻辑分析仪顶着,时常要抓点IIC数据,工作繁复,于是写了一个软件辅助之,特发上来共享。

前面不赘述了,设置好仪器,抓取数据,分析仪软件导出数据,得到如下txt:
TIM20180425215754.png
显然,从这一堆数据里扒东西,甚是麻烦,用iic_ansys.exe转换一下,得到如下txt:
TIM20180425220007.png
是不是清晰多了?

附件:
xxzouzhichao@qq.com

#142 DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/MQTT/物联网 » 写了一个小工具-步进电机S曲线加速 » 2018-04-24 22:07:39

bunny
回复: 5

1,该程序用于计算步进电机S加速曲线;
2,调用方法step_s.exe step v0 vx a_max a0 >step.csv,其中
    step为单个脉冲下步进电机的行程
    v0为当前速度
    vx为目标速度
    a_max为最大加速度
    a0为起步加速度
    step.csv为输出数据列表,依次为t,a,t,v,t,s数据
    例如:step_s.exe 0.01 2.0 10.0 1.0 0.01 >step_motor.csv

输出数据示例:
step.png

附件:
步进电机S加速计算

#149 硬件设计 KiCAD/Protel/DXP/PADS/ORCAD/EAGLE » 示波器——选择合适的带宽 » 2018-03-17 12:52:17

bunny
回复: 2

通常观测高速信号,带宽高高益善,无奈钱包很受伤,所以折中一下是很有必要的。
先从时钟信号开始,时钟信号多为占空比50%的方波,傅立叶变换如下:
u = (4/pi) * (sin(w*t) + sin(3*w*t)/3 + sin(5*w*t)/5 + sin(7*w*t)/7 + ... + sin(n*w*t)/n)
n代表高次谐波,到底n取多少合适?
首先看看n=5次谐波的波形:
5次谐波
n=9次谐波的波形:
9次谐波
n=19次谐波的波形:
19次谐波
一般而言,5次勉强够,9次波形很不错了,19次基本上细节非常好了,以50MHz时钟为例,300MHz/500Mhz带宽示波器是可以的
示例数据none.xls

问题来了,如果一个50MHz的时钟,占空比为10%,那么300MHz/500Mhz带宽示波器还够吗?
答案:50MHz 10%占空比与250MHz 50%对示波器带宽需求是差不多的,显然300MHz/500Mhz带宽示波器是不太够的

未完待续

#154 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 2018马上就来了,趁着年前发一个以前写的大数运算的代码 » 2018-02-13 22:06:50

晕哥 说:

感谢楼上两位对小站的支持!

不过论坛好像对贴图支持不太好啊,有些不方便

#155 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 2018马上就来了,趁着年前发一个以前写的大数运算的代码 » 2018-02-13 22:04:42

晕哥 说:

感谢楼上两位对小站的支持!

今年转战你的论坛,希望你的论坛越办越好

#156 Re: Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 2018马上就来了,趁着年前发一个以前写的大数运算的代码 » 2018-02-13 22:03:39

daydayup 说:

哈,这个不错,可以多少位十进制数,有没有限制?

基于字符串的运算,跟小学时候的手算是一个思路,无位数限制,就是运算速度慢点

#157 Qt/MSVC/MINGW/C++/MFC/GTK+/Delphi/BCB » 2018马上就来了,趁着年前发一个以前写的大数运算的代码 » 2018-02-13 21:46:58

bunny
回复: 11

朝花夕拾,根据印象重新写的,先贴一个整数的加法运算

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int bool;
#define false (-1)
#define true (0)

static bool char_check(char c) {
    if (c > '9') {
        return false;
    }
    if (c < '0') {
        return false;
    }
    return true;
}

static bool str_check(const char* src) {
    for ( ; *src; src++) {
        if (false == char_check(*src)) {
            return false;
        }
    }
    return true;
}

static void str_reverse(char* s) {
    char temp;
    char* r = s + strlen(s) - 1;
    while (s < r) {
        temp = *s;
        *s++ = *r;
        *r-- = temp;
    }
}

static bool char_add(char a, char b, char* c, char* d) {
    if (false == char_check(a)) {
        return false;
    }
    if (false == char_check(b)) {
        return false;
    }
    a -= '0';
    b -= '0';
    *d = a + b + (*c);
    if (*d > 9) {
        *d -= 10;
        *c = 1;
    }
    else {
        *c = 0;
    }
    *d += '0';
    return true;
}

static bool str_add(const char* a, const char* b, char* d) {
    char aa, bb, c = 0;
    int len_a = strlen(a), len_b = strlen(b);
    char* p_a = a + len_a - 1;
    char* p_b = b + len_b - 1;
    char* p_d = d;
    if (false == str_check(a)) {
        return false;
    }
    if (false == str_check(b)) {
        return false;
    }
    for ( ; (len_a > 0) || (len_b > 0); ) {
        aa = len_a > 0? *p_a-- : '0';
        bb = len_b > 0? *p_b-- : '0';
        char_add(aa, bb, &c, p_d++);
        len_a--;
        len_b--;
    }
    str_reverse(d);
    return true;
}

int main()
{
    char* a = "16664129129421912941294";
    char* b = "34666666666543854397591";
    char c[100] = "";
    str_add(a, b, c);
    printf("%s!\n", c);
    return 0;
}

#159 Re: Nuvoton N32905/N32926/NUC972/N9H20/N9H26/N9H30 » 又多一个选择,紫芯内置8MB SDRAM 的ASM9128T » 2017-12-30 16:16:21

daydayup 说:

RISC-32 处理器是通用微处理器 RISC 家族中的一员。RISC-32 属于 5TEJ 版 RISC-32
架构,针对的是多任务应用,包括全储存器管理,高性能,小核心尺寸和低功耗都是其重要
的特点。RISC-32 处理器支持 32 位 RISC-32 和 16 位 THUMB 指令集,使得用户能在高
性能和高代码密度上取得平衡。 支持 8 位 Java 指令集并且包括 Java 字节代码有效执行的
功能部件,提供和 JIT(Just-In-Time 编译器)相似的 Java 性能,这些性能为下一代 Java
无线和嵌入式的设备提供了有力支持。为了提高 DSP 性能,还包含了一个增强的乘法器设
计。RISC-32处理器支持 RISC 调试架构,包括对辅助硬件和软件调试的逻辑。

官方宣称用 RISC-32内核,其实这不就是一个ARM9内核嘛, 开发工具都是用ADS.
难道是指令集兼容,内核改改???

估计是因为版权问题,没有缴费的

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn