活动介绍

par for loop

时间: 2025-06-30 11:05:44 浏览: 11
### 并行 For 循环的实现与用法 并行 `for` 循环是一种通过利用多核处理器来加速迭代计算的技术。它允许将循环中的每次迭代分配到不同的线程或核心上执行,从而提高程序性能[^3]。 #### 使用 OpenMP 实现 C++ 中的 Parallel For Loop OpenMP 是一种广泛使用的 API,用于支持多平台共享内存 multiprocessing 编程。以下是使用 OpenMP 的简单例子: ```cpp #include <iostream> #include <omp.h> int main() { int n = 10; #pragma omp parallel for for (int i = 0; i < n; ++i) { std::cout << "Thread ID: " << omp_get_thread_num() << ", Iteration: " << i << std::endl; } return 0; } ``` 在这个例子中,`#pragma omp parallel for` 告诉编译器将这个 `for` 循环分解成多个线程并发运行。每个线程会打印其自身的线程编号以及当前迭代次数[^4]。 #### Python 中的 Parallel For Loop 使用 Multiprocessing 模块 Python 提供了多种方法来实现并行化处理,其中最常用的是 `multiprocessing` 库。下面是一个简单的示例: ```python from multiprocessing import Pool def square(x): return x * x if __name__ == "__main__": data = range(10) with Pool(processes=4) as pool: results = pool.map(square, data) print(results) ``` 此代码创建了一个进程池,并将函数 `square` 映射到数据列表上的每一个元素。这些操作会被分布在四个独立进程中完成[^5]。 #### Java 中的 Parallel Streams Java 8 引入了流(Stream)API 和并行流的概念,可以轻松地对集合对象应用并行运算: ```java import java.util.Arrays; public class Main { public static void main(String[] args) { Arrays.stream(new int[]{1, 2, 3, 4, 5}) .parallel() .map(i -> i * i) .forEach(System.out::println); } } ``` 这里 `.parallel()` 方法调用了并行版本的 Stream 处理逻辑,使得映射和遍历能够被自动分发给可用的核心去执行[^6]。 #### 性能注意事项 尽管并行编程提供了显著的速度提升潜力,但也需要注意一些潜在问题,比如同步开销、负载均衡不足或者虚假共享等问题可能会影响最终效果[^7]。
阅读全文

相关推荐

/****************************************************************************/ /* */ /* 音频测试:MIC_IN读取音频数据,从LINE_OUT播出 */ /* */ /* 2014年7月1日 */ /* */ /****************************************************************************/ #include "TL6748.h" // 创龙 DSP6748 开发板相关声明 #include "edma_event.h" #include "interrupt.h" #include "soc_OMAPL138.h" #include "hw_syscfg0_OMAPL138.h" #include "codecif.h" #include "mcasp.h" #include "aic31.h" #include "edma.h" #include "psc.h" #include "uartStdio.h" #include <string.h> /****************************************************************************** ** 宏定义 *******************************************************************************/ /* ** Values which are configurable */ /* Slot size to send/receive data */ #define SLOT_SIZE (16u) /* Word size to send/receive data. Word size <= Slot size */ #define WORD_SIZE (16u) /* Sampling Rate which will be used by both transmit and receive sections */ #define SAMPLING_RATE (48000u) /* Number of channels, L & R */ #define NUM_I2S_CHANNELS (2u) /* Number of samples to be used per audio buffer */ #define NUM_SAMPLES_PER_AUDIO_BUF (2000u) /* Number of buffers used per tx/rx */ #define NUM_BUF (3u) /* Number of linked parameter set used per tx/rx */ #define NUM_PAR (2u) /* Specify where the parameter set starting is */ #define PAR_ID_START (40u) /* Number of samples in loop buffer */ #define NUM_SAMPLES_LOOP_BUF (10u) /* AIC3106 codec address */ #define I2C_SLAVE_CODEC_AIC31 (0x18u) /* Interrupt channels to map in AINTC */ #define INT_CHANNEL_I2C (2u) #define INT_CHANNEL_MCASP (2u) #define INT_CHANNEL_EDMACC (2u) /* McASP Serializer for Receive */ #define MCASP_XSER_RX (12u) /* McASP Serializer for Transmit */ #define MCASP_XSER_TX (11u) /* ** Below Macros are calculated based on the above inputs */ #define NUM_TX_SERIALIZERS ((NUM_I2S_CHANNELS >> 1) \ + (NUM_I2S_CHANNELS & 0x01)) #define NUM_RX_SERIALIZERS ((NUM_I2S_CHANNELS >> 1) \ + (NUM_I2S_CHANNELS & 0x01)) #define I2S_SLOTS ((1 << NUM_I2S_CHANNELS) - 1) #define BYTES_PER_SAMPLE ((WORD_SIZE >> 3) \ * NUM_I2S_CHANNELS) #define AUDIO_BUF_SIZE (NUM_SAMPLES_PER_AUDIO_BUF \ * BYTES_PER_SAMPLE) #define TX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET(1) | (1 \ << EDMA3CC_OPT_TCINTEN_SHIFT)) #define RX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET(0) | (1 \ << EDMA3CC_OPT_TCINTEN_SHIFT)) #define PAR_RX_START (PAR_ID_START) #define PAR_TX_START (PAR_RX_START + NUM_PAR) /* ** Definitions which are not configurable */ #define SIZE_PARAMSET (32u) #define OPT_FIFO_WIDTH (0x02 << 8u) /****************************************************************************** ** 函数原型声明 *******************************************************************************/ static void McASPErrorIsr(void); static void McASPErrorIntSetup(void); static void AIC31I2SConfigure(void); static void McASPI2SConfigure(void); static void McASPTxDMAComplHandler(void); static void McASPRxDMAComplHandler(void); static void EDMA3CCComplIsr(void); static void I2SDataTxRxActivate(void); static void I2SDMAParamInit(void); static void ParamTxLoopJobSet(unsigned short parId); static void BufferTxDMAActivate(unsigned int txBuf, unsigned short numSamples, unsigned short parToUpdate, unsigned short linkAddr); static void BufferRxDMAActivate(unsigned int rxBuf, unsigned short parId, unsigned short parLink); /****************************************************************************/ /* 全局变量 */ /****************************************************************************/ static unsigned char loopBuf[NUM_SAMPLES_LOOP_BUF * BYTES_PER_SAMPLE] = {0}; /* ** Transmit buffers. If any new buffer is to be added, define it here and ** update the NUM_BUF. */ static unsigned char txBuf0[AUDIO_BUF_SIZE]; static unsigned char txBuf1[AUDIO_BUF_SIZE]; static unsigned char txBuf2[AUDIO_BUF_SIZE]; /* ** Receive buffers. If any new buffer is to be added, define it here and ** update the NUM_BUF. */ static unsigned char rxBuf0[AUDIO_BUF_SIZE]; static unsigned char rxBuf1[AUDIO_BUF_SIZE]; static unsigned char rxBuf2[AUDIO_BUF_SIZE]; /* ** Next buffer to receive data. The data will be received in this buffer. */ static volatile unsigned int nxtBufToRcv = 0; /* ** The RX buffer which filled latest. */ static volatile unsigned int lastFullRxBuf = 0; /* ** The offset of the paRAM ID, from the starting of the paRAM set. */ static volatile unsigned short parOffRcvd = 0; /* ** The offset of the paRAM ID sent, from starting of the paRAM set. */ static volatile unsigned short parOffSent = 0; /* ** The offset of the paRAM ID to be sent next, from starting of the paRAM set. */ static volatile unsigned short parOffTxToSend = 0; /* ** The transmit buffer which was sent last. */ static volatile unsigned int lastSentTxBuf = NUM_BUF - 1; /* Array of receive buffer pointers */ static unsigned int const rxBufPtr[NUM_BUF] = { (unsigned int) rxBuf0, (unsigned int) rxBuf1, (unsigned int) rxBuf2 }; /* Array of transmit buffer pointers */ static unsigned int const txBufPtr[NUM_BUF] = { (unsigned int) txBuf0, (unsigned int) txBuf1, (unsigned int) txBuf2 }; /* ** Default paRAM for Transmit section. This will be transmitting from ** a loop buffer. */ static struct EDMA3CCPaRAMEntry const txDefaultPar = { (unsigned int)(EDMA3CC_OPT_DAM | (0x02 << 8u)), /* Opt field */ (unsigned int)loopBuf, /* source address */ (unsigned short)(BYTES_PER_SAMPLE), /* aCnt */ (unsigned short)(NUM_SAMPLES_LOOP_BUF), /* bCnt */ (unsigned int) SOC_MCASP_0_DATA_REGS, /* dest address */ (short) (BYTES_PER_SAMPLE), /* source bIdx */ (short)(0), /* dest bIdx */ (unsigned short)(PAR_TX_START * SIZE_PARAMSET), /* link address */ (unsigned short)(0), /* bCnt reload value */ (short)(0), /* source cIdx */ (short)(0), /* dest cIdx */ (unsigned short)1 /* cCnt */ }; /* ** Default paRAM for Receive section. */ static struct EDMA3CCPaRAMEntry const rxDefaultPar = { (unsigned int)(EDMA3CC_OPT_SAM | (0x02 << 8u)), /* Opt field */ (unsigned int)SOC_MCASP_0_DATA_REGS, /* source address */ (unsigned short)(BYTES_PER_SAMPLE), /* aCnt */ (unsigned short)(1), /* bCnt */ (unsigned int)rxBuf0, /* dest address */ (short) (0), /* source bIdx */ (short)(BYTES_PER_SAMPLE), /* dest bIdx */ (unsigned short)(PAR_RX_START * SIZE_PARAMSET), /* link address */ (unsigned short)(0), /* bCnt reload value */ (short)(0), /* source cIdx */ (short)(0), /* dest cIdx */ (unsigned short)1 /* cCnt */ }; /****************************************************************************/ /* 函数声明 */ /****************************************************************************/ static void ParamTxLoopJobSet(unsigned short parId); static void I2SDMAParamInit(void); static void AIC31I2SConfigure(void); static void McASPI2SConfigure(void); static void EDMA3IntSetup(void); static void McASPErrorIntSetup(void); static void I2SDataTxRxActivate(void); void BufferTxDMAActivate(unsigned int txBuf, unsigned short numSamples, unsigned short parId, unsigned short linkPar); static void BufferRxDMAActivate(unsigned int rxBuf, unsigned short parId, unsigned short parLink); static void McASPRxDMAComplHandler(void); static void McASPTxDMAComplHandler(void); static void EDMA3CCComplIsr(void); static void McASPErrorIsr(void); /****************************************************************************/ /* 主函数 */ /****************************************************************************/ int main(void) { unsigned short parToSend; unsigned short parToLink; UARTStdioInit(); UARTPuts("\r\n ============Test Start===========.\r\n", -1); UARTPuts("Welcome to StarterWare Audio_MIC_In Demo application.\r\n\r\n", -1); UARTPuts("This application loops back the input at MIC_IN of the EVM to the LINE_OUT of the EVM\r\n\r\n", -1); /* Set up pin mux for I2C module 0 */ I2CPinMuxSetup(0); McASPPinMuxSetup(); /* Power up the McASP module */ PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCASP0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); /* Power up EDMA3CC_0 and EDMA3TC_0 */ PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); #ifdef _TMS320C6X // Initialize the DSP interrupt controller IntDSPINTCInit(); #else /* Initialize the ARM Interrupt Controller.*/ IntAINTCInit(); #endif /* Initialize the I2C 0 interface for the codec AIC31 */ I2CCodecIfInit(SOC_I2C_0_REGS, INT_CHANNEL_I2C, I2C_SLAVE_CODEC_AIC31); EDMA3Init(SOC_EDMA30CC_0_REGS, 0); EDMA3IntSetup(); McASPErrorIntSetup(); #ifdef _TMS320C6X IntGlobalEnable(); #else /* Enable the interrupts generation at global level */ IntMasterIRQEnable(); IntGlobalEnable(); IntIRQEnable(); #endif /* ** Request EDMA channels. Channel 0 is used for reception and ** Channel 1 is used for transmission */ EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_MCASP0_TX, EDMA3_CHA_MCASP0_TX, 0); EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_MCASP0_RX, EDMA3_CHA_MCASP0_RX, 0); /* Initialize the DMA parameters */ I2SDMAParamInit(); /* Configure the Codec for I2S mode */ AIC31I2SConfigure(); /* Configure the McASP for I2S */ McASPI2SConfigure(); /* Activate the audio transmission and reception */ I2SDataTxRxActivate(); /* ** Looop forever. if a new buffer is received, the lastFullRxBuf will be ** updated in the rx completion ISR. if it is not the lastSentTxBuf, ** buffer is to be sent. This has to be mapped to proper paRAM set. */ while(1) { if(lastFullRxBuf != lastSentTxBuf) { /* ** Start the transmission from the link paramset. The param set ** 1 will be linked to param set at PAR_TX_START. So do not ** update paRAM set1. */ parToSend = PAR_TX_START + (parOffTxToSend % NUM_PAR); parOffTxToSend = (parOffTxToSend + 1) % NUM_PAR; parToLink = PAR_TX_START + parOffTxToSend; lastSentTxBuf = (lastSentTxBuf + 1) % NUM_BUF; /* Copy the buffer */ memcpy((void *)txBufPtr[lastSentTxBuf], (void *)rxBufPtr[lastFullRxBuf], AUDIO_BUF_SIZE); /* ** Send the buffer by setting the DMA params accordingly. ** Here the buffer to send and number of samples are passed as ** parameters. This is important, if only transmit section ** is to be used. */ BufferTxDMAActivate(lastSentTxBuf, NUM_SAMPLES_PER_AUDIO_BUF, (unsigned short)parToSend, (unsigned short)parToLink); } } } /* ** Assigns loop job for a parameter set */ static void ParamTxLoopJobSet(unsigned short parId) { EDMA3CCPaRAMEntry paramSet; memcpy(¶mSet, &txDefaultPar, SIZE_PARAMSET - 2); /* link the paRAM to itself */ paramSet.linkAddr = parId * SIZE_PARAMSET; EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, parId, ¶mSet); } /* ** Initializes the DMA parameters. ** The RX basic paRAM set(channel) is 0 and TX basic paRAM set (channel) is 1. ** ** The RX paRAM set 0 will be initialized to receive data in the rx buffer 0. ** The transfer completion interrupt will not be enabled for paRAM set 0; ** paRAM set 0 will be linked to linked paRAM set starting (PAR_RX_START) of RX. ** and further reception only happens via linked paRAM set. ** For example, if the PAR_RX_START value is 40, and the number of paRAMS is 2, ** reception paRAM set linking will be initialized as 0-->40-->41-->40 ** ** The TX paRAM sets will be initialized to transmit from the loop buffer. ** The size of the loop buffer can be configured. ** The transfer completion interrupt will not be enabled for paRAM set 1; ** paRAM set 1 will be linked to linked paRAM set starting (PAR_TX_START) of TX. ** All other paRAM sets will be linked to itself. ** and further transmission only happens via linked paRAM set. ** For example, if the PAR_RX_START value is 42, and the number of paRAMS is 2, ** So transmission paRAM set linking will be initialized as 1-->42-->42, 43->43. */ static void I2SDMAParamInit(void) { EDMA3CCPaRAMEntry paramSet; int idx; /* Initialize the 0th paRAM set for receive */ memcpy(¶mSet, &rxDefaultPar, SIZE_PARAMSET - 2); EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX, ¶mSet); /* further paramsets, enable interrupt */ paramSet.opt |= RX_DMA_INT_ENABLE; for(idx = 0 ; idx < NUM_PAR; idx++) { paramSet.destAddr = rxBufPtr[idx]; paramSet.linkAddr = (PAR_RX_START + ((idx + 1) % NUM_PAR)) * (SIZE_PARAMSET); paramSet.bCnt = NUM_SAMPLES_PER_AUDIO_BUF; /* ** for the first linked paRAM set, start receiving the second ** sample only since the first sample is already received in ** rx buffer 0 itself. */ if( 0 == idx) { paramSet.destAddr += BYTES_PER_SAMPLE; paramSet.bCnt -= BYTES_PER_SAMPLE; } EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, (PAR_RX_START + idx), ¶mSet); } /* Initialize the required variables for reception */ nxtBufToRcv = idx % NUM_BUF; lastFullRxBuf = NUM_BUF - 1; parOffRcvd = 0; /* Initialize the 1st paRAM set for transmit */ memcpy(¶mSet, &txDefaultPar, SIZE_PARAMSET); EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX, ¶mSet); /* rest of the params, enable loop job */ for(idx = 0 ; idx < NUM_PAR; idx++) { ParamTxLoopJobSet(PAR_TX_START + idx); } /* Initialize the variables for transmit */ parOffSent = 0; lastSentTxBuf = NUM_BUF - 1; } /* ** Function to configure the codec for I2S mode */ static void AIC31I2SConfigure(void) { volatile unsigned int delay = 0xFFF; AIC31Reset(SOC_I2C_0_REGS); while(delay--); /* Configure the data format and sampling rate */ AIC31DataConfig(SOC_I2C_0_REGS, AIC31_DATATYPE_I2S, SLOT_SIZE, 0); AIC31SampleRateConfig(SOC_I2C_0_REGS, AIC31_MODE_BOTH, SAMPLING_RATE); /* Initialize both ADC and DAC */ AIC31ADCInit(SOC_I2C_0_REGS); AIC31DACInit(SOC_I2C_0_REGS); } /* ** Configures the McASP Transmit Section in I2S mode. */ static void McASPI2SConfigure(void) { McASPRxReset(SOC_MCASP_0_CTRL_REGS); McASPTxReset(SOC_MCASP_0_CTRL_REGS); /* Enable the FIFOs for DMA transfer */ McASPReadFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1); McASPWriteFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1); /* Set I2S format in the transmitter/receiver format units */ McASPRxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, MCASP_RX_MODE_DMA); McASPTxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE, MCASP_TX_MODE_DMA); /* Configure the frame sync. I2S shall work in TDM format with 2 slots */ McASPRxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_RX_FS_WIDTH_WORD, MCASP_RX_FS_EXT_BEGIN_ON_FALL_EDGE); McASPTxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_TX_FS_WIDTH_WORD, MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE); /* configure the clock for receiver */ McASPRxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL, 0, 0); McASPRxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_POL_RIS_EDGE); McASPRxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLKCHCK_DIV32, 0x00, 0xFF); /* configure the clock for transmitter */ McASPTxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL, 0, 0); McASPTxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_POL_FALL_EDGE); McASPTxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLKCHCK_DIV32, 0x00, 0xFF); /* Enable synchronization of RX and TX sections */ McASPTxRxClkSyncEnable(SOC_MCASP_0_CTRL_REGS); /* Enable the transmitter/receiver slots. I2S uses 2 slots */ McASPRxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS); McASPTxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS); /* ** Set the serializers, Currently only one serializer is set as ** transmitter and one serializer as receiver. */ McASPSerializerRxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_RX); McASPSerializerTxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_TX); /* ** Configure the McASP pins ** Input - Frame Sync, Clock and Serializer Rx ** Output - Serializer Tx is connected to the input of the codec */ McASPPinMcASPSet(SOC_MCASP_0_CTRL_REGS, 0xFFFFFFFF); McASPPinDirOutputSet(SOC_MCASP_0_CTRL_REGS,MCASP_PIN_AXR(MCASP_XSER_TX)); McASPPinDirInputSet(SOC_MCASP_0_CTRL_REGS, MCASP_PIN_AFSX | MCASP_PIN_ACLKX | MCASP_PIN_AHCLKX | MCASP_PIN_AXR(MCASP_XSER_RX)); /* Enable error interrupts for McASP */ McASPTxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_TX_DMAERROR | MCASP_TX_CLKFAIL | MCASP_TX_SYNCERROR | MCASP_TX_UNDERRUN); McASPRxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_RX_DMAERROR | MCASP_RX_CLKFAIL | MCASP_RX_SYNCERROR | MCASP_RX_OVERRUN); } /* ** Sets up the interrupts for EDMA in AINTC */ static void EDMA3IntSetup(void) { #ifdef _TMS320C6X IntRegister(C674X_MASK_INT5, EDMA3CCComplIsr); IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_INT1); IntEnable(C674X_MASK_INT5); #else IntRegister(SYS_INT_CCINT0, EDMA3CCComplIsr); IntChannelSet(SYS_INT_CCINT0, INT_CHANNEL_EDMACC); IntSystemEnable(SYS_INT_CCINT0); #endif } /* ** Sets up the error interrupts for McASP in AINTC */ static void McASPErrorIntSetup(void) { #ifdef _TMS320C6X IntRegister(C674X_MASK_INT6, McASPErrorIsr); IntEventMap(C674X_MASK_INT6, SYS_INT_MCASP0_INT); IntEnable(C674X_MASK_INT6); #else /* Register the error ISR for McASP */ IntRegister(SYS_INT_MCASPINT, McASPErrorIsr); IntChannelSet(SYS_INT_MCASPINT, INT_CHANNEL_MCASP); IntSystemEnable(SYS_INT_MCASPINT); #endif } /* ** Activates the data transmission/reception ** The DMA parameters shall be ready before calling this function. */ static void I2SDataTxRxActivate(void) { /* Start the clocks */ McASPRxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL); McASPTxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL); /* Enable EDMA for the transfer */ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX, EDMA3_TRIG_MODE_EVENT); EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX, EDMA3_TRIG_MODE_EVENT); /* Activate the serializers */ McASPRxSerActivate(SOC_MCASP_0_CTRL_REGS); McASPTxSerActivate(SOC_MCASP_0_CTRL_REGS); /* make sure that the XDATA bit is cleared to zero */ while(McASPTxStatusGet(SOC_MCASP_0_CTRL_REGS) & MCASP_TX_STAT_DATAREADY); /* Activate the state machines */ McASPRxEnable(SOC_MCASP_0_CTRL_REGS); McASPTxEnable(SOC_MCASP_0_CTRL_REGS); } /* ** Activates the DMA transfer for a parameterset from the given buffer. */ void BufferTxDMAActivate(unsigned int txBuf, unsigned short numSamples, unsigned short parId, unsigned short linkPar) { EDMA3CCPaRAMEntry paramSet; /* Copy the default paramset */ memcpy(¶mSet, &txDefaultPar, SIZE_PARAMSET - 2); /* Enable completion interrupt */ paramSet.opt |= TX_DMA_INT_ENABLE; paramSet.srcAddr = txBufPtr[txBuf]; paramSet.linkAddr = linkPar * SIZE_PARAMSET; paramSet.bCnt = numSamples; EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, parId, ¶mSet); } /* ** Activates the DMA transfer for a parameter set from the given buffer. */ static void BufferRxDMAActivate(unsigned int rxBuf, unsigned short parId, unsigned short parLink) { EDMA3CCPaRAMEntry paramSet; /* Copy the default paramset */ memcpy(¶mSet, &rxDefaultPar, SIZE_PARAMSET - 2); /* Enable completion interrupt */ paramSet.opt |= RX_DMA_INT_ENABLE; paramSet.destAddr = rxBufPtr[rxBuf]; paramSet.bCnt = NUM_SAMPLES_PER_AUDIO_BUF; paramSet.linkAddr = parLink * SIZE_PARAMSET ; EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, parId, ¶mSet); } /* ** This function will be called once receive DMA is completed */ static void McASPRxDMAComplHandler(void) { unsigned short nxtParToUpdate; /* ** Update lastFullRxBuf to indicate a new buffer reception ** is completed. */ lastFullRxBuf = (lastFullRxBuf + 1) % NUM_BUF; nxtParToUpdate = PAR_RX_START + parOffRcvd; parOffRcvd = (parOffRcvd + 1) % NUM_PAR; /* ** Update the DMA parameters for the received buffer to receive ** further data in proper buffer */ BufferRxDMAActivate(nxtBufToRcv, nxtParToUpdate, PAR_RX_START + parOffRcvd); /* update the next buffer to receive data */ nxtBufToRcv = (nxtBufToRcv + 1) % NUM_BUF; } /* ** This function will be called once transmit DMA is completed */ static void McASPTxDMAComplHandler(void) { ParamTxLoopJobSet((unsigned short)(PAR_TX_START + parOffSent)); parOffSent = (parOffSent + 1) % NUM_PAR; } /* ** EDMA transfer completion ISR */ static void EDMA3CCComplIsr(void) { #ifdef _TMS320C6X IntEventClear(SYS_INT_EDMA3_0_CC0_INT1); #else IntSystemStatusClear(SYS_INT_CCINT0); #endif /* Check if receive DMA completed */ if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_RX)) { /* Clear the interrupt status for the 0th channel */ EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX); McASPRxDMAComplHandler(); } /* Check if transmit DMA completed */ if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_TX)) { /* Clear the interrupt status for the first channel */ EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX); McASPTxDMAComplHandler(); } } /* ** Error ISR for McASP */ static void McASPErrorIsr(void) { #ifdef _TMS320C6X IntEventClear(SYS_INT_MCASP0_INT); #else IntSystemStatusClear(SYS_INT_MCASPINT); #endif ; /* Perform any error handling here.*/ } /***************************** End Of File ***********************************/ 将以上代码和以下代码合在一起:#include "math.h" #include "mathlib.h" #include "dsplib.h" #define PI 3.1415926535 #define F_TOL (1e-06) #define Tn 1024 #define Fs 48000.0 #define N 132 // 滤波器阶数(偶数) #define FilterCount 5 const float F1s[FilterCount] = {20.0, 400.0, 1200.0, 4000.0, 13000.0}; const float F2s[FilterCount] = {400.0, 1200.0, 4000.0, 13000.0, 20000.0}; #pragma DATA_ALIGN(FIR_In, 8); float FIR_In[Tn]; #pragma DATA_ALIGN(FIR_Outs, 8); float FIR_Outs[FilterCount][Tn]; #pragma DATA_ALIGN(FIR_CombinedOut, 8); float FIR_CombinedOut[Tn]; #pragma DATA_ALIGN(Bs, 8); float Bs[FilterCount][N]; void FIRTest(void); void design_blackman_bandpass_fir(float *h, int n, float f1, float f2, float fs); void blackman_window(float *w, int n); void normalize_filter_response(float *h, int n, float f1, float f2, float fs); int main(void) { int i; // 声明循环变量 for (i = 0; i < FilterCount; i++) { design_blackman_bandpass_fir(Bs[i], N, F1s[i], F2s[i], Fs); } FIRTest(); return 0; } void blackman_window(float *w, int n) { int i; // 声明循环变量 for (i = 0; i < n; i++) { w[i] = 0.42f - 0.5f * cosf(2.0f * PI * i / (n - 1)) + 0.08f * cosf(4.0f * PI * i / (n - 1)); } } void normalize_filter_response(float *h, int n, float f1, float f2, float fs) { float center_freq = (f1 + f2) / 2.0f; float omega = 2.0f * PI * center_freq / fs; float real_gain = 0.0f; int i; // 声明循环变量 for (i = 0; i < n; i++) { real_gain += h[i] * cosf(omega * (i - (n-1)/2.0f)); } if (fabsf(real_gain) > F_TOL) { for (i = 0; i < n; i++) { h[i] /= real_gain; } } } void design_blackman_bandpass_fir(float *h, int n, float f1, float f2, float fs) { float w[N]; float fc1 = f1 / fs; float fc2 = f2 / fs; int i; // 声明循环变量 blackman_window(w, n); for (i = 0; i < n; i++) { float m = i - (n - 1)/2.0f; h[i] = (fabsf(m) < F_TOL) ? 2.0f * (fc2 - fc1) : (sinf(2.0f * PI * fc2 * m) - sinf(2.0f * PI * fc1 * m)) / (PI * m); h[i] *= w[i]; } normalize_filter_response(h, n, f1, f2, fs); } void FIRTest(void) { int i, j; // 声明循环变量 // 生成测试信号 - 每个频段一个测试频率 for (i = 0; i < Tn; i++) { float t = (float)i / Fs; FIR_In[i] = 5.0f * sinf(2.0f * PI * 10.0f * t) + 5.0f * sinf(2.0f * PI * 15000.0f * t)+ 5.0f * sinf(2.0f * PI * 25000.0f * t); } // 初始化并处理滤波器输出 for (i = 0; i < Tn; i++) { FIR_CombinedOut[i] = 0.0f; } for (j = 0; j < FilterCount; j++) { DSPF_sp_fir_r2(FIR_In, Bs[j], FIR_Outs[j], N, Tn); // 累加各滤波器输出 for (i = 0; i < Tn; i++) { FIR_CombinedOut[i] += FIR_Outs[j][i]; } } } 将测试信号去掉,合成后的代码输入就是音频输入,输出就是音频输出,滤波器来处理数据

