配置SCI
配置引脚,支持中断+FIFO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| void initSCIAFIFO(void) { GPIO_setMasterCore(43, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_43_SCIRXDA); GPIO_setDirectionMode(43, GPIO_DIR_MODE_IN); GPIO_setPadConfig(43, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(43, GPIO_QUAL_ASYNC);
GPIO_setMasterCore(42, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_42_SCITXDA); GPIO_setDirectionMode(42, GPIO_DIR_MODE_OUT); GPIO_setPadConfig(42, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(42, GPIO_QUAL_ASYNC);
SCI_disableModule(SCIA_BASE); SCI_performSoftwareReset(SCIA_BASE);
SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
SCI_enableFIFO(SCIA_BASE); SCI_resetTxFIFO(SCIA_BASE); SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX8, SCI_FIFO_RX4);
SCI_enableModule(SCIA_BASE); }
|
全局中断配置,在main函数里边初始化中断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void main(void) { Device_init(); Device_initGPIO(); Board_init(); initSCIAFIFO(); Interrupt_initModule(); Interrupt_initVectorTable(); Interrupt_register(INT_SCIA_TX, sciaTXFIFOISR); Interrupt_enable(INT_SCIA_TX); ...... }
|
实现发送中断服务函数,跟阻塞式发送不一样的是,我们需要使用非阻塞式接口:SCI_writeCharNonBlocking
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| __interrupt void sciaTXFIFOISR(void) { while((txBufferIndex < txDataCount) && (SCI_getTxFIFOStatus(SCIA_BASE) != SCI_FIFO_TX15)) { SCI_writeCharNonBlocking(SCIA_BASE, txBuffer[txBufferIndex++]); }
if((txBufferIndex >= txDataCount) && (SCI_getTxFIFOStatus(SCIA_BASE) == SCI_FIFO_TX0)) { isTransmitting = false; SCI_disableInterrupt(SCIA_BASE, SCI_INT_TXFF); } SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); }
|
JustFloat
自定义单帧数据类型:Float类型数据,使用union
是为了方便通过uint16_t
的方式进行序列化
1 2 3 4 5 6 7 8 9
| #define TX_BUFFER_SIZE 32 #define CH_COUNT 5 #define PI 3.14159265358979323846f
typedef union { float DataFloat; uint16_t DataUint16[2]; } FloatUnion;
|
实现单帧数据的发送:确保帧尾能对的上,每一次发送都要发送使能中断,第一次需要手动触发发送中断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| void SCIA_sendFrame(float chn1, float chn2, float chn3, float chn4, float chn5) {
while(isTransmitting) { }
FloatUnion data[CH_COUNT];
data[0].DataFloat = chn1; data[1].DataFloat = chn2; data[2].DataFloat = chn3; data[3].DataFloat = chn4; data[4].DataFloat = chn5;
txBufferIndex = 0; txDataCount = 0;
int i; for(i = 0; i < CH_COUNT; i++) { txBuffer[txDataCount++] = (uint8_t)(data[i].DataUint16[0] & 0xFF); txBuffer[txDataCount++] = (uint8_t)((data[i].DataUint16[0] >> 8) & 0xFF); txBuffer[txDataCount++] = (uint8_t)(data[i].DataUint16[1] & 0xFF); txBuffer[txDataCount++] = (uint8_t)((data[i].DataUint16[1] >> 8) & 0xFF); }
txBuffer[txDataCount++] = 0x00; txBuffer[txDataCount++] = 0x00; txBuffer[txDataCount++] = 0x80; txBuffer[txDataCount++] = 0x7F;
isTransmitting = true; txBufferIndex = 0; SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXFF); while((txBufferIndex < txDataCount) && (SCI_getTxFIFOStatus(SCIA_BASE) != SCI_FIFO_TX15)) { SCI_writeCharNonBlocking(SCIA_BASE, txBuffer[txBufferIndex++]); } }
|
模拟数据
我们来实现模拟数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| float angle = 0.0f; while(1) { float normalized_angle = normalize_angle(angle); float sin_val; float cos_val;
sin_val = limit_range(sinf(normalized_angle), -1.0f, 1.0f); cos_val = limit_range(cosf(normalized_angle*2), -1.0f, 1.0f);
SCIA_sendFrame(angle, round_to_2_decimal(sin_val), round_to_2_decimal(sin_val+cos_val), limit_range(round_to_2_decimal(sin_val * cos_val), -1.0f, 1.0f), limit_range(round_to_2_decimal(cos_val * cos_val), 0.0f, 1.0f));
angle += 0.1f; DEVICE_DELAY_US(10); }
|
值得一提的是,三角函数它是通过查表法来实现的,angle
值太大会有误差,我们需要设计归一化函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| float normalize_angle(float angle) { const float two_pi = 2.0f * PI; float normalized = fmodf(angle, two_pi); if(normalized < -PI) normalized += two_pi; if(normalized > PI) normalized -= two_pi; return normalized; }
float round_to_2_decimal(float value) { const float factor = 100.0f; float temp = value * factor; if(temp >= 0.0f) { temp = floorf(temp + 0.5f); } else { temp = ceilf(temp - 0.5f); } if(fabsf(temp) < 1e-6f) { return 0.0f; } return temp / factor; }
float limit_range(float value, float min, float max) { if(value > max) return max; if(value < min) return min; return value; }
|
运行效果
VOFA+的实时运行效果:显示5个通道的波形数据
