页次: 1
精简一下代码
#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;
}
#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;
}
#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;
}
请问有大佬测试过这个代码吗,我自己写的的计算出来全是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);
}
------------------------
错不在这!
而是这里
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,疏忽了
xxzouzhichao 说:Gentlepig 说:正在学习qt5,能否分享下源码?
作为一个QT应用程序而言,其实本身没啥亮点,无非就是对话框拖几个控件进来,简单到不能再简单了,可以说毫无参考价值,百度一下比比皆是
这个程序的核心是一段不涉及Qt界面的计算代码,这部分代码不方便开源,请谅解理解。
我把核心计算代码删掉了,改成了一个简单的Qt例程,你可以参考参考
led_loop1.zip
模拟器软件:
led_loop.zip
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;
昨天突然QQ上好些人加我,搞半天才知道是做电赛F题纸张计数来找数据拟合算法的,由于以前发布过最小二乘法的帖子,他们顺着百度扒过来的,废话少说,先上题目:
原理:电容法,自己百度平板电容计算公式
推导:
问题来了,电容量x与纸张数量y的关系满足(x + a) * (y + b) = c的关系,自校准需要得到a b c的值,当然首选最小二乘法拟合,然而非线性的拟合还是有点复杂的,熬夜折腾几小时终于搞定了这个算法源码!
先是用matlab脚本实现了功能,效果还不错
然后用C重写,算出来结果与matlab一致
提供一个exe程序供验证用,把数据放到data.txt里面,然后双击xy_fit.exe即可
源码出售,绝对原创,有意请联系,有效时间1天
请教下,虚线选中的覆铜,有些地方可以连起来而实际没连起来,是为了控制电流走向吗?
https://whycan.cn/files/members/1209/15.png
是的
首先,摘一段别处的科普文章http://www.av010.com/zixun/news_info_16082.html/
截取其中一段贴图:
用RLC搭建其等效模型:
扫频结果:
为什么会是这样一个等效模型?模型的参数是如何确定的?
这个问题问得好,这个问题其实是一个中等难度的物理建模,以后再用simulink写另一个帖子吧
单片机最常见的晶振应用电路:
这个电路内部结构相信大部分人都知道,仿真一下:
波形图:
把74HC04换成74HC14(斯密特反相器):
波形图:
74HC14(斯密特反相器)还可以搭建更简单的RC振荡器:
波形图:
用NPN三极管做的反相器代替74HC04:
波形图:
此外,还有一类不多见的晶振接法,以下摘自PT4330数据手册:
以下摘自SA626/SA625/SA605数据手册:
如此看来,这种接法也不算少见,以下摘自SA626内部结构图
搭建电路仿真:
这个电路有一个特殊用途,可以通过LC选频,输出晶振的倍频,比如下图10Mhz晶振就可以出来20MHz正弦波:
波形图:
192pF 330nH的谐振频率为20MHz
更正一段代码:
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); }
更正一段代码:
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);
}
直接上源码:
#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;
}
测试结果比对:
新换了一工作,要学的东西太多了,自己旧电脑(N3150的无风扇小盒子)不堪重负,遂有了新买电脑的想法,奈何银子紧张,本来琢磨着上amd的锐龙2600/2700,搞下来一个主机估计要四千多(intel更贵啦),最后一咬牙,还是上了假货宝的贼船,去捡了志强E5的破烂
E5-2420 6核12线程,1.9GHz(志强都这尿性),32G内存(做电源/信号完整性仿真不得不上大内存,可惜不支持64G),2200块,性价比一般,不推荐购买
电脑拿到手,先装了cadence和sigrity,先试试sigrity吧,以前画的一个imx6ul的板子,仿一下ddr的插损回损吧
先上allegro的layout:
转换成sigrity spd文件后:
DDR3 DQ AC的插损回损:
DDR3 DQS CLK差分对的插损回损:
先上源代码!
#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;
}
输出结果:
对比matlab输出结果:
先上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,测试:
输入文件:
输出文件:
先上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文件,测试:
再上传codeblock工程文件以及测试汇编代码:
codeblock工程文件及测试demo
先上传flex&yacc源文件及转换工具
flex&yacc + pre_compiler
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);
}
先贴代码吧:
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;
}
}
. {
}
%%
穷人一个,买不起高端仪器,调数字电路只好用淘宝二十几块的逻辑分析仪顶着,时常要抓点IIC数据,工作繁复,于是写了一个软件辅助之,特发上来共享。
前面不赘述了,设置好仪器,抓取数据,分析仪软件导出数据,得到如下txt:
显然,从这一堆数据里扒东西,甚是麻烦,用iic_ansys.exe转换一下,得到如下txt:
是不是清晰多了?
通常观测高速信号,带宽高高益善,无奈钱包很受伤,所以折中一下是很有必要的。
先从时钟信号开始,时钟信号多为占空比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次谐波的波形:
n=9次谐波的波形:
n=19次谐波的波形:
一般而言,5次勉强够,9次波形很不错了,19次基本上细节非常好了,以50MHz时钟为例,300MHz/500Mhz带宽示波器是可以的
示例数据none.xls
问题来了,如果一个50MHz的时钟,占空比为10%,那么300MHz/500Mhz带宽示波器还够吗?
答案:50MHz 10%占空比与250MHz 50%对示波器带宽需求是差不多的,显然300MHz/500Mhz带宽示波器是不太够的
未完待续
朝花夕拾,根据印象重新写的,先贴一个整数的加法运算
#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;
}
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.
难道是指令集兼容,内核改改???
估计是因为版权问题,没有缴费的
页次: 1