* This program demonstrates the effect of using the * generic parameter 'recompute_score' of the operator * find_shape_model_3d. * * By setting 'recompute_score' to 'true', the score * is recomputed after the pose refinement, which * may lead to slightly different (but more consistent) * score values at the cost of a slightly larger * execution time. * * For this, a 3D shape model of a cube is searched in * a sequence of artificially created images by using * find_shape_model_3d. The images are created by * changing the longitude of the camera in the object * centered spherical coordinate system. * * The matching is performed twice. In the first run, * 'recompute_score' is set to 'false', while in the * second run, 'recompute_score' is set to 'true'. The * score is stored for each of the two runs over all * images. Finally, the score values are plotted with * respect to the camera longitude. * * Note that the variation of the score values is * significantly higher when setting 'recompute_score' * to 'false'. Also note that in real images typically * the variation of the score is lower. * gen_cam_par_area_scan_division (0.01, 0, 7e-6, 7e-6, 320, 240, 640, 480, CamParam) get_cam_par_data (CamParam, 'image_width', Width) get_cam_par_data (CamParam, 'image_height', Height) dev_close_window () dev_open_window (0, 0, Width, Height, 'black', WindowHandle) dev_set_part (0, 0, Height - 1, Width - 1) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_update_off () * * Generate a cube X := [-1,-1,1,1,-1,-1,1,1] Y := [1,-1,-1,1,1,-1,-1,1] Z := [-1,-1,-1,-1,1,1,1,1] Polygons := [4,0,1,2,3,4,4,5,6,7,4,0,1,5,4,4,3,2,6,7,4,0,3,7,4,4,1,2,6,5] gen_object_model_3d_from_points (X, Y, Z, ObjectModel3DID) set_object_model_3d_attrib_mod (ObjectModel3DID, 'polygons', [], Polygons) * * Prepare the 3D object model for matching prepare_object_model_3d (ObjectModel3DID, 'shape_based_matching_3d', 'true', [], []) * * Display the 3D object model disp_object_model_3d_safe (WindowHandle, ObjectModel3DID, CamParam, [0,0,11,30,40,0,0], [], []) disp_message (WindowHandle, '3D Object Model of a Cube', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () * * * Generate the 3D shape model create_cube_shape_model_3d (WindowHandle, ObjectModel3DID, CamParam, ShapeModel3DID) clear_object_model_3d (ObjectModel3DID) * Scores1 := [] Scores2 := [] Times1 := [] Times2 := [] Longitudes := [] Latitude := rad(45) Distance := 11.5 dev_set_color ('green') dev_set_line_width (2) for Longitude := rad(30) to rad(60) by rad(0.25) convert_point_3d_spher_to_cart (Longitude, Latitude, Distance, '-y', '-z', CamX, CamY, CamZ) create_cam_pose_look_at_point (CamX, CamY, CamZ, 0, 0, 0, '-y', 0, CamPose) * Prevent flickering set_system ('flush_graphic', 'false') * * Generate an artificial image of the cube project_cube_image (Image, CamPose, CamParam, X, Y, Z, Polygons) * * Find the cube by using 3D shape-based matching * ('recompute_score' = 'false') count_seconds (Seconds1) find_shape_model_3d (Image, ShapeModel3DID, 0.7, 0.9, 0, [], [], Pose1, CovPose1, Score1) count_seconds (Seconds2) Time1 := (Seconds2 - Seconds1) * 1000.0 * Find the cube by using 3D shape-based matching * ('recompute_score' = 'true') count_seconds (Seconds1) find_shape_model_3d (Image, ShapeModel3DID, 0.7, 0.9, 0, 'recompute_score', 'true', Pose2, CovPose2, Score2) count_seconds (Seconds2) Time2 := (Seconds2 - Seconds1) * 1000.0 * * Display the matching result dev_display (Image) if (|Score1| == 1 and |Score2| == 1) * Display the match project_shape_model_3d (ModelContours, ShapeModel3DID, CamParam, Pose1, 'true', rad(30)) dev_display (ModelContours) * Display the matching time and score disp_message (WindowHandle, 'Matching at Longitude: ' + deg(Longitude)$'3.1f' + ' deg (from 30 to 60 deg)', 'window', 12, 12, 'white', 'false') gen_matching_result_message (Time1, Time2, Score1, Score2, Message) disp_message (WindowHandle, Message, 'window', 420, 12, ['white','yellow','green'], 'false') * Remember the score values Longitudes := [Longitudes,deg(Longitude)] Scores1 := [Scores1,Score1] Scores2 := [Scores2,Score2] Times1 := [Times1,Time1] Times2 := [Times2,Time2] endif * Prevent flickering set_system ('flush_graphic', 'true') * Show what we painted in the loop by drawing a invisible line disp_line (WindowHandle, -1, -1, -1, -1) endfor * * Display the score values dev_clear_window () Title := ['\'recompute_score\'=\'false\'','\'recompute_score\'=\'true\''] Colors := ['yellow','green'] plot_tuple (WindowHandle, Longitudes, [Scores1,Scores2], 'Longitude [deg]', 'Matching score', Colors, ['ticks_x','ticks_y','end_y'], [6,.01,1]) disp_message (WindowHandle, Title, 'window', 12, 350, Colors, 'false') disp_continue_message (WindowHandle, 'black', 'true') stop () dev_clear_window () plot_tuple (WindowHandle, Longitudes, [Times1,Times2], 'Longitude [deg]', 'Matching time [ms]', Colors, 'ticks_x', 6) disp_message (WindowHandle, Title, 'window', 12, 350, Colors, 'false') * * Clear the 3D shape model clear_shape_model_3d (ShapeModel3DID)

* This example program shows how 128 images of the interior of a church can be * combined into a mosaic that covers a 360x130 degree view. The images were acquired * with a camera in which the exposure and white balance were set to automatic. * Therefore, there are very large brightness and color differences between the images. * Hence, adjust_mosaic_images is used to align the images radiometrically. * Furthermore, blending is used to hide the transitions between the individual * images that make up the mosaic. dev_update_off () dev_close_window () dev_open_window (0, 0, 978, 324, 'black', WindowHandle) dev_set_part (0, 0, 647, 1955) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Reading images...') * Read the 128 images that make up the mosaic. gen_empty_obj (Images) for J := 1 to 128 by 1 read_image (Image, 'panorama/sankt_martin_automatic_' + J$'03d') concat_obj (Images, Image, Images) endfor get_image_size (Image, Width, Height) * Construct the tuples that determine which images should be matched. The * mosaic images were acquired as 16 vertical strips of 8 images each. * For each image, we match the image below the current image in the same * strip and the image to the left of the current image in the adjacent strip. FF := [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8] TT := [2,9,3,10,4,11,5,12,6,13,7,14,8,15,16] From := [] To := [] for J := 0 to 15 by 1 From := [From,(FF - 1 + 8 * J) % 128 + 1] To := [To,(TT - 1 + 8 * J) % 128 + 1] endfor * Initialize the data that is required for the self-calibration. HomMatrices2D := [] Rows1 := [] Cols1 := [] Rows2 := [] Cols2 := [] NumMatches := [] for J := 0 to |From| - 1 by 1 * Select the images to match. select_obj (Images, ImageF, From[J]) select_obj (Images, ImageT, To[J]) * Perform the point extraction of the images. points_foerstner (ImageF, 1, 2, 3, 50, 0.1, 'gauss', 'true', RowsF, ColsF, CoRRJunctions, CoRCJunctions, CoCCJunctions, RowArea, ColumnArea, CoRRArea, CoRCArea, CoCCArea) points_foerstner (ImageT, 1, 2, 3, 50, 0.1, 'gauss', 'true', RowsT, ColsT, CoRRJunctions1, CoRCJunctions1, CoCCJunctions1, RowArea1, ColumnArea1, CoRRArea1, CoRCArea1, CoCCArea1) concat_obj (ImageT, ImageF, ImageTF) tile_images_offset (ImageTF, TiledImage, [0,0], [0,Width + 20], [-1,-1], [-1,-1], [-1,-1], [-1,-1], 2 * Width + 20, Height) gen_cross_contour_xld (PointsF, RowsF, ColsF + Width + 20, 6, rad(45)) gen_cross_contour_xld (PointsT, RowsT, ColsT, 6, rad(0)) * Convert the images to gray value images. rgb1_to_gray (ImageF, ImageFG) rgb1_to_gray (ImageT, ImageTG) * Determine the projective transformation between the images. proj_match_points_ransac (ImageFG, ImageTG, RowsF, ColsF, RowsT, ColsT, 'ncc', 10, 0, 0, 648, 968, [rad(-10),rad(40)], 0.5, 'gold_standard', 10, 42, HomMat2D, Points1, Points2) * After this, we accumulate the required data. HomMatrices2D := [HomMatrices2D,HomMat2D] Rows1 := [Rows1,subset(RowsF,Points1)] Cols1 := [Cols1,subset(ColsF,Points1)] Rows2 := [Rows2,subset(RowsT,Points2)] Cols2 := [Cols2,subset(ColsT,Points2)] NumMatches := [NumMatches,|Points1|] * The rest of the code within the loop visualizes the point matches. RF := subset(RowsF,Points1) CF := subset(ColsF,Points1) + Width + 20 RT := subset(RowsT,Points2) CT := subset(ColsT,Points2) gen_empty_obj (Matches) for K := 0 to |RF| - 1 by 1 gen_contour_polygon_xld (Match, [RF[K],RT[K]], [CF[K],CT[K]]) concat_obj (Matches, Match, Matches) endfor dev_clear_window () dev_display (TiledImage) dev_set_color ('blue') dev_display (Matches) dev_set_color ('green') dev_display (PointsF) dev_display (PointsT) dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Matches between images ' + From[J]$'d' + ' and ' + To[J]$'d') endfor dev_clear_window () dev_set_window_extents (-1, -1, 856, 428) dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Performing self-calibration...') * Perform the self-calibration. stationary_camera_self_calibration (128, 968, 648, 6, From, To, HomMatrices2D, Rows1, Cols1, Rows2, Cols2, NumMatches, 'gold_standard', ['focus','principal_point','kappa'], 'true', CameraMatrix, Kappa, RotationMatrices, X, Y, Z, Error) dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Removing radial distortions...') * Remove the radial distortions from the images. cam_mat_to_cam_par (CameraMatrix, Kappa, 968, 648, CamParam) change_radial_distortion_cam_par ('fixed', CamParam, 0, CamParOut) gen_radial_distortion_map (Map, CamParam, CamParOut, 'bilinear') map_image (Images, Map, Images) dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Adjusting the images radiometrically...') * Before we adjust the images radiometrically, we compute the perspective * transformations between the images from the camera matrix and the rotation * matrices that are returned by the self-calibration. They are more accurate * than the perspective transformations that are returned by the matching * since they have been optimized over all images. For details on how the * perspective transformation matrices are computed by the code below, see the * documentation of stationary_camera_self_calibration. hom_mat2d_invert (CameraMatrix, CameraMatrixInv) PermMat := [0.0,1.0,0.5,1.0,0.0,0.5,0.0,0.0,1.0] hom_mat2d_invert (PermMat, PermMatInv) hom_mat2d_compose (CameraMatrixInv, PermMatInv, CamMatPermInv) hom_mat2d_compose (PermMat, CameraMatrix, CamMatPerm) HomMats2D := [] for J := 0 to |From| - 1 by 1 RotMatFrom := RotationMatrices[9 * (From[J] - 1):9 * (From[J] - 1) + 8] RotMatTo := RotationMatrices[9 * (To[J] - 1):9 * (To[J] - 1) + 8] hom_mat2d_transpose (RotMatFrom, RotMatFromInv) hom_mat2d_compose (RotMatTo, RotMatFromInv, RotMat) hom_mat2d_compose (RotMat, CamMatPermInv, RotCamMatInv) hom_mat2d_compose (CamMatPerm, RotCamMatInv, HomMat2D) HomMats2D := [HomMats2D,HomMat2D] endfor * Now adjust the images radiometrically. Since the exposure and white balance * were set to automatic, we calculate 'mult_gray'. Since the camera is a consumer * camera and therefore has a highly nonlinear response, we compute 'response'. * To compensate the vignetting in the images, we compute 'vignetting'. Finally, * to speed up the optimization, we use a subsampling by a factor of 4. adjust_mosaic_images (Images, CorrectedImages, From, To, 118, HomMats2D, 'gold_standard', ['mult_gray','response','vignetting','subsampling_4'], 'laguerre') * Since the reference image was not aligned perfectly horizontally, we modify the * calibrated rotation matrices by rotating them by -5.5 degrees around the x axis. hom_mat3d_identity (HomMat3D) hom_mat3d_rotate (HomMat3D, rad(-5.5), 'x', 0, 0, 0, HomMat3D) RotMat := [HomMat3D[0:2],HomMat3D[4:6],HomMat3D[8:10]] RotMats := [] for J := 0 to 127 by 1 RotMatCalib := RotationMatrices[J * 9:J * 9 + 8] hom_mat2d_compose (RotMatCalib, RotMat, RotMatRot) RotMats := [RotMats,RotMatRot] endfor dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating spherical mosaic of the original images...') * Create the spherical mosaic of the original images. gen_spherical_mosaic (Images, SphericalMosaicOrig, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'voronoi', 'bilinear') get_image_size (SphericalMosaicOrig, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicOrig) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Spherical mosaic of the original images') set_tposition (WindowHandle, Height - 150, 20) write_string (WindowHandle, 'Press \'Run\' to continue') stop () dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating spherical mosaic of the radiometrically adjusted images...') * Create the spherical mosaic of the radiometrically adjusted images. gen_spherical_mosaic (CorrectedImages, SphericalMosaicAdjust, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'voronoi', 'bilinear') get_image_size (SphericalMosaicAdjust, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicAdjust) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Spherical mosaic of the radiometrically adjusted images') set_tposition (WindowHandle, Height - 150, 20) write_string (WindowHandle, 'Press \'Run\' to continue') stop () dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating blended spherical mosaic of the radiometrically adjusted images...') * Create the blended spherical mosaic of the radiometrically adjusted images. gen_spherical_mosaic (CorrectedImages, SphericalMosaicAdjustBlend, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'blend', 'bilinear') get_image_size (SphericalMosaicAdjustBlend, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicAdjustBlend) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Blended spherical mosaic of the radiometrically adjusted images')

以下代码实现的功能,代码中所有信号的在代码中起到什么作用,代码是否具有普适性 ------------------------------------------------------------------------- -- This confidential and proprietary software_information may be used -- -- only as authorized by a licensing agreement for OCAM Limited -- -- (c) COPYRIGHT 2017-2020 OCAM Limited -- -- ALL RIGHTS RESERVED -- -- The entire notice above must be reproduced on all authorizd copies -- -- and copies may be made to the extent permitted by a licensing -- -- agreement from OCAM Limited. -- ------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; ------------------------------------------------------------------------------------------------------------------------ entity idream_axis_csc_96_64_module is generic(ppc_byten :integer :=16; axi_byten :integer :=12); port( reset : in std_logic; clk_axi : in std_logic; clk_o : in std_logic; vs_in : in std_logic; en_in : in std_logic; Vheight : in std_logic_vector(15 downto 0); row_size : in std_logic_vector(15 downto 0); --for axis m0_axis_tdata : in std_logic_vector(axi_byten*8-1 downto 0); m0_axis_tlast : in std_logic; m0_axis_tready : out std_logic; m0_axis_tstrb : in std_logic_vector(axi_byten-1 downto 0); m0_axis_tuser : in std_logic; m0_axis_tvalid : in std_logic; m1_axis_tdata : in std_logic_vector(axi_byten*8-1 downto 0); m1_axis_tlast : in std_logic; m1_axis_tready : out std_logic; m1_axis_tstrb : in std_logic_vector(axi_byten-1 downto 0); m1_axis_tuser : in std_logic; m1_axis_tvalid : in std_logic; --vp in m_axis_tdata : out std_logic_vector(ppc_byten*8-1 downto 0); m_axis_tlast : out std_logic; m_axis_tready : in std_logic; m_axis_tstrb : out std_logic_vector(ppc_byten-1 downto 0); m_axis_tuser : out std_logic; m_axis_tvalid : out std_logic ); end entity; architecture RTL of idream_axis_csc_96_64_module is ------------------------------------------------------------------------------------------------------------------ component idream_bitwidth_simple_module is generic(bit_i :integer :=12; bit_o :integer :=64; par_i :integer :=16 ;--delay par_i+2 clks par_o :integer :=3; mux_i :integer :=192 ); port( reset : in std_logic; clk : in std_logic; pv_in : in std_logic; en_in : in std_logic; data_in : in std_logic_vector(bit_i-1 downto 0); --ddr_bus pv_out : out std_logic; en_out : out std_logic; data_out : out std_logic_vector(bit_o-1 downto 0) ); end component; ------------------------------------------------------------------------------------------------------------------ component idream_axis_csc_read_module is generic(ppc_byten :integer :=8); port( reset : in std_logic; vs_in : in std_logic; write_size : in std_logic_vector(31 downto 0); dbg_fsm : in std_logic_vector(3 downto 0); --for axis clk_o : in std_logic; m_axis_tdata : out std_logic_vector(ppc_byten*8-1 downto 0); m_axis_tlast : out std_logic; m_axis_tready : in std_logic; m_axis_tstrb : out std_logic_vector(ppc_byten-1 downto 0); m_axis_tuser : out std_logic; m_axis_tvalid : out std_logic; --vp in clk_i : in std_logic; ram_wraddr : in std_logic_vector(15 downto 0); ram_wrdata : in std_logic_vector(127 downto 0); ram_wren : in std_logic; ready_en : in std_logic; busy_en : in std_logic; read_size : out std_logic_vector(31 downto 0); frame_size : in std_logic_vector(31 downto 0) ); end component; ------------------------------------------------------------------------------------------------------------------ component ila_axis is port( clk : in std_logic; probe0 : in std_logic_vector(127 downto 0); probe1 : in std_logic_vector(35 downto 0); probe2 : in std_logic_vector(0 downto 0); probe3 : in std_logic_vector(0 downto 0); probe4 : in std_logic_vector(0 downto 0); probe5 : in std_logic_vector(0 downto 0) ); end component; --------------------------------------------------------------------------------------------------- component vio_aux is port( clk : in std_logic; probe_out0 : out std_logic_vector(0 downto 0); probe_out1 : out std_logic_vector(15 downto 0) ); end component; -------------------------------------------------------------------------------------------- constant idle_status : std_logic_vector(3 downto 0):=x"0"; constant start0_status : std_logic_vector(3 downto 0):=x"1"; constant trans0_status : std_logic_vector(3 downto 0):=x"2"; constant stop_status : std_logic_vector(3 downto 0):=x"3"; constant wait_status : std_logic_vector(3 downto 0):=x"4"; constant start1_status : std_logic_vector(3 downto 0):=x"5"; constant trans1_status : std_logic_vector(3 downto 0):=x"6"; signal transmit_FSM,next_FSM : std_logic_vector(3 downto 0):=x"0"; signal width_byte : std_logic_vector(15 downto 0):=x"0A08";--856*3 signal vs_delay,en_delay : std_logic_vector(3 downto 0):=(others=>'0'); signal one_shot,one_wren : std_logic_vector(1 downto 0):=(others=>'0'); signal axis0_tready,axis1_tready,busy_en,ready_en : std_logic:='0'; signal ram_wren,ram_wren_d,ram_wren_c,ram_wrlast,col_en : std_logic:='0'; signal ram_wraddr,col_cnt : std_logic_vector(15 downto 0):=(others=>'0'); signal ram_wrdata,ram_wrdata0,ram_wrdata1,one_wrdata0,one_wrdata1,dbg_data,ram_wrdata_d : std_logic_vector(axi_byten*8-1 downto 0):=(others=>'0'); signal ram_wrdata_c : std_logic_vector(127 downto 0):=(others=>'0'); signal sub_num : std_logic_vector(3 downto 0):=(others=>'0'); signal read_size,write_size,frame_size : std_logic_vector(31 downto 0):=(others=>'0'); -------------------------------------------------------------------------------------------- begin m0_axis_tready <= axis0_tready; m1_axis_tready <= axis1_tready; width_byte <= row_size; frame_size <= Vheight * width_byte; ram_wrdata0 <= m0_axis_tdata(7+72 downto 0+72)&m0_axis_tdata(15+72 downto 8+72)&m0_axis_tdata(23+72 downto 16+72)& m0_axis_tdata(7+48 downto 0+48)&m0_axis_tdata(15+48 downto 8+48)&m0_axis_tdata(23+48 downto 16+48)& m0_axis_tdata(7+24 downto 0+24)&m0_axis_tdata(15+24 downto 8+24)&m0_axis_tdata(23+24 downto 16+24)& m0_axis_tdata(7 downto 0)&m0_axis_tdata(15 downto 8)&m0_axis_tdata(23 downto 16); ram_wrdata1 <= m1_axis_tdata(7+72 downto 0+72)&m1_axis_tdata(15+72 downto 8+72)&m1_axis_tdata(23+72 downto 16+72)& m1_axis_tdata(7+48 downto 0+48)&m1_axis_tdata(15+48 downto 8+48)&m1_axis_tdata(23+48 downto 16+48)& m1_axis_tdata(7+24 downto 0+24)&m1_axis_tdata(15+24 downto 8+24)&m1_axis_tdata(23+24 downto 16+24)& m1_axis_tdata(7 downto 0)&m1_axis_tdata(15 downto 8)&m1_axis_tdata(23 downto 16); ------------------------------------------------------------------------------------------------------------------ --FSM process(clk_axi,reset) begin if(reset='1') then transmit_FSM <= idle_status; elsif(clk_axi'event and clk_axi='1') then case transmit_FSM is when idle_status => if(vs_delay(2)='0' and vs_delay(3)='1') then transmit_FSM <= start0_status; else null; end if; when start0_status => next_FSM <= start1_status; if(m0_axis_tuser='0') then transmit_FSM <= trans0_status; else null; end if; when start1_status => next_FSM <= trans1_status; if(m1_axis_tuser='0') then transmit_FSM <= trans1_status; else null; end if; when trans0_status => if(en_delay(2)='0' and en_delay(3)='1')or(m0_axis_tuser='1') then transmit_FSM <= wait_status; elsif(m0_axis_tlast='1' and axis0_tready='1') then transmit_FSM <= next_FSM; else null; end if; when trans1_status => if(en_delay(2)='0' and en_delay(3)='1')or(m1_axis_tuser='1') then transmit_FSM <= wait_status; elsif(m1_axis_tlast='1' and axis1_tready='1') then transmit_FSM <= trans0_status; else null; end if; when wait_status => if(m0_axis_tuser='1' and m1_axis_tuser='1') then transmit_FSM <= stop_status; else null; end if; when stop_status => if(vs_delay(2)='1' and vs_delay(3)='0') then transmit_FSM <= idle_status; else null; end if; when others => transmit_FSM <= idle_status; end case; else null; end if; end process; ------------------------------------------------------------------------------------------------------------------ --data process(clk_axi) begin if(clk_axi'event and clk_axi='1') then case transmit_FSM is when idle_status => axis0_tready <= '0'; axis1_tready <= '0'; one_wren <= "00"; busy_en <= '0'; when start0_status => busy_en <= '1'; one_shot(0) <= '0'; one_wren(0) <= one_shot(0); axis0_tready <= m0_axis_tuser; if(one_shot(0)='1') then ram_wrdata <= one_wrdata0; else ram_wrdata <= ram_wrdata0; end if; when start1_status => one_shot(1) <= '0'; one_wren(1) <= one_shot(1); axis1_tready <= m1_axis_tuser; if(one_shot(1)='1') then ram_wrdata <= one_wrdata1; else ram_wrdata <= ram_wrdata1; end if; when trans0_status => axis1_tready <= m0_axis_tlast and (not m1_axis_tuser) and axis0_tready; ram_wrdata <= ram_wrdata0; if(sub_num>=6)or(m0_axis_tlast='1' and axis0_tready='1') then axis0_tready <= '0'; else axis0_tready <= not m0_axis_tuser; end if; if(m0_axis_tuser='1' and m0_axis_tvalid='1' and axis0_tready='1') then one_shot(0) <= '1'; else null; end if; when trans1_status => axis0_tready <= m1_axis_tlast and (not m0_axis_tuser) and axis1_tready; ram_wrdata <= ram_wrdata1; if(sub_num>=6)or(m1_axis_tlast='1' and axis1_tready='1') then axis1_tready <= '0'; else axis1_tready <= not m1_axis_tuser; end if; if(m1_axis_tuser='1' and m1_axis_tvalid='1' and axis1_tready='1') then one_shot(1) <= '1'; else null; end if; when wait_status => axis0_tready <= not m0_axis_tuser; axis1_tready <= not m1_axis_tuser; if(m0_axis_tuser='1' and m0_axis_tvalid='1' and axis0_tready='1') then one_shot(0) <= '1'; else null; end if; if(m1_axis_tuser='1' and m1_axis_tvalid='1' and axis1_tready='1') then one_shot(1) <= '1'; else null; end if; when stop_status => axis0_tready <= '0'; axis1_tready <= '0'; when others => null; end case; else null; end if; end process; ------------------------------------------------------------------------------------------------------------------ process(clk_axi) begin if(clk_axi'event and clk_axi='1') then vs_delay <= vs_delay(2 downto 0)&vs_in; en_delay <= en_delay(2 downto 0)&en_in; if((transmit_FSM=trans0_status or transmit_FSM=wait_status)and m0_axis_tuser='1' and m0_axis_tvalid='1' and axis0_tready='1')or((transmit_FSM=trans1_status or transmit_FSM=wait_status) and m1_axis_tuser='1' and m1_axis_tvalid='1' and axis1_tready='1') then ram_wren <= '0'; else ram_wren <= ((m0_axis_tvalid and axis0_tready) or one_wren(0))or((m1_axis_tvalid and axis1_tready) or one_wren(1)); end if; ram_wrlast <= (m0_axis_tlast and axis0_tready and m0_axis_tvalid)or(m1_axis_tlast and axis1_tready and m1_axis_tvalid); if(busy_en='0')or(ram_wrlast='1') then col_cnt <= (others=>'0'); elsif(ram_wren='1') then col_cnt <= col_cnt + conv_std_logic_vector(axi_byten,8); else null; end if; if(busy_en='0')or(ram_wrlast='1') then col_en <= '1'; elsif(col_cnt>=width_byte-axi_byten and ram_wren='1') then col_en <= '0'; else null; end if; if(m0_axis_tvalid='1' and axis0_tready='1') then one_wrdata0 <= ram_wrdata0; else null; end if; if(m1_axis_tvalid='1' and axis1_tready='1') then one_wrdata1 <= ram_wrdata1; else null; end if; if(busy_en='0') then ram_wraddr <= (others=>'0'); elsif(ram_wren_c='1') then ram_wraddr <= ram_wraddr +'1'; else null; end if; if(busy_en='0') then write_size <= (others=>'0'); elsif(ram_wren='1' and col_en='1') then write_size <= write_size + conv_std_logic_vector(axi_byten,8); else null; end if; if(busy_en='0') then for i in 0 to axi_byten/2-1 loop dbg_data(16*i+15 downto 16*i) <= conv_std_logic_vector(i,16); end loop; elsif(ram_wren_d='1') then for i in 0 to axi_byten/2-1 loop dbg_data(16*i+15 downto 16*i) <= dbg_data(16*i+15 downto 16*i) + conv_std_logic_vector(axi_byten/2,8); end loop; else null; end if; sub_num <= write_size(13 downto 10) - read_size(13 downto 10);--when (32/8)*byte_n*512/8=1024,set 13 downto 10 if(sub_num>1)or(write_size>=frame_size)or(transmit_FSM=wait_status) then ready_en <= busy_en; else ready_en <= '0'; end if; ram_wren_d <= ram_wren and col_en; ram_wrdata_d <= ram_wrdata; else null; end if; end process; ------------------------------------------------------------------------------------------------------------------ --uila_axis : ila_axis -- port map( -- clk => clk_axi , -- probe0 => ram_wrdata_c , -- probe1 => write_size(26 downto 0) & transmit_FSM & ram_wren_c & col_en & en_in & ram_wren & m_axis_err, -- probe2(0) => axis0_tready , -- probe3(0) => m0_axis_tlast , -- probe4(0) => m0_axis_tuser , -- probe5(0) => m0_axis_tvalid -- ); ------------------------------------------------------------------------------------------------------------------ uidream_bitwidth_simple_module : idream_bitwidth_simple_module generic map(bit_i => 96 , bit_o => 128 , par_i => 4 ,--delay par_i+2 clks par_o => 3 , mux_i => 384 ) port map( reset => reset , clk => clk_axi , pv_in => ram_wren_d , en_in => busy_en , data_in => ram_wrdata_d ,--dbg_data ram_wrdata_d --ddr_bus pv_out => ram_wren_c , en_out => open , data_out => ram_wrdata_c ); ------------------------------------------------------------------------------------------------------------------ uidream_axis_csc_read_module : idream_axis_csc_read_module generic map(ppc_byten => ppc_byten) port map( reset => reset , vs_in => vs_in , write_size => write_size , dbg_fsm => transmit_FSM , --for axis clk_o => clk_o , m_axis_tdata => m_axis_tdata , m_axis_tlast => m_axis_tlast , m_axis_tready => m_axis_tready , m_axis_tstrb => m_axis_tstrb , m_axis_tuser => m_axis_tuser , m_axis_tvalid => m_axis_tvalid , --vp in clk_i => clk_axi , ram_wraddr => ram_wraddr , ram_wrdata => ram_wrdata_c , ram_wren => ram_wren_c , ready_en => ready_en , busy_en => busy_en , read_size => read_size , frame_size => frame_size ); ----------------------------------------------------------------------------------------------------------------- end RTL;

#define LED_PIN P1_6 #define STEP_A_PIN P3_5 #define STEP_B_PIN P3_4 #define STEP_C_PIN P3_3 #define STEP_D_PIN P3_2 #define RS_485_PIN P5_4 #define BUTTON_PIN P1_7 #define LIMIT_UP_PIN P3_7 #define LIMIT_DOWN_PIN P3_6 #define ModBus_Master_UART UART_1 #include <STC8HX.h> uint32 sys_clk = 33000000;//设置PWM、定时器、串口、EEPROM频率参数 #include "mylib/MB_Master.h" void MotorControl(); void ButtonScan(); void ProcessButton(); void CheckLimits(); // 全局变量 volatile SystemState gSystemState = SYS_STATE_INIT; // 系统状态 volatile MotorState gMotorState = MOTOR_STATE_STOP; // 电机状态 volatile unsigned char gStepIndex = 0; // 步进序列索引 volatile unsigned int gCurrentPosition = 0; // 当前位置 volatile unsigned int gTargetPosition = 0; // 目标位置 volatile unsigned int gStepDelay = 5; // 步进延时(ms) volatile unsigned int gSystemTimer = 0; // 系统计时器 volatile unsigned int gButtonTimer = 0; // 按钮计时器 volatile unsigned char gButtonPressCount = 0; // 按钮按下次数 volatile bit gButtonState = 0; // 按钮状态 volatile bit gButtonLastState = 0; // 按钮上次状态 volatile unsigned char gModbusAddress = 0x01; // Modbus地址 volatile unsigned int gStroke = 1000; // 行程步数 volatile unsigned int gDecelDistance = 50; // 减速距离 // 系统状态定义 typedef enum { SYS_STATE_INIT = 0, // 初始化状态 SYS_STATE_IDLE = 1, // 空闲状态 SYS_STATE_WORK = 2, // 工作状态 SYS_STATE_CONFIG = 3, // 配置状态 SYS_STATE_TEST = 4, // 测试状态 SYS_STATE_ERROR = 5, // 错误状态 } SystemState; // 函数声明 void SystemInit(void); void MotorControl(void); void ButtonScan(void); void ProcessButton(void); void ModbusPoll(void); void SavePositionToEeprom(void); void LoadPositionFromEeprom(void); void MoveToTarget(void); void CheckLimits(void); void SetLedState(unsigned char state, unsigned int blinkRate); while(1) { ButtonScan(); // 扫描按钮 ProcessButton(); // 处理按钮事件 CheckLimits(); // 检查限位开关 ModbusPoll(); // 处理Modbus通信 // 根据系统状态执行不同操作 switch(gSystemState) { case SYS_STATE_INIT: // 初始化状态,等待到达上限位 if(gMotorState == MOTOR_STATE_STOP && LIMIT_UP_PIN == 0) { gSystemState = SYS_STATE_IDLE; gCurrentPosition = 0; SavePositionToEeprom(); SetLedState(0, 0); // LED常亮表示就绪 } /*步进电机控制 */ void MotorControl(){ static unsigned int stepTimer = 0; if(gMotorState != MOTOR_STATE_STOP){ if(gSystemTimer - stepTimer > gStepDelay){ stepTimer = gSystemTimer if(gCurrentPosition > gTargetPosition && gCurrentPosition - gTargetPosition < gDecelDistance){ gStepDelay = 10; // 减速 } else{ if(gCurrentPosition < gTargetPosition && gTargetPosition - gCurrentPosition < gDecelDistance){ gStepDelay = 10; // 减速 } else{ gStepDelay = 5; // 正常速度 } } } if(gMotorState == MOTOR_STATE_FWD){ gStepIndex = (gStepIndex + 1) % 8; gCurrentPosition++; P3 = (P3 & 0xE0) | stepTable[gStepIndex];// 正转控制 } else{ gStepIndex = (gStepIndex + 7) % 8; gCurrentPosition--; P3 = (P3 & 0xE0) | stepTable[gStepIndex];// 反转控制 } if((gMotorState == MOTOR_STATE_FWD && gCurrentPosition >= gTargetPosition) || (gMotorState == MOTOR_STATE_REV && gCurrentPosition <= gTargetPosition)){ gMotorState = MOTOR_STATE_STOP; P1 = (P1 & 0xE0); // 关闭所有步进相 SavePositionToEeprom(); } } } /*按钮扫描 */ void ButtonScan(){ static unsigned int debounceTimer = 0; if(gSystemTimer - debounceTimer > 20){ debounceTimer = gSystemTimer; gButtonLastState = gButtonState; gButtonState = BUTTON_PIN; if(gButtonState == 0 && gButtonLastState == 1){ gButtonPressCount++; gButtonTimer = gSystemTimer; } if(gButtonState == 0 && gSystemTimer - gButtonTimer > 3000){ // 长按3秒,恢复出厂设置 gButtonPressCount = 0; } } } /* 处理按钮事件 */ void ProcessButton(){ if(gButtonPressCount > 0 && gSystemTimer - gButtonTimer > 500){ switch(gButtonPressCount) { case 1: // 短按1次 - 切换工作/自动配置模式 if(gSystemState == SYS_STATE_WORK) { gSystemState = SYS_STATE_CONFIG; SetLedState(1, 1000); // LED慢闪表示配置模式 } else { gSystemState = SYS_STATE_WORK; SetLedState(0, 0); // LED常亮表示工作模式 } break; case 2: // 短按2次 - 进入测试模式 gSystemState = SYS_STATE_TEST; SetLedState(1, 300); // LED中速闪烁表示测试模式 break; case 3: // 短按3次 - 电机正转(向上) if(gSystemState == SYS_STATE_WORK || gSystemState == SYS_STATE_TEST) { if(gMotorState == MOTOR_STATE_STOP) { gTargetPosition = 0; // 目标是上限位 gMotorState = MOTOR_STATE_FWD; } else if(gMotorState == MOTOR_STATE_FWD) { gMotorState = MOTOR_STATE_STOP; } } break; case 4: // 短按4次 - 电机反转(向下) if(gSystemState == SYS_STATE_WORK || gSystemState == SYS_STATE_TEST) { if(gMotorState == MOTOR_STATE_STOP) { gTargetPosition = gStroke; // 目标是下限位 gMotorState = MOTOR_STATE_REV; } else if(gMotorState == MOTOR_STATE_REV) { gMotorState = MOTOR_STATE_STOP; } } break; } gButtonPressCount = 0; } } // 定时器0中断服务函数 (系统时基) void Timer0_ISR(void) interrupt 1 { // 重新加载初值 TH0 = 0xFC; TL0 = 0x66; gSystemTimer++; // 系统计时器递增 MotorControl(); // 步进电机控制 } // 保存位置到EEPROM void SavePositionToEeprom(void) { // EEPROM写入代码 // 此处省略具体实现 } // 从EEPROM加载位置 void LoadPositionFromEeprom(void) { // EEPROM读取代码 // 此处省略具体实现 } // Modbus轮询处理 void ModbusPoll(void) { // Modbus通信处理代码 // 此处省略具体实现 } /*/检查限位开关 */ void CheckLimits(){ if(LIMIT_UP_PIN == 0 && gMotorState == MOTOR_STATE_FWD){ gCurrentPosition = 0; gMotorState = MOTOR_STATE_STOP; P3 = (P3 & 0xE0); // 关闭所有步进相 SavePositionToEeprom(); } if(LIMIT_DOWN_PIN == 0 && gMotorState == MOTOR_STATE_REV){ gCurrentPosition = gStroke; gMotorState = MOTOR_STATE_STOP; P3 = (P3 & 0xE0); // 关闭所有步进相 SavePositionToEeprom(); } } // 设置LED状态 void SetLedState(unsigned char blink, unsigned int blinkRate) { static unsigned int ledTimer = 0; static bit ledState = 0; if(blink) { if(gSystemTimer - ledTimer > blinkRate) { ledTimer = gSystemTimer; ledState = !ledState; LED_PIN = ledState; } } else { LED_PIN = 0; // 常亮 } } // 主函数 void main(void) { SystemInit(); // 系统初始化 // 初始化位置到上限位 gSystemState = SYS_STATE_INIT; SetLedState(1, 500); // LED快闪表示初始化 // 读取保存的位置 LoadPositionFromEeprom(); // 移动到上限位 gTargetPosition = 0; gMotorState = MOTOR_STATE_FWD; // 主循环 while(1) { ButtonScan(); // 扫描按钮 ProcessButton(); // 处理按钮事件 CheckLimits(); // 检查限位开关 ModbusPoll(); // 处理Modbus通信 // 根据系统状态执行不同操作 switch(gSystemState) { case SYS_STATE_INIT: // 初始化状态,等待到达上限位 if(gMotorState == MOTOR_STATE_STOP && LIMIT_UP_PIN == 0) { gSystemState = SYS_STATE_IDLE; gCurrentPosition = 0; SavePositionToEeprom(); SetLedState(0, 0); // LED常亮表示就绪 } break; case SYS_STATE_WORK: // 工作状态,处理位置控制 MoveToTarget(); break; case SYS_STATE_CONFIG: // 配置状态,处理自动地址分配 // 此处省略自动地址分配逻辑 break; case SYS_STATE_TEST: // 测试状态,处理电机测试 break; case SYS_STATE_ERROR: // 错误状态,闪烁LED报警 SetLedState(1, 200); break; } // 延时一小段时间 _nop_(); _nop_(); } } void setup() { P3M1&=~0x20;P3M0|=0x20;//推挽输出 P3M1&=~0x10;P3M0|=0x10;//推挽输出 P3M1&=~0x08;P3M0|=0x08;//推挽输出 P3M1&=~0x04;P3M0|=0x04;//推挽输出 P5M1&=~0x10;P5M0|=0x10;//推挽输出 P3M1|=0x80;P3M0&=~0x80;//高阻输入 P3M1|=0x40;P3M0&=~0x40;//高阻输入 P3 = 0x00; //步进电机初始为0 LED_PIN = 0; //LED初始熄灭 TMOD = 0xF0; TH0 = 0xFC; TL0 = 0x66; EA = 1; // 控制总中断 ET0 = 1; // 控制定时器中断 TR0 = 1;// 定时器0开始计时 } void loop() { MBMasterInit(UART_1, UART1_RX_P30, UART1_TX_P31, 9600, TIM_1, MB_M_PAR_NONE); } void main(void) { setup(); while(1){ loop(); } } 根据以上代码加一个自动配置模式,以及不使用modbus分配地址,通过有没有接收到信号来分配地址,做一个3次检测防止误检测;检测到信号后第一个设备分配地址为1,后面设备地址依次加1;如果没有检测到信号能发出一个值来代表等待分配地址,超过检测3次没有检测到信号则是强制给第一个设备分配为1,后面设备地址依次加1,一直分配设备结束为止,以及加上一个步进电机运动过程中能够手动按下刹车,按键只有程序中出现的一个,以现有的功能加上上述文字描述的功能

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ FMAC_HandleTypeDef hfmac; DMA_HandleTypeDef handle_GPDMA1_Channel1; /* USER CODE BEGIN PV */ /* FMAC configuration structure */ FMAC_FilterConfigTypeDef sFmacConfig; /* Array of filter coefficients A (feedback coefficients) in Q1.15 format */ static int16_t aFilterCoeffA[COEFF_VECTOR_A_SIZE] = { 10432,-17296, 17696,-12512, 5536, -1296 }; /* Array of filter coefficients B (feed-forward taps) in Q1.15 format */ static int16_t aFilterCoeffB[COEFF_VECTOR_B_SIZE] = { 828, 1170, 2360, 2293, 2360, 1170, 828 }; /* Array of input values in Q1.15 format */ static int16_t aInputValues[ARRAY_SIZE] = { 0, 660, -194, 1731, 1, 2194, 725, 2018, 1775, 1501, 2703, 1085, 3072, 1084, 2701, 1499, 1772, 2014, 721, 2189, -5, 1725, -200, 653, -6, -666, 187, -1737, -7, -2199, -730, -2022, -1778, -1504, -2705, -1086, -3072, -1083, -2700, -1496, -1768, -2010, -716, -2184, 10, -1719, 206, -647, 13, 672, -181, 1742, 12, 2204, 734, 2026, 1781, 1506, 2706, 1086, 3072, 1082, 2698, 1494, 1765, 2006, 712, 2179, -16, 1713, -212, 640, -19, -679, 175, -1748, -18, -2209, -739, -2030, -1784, -1509, -2708, -1087, -3072, -1081, -2696, -1491, -1762, -2002, -707, -2173, 21, -1707, 218, -634, 26, 685, -169, 1754, 23, 2214, 743, 2033, 1787, 1511, 2710, 1088, 3072, 1080, 2695, 1489, 1758, 1998, 702, 2168, -27, 1701, -225, 628, -32, -691, 163, -1760, -29, -2219, -748, -2037, -1791, -1513, -2711, -1089, -3072, -1080, -2693, -1486, -1755, -1994, -698, -2163, 33, -1695, 231, -621, 39, 698, -156, 1766, 34, 2224, 752, 2041, 1794, 1516, 2713, 1089, 3072, 1079, 2691, 1484, 1752, 1990, 693, 2158, -38, 1689, -237, 615, -45, -704, 150, -1772, -40, -2229, -757, -2045, -1797, -1518, -2714, -1090, -3071, -1078, -2689, -1481, -1749, -1986, -688, -2153, 44, -1683, 243, -608, 52, 710, -144, 1778, 45, 2234, 761, 2049, 1800, 1520, 2716, 1091, 3071, 1077, 2687, 1478, 1745, 1982, 684, 2148, -50, 1677, -250, 602, -58, -717, 138, -1784, -51, -2239, -766, -2052, -1803, -1523, -2717, -1092, -3071, -1076, -2686, -1476, -1742, -1978, -679, -2142, 55, -1671, 256, -596, 64, 723, -132, 1790, 56, 2244, 770, 2056, 1806, 1525, 2719, 1092, 3071, 1075, 2684, 1473 }; /* Array of output data to preload in Q1.15 format */ static int16_t aOutputDataToPreload[COEFF_VECTOR_A_SIZE] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; /* Array of calculated filtered data in Q1.15 format */ static int16_t aCalculatedFilteredData[ARRAY_SIZE]; /* Expected number of calculated samples */ uint16_t ExpectedCalculatedOutputSize = MEMORY_PARAMETER_D2; /* Status of the FMAC callbacks */ __IO uint32_t HalfOutputDataReadyCallback = CALLBACK_NOT_CALLED; __IO uint32_t OutputDataReadyCallback = CALLBACK_NOT_CALLED; __IO uint32_t ErrorCount = 0; /* Array of reference filtered data for IIR "7 feed-forward taps, 6 feedback coefficients, gain = 1" in Q1.15 format */ static const int16_t aRefFilteredData[ARRAY_SIZE] = { 0x01c6, 0x0403, 0x03a5, 0x03e6, 0x05b0, 0x0588, 0x051d, 0x0664, 0x06c7, 0x057a, 0x0631, 0x06c8, 0x0539, 0x0500, 0x05a5, 0x0453, 0x02f5, 0x03b2, 0x02a0, 0x00b3, 0x00fe, 0x008c, 0xfe75, 0xfe03, 0xfe6e, 0xfc64, 0xfb84, 0xfc4c, 0xfb0a, 0xf9ba, 0xfa9c, 0xfa87, 0xf8df, 0xf9d2, 0xfaa0, 0xf95d, 0xf9da, 0xfb7d, 0xfaf9, 0xfac9, 0xfd0d, 0xfd3b, 0xfcc5, 0xfecf, 0xfffd, 0xff53, 0x00ae, 0x02be, 0x01f7, 0x029c, 0x04cb, 0x0487, 0x041b, 0x0609, 0x066e, 0x0504, 0x0663, 0x0722, 0x0576, 0x0598, 0x06be, 0x0521, 0x03f7, 0x0544, 0x03f1, 0x01fe, 0x02b2, 0x0246, 0xffbf, 0xffb1, 0x0031, 0xfd99, 0xfcdc, 0xfdc8, 0xfc12, 0xfa6f, 0xfbac, 0xfb1e, 0xf8f9, 0xfa31, 0xfaba, 0xf8e4, 0xf963, 0xfb2a, 0xf9ea, 0xf9ac, 0xfc34, 0xfbdb, 0xfb28, 0xfd85, 0xfe95, 0xfd63, 0xff3a, 0x0162, 0x0027, 0x011e, 0x03b3, 0x032b, 0x02bf, 0x056e, 0x05a2, 0x0426, 0x0638, 0x071b, 0x0536, 0x05d6, 0x0788, 0x057c, 0x04b2, 0x0696, 0x04fd, 0x0307, 0x0458, 0x03e4, 0x00e7, 0x0179, 0x0201, 0xfede, 0xfe5d, 0xff91, 0xfd45, 0xfb6b, 0xfd2c, 0xfbff, 0xf96e, 0xfb01, 0xfb45, 0xf8b6, 0xf963, 0xfb49, 0xf91d, 0xf8f0, 0xfbb9, 0xfabb, 0xf9b5, 0xfc8b, 0xfd49, 0xfb76, 0xfdeb, 0x0004, 0xfe37, 0xff85, 0x028d, 0x017c, 0x0122, 0x04a4, 0x046f, 0x02e1, 0x05bb, 0x06b8, 0x046c, 0x05c4, 0x07f7, 0x0556, 0x0516, 0x07a2, 0x05ae, 0x03b5, 0x05e6, 0x0542, 0x01d6, 0x0342, 0x03c8, 0x0010, 0xfff2, 0x0195, 0xfe7f, 0xfca1, 0xff07, 0xfd19, 0xfa2a, 0xfc41, 0xfc38, 0xf8c9, 0xf9e7, 0xfbd7, 0xf89e, 0xf8a2, 0xfbb2, 0xf9e3, 0xf881, 0xfc01, 0xfc27, 0xf9a9, 0xfcd9, 0xfec2, 0xfc37, 0xfdf0, 0x0173, 0xff87, 0xff61, 0x03bb, 0x02e9, 0x0141, 0x0506, 0x05fc, 0x031a, 0x056e, 0x0801, 0x04ab, 0x051b, 0x0864, 0x05e5, 0x03f9, 0x074f, 0x0640, 0x0277, 0x04f3, 0x0570, 0x0109, 0x018d, 0x03b9, 0xff9d, 0xfe01, 0x0128, 0xfe56, 0xfb14, 0xfdf5, 0xfd7c, 0xf90e, 0xfaf7, 0xfccf, 0xf864, 0xf8c4, 0xfc36, 0xf94a, 0xf79e, 0xfc01, 0xfb37, 0xf810, 0xfc24, 0xfdb8, 0xfa2e, 0xfc8d, 0x0081, 0xfd5b, 0xfd9c, 0x02d3, 0x0120, 0xff50, 0x043e, 0x04e9, 0x0148, 0x04e8, 0x07af, 0x0377, 0x04c1, 0x08e7, 0x058c, 0x03d3, 0x088c, 0x06c6, 0x02b3, 0x0682, 0x06e5, 0x019d }; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void SystemPower_Config(void); static void MX_GPDMA1_Init(void); static void MX_ICACHE_Init(void); static void MX_FMAC_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* STM32U5xx HAL library initialization: - Configure the Flash prefetch - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 3 - Low Level Initialization */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* Configure the System Power */ SystemPower_Config(); /* USER CODE BEGIN SysInit */ /* Configure LED1 */ BSP_LED_Init(LED1); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPDMA1_Init(); MX_ICACHE_Init(); MX_FMAC_Init(); /* USER CODE BEGIN 2 */ /*## Configure the FMAC peripheral ###########################################*/ sFmacConfig.InputBaseAddress = INPUT_BUFFER_BASE; sFmacConfig.InputBufferSize = INPUT_BUFFER_SIZE; sFmacConfig.InputThreshold = INPUT_THRESHOLD; sFmacConfig.CoeffBaseAddress = COEFFICIENT_BUFFER_BASE; sFmacConfig.CoeffBufferSize = COEFFICIENT_BUFFER_SIZE; sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE; sFmacConfig.OutputBufferSize = OUTPUT_BUFFER_SIZE; sFmacConfig.OutputThreshold = OUTPUT_THRESHOLD; sFmacConfig.pCoeffA = aFilterCoeffA; sFmacConfig.CoeffASize = COEFF_VECTOR_A_SIZE; sFmacConfig.pCoeffB = aFilterCoeffB; sFmacConfig.CoeffBSize = COEFF_VECTOR_B_SIZE; sFmacConfig.Filter = FMAC_FUNC_IIR_DIRECT_FORM_1; sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_POLLING; sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA; sFmacConfig.Clip = FMAC_CLIP_DISABLED; sFmacConfig.P = COEFF_VECTOR_B_SIZE; sFmacConfig.Q = COEFF_VECTOR_A_SIZE; sFmacConfig.R = GAIN; if (HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*## Preload the input and output buffers ####################################*/ if (HAL_FMAC_FilterPreload(&hfmac, aInputValues, INPUT_BUFFER_SIZE, aOutputDataToPreload, COEFF_VECTOR_A_SIZE) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*## Start calculation of IIR filter in polling/DMA mode #####################*/ if (HAL_FMAC_FilterStart(&hfmac, aCalculatedFilteredData, &ExpectedCalculatedOutputSize) != HAL_OK) { /* Processing Error */ Error_Handler(); } /*## Wait for the end of the handling (no new data written) #################*/ /* For simplicity reasons, this example is just waiting till the end of the calculation, but the application may perform other tasks while the operation is ongoing. */ while(HalfOutputDataReadyCallback == CALLBACK_NOT_CALLED) { } while(OutputDataReadyCallback == CALLBACK_NOT_CALLED) { } /*## Stop the calculation of IIR filter in polling/DMA mode ##################*/ if (HAL_FMAC_FilterStop(&hfmac) != HAL_OK) { /* Processing Error */ Error_Handler(); } /*## Check the final error status ############################################*/ if(ErrorCount != 0) { /* Processing Error */ Error_Handler(); } /*## Compare FMAC results to the reference values #####################*/ for (uint32_t i = 0; i < ExpectedCalculatedOutputSize; i++) { if (aCalculatedFilteredData[i] != aRefFilteredData[i]) { /* Processing Error */ Error_Handler(); } } /* There is no error in the output values: Turn LED1 on */ BSP_LED_On(LED1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 80; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_0; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { Error_Handler(); } } /** * @brief Power Configuration * @retval None */ static void SystemPower_Config(void) { /* * Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral */ HAL_PWREx_DisableUCPDDeadBattery(); /* * Switch to SMPS regulator instead of LDO */ if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN PWR */ /* USER CODE END PWR */ } /** * @brief FMAC Initialization Function * @param None * @retval None */ static void MX_FMAC_Init(void) { /* USER CODE BEGIN FMAC_Init 0 */ /* USER CODE END FMAC_Init 0 */ /* USER CODE BEGIN FMAC_Init 1 */ /* USER CODE END FMAC_Init 1 */ hfmac.Instance = FMAC; if (HAL_FMAC_Init(&hfmac) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN FMAC_Init 2 */ /* USER CODE END FMAC_Init 2 */ } /** * @brief GPDMA1 Initialization Function * @param None * @retval None */ static void MX_GPDMA1_Init(void) { /* USER CODE BEGIN GPDMA1_Init 0 */ /* USER CODE END GPDMA1_Init 0 */ /* Peripheral clock enable */ __HAL_RCC_GPDMA1_CLK_ENABLE(); /* GPDMA1 interrupt Init */ HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn); /* USER CODE BEGIN GPDMA1_Init 1 */ /* USER CODE END GPDMA1_Init 1 */ /* USER CODE BEGIN GPDMA1_Init 2 */ /* USER CODE END GPDMA1_Init 2 */ } /** * @brief ICACHE Initialization Function * @param None * @retval None */ static void MX_ICACHE_Init(void) { /* USER CODE BEGIN ICACHE_Init 0 */ /* USER CODE END ICACHE_Init 0 */ /* USER CODE BEGIN ICACHE_Init 1 */ /* USER CODE END ICACHE_Init 1 */ /** Enable instruction cache in 1-way (direct mapped cache) */ if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK) { Error_Handler(); } if (HAL_ICACHE_Enable() != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ICACHE_Init 2 */ /* USER CODE END ICACHE_Init 2 */ } /* USER CODE BEGIN 4 */ /** * @brief FMAC half output data ready callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) { HalfOutputDataReadyCallback = CALLBACK_CALLED; } /** * @brief FMAC output data ready callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) { OutputDataReadyCallback = CALLBACK_CALLED; } /** * @brief FMAC error callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac) { ErrorCount++; } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); /* LED1 is blinking */ BSP_LED_Toggle(LED1); HAL_Delay(500); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT *根据以上的代码,使用STM32U575,ADC单通道采集,FMAC使用FIR滤波器功能,如何设计出ADC采集数据,通过GPDMA1,FMAC处理数据的代码,现已通过stm32 cubemx配置好了GPDMA1,使用标准轮询模式。需要完整的源文件和头文件

#include <stdint.h> #include <stdbool.h> #include "hw_memmap.h" #include "debug.h" #include "gpio.h" #include "hw_i2c.h" #include "hw_types.h" #include "i2c.h" #include "pin_map.h" #include "sysctl.h" #include "systick.h" #include "interrupt.h" #include "uart.h" #include "hw_ints.h" #include "string.h" #include <stdio.h> #include <ctype.h> // ???????? #define SYSTICK_FREQUENCY 1000 // 1000Hz???? #define FLOW_FLASH_TIME1 1000 // 1????? #define FLOW_FLASH_TIME2 2000 // 2????? // I2C?????? #define TCA6424_I2CADDR 0x22 #define PCA9557_I2CADDR 0x18 // PCA9557????? #define PCA9557_INPUT 0x00 #define PCA9557_OUTPUT 0x01 #define PCA9557_POLINVERT 0x02 #define PCA9557_CONFIG 0x03 // TCA6424????? #define TCA6424_CONFIG_PORT0 0x0c #define TCA6424_CONFIG_PORT1 0x0d #define TCA6424_CONFIG_PORT2 0x0e #define TCA6424_INPUT_PORT0 0x00 #define TCA6424_INPUT_PORT1 0x01 #define TCA6424_INPUT_PORT2 0x02 #define TCA6424_OUTPUT_PORT0 0x04 #define TCA6424_OUTPUT_PORT1 0x05 #define TCA6424_OUTPUT_PORT2 0x06 #define MAX_RECEIVE_LEN 100 // ??????????? #define MAX_PARAMS 5 // ???? void UARTStringPut(const char *cMessage); void UARTStringPutNonBlocking(const char *cMessage); void Delay(uint32_t value); void S800_GPIO_Init(void); void S800_I2C0_Init(void); void S800_UART_Init(void); uint8_t I2C0_WriteByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t WriteData); uint8_t I2C0_ReadByte(uint8_t DevAddr, uint8_t RegAddr); void checkbutton(void); void start_up(void); void flow_display(void); void settime(uint8_t flash_place, bool direction); void display_time(uint8_t flash_place); void setdate(uint8_t flash_place, bool direction); void display_date(uint8_t flash_place); void setalarm(uint8_t flash_place, bool direction); void display_alarm(uint8_t flash_place); void date_transform(void); void year_cheak(void); void display_studentcode(void); void display_name(void); void order_process(char *cmassage); void separate_alpha_digit(char *str, char *digits); void cmd_proc(char *cmd); // ??????? volatile uint16_t systick_1ms_counter = 0, systick_10ms_counter = 0; volatile uint16_t systick_20ms_counter = 0, systick_100ms_counter = 0; volatile uint16_t systick_1s_counter = 0, systick_flash_counter = 0; volatile uint8_t systick_1ms_status = 0, systick_10ms_status = 0; volatile uint8_t systick_20ms_status = 0, systick_100ms_status = 0; volatile uint8_t systick_1s_status = 0; // ?????? volatile uint8_t flash_place = 0, flash_flag = 0, startup_flag = 0; uint8_t pos = 0; // ????? volatile uint16_t pos_flash_cnt = 0; // ???????? volatile uint16_t time_pos_flash_cnt = 0; volatile uint16_t date_pos_flash_cnt = 0; volatile uint16_t alarm_pos_flash_cnt = 0; volatile uint8_t state = 0, set_flag = 0; // ??????? volatile uint8_t uart_cmd_ready = 0; uint8_t setdate_flag = 0; uint8_t settime_flag = 0; uint8_t setalarm_flag = 0; uint8_t setdisplay_flag = 0; uint8_t setformat_flag = 0; uint8_t gettime_flag = 0; uint8_t getdate_flag = 0; uint8_t getalarm_flag = 0; uint8_t getdisplay_flag = 0; uint8_t getformat_flag = 0; uint8_t display_on = 1; // ???? uint32_t ui32SysClock; // ?????? (0-9, A-F) uint8_t seg7[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71}; uint8_t dis_pos[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};//????? uint8_t led7[] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // LED?? // ???? volatile uint8_t status_SW[8] = {0}, last_status_SW[8] = {0}; volatile uint8_t keyflag[8] = {0}, delayflag[8] = {0}; volatile uint16_t keydelay[8] = {0}; // ?????? uint8_t start_pos = 0; // ?????? uint8_t flow16[16] = {0}; // ?????? uint16_t flow_cnt = 0; // ???? uint16_t flow_flash_cnt = 0; // ??????? uint16_t flow_flash_time = FLOW_FLASH_TIME1; // ???? // ???? char receive_order[50]; // ????? char settime_order[9] = "T12:00:00"; char setalarmtime_order[9] = "A12:00:00"; char setdate_order[11] = "D2025-06-12"; char timestr[20]; char datestr[20]; char alarmstr[20]; // ???? uint8_t resetclock_flag = 0, help_flag = 0; // ???? volatile uint32_t second = 43200; // ??? (??12:00:00) char currenttime[] = "TIME12:00:00"; // ???? volatile uint32_t year = 2025, month = 6, day = 12, total_days = 164; char currentdate[] = "DATE2025-06-12"; uint16_t days_mon[13] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 365};//????????????? uint8_t time_flash[7] = {8, 7, 5, 4, 2, 1, 0}; // ?????? uint8_t date_flash[9] = {8, 7, 6, 5, 4, 3, 2, 1, 0}; // ?????? // ???? uint32_t alarm_time = 43500; // ???? (??12:05:00) char currentalarm[] = "ALARM12-05-00"; volatile uint16_t alarm_flash_cnt = 0; uint8_t alarm_pos = 0; volatile uint8_t alarm_ring_flag = 0; uint16_t ringtime = 0, ringcnt = 0; // ??? int main(void) { uint8_t j = 0; // ??????? ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480),20000000); // SysTick?????? SysTickPeriodSet(ui32SysClock / SYSTICK_FREQUENCY); SysTickEnable(); SysTickIntEnable(); // ????? S800_GPIO_Init(); S800_I2C0_Init(); S800_UART_Init(); // ???? IntEnable(INT_UART0); UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); IntMasterEnable(); // ?????? start_up(); // ??? while (1) { if (uart_cmd_ready) { uart_cmd_ready = 0; order_process(receive_order); cmd_proc(receive_order); } if (settime_flag) { settime_flag = 0; second=(settime_order[1]-'0')*36000+(settime_order[2]-'0')*3600+(settime_order[4]-'0')*600+(settime_order[5]-'0')*60+(settime_order[7]-'0')*10+(settime_order[8]-'0'); } if (setdate_flag) { setdate_flag = 0; year=(setdate_order[1]-'0')*1000+(setdate_order[2]-'0')*100+(setdate_order[3]-'0')*10+(setdate_order[4]-'0'); year=(year)%10000; month=(setdate_order[6]-'0')*10 + (setdate_order[7]-'0'); day=(setdate_order[9]-'0')*10+(setdate_order[10]-'0'); total_days=0; year_cheak(); for(;j<month;j++){ total_days+=days_mon[j]; } j=0; total_days+=day; total_days-=days_mon[month-1]; } if (setalarm_flag) { setalarm_flag = 0; alarm_time=(setalarmtime_order[1]-'0')*36000+(setalarmtime_order[2]-'0')*3600+(setalarmtime_order[4]-'0')*600+(setalarmtime_order[5]-'0')*60+(setalarmtime_order[7]-'0')*10+(setalarmtime_order[8]-'0'); alarm_time=alarm_time%86400; } if (gettime_flag) { gettime_flag = 0; UARTStringPutNonBlocking(timestr); UARTStringPutNonBlocking("\n"); } // ?????? if (getdate_flag) { getdate_flag = 0; UARTStringPutNonBlocking(datestr); UARTStringPutNonBlocking("\n"); } if (getalarm_flag) { getalarm_flag = 0; UARTStringPutNonBlocking(alarmstr); UARTStringPutNonBlocking("\n"); } if (getdisplay_flag) { if(display_on == 1){ UARTStringPutNonBlocking("ON\n"); } else UARTStringPutNonBlocking("OFF\n"); } if(getformat_flag) { } if (resetclock_flag) { resetclock_flag = 0; second = 43200; // ???? 12:00:00 alarm_time = 43500; // ???? 12:05:00 setformat_flag = 0; // ??? display_on = 1;// ?????? } if (help_flag) { help_flag = 0; UARTStringPut("INITCLOCK\nT12:30:00\nA12:30:00\nD2024-06-18\nGETTIME\nGETDATE\nGETALARM\n"); } // ????? switch (state) { case 0: // ???? if (keyflag[5]) { keyflag[5] = 0; flow_flash_time = (flow_flash_time == FLOW_FLASH_TIME1) ? FLOW_FLASH_TIME2 : FLOW_FLASH_TIME1; } flow_display(); break; case 1: // ????/?? if (set_flag == 0) { flash_place = 6; } else { flash_place %= 6; if (keyflag[3]) { // ?? keyflag[3] = 0; flash_place = (flash_place + 5) % 6; } if (keyflag[2]) { // ?? keyflag[2] = 0; flash_place = (flash_place + 1) % 6; } if (keyflag[6] || delayflag[6]) { // ?? keyflag[6] = delayflag[6] = 0; settime(flash_place, 1); } if (keyflag[7] || delayflag[7]) { // ?? keyflag[7] = delayflag[7] = 0; settime(flash_place, 0); } } display_time(time_flash[flash_place]); break; case 2: // ????/?? if (set_flag == 0) { flash_place = 8; } else { flash_place %= 8; if (keyflag[3]) { // ?? keyflag[3] = 0; flash_place = (flash_place + 7) % 8; } if (keyflag[2]) { // ?? keyflag[2] = 0; flash_place = (flash_place + 1) % 8; } if (keyflag[6] || delayflag[6]) { // ?? keyflag[6] = delayflag[6] = 0; setdate(flash_place, 1); } if (keyflag[7] || delayflag[7]) { // ?? keyflag[7] = delayflag[7] = 0; setdate(flash_place, 0); } } display_date(date_flash[flash_place]); break; case 3: // ????/?? if (set_flag == 0) { flash_place = 6; } else { flash_place %= 6; if (keyflag[3]) { // ?? keyflag[3] = 0; flash_place = (flash_place + 5) % 6; } if (keyflag[2]) { // ?? keyflag[2] = 0; flash_place = (flash_place + 1) % 6; } if (keyflag[6] || delayflag[6]) { // ?? keyflag[6] = delayflag[6] = 0; setalarm(flash_place, 1); } if (keyflag[7] || delayflag[7]) { // ?? keyflag[7] = delayflag[7] = 0; setalarm(flash_place, 0); } } display_alarm(time_flash[flash_place]); break; } // ???? if (second == alarm_time) { alarm_ring_flag = 1; state = 1; } if (alarm_ring_flag && systick_100ms_status) { systick_100ms_status = 0; if (++ringcnt >= 5) { ringcnt = 0; //GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_5, ~GPIOPinRead(GPIO_PORTK_BASE, GPIO_PIN_5)); } if (++ringtime >= 100 || keyflag[4]) { keyflag[4] = 0; alarm_ring_flag = 0; ringtime = 0; //GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_5, 0x00); } } } } // ???? void start_up(void) { uint8_t systick_500ms_counter = 0, flash_counter = 0; startup_flag = 1; // ?????? // 8????? while (flash_counter < 16) { if (systick_100ms_status) { systick_100ms_status = 0; if (++systick_500ms_counter >= 5) { systick_500ms_counter = 0; flash_counter++; } } // ??/???? if (flash_counter == 1) { I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0x00); // LED?? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0xFF); // ????? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, 0xFF); } if (flash_counter == 2) { I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0xFF); // LED?? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); // ????? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, 0xFF); } // ???? if ((flash_counter % 2 == 0) && (flash_counter >= 3) && (flash_counter <= 8)) { I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0x00); // LED?? display_studentcode(); } // ???? if ((flash_counter % 2 == 0) && (flash_counter >= 9)) { I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0x00); // LED?? display_name(); } // ????? if ((flash_counter % 2 == 1) && (flash_counter >= 3)) { I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0xFF); // LED?? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); // ????? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, 0xFF); } } I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0xFF); // LED?? startup_flag = 0; // ?????? } // ???? void settime(uint8_t flash_place, bool direction) { if (direction == 0) { // ?? switch (flash_place) { case 0: second = (second + 1) % 86400; break; case 1: second = (second + 10) % 86400; break; case 2: second = (second + 60) % 86400; break; case 3: second = (second + 600) % 86400; break; case 4: second = (second + 3600) % 86400; break; case 5: second = (second + 36000) % 86400; break; } } else { // ?? switch (flash_place) { case 0: second = (second + 86399) % 86400; break; case 1: second = (second + 86390) % 86400; break; case 2: second = (second + 86340) % 86400; break; case 3: second = (second + 85800) % 86400; break; case 4: second = (second + 82800) % 86400; break; case 5: second = (second + 50400) % 86400; break; } } } // ???? void setdate(uint8_t flash_place, bool direction) { if (direction == 0) { // ?? switch (flash_place) { case 0: total_days += 1; break; case 1: total_days += 10; break; case 2: total_days += days_mon[month - 1]; break; case 3: total_days += days_mon[month - 1]; break; case 4: year = (year + 1) % 10000; break; case 5: year = (year + 10) % 10000; break; case 6: year = (year + 100) % 10000; break; case 7: year = (year + 1000) % 10000; break; } } else { // ?? switch (flash_place) { case 0: total_days -= 1; break; case 1: total_days -= 10; break; case 2: total_days -= days_mon[month - 1]; break; case 3: total_days -= days_mon[month - 1]; break; case 4: year = (year + 9999) % 10000; break; case 5: year = (year + 9990) % 10000; break; case 6: year = (year + 9900) % 10000; break; case 7: year = (year + 9000) % 10000; break; } } } // ???? void setalarm(uint8_t flash_place, bool direction) { if (direction == 0) { // ?? switch (flash_place) { case 0: alarm_time = (alarm_time + 1) % 86400; break; case 1: alarm_time = (alarm_time + 10) % 86400; break; case 2: alarm_time = (alarm_time + 60) % 86400; break; case 3: alarm_time = (alarm_time + 600) % 86400; break; case 4: alarm_time = (alarm_time + 3600) % 86400; break; case 5: alarm_time = (alarm_time + 36000) % 86400; break; } } else { // ?? switch (flash_place) { case 0: alarm_time = (alarm_time + 86399) % 86400; break; case 1: alarm_time = (alarm_time + 86390) % 86400; break; case 2: alarm_time = (alarm_time + 86340) % 86400; break; case 3: alarm_time = (alarm_time + 85800) % 86400; break; case 4: alarm_time = (alarm_time + 82800) % 86400; break; case 5: alarm_time = (alarm_time + 50400) % 86400; break; } } } // ???? void display_studentcode(void) { uint8_t code[] = {3, 1, 9, 1, 0, 3, 3, 0}; static uint8_t pos = 0; if (systick_1ms_status) { systick_1ms_status = 0; I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, seg7[code[pos]]); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, dis_pos[pos]); if (++pos_flash_cnt >= 3) { pos_flash_cnt = 0; pos = (pos + 1) % 8; } } } // ???? void display_name(void) { uint8_t name[] = {0x7e, 0x77, 0x54, 0x3d, 0x76, 0x77, 0x5c, 0x31};//wanghaor static uint8_t pos = 0; if (systick_1ms_status) { systick_1ms_status = 0; I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, name[pos]); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, dis_pos[pos]); if (++pos_flash_cnt >= 3) { pos_flash_cnt = 0; pos = (pos + 1) % 8; } } } // ????????? void year_cheak(void) { if (year % 100) { if (year % 4 == 0) { days_mon[1] = 29; days_mon[12] = 366; } else { days_mon[1] = 28; days_mon[12] = 365; } } else { if (year % 400 == 0) { days_mon[1] = 29; days_mon[12] = 366; } else { days_mon[1] = 28; days_mon[12] = 365; } } } // ???? void display_alarm(uint8_t flash_place) { uint8_t num = 0, pos = 0; if (systick_1ms_status) { systick_1ms_status = 0; if (++alarm_flash_cnt >= 3) { alarm_flash_cnt = 0; alarm_pos = (alarm_pos + 1) % 8; } } switch (alarm_pos) { case 0: num = seg7[alarm_time / 3600 / 10]; pos = 0x01; break; case 1: num = seg7[alarm_time / 3600 % 10]; pos = 0x02; break; case 2: num = 0x40; pos = 0x04; break; case 3: num = seg7[(alarm_time % 3600) / 60 / 10]; pos = 0x08; break; case 4: num = seg7[(alarm_time % 3600) / 60 % 10]; pos = 0x10; break; case 5: num = 0x40; pos = 0x20; break; case 6: num = seg7[(alarm_time % 60) / 10]; pos = 0x40; break; case 7: num = seg7[alarm_time % 60 % 10]; pos = 0x80; break; } // ???? if (flash_place && flash_flag) { if ((alarm_pos + 1) == flash_place) { num = 0x00; } } I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, num); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, pos); } // ???? void display_date(uint8_t flash_place) { static uint8_t digit_index = 0; // ??????? (0-7) uint8_t num = 0; uint8_t digit_select = 0; // ?????? // ????????? date_transform(); if (systick_1ms_status) { systick_1ms_status = 0; if (++date_pos_flash_cnt >= 3) { date_pos_flash_cnt = 0; digit_index = (digit_index + 1) % 8; } } // ??????????????? switch (digit_index) { case 0: num = seg7[year / 1000]; digit_select = 0x01; // ?1???? break; case 1: num = seg7[(year % 1000) / 100]; digit_select = 0x02; // ?2???? break; case 2: num = seg7[(year % 100) / 10]; digit_select = 0x04; // ?3???? break; case 3: num = seg7[year % 10] | 0x80; // ???? digit_select = 0x08; // ?4???? break; case 4: num = seg7[month / 10]; digit_select = 0x10; // ?5???? break; case 5: num = seg7[month % 10] | 0x80; // ???? digit_select = 0x20; // ?6???? break; case 6: num = seg7[day / 10]; digit_select = 0x40; // ?7???? break; case 7: num = seg7[day % 10]; digit_select = 0x80; // ?8???? break; } // ????:????????????? if (flash_place != 0 && flash_flag) { if ((digit_index + 1) == flash_place) { num = 0x00; // ????? } } I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, num); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, digit_select); } // ???? void display_time(uint8_t flash_place) { uint8_t num = 0; static uint8_t digit_index = 0; uint8_t digit_select = 0; if (systick_1ms_status) { systick_1ms_status = 0; if (++time_pos_flash_cnt >= 3) { time_pos_flash_cnt = 0; digit_index = (digit_index + 1) % 8; } } switch (digit_index) { case 0: num = seg7[second / 3600 / 10]; digit_select = 0x01; break; case 1: num = seg7[second / 3600 % 10]; digit_select = 0x02; break; case 2: num = 0x40; digit_select = 0x04; break; case 3: num = seg7[(second % 3600) / 60 / 10]; digit_select = 0x08; break; case 4: num = seg7[(second % 3600) / 60 % 10]; digit_select = 0x10; break; case 5: num = 0x40; digit_select = 0x20; break; case 6: num = seg7[(second % 60) / 10]; digit_select = 0x40; break; case 7: num = seg7[second % 60 % 10]; digit_select= 0x80; break; } // ???? if (flash_place && flash_flag) { if ((digit_index + 1) == flash_place) { num = 0x00; } } I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, num); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, digit_select); } // ???? (??? -> ???) void date_transform(void) { year_cheak(); uint16_t days = total_days; month = 1; // 正确计算月份 while (days > days_mon[month-1]) { days -= days_mon[month-1]; month++; if (month > 12) { year++; month = 1; year_cheak(); } } day = days; } // ???? static uint8_t s_pos_index = 0; // ????(0-7) static uint8_t s_flow_counter = 0; // ????? // ???? void flow_display(void) { uint8_t num = 0; uint8_t segment_data = 0; uint8_t digit_select = 0; // ???????????? if (systick_1ms_status) { systick_1ms_status = 0; if (++pos_flash_cnt >= 3) { pos_flash_cnt = 0; s_pos_index = (s_pos_index + 1) % 8; } if (++flow_flash_cnt >= flow_flash_time) { flow_flash_cnt = 0; s_flow_counter = (s_flow_counter + 1) % 16; } } // ???????? flow16[0] = seg7[year / 1000]; flow16[1] = seg7[(year % 1000) / 100]; flow16[2] = seg7[(year % 100) / 10]; flow16[3] = seg7[year % 10] | 0x80; flow16[4] = seg7[month / 10]; flow16[5] = seg7[month % 10] | 0x80; flow16[6] = seg7[day / 10]; flow16[7] = seg7[day % 10]; flow16[8] = seg7[second / 3600 / 10]; flow16[9] = seg7[second / 3600 % 10]; flow16[10] = 0x40; flow16[11] = seg7[(second % 3600) / 60 / 10]; flow16[12] = seg7[(second % 3600) / 60 % 10]; flow16[13] = 0x40; flow16[14] = seg7[(second % 60) / 10]; flow16[15] = seg7[second % 10]; // ??????????? switch (s_pos_index) { case 0: segment_data = flow16[s_flow_counter]; digit_select = 0x01; break; case 1: segment_data = flow16[(s_flow_counter + 1) % 16]; digit_select = 0x02; break; case 2: segment_data = flow16[(s_flow_counter + 2) % 16]; digit_select = 0x04; break; case 3: segment_data = flow16[(s_flow_counter + 3) % 16]; digit_select = 0x08; break; case 4: segment_data = flow16[(s_flow_counter + 4) % 16]; digit_select = 0x10; break; case 5: segment_data = flow16[(s_flow_counter + 5) % 16]; digit_select = 0x20; break; case 6: segment_data = flow16[(s_flow_counter + 6) % 16]; digit_select = 0x40; break; case 7: segment_data = flow16[(s_flow_counter + 7) % 16]; digit_select = 0x80; break; } // ??????? I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, 0x00); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT1, segment_data); I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_OUTPUT_PORT2, digit_select); } // ???? void checkbutton(void) { uint8_t i = 0; uint8_t key_sw = ~I2C0_ReadByte(TCA6424_I2CADDR, TCA6424_INPUT_PORT0); for (; i < 8; i++) { last_status_SW[i] = status_SW[i]; status_SW[i] = key_sw & (1 << i); // ?????? if (last_status_SW[i] == 0 && status_SW[i] == (1 << i)) { keyflag[i] = 1; } // ???? if (last_status_SW[i] == (1 << i) && status_SW[i] == (1 << i)) { keydelay[i]++; if (keydelay[i] >= 9 && i != 3) { keydelay[i] = 0; delayflag[i] = 1; } } else { keydelay[i] = 0; } // ???? if (last_status_SW[i] == (1 << i) && status_SW[i] == 0) { keyflag[i] = 0; } } // SW1: ???? (??/??/??/??) if (keyflag[0]) { keyflag[0] = 0; state = (state + 1) % 4; set_flag = 0; s_flow_counter = 0; } // SW2: ?????? if (keyflag[1]) { keyflag[1] = 0; set_flag = 1 - set_flag; } } // UART??? void S800_UART_Init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)); // ??UART?? GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // ??UART: 115200, 8-N-1 UARTConfigSetExpClk(UART0_BASE, ui32SysClock, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // ??FIFO UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX2_8, UART_FIFO_RX7_8); // ???? UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); IntEnable(INT_UART0); UARTStringPut("\r\nDigital Clock Initialized!\r\n"); } // GPIO??? void S800_GPIO_Init(void) { // ??GPIO?? SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOJ)); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOK)); // ?????? GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0); GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1); GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_5); // ??? // ?????? GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1); GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); } // I2C??? void S800_I2C0_Init(void) { uint8_t result; // ??I2C?? SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // ??I2C?? GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); // ???I2C I2CMasterInitExpClk(I2C0_BASE, ui32SysClock, true); I2CMasterEnable(I2C0_BASE); // ??TCA6424 result = I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_CONFIG_PORT0, 0xFF); // Port0?? result = I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_CONFIG_PORT1, 0x00); // Port1?? result = I2C0_WriteByte(TCA6424_I2CADDR, TCA6424_CONFIG_PORT2, 0x00); // Port2?? // ??PCA9557 result = I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_CONFIG, 0x00); // ???? result = I2C0_WriteByte(PCA9557_I2CADDR, PCA9557_OUTPUT, 0xFF); // ???? // ?????? result = I2C0_ReadByte(TCA6424_I2CADDR, TCA6424_INPUT_PORT0); } // I2C??? uint8_t I2C0_WriteByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t WriteData) { uint8_t rop; while (I2CMasterBusy(I2C0_BASE)) {}; I2CMasterSlaveAddrSet(I2C0_BASE, DevAddr, false); I2CMasterDataPut(I2C0_BASE, RegAddr); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); while (I2CMasterBusy(I2C0_BASE)) {}; rop = (uint8_t)I2CMasterErr(I2C0_BASE); I2CMasterDataPut(I2C0_BASE, WriteData); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); while (I2CMasterBusy(I2C0_BASE)) {}; rop = (uint8_t)I2CMasterErr(I2C0_BASE); return rop; } // I2C??? uint8_t I2C0_ReadByte(uint8_t DevAddr, uint8_t RegAddr) { uint8_t value; while (I2CMasterBusy(I2C0_BASE)) {}; I2CMasterSlaveAddrSet(I2C0_BASE, DevAddr, false); I2CMasterDataPut(I2C0_BASE, RegAddr); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); while (I2CMasterBusBusy(I2C0_BASE)); if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE) { return 0; } Delay(100); // ???? I2CMasterSlaveAddrSet(I2C0_BASE, DevAddr, true); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); while (I2CMasterBusBusy(I2C0_BASE)); value = I2CMasterDataGet(I2C0_BASE); if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE) { return 0; } Delay(100); return value; } // SysTick???? void SysTick_Handler(void) { systick_1ms_status = 1; // 1???? if (systick_1s_counter == 0) { systick_1s_counter = 1000; if (!startup_flag) { second = (second + 1) % 86400;//???????1 } systick_1s_status = 1; } else { systick_1s_counter--; } // ????? if (systick_flash_counter == 0) { systick_flash_counter = 300; flash_flag = 1 - flash_flag; } else { systick_flash_counter--; } // 100????? if (systick_100ms_counter == 0) { systick_100ms_counter = 100; systick_100ms_status = 1; } else { systick_100ms_counter--; } // 20????? (??????) if (systick_20ms_counter == 0) { systick_20ms_counter = 20; systick_20ms_status = 1; checkbutton(); } else { systick_20ms_counter--; } // 10????? if (systick_10ms_counter == 0) { systick_10ms_counter = 10; systick_10ms_status = 1; } else { systick_10ms_counter--; } } // UART???? void UART0_Handler(void) { static uint8_t cnt = 0; int32_t uart0_int_status; char ch; uart0_int_status = UARTIntStatus(UART0_BASE, true); UARTIntClear(UART0_BASE, uart0_int_status); if (uart0_int_status & (UART_INT_RX | UART_INT_RT)) { while (UARTCharsAvail(UART0_BASE) && cnt < MAX_RECEIVE_LEN - 1) { ch = UARTCharGetNonBlocking(UART0_BASE); // ????????????? if (ch == '\r' || ch == '\n') { if (cnt > 0) { receive_order[cnt] = '\0'; uart_cmd_ready = 1; // ???????? } cnt = 0; } else { receive_order[cnt++] = ch; } } // ??????? if (cnt >= MAX_RECEIVE_LEN - 1) { receive_order[cnt] = '\0'; uart_cmd_ready = 1; cnt = 0; } } } void order_process(char *cmassage) { int read_index = 0; int write_index = 0; char ch; while ((ch = cmassage[read_index]) != '\0') { if (ch >= 'a' && ch <= 'z') {//????? cmassage[write_index] = ch - 'a' + 'A'; write_index++; } else if ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == ' ' || ch == ':' || ch == '*') { cmassage[write_index] = ch; // ?????????? write_index++; } // ??????? read_index++; } // ????????? cmassage[write_index] = '\0'; } void separate_alpha_digit(char *str, char *digits) { int i = 0, alpha_idx = 0, digit_idx = 0; while (str[i] != '\0') { if (isalnum((unsigned char)str[i])) { // ?????????? if (isalpha((unsigned char)str[i])) { // ??:?????? str[alpha_idx++] = str[i]; } else if (isdigit((unsigned char)str[i])) { // ??:??digits digits[digit_idx++] = str[i]; } } i++; } // ???????? str[alpha_idx] = '\0'; digits[digit_idx] = '\0'; } void cmd_proc(char *cmd) { char digits[20]; separate_alpha_digit(cmd, digits); if(strcmp(cmd, "RST") == 0){ resetclock_flag = 1; } //set date else if(strcmp(cmd, "SETDATEYEAR") == 0){ setdate_flag = 1; setdate_order[1] = digits[0];setdate_order[2] = digits[1];setdate_order[3] = digits[2];setdate_order[4] = digits[3]; setdate_order[6] = month/10+'0';setdate_order[7] = month%10+'0'; setdate_order[9] = day/10+'0';setdate_order[10] = day%10+'0'; } else if(strcmp(cmd, "SETDATEMONTH") == 0){ setdate_flag = 1; setdate_order[1] = year/1000+'0';setdate_order[2] = year%1000/100+'0';setdate_order[3] = year%100/10+'0';setdate_order[4] = year%10+'0'; setdate_order[6] = digits[0];setdate_order[7] = digits[1]; setdate_order[9] = day/10+'0';setdate_order[10] = day%10+'0'; } else if(strcmp(cmd, "SETDATEDAY") == 0){ setdate_flag = 1; setdate_order[1] = year/1000+'0';setdate_order[2] = year%1000/100+'0';setdate_order[3] = year%100/10+'0';setdate_order[4] = year%10+'0'; setdate_order[6] = month/10+'0';setdate_order[7] = month%10+'0'; setdate_order[9] = digits[0];setdate_order[10] = digits[1]; } else if(strcmp(cmd, "SETDATEYEARMONTH") == 0){ setdate_flag = 1; setdate_order[1] = digits[0];setdate_order[2] = digits[1];setdate_order[3] = digits[2];setdate_order[4] = digits[3]; setdate_order[6] = digits[4];setdate_order[7] = digits[5]; setdate_order[9] = day/10+'0';setdate_order[10] = day%10+'0'; } else if(strcmp(cmd, "SETDATEYEARDAY")== 0){ setdate_flag = 1; setdate_order[1] = digits[0];setdate_order[2] = digits[1];setdate_order[3] = digits[2];setdate_order[4] = digits[3]; setdate_order[6] = month/10+'0';setdate_order[7] = month%10+'0'; setdate_order[9] = digits[4];setdate_order[10] = digits[5]; } else if(strcmp(cmd, "SETDATEMONTHDAY") == 0){ setdate_flag = 1; setdate_order[1] = year/1000+'0';setdate_order[2] = year%1000/100+'0';setdate_order[3] = year%100/10+'0';setdate_order[4] = year%10+'0'; setdate_order[6] = digits[0];setdate_order[7] = digits[1]; setdate_order[9] = digits[2];setdate_order[10] = digits[3]; } else if(strcmp(cmd, "SETDATEYEARMONTHDAY") == 0){ setdate_flag = 1; setdate_order[1] = digits[0];setdate_order[2] = digits[1];setdate_order[3] = digits[2];setdate_order[4] = digits[3]; setdate_order[6] = digits[4];setdate_order[7] = digits[5]; setdate_order[9] = digits[6];setdate_order[10] = digits[7]; } //set time else if(strcmp(cmd, "SETTIMEHOUR") == 0){ settime_flag = 1; settime_order[1] = digits[0];settime_order[2] = digits[1]; settime_order[4] = second%3600/60/10+'0';settime_order[5] = second%3600/60%10+'0'; settime_order[7] = second%60/10+'0';settime_order[8] = second%10+'0'; } else if((strcmp(cmd,"SETTIMEMINUTE") == 0) || (strcmp(cmd, "SETTIMEMIN") == 0)){ settime_flag = 1; settime_order[1] = second/3600/10+'0';settime_order[2] = second/3600%10+'0'; settime_order[4] = digits[0];settime_order[5] = digits[1]; settime_order[7] = second%60/10+'0';settime_order[8] = second%10+'0'; } else if((strcmp(cmd,"SETTIMESECOND") == 0) || (strcmp(cmd, "SETTIMESEC") == 0)){ settime_flag = 1; settime_order[1] = second/3600/10+'0';settime_order[2] = second/3600%10+'0'; settime_order[4] = second%3600/60/10+'0';settime_order[5] = second%3600/60%10+'0'; settime_order[7] = digits[0];settime_order[8] = digits[1]; } else if((strcmp(cmd, "SETTIMEHOURMINUTE") == 0) || (strcmp(cmd, "SETTIMEHOURMIN") == 0)){ settime_flag = 1; settime_order[1] = digits[0];settime_order[2] = digits[1]; settime_order[4] = digits[2];settime_order[5] = digits[3]; settime_order[7] = second%60/10+'0';settime_order[8] = second%10+'0'; } else if((strcmp(cmd, "SETTIMEHOURSECOND") == 0) || (strcmp(cmd, "SETTIMEHOURSEC") == 0)){ settime_flag = 1; settime_order[1] = digits[0];settime_order[2] = digits[1]; settime_order[4] = second%3600/60/10+'0';settime_order[5] = second%3600/60%10+'0'; settime_order[7] = digits[2];settime_order[8] = digits[3]; } else if((strcmp(cmd, "SETTIMEMINUTESECOND") == 0) || (strcmp(cmd, "SETTIMEMINSEC") == 0)){ settime_flag = 1; settime_order[1] = second/3600/10+'0';settime_order[2] = second/3600/10+'0'; settime_order[4] = digits[0];settime_order[5] = digits[1]; settime_order[7] = digits[2];settime_order[8] = digits[3]; } else if((strcmp(cmd, "SETTIMEHOURMINUTESECOND") == 0) || (strcmp(cmd, "SETTIMEHOURMINSEC") == 0)){ settime_flag = 1; settime_order[1] = digits[0];settime_order[2] = digits[1]; settime_order[4] = digits[2];settime_order[5] = digits[3]; settime_order[7] = digits[4];settime_order[8] = digits[5]; } //set alarm else if(strcmp(cmd, "SETALARMHOUR") == 0){ setalarm_flag = 1; setalarmtime_order[1] = digits[0];setalarmtime_order[2] = digits[1]; setalarmtime_order[4] = alarm_time%3600/60/10+'0';setalarmtime_order[5] = alarm_time%3600/60%10+'0'; setalarmtime_order[7] = alarm_time%60/10+'0';setalarmtime_order[8] = alarm_time%10+'0'; } else if((strcmp(cmd,"SETALARMMINUTE") == 0) || (strcmp(cmd, "SETALARMMIN") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = alarm_time/3600/10+'0';setalarmtime_order[2] = alarm_time/3600%10+'0'; setalarmtime_order[4] = digits[0];setalarmtime_order[5] = digits[1]; setalarmtime_order[7] = alarm_time%60/10+'0';setalarmtime_order[8] = alarm_time%10+'0'; } else if((strcmp(cmd,"SETALARMSECOND") == 0) || (strcmp(cmd, "SETALARMSEC") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = alarm_time/3600/10+'0';setalarmtime_order[2] = alarm_time/3600%10+'0'; setalarmtime_order[4] = alarm_time%3600/60/10+'0';setalarmtime_order[5] = alarm_time%3600/60%10+'0'; setalarmtime_order[7] = digits[0];setalarmtime_order[8] = digits[1]; } else if((strcmp(cmd, "SETALARMHOURMINUTE") == 0) || (strcmp(cmd, "SETALARMHOURMIN") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = digits[0];setalarmtime_order[2] = digits[1]; setalarmtime_order[4] = digits[2];setalarmtime_order[5] = digits[3]; setalarmtime_order[7] = alarm_time%60/10+'0';setalarmtime_order[8] = alarm_time%10+'0'; } else if((strcmp(cmd, "SETALARMHOURSECOND") == 0) || (strcmp(cmd, "SETALARMHOURSEC") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = digits[0];setalarmtime_order[2] = digits[1]; setalarmtime_order[4] = alarm_time%3600/60/10+'0';setalarmtime_order[5] = alarm_time%3600/60%10+'0'; setalarmtime_order[7] = digits[2];setalarmtime_order[8] = digits[3]; } else if((strcmp(cmd, "SETALARMMINUTESECOND") == 0) || (strcmp(cmd, "SETALARMMINSEC") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = alarm_time/3600/10+'0';setalarmtime_order[2] = alarm_time/3600/10+'0'; setalarmtime_order[4] = digits[0];setalarmtime_order[5] = digits[1]; setalarmtime_order[7] = digits[2];setalarmtime_order[8] = digits[3]; } else if((strcmp(cmd, "SETALARMHOURMINUTESECOND") == 0) || (strcmp(cmd, "SETALARMHOURMINSEC") == 0)){ setalarm_flag = 1; setalarmtime_order[1] = digits[0];setalarmtime_order[2] = digits[1]; setalarmtime_order[4] = digits[2];setalarmtime_order[5] = digits[3]; setalarmtime_order[7] = digits[4];setalarmtime_order[8] = digits[5]; } //set display else if(strcmp(cmd, "SETDISPLAYON") == 0){ display_on = 1; } else if(strcmp(cmd, "SETDISPLAYOFF") == 0){ display_on = 0; } //set format else if(strcmp(cmd, "SETFORMATLEFT") == 0){ setformat_flag = 0; } else if (strcmp(cmd, "SETFORMATRIGHT") == 0){ setformat_flag = 1; } // get date else if(strcmp(cmd, "GETDATEYEAR") == 0){ getdate_flag = 1; datestr[0]= year/1000+'0';datestr[1]=year%1000/100+'0';datestr[2]=year%100/10+'0';datestr[3] = year%10+'0'; } else if(strcmp(cmd, "GETDATEMONTH") == 0){ getdate_flag = 1; datestr[0] = month/10+'0'; datestr[1] = month%10+'0'; } else if(strcmp(cmd, "GETDATEDAY") == 0){ getdate_flag = 1; datestr[0] = day/10+'0'; datestr[1] = day%10+'0'; } else if(strcmp(cmd, "GETDATEYEARMONTH") == 0){ getdate_flag = 1; datestr[0]= year/1000+'0';datestr[1]=year%1000/100+'0';datestr[2]=year%100/10+'0';datestr[3] = year%10+'0';datestr[4]='-';datestr[5] = month/10+'0'; datestr[6] = month%10+'0'; } else if(strcmp(cmd, "GETDATEYEARDAY") == 0){ getdate_flag = 1; datestr[0]= year/1000+'0';datestr[1]=year%1000/100+'0';datestr[2]=year%100/10+'0';datestr[3] = year%10+'0';datestr[4]='-';datestr[5] = day/10+'0'; datestr[6] = day%10+'0'; } else if(strcmp(cmd, "GETDATEMONTHDAY") == 0){ getdate_flag = 1; datestr[0] = month/10+'0'; datestr[1] = month%10+'0';datestr[2]='-';datestr[3] = day/10+'0'; datestr[4] = day%10+'0'; } else if(strcmp(cmd, "GETDATEYEARMONTHDAY") == 0){ getdate_flag = 1; datestr[0]= year/1000+'0';datestr[1]=year%1000/100+'0';datestr[2]=year%100/10+'0';datestr[3] = year%10+'0';datestr[4]='-';datestr[5] = month/10+'0'; datestr[6] = month%10+'0'; datestr[7]='-';datestr[8]=day/10+'0';datestr[9] = day%10+'0'; } //get time else if(strcmp(cmd, "GETTIMEHOUR") == 0){ gettime_flag = 1; timestr[0] = second/3600/10+'0';timestr[1] = second/3600%10+'0'; } else if((strcmp(cmd, "GETTIMEMINUTE") == 0) || (strcmp(cmd, "GETTIMEMIN") == 0)){ gettime_flag = 1; timestr[0] = second%3600/60/10+'0';timestr[1] = second%3600/60%10+'0'; } else if((strcmp(cmd, "GETTIMESECOND") == 0) || (strcmp(cmd, "GETTIMESEC") == 0)){ gettime_flag = 1; timestr[0] = second%60/10+'0';timestr[1] = second%60%10+'0'; } else if((strcmp(cmd, "GETTIMEHOURMINUTE") == 0) || (strcmp(cmd, "GETTIMEHOURMIN") == 0)){ gettime_flag = 1; timestr[0] = second/3600/10+'0';timestr[1] = second/3600%10+'0';timestr[2]=':';timestr[3] = second%3600/60/10+'0';timestr[4] = second%3600/60%10+'0'; } else if((strcmp(cmd, "GETTIMEMINUTESECOND") == 0) || (strcmp(cmd, "GETTIMEMINSEC") == 0)){ gettime_flag = 1; timestr[0] = second%3600/60/10+'0';timestr[1] = second%3600/60%10+'0';timestr[2]=':';timestr[3] = second%60/10+'0';timestr[4] = second%60%10+'0'; } else if((strcmp(cmd, "GETTIMEHOURSECOND") == 0) || (strcmp(cmd, "GETTIMEHOURSEC") == 0)){ gettime_flag = 1; timestr[0] = second/3600/10+'0';timestr[1] = second/3600%10+'0';timestr[2]=':';timestr[3] = second%60/10+'0';timestr[4] = second%60%10+'0'; } else if((strcmp(cmd, "GETTIMEHOURMINUTESECOND") == 0) || (strcmp(cmd, "GETTIMEHOURMINSEC") == 0)){ gettime_flag = 1; timestr[0] = second/3600/10+'0';timestr[1] = second/3600%10+'0';timestr[2]=':';timestr[3] = second%3600/60/10+'0';timestr[4] = second%3600/60%10+'0'; timestr[5] = ':';timestr[6] = second%60/10+'0';timestr[7] = second%60%10+'0'; } //get alarm else if((strcmp(cmd, "GETALARM") == 0)){ getalarm_flag = 1; alarmstr[0] = alarm_time/3600/10+'0';alarmstr[1] = alarm_time/3600%10+'0';alarmstr[2]=':';alarmstr[3] = alarm_time%3600/60/10+'0';alarmstr[4] = alarm_time%3600/60%10+'0'; alarmstr[5] = ':';alarmstr[6] = alarm_time%60/10+'0';alarmstr[7] = alarm_time%60%10+'0'; } //get format else if(strcmp(cmd, "GETFORMAT") == 0){ getformat_flag = 1; } //get display else if(strcmp(cmd, "GETDISPLAY") == 0){ getdisplay_flag = 1; } } // ???? void Delay(uint32_t value) { uint32_t ui32Loop; for (ui32Loop = 0; ui32Loop < value; ui32Loop++) {}; } // ??????? void UARTStringPut(const char *cMessage) { while (*cMessage != '\0') { UARTCharPut(UART0_BASE, *(cMessage++)); } } // ???????? void UARTStringPutNonBlocking(const char *cMessage) { while (*cMessage != '\0') { UARTCharPutNonBlocking(UART0_BASE, *(cMessage++)); } }代码无法实现串口通信,是什么问题

最新推荐

recommend-type

开发界面语义化:声控 + 画图协同生成代码.doc

开发界面语义化:声控 + 画图协同生成代码.doc
recommend-type

LABVIEW与三菱PLC通信:实现数据批量读写的高效库解决方案

如何通过LabVIEW与三菱PLC建立高效的通信桥梁,实现数据批量读写。首先概述了LabVIEW和三菱PLC的基本概念及其在工业自动化中的重要性。接着重点讲解了利用Modbus RTU协议构建通信连接的具体步骤和技术细节,包括初始化通信、发送读写请求、处理响应数据和关闭连接等功能。文中还提供了一个简化的代码示例,展示了如何在LabVIEW环境中实现这一过程。最后对这项技术进行了总结和展望,强调其在提高数据交互效率方面的潜力以及未来的广泛应用前景。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些熟悉LabVIEW或三菱PLC的人士。 使用场景及目标:适用于需要频繁进行数据交互的工业控制系统,如生产线监控、设备状态监测等场合。主要目的是提升数据传输的速度和可靠性,从而优化整个系统的运行效率。 阅读建议:读者可以通过本文深入了解LabVIEW与三菱PLC通信的实现方法,掌握批量数据读写库的设计思路,并将其应用于实际工程项目中。建议边阅读边尝试动手实践相关代码,以便更好地理解和吸收所学知识。
recommend-type

欧姆龙PLC NJ系列模切机程序:高级伺服运动与张力控制的应用实例

欧姆龙PLC NJ系列模切机项目的编程细节及其关键技术。主要内容涵盖12轴EtherCAT总线伺服运动控制,包括回零、点动、定位和速度控制;张力控制采用PID算法并进行收放卷径计算;隔膜自动纠偏控制利用模拟量数据平均化处理;同步运动控制实现凸轮表追剪和裁切;以及结构化编程和ST语言功能块的使用。项目结构规范,注释详尽,有助于理解和维护代码。通过本项目的学习,可以掌握PLC高端复杂应用的实际操作技能。 适合人群:从事工业自动化领域的工程师和技术人员,特别是对PLC编程和伺服运动控制有浓厚兴趣的人群。 使用场景及目标:适用于需要深入了解PLC编程技巧和自动化控制系统原理的技术人员。目标是提升编程能力和对复杂自动化系统的工作机制的理解。 其他说明:本文不仅提供具体的编程指导,还强调了项目管理和代码规范的重要性,为读者提供了全面的学习体验。
recommend-type

Python程序TXLWizard生成TXL文件及转换工具介绍

### 知识点详细说明: #### 1. 图形旋转与TXL向导 图形旋转是图形学领域的一个基本操作,用于改变图形的方向。在本上下文中,TXL向导(TXLWizard)是由Esteban Marin编写的Python程序,它实现了特定的图形旋转功能,主要用于电子束光刻掩模的生成。光刻掩模是半导体制造过程中非常关键的一个环节,它确定了在硅片上沉积材料的精确位置。TXL向导通过生成特定格式的TXL文件来辅助这一过程。 #### 2. TXL文件格式与用途 TXL文件格式是一种基于文本的文件格式,它设计得易于使用,并且可以通过各种脚本语言如Python和Matlab生成。这种格式通常用于电子束光刻中,因为它的文本形式使得它可以通过编程快速创建复杂的掩模设计。TXL文件格式支持引用对象和复制对象数组(如SREF和AREF),这些特性可以用于优化电子束光刻设备的性能。 #### 3. TXLWizard的特性与优势 - **结构化的Python脚本:** TXLWizard 使用结构良好的脚本来创建遮罩,这有助于开发者创建清晰、易于维护的代码。 - **灵活的Python脚本:** 作为Python程序,TXLWizard 可以利用Python语言的灵活性和强大的库集合来编写复杂的掩模生成逻辑。 - **可读性和可重用性:** 生成的掩码代码易于阅读,开发者可以轻松地重用和修改以适应不同的需求。 - **自动标签生成:** TXLWizard 还包括自动为图形对象生成标签的功能,这在管理复杂图形时非常有用。 #### 4. TXL转换器的功能 - **查看.TXL文件:** TXL转换器(TXLConverter)允许用户将TXL文件转换成HTML或SVG格式,这样用户就可以使用任何现代浏览器或矢量图形应用程序来查看文件。 - **缩放和平移:** 转换后的文件支持缩放和平移功能,这使得用户在图形界面中更容易查看细节和整体结构。 - **快速转换:** TXL转换器还提供快速的文件转换功能,以实现有效的蒙版开发工作流程。 #### 5. 应用场景与技术参考 TXLWizard的应用场景主要集中在电子束光刻技术中,特别是用于设计和制作半导体器件时所需的掩模。TXLWizard作为一个向导,不仅提供了生成TXL文件的基础框架,还提供了一种方式来优化掩模设计,提高光刻过程的效率和精度。对于需要进行光刻掩模设计的工程师和研究人员来说,TXLWizard提供了一种有效的方法来实现他们的设计目标。 #### 6. 系统开源特性 标签“系统开源”表明TXLWizard遵循开放源代码的原则,这意味着源代码对所有人开放,允许用户自由地查看、修改和分发软件。开源项目通常拥有活跃的社区,社区成员可以合作改进软件,添加新功能,或帮助解决遇到的问题。这种开放性促进了技术创新,并允许用户根据自己的需求定制软件。 #### 7. 压缩包子文件的文件名称列表 文件名称列表中的“txlwizard-master”可能指的是TXLWizard项目的主版本库或主分支。这个名称表明了这是项目源代码的中心点,其他开发者会从这个主分支拉取代码进行合作开发或部署。以“-master”结尾通常是版本控制系统中表示主要开发线路的常见约定,例如Git中的master(现在更常被称为main)分支。 通过这些知识点的详细解释,我们可以看到TXLWizard不仅是一个用于生成TXL文件的工具,它还整合了一系列的功能,使得电子束光刻掩模的设计工作更为高效和直观。同时,作为一个开源项目,它能够借助社区的力量不断进步,为用户带来更多的便利和创新。
recommend-type

【创新图生成:扣子平台的技术前沿与创新思维】:引领图像生成技术的新潮流

# 1. 扣子平台的图像生成技术概述 在当今数字化时代,图像生成技术正成为推动技术创新和社会变革的关键力量。扣子平台正是这一技术革新的代表。本章将对扣子平台的图像生成技术进行一个全面概述,探究它如何将理论技术转化为实际应用,并带来显著的社会影响。 扣子平台运用了先进的图像生成技术,将现实世界和数字空间无缝融合,打造了沉浸式的视觉体验。其技术的核心是通过高度复杂的算法模型,快速生成高质
recommend-type

海康威视机器视觉工程师考核

<think>好的,我现在需要帮助用户了解海康威视机器视觉工程师的考核内容和要求。根据用户提供的引用资料,特别是引用[1]和[2],里面提到了考核素材包分为初级和中级,涵盖理论、算法、应用案例等。首先,我要整理这些信息,确保结构清晰,符合用户要求的格式。 接下来,我需要确认素材包的具体内容,比如初级和中级的不同点。引用[2]提到初级包含基础理论、算法实现和实际案例,中级则增加复杂算法和项目分析。这部分需要分点说明,方便用户理解层次。 另外,用户可能想知道如何准备考核,比如下载素材、学习顺序、模拟考核等,引用[2]中有使用说明和注意事项,这部分也要涵盖进去。同时要注意提醒用户考核窗口已关闭,
recommend-type

Linux环境下Docker Hub公共容器映像检测工具集

在给出的知识点中,我们需要详细解释有关Docker Hub、公共容器映像、容器编排器以及如何与这些工具交互的详细信息。同时,我们会涵盖Linux系统下的相关操作和工具使用,以及如何在ECS和Kubernetes等容器编排工具中运用这些检测工具。 ### Docker Hub 和公共容器映像 Docker Hub是Docker公司提供的一项服务,它允许用户存储、管理以及分享Docker镜像。Docker镜像可以视为应用程序或服务的“快照”,包含了运行特定软件所需的所有必要文件和配置。公共容器映像指的是那些被标记为公开可见的Docker镜像,任何用户都可以拉取并使用这些镜像。 ### 静态和动态标识工具 静态和动态标识工具在Docker Hub上用于识别和分析公共容器映像。静态标识通常指的是在不运行镜像的情况下分析镜像的元数据和内容,例如检查Dockerfile中的指令、环境变量、端口映射等。动态标识则需要在容器运行时对容器的行为和性能进行监控和分析,如资源使用率、网络通信等。 ### 容器编排器与Docker映像 容器编排器是用于自动化容器部署、管理和扩展的工具。在Docker环境中,容器编排器能够自动化地启动、停止以及管理容器的生命周期。常见的容器编排器包括ECS和Kubernetes。 - **ECS (Elastic Container Service)**:是由亚马逊提供的容器编排服务,支持Docker容器,并提供了一种简单的方式来运行、停止以及管理容器化应用程序。 - **Kubernetes**:是一个开源平台,用于自动化容器化应用程序的部署、扩展和操作。它已经成为容器编排领域的事实标准。 ### 如何使用静态和动态标识工具 要使用这些静态和动态标识工具,首先需要获取并安装它们。从给定信息中了解到,可以通过克隆仓库或下载压缩包并解压到本地系统中。之后,根据需要针对不同的容器编排环境(如Dockerfile、ECS、Kubernetes)编写配置,以集成和使用这些检测工具。 ### Dockerfile中的工具使用 在Dockerfile中使用工具意味着将检测工具的指令嵌入到构建过程中。这可能包括安装检测工具的命令、运行容器扫描的步骤,以及将扫描结果集成到镜像构建流程中,确保只有通过安全和合规检查的容器镜像才能被构建和部署。 ### ECS与Kubernetes中的工具集成 在ECS或Kubernetes环境中,工具的集成可能涉及到创建特定的配置文件、定义服务和部署策略,以及编写脚本或控制器来自动执行检测任务。这样可以在容器编排的过程中实现实时监控,确保容器编排器只使用符合预期的、安全的容器镜像。 ### Linux系统下的操作 在Linux系统下操作这些工具,用户可能需要具备一定的系统管理和配置能力。这包括使用Linux命令行工具、管理文件系统权限、配置网络以及安装和配置软件包等。 ### 总结 综上所述,Docker Hub上的静态和动态标识工具提供了一种方法来检测和分析公共容器映像,确保这些镜像的安全性和可靠性。这些工具在Linux开发环境中尤为重要,因为它们帮助开发人员和运维人员确保他们的容器映像满足安全要求。通过在Dockerfile、ECS和Kubernetes中正确使用这些工具,可以提高应用程序的安全性,减少由于使用不安全的容器镜像带来的风险。此外,掌握Linux系统下的操作技能,可以更好地管理和维护这些工具,确保它们能够有效地发挥作用。
recommend-type

【扣子平台图像艺术探究:理论与实践的完美结合】:深入学习图像生成的艺术

# 1. 图像艺术的理论基础 艺术领域的每一个流派和技巧都有其理论基础。在图像艺术中,理论基础不仅是对艺术表现形式的认知,也是掌握艺术创作内在逻辑的关键。深入理解图像艺术的理论基础,能够帮助艺术家们在创作过程中更加明确地表达自己的艺术意图,以及更好地与观众沟通。 图像艺术的理论
recommend-type

增广路定理的证明

<think>嗯,用户想查找增广路定理的证明,关于图论和网络流算法的。我得先理解增广路定理是什么,然后找到相关的证明方法。根据之前的引用,尤其是引用5提到最大流最小割定理,里面有三个等价条件,其中第二个是残余网络中没有增广路径时,流就是最大流。这可能和增广路定理相关,也就是当残余网络中没有增广路时,当前流就是最大流,这可能就是增广路定理的内容。 首先,我需要明确增广路定理的陈述。根据引用5,增广路定理可能指的是:一个流是最大流当且仅当残余网络中不存在增广路径。这个定理的证明需要用到最大流最小割定理,也就是第三个条件,即最大流的流量等于最小割的容量。 证明的步骤可能需要分为两个方向:必要性(
recommend-type

Pulse:基于SwiftUI的Apple平台高效日志记录与网络监控

从给定文件信息中,我们可以提取出以下IT知识点进行详细阐述: **Pulse概览:** Pulse是一个专门针对Apple平台(如iOS、iPadOS、macOS等)的功能强大的日志记录系统。其设计目的是为了简化开发者在这些平台上调试网络请求和应用日志的过程。Pulse的核心特色是它使用SwiftUI来构建,这有助于开发者利用现代Swift语言的声明式UI优势来快速开发和维护。 **SwiftUI框架:** SwiftUI是一种声明式框架,由苹果公司推出,用于构建用户界面。与传统的UIKit相比,SwiftUI使用更加简洁的代码来描述界面和界面元素,它允许开发者以声明的方式定义视图和界面布局。SwiftUI支持跨平台,这意味着同一套代码可以在不同的Apple设备上运行,大大提高了开发效率和复用性。Pulse选择使用SwiftUI构建,显示了其对现代化、高效率开发的支持。 **Network Inspector功能:** Pulse具备Network Inspector功能,这个功能使得开发者能够在开发iOS应用时,直接从应用内记录和检查网络请求和日志。这种内嵌式的网络诊断能力非常有助于快速定位网络请求中的问题,如不正确的URL、不返回预期响应等。与传统的需要外部工具来抓包和分析的方式相比,这样的内嵌式工具大大减少了调试的复杂性。 **日志记录和隐私保护:** Pulse强调日志是本地记录的,并保证不会离开设备。这种做法对隐私保护至关重要,尤其是考虑到当前数据保护法规如GDPR等的严格要求。因此,Pulse的设计在帮助开发者进行问题诊断的同时,也确保了用户数据的安全性。 **集成和框架支持:** Pulse不仅仅是一个工具,它更是一个框架。它能够记录来自URLSession的事件,这意味着它可以与任何使用URLSession进行网络通信的应用或框架配合使用,包括但不限于Apple官方的网络库。此外,Pulse与使用它的框架(例如Alamofire)也能够良好配合,Alamofire是一个流行的网络请求库,广泛应用于Swift开发中。Pulse提供了一个PulseUI视图组件,开发者可以将其集成到自己的应用中,从而展示网络请求和其他事件。 **跨平台体验:** 开发者不仅可以在iOS应用中使用Pulse Console记录日志,还可以在macOS上通过Pulse应用程序查看和共享这些日志。这种跨平台的能力意味着开发者可以在不同的设备上进行日志分析,增强了开发和调试的灵活性。 **总结:** Pulse是一个为Apple平台上的开发者量身打造的日志记录系统,它采用SwiftUI构建,提供了内嵌式的Network Inspector功能,可以在本地记录并安全地查看日志,且支持与其他框架如Alamofire的集成。它不仅提升了调试的便捷性和效率,同时也顾及到了用户的隐私保护。Pulse的跨平台查看能力也是其一大亮点,使得开发者能够在一个统一的环境中处理iOS和macOS上的日志数据。对于使用Swift开发Apple应用的开发者而言,Pulse无疑是一个强大的调试辅助工具。