From 8acb95d566479dcd4bc16effbc32a10ab31c78ce Mon Sep 17 00:00:00 2001 From: 4x-tech Date: Mon, 17 Nov 2025 17:02:53 +0800 Subject: [PATCH] move to ccs based on 39cc590260f6d69837dd16740b7b8612e8935592 --- .gitignore | 7 ++ 3rd/config.h | 7 ++ 3rd/delay.c | 9 ++ 3rd/delay.h | 7 ++ 3rd/dfoc.c | 186 +++++++++++++++++++++++++++++++++++++ 3rd/dfoc.h | 20 ++++ 3rd/lowpass_filter.c | 48 ++++++++++ 3rd/lowpass_filter.h | 12 +++ 3rd/mt6701.c | 215 +++++++++++++++++++++++++++++++++++++++++++ 3rd/mt6701.h | 32 +++++++ 3rd/pid_control.c | 51 ++++++++++ 3rd/pid_control.h | 9 ++ 3rd/pwm.c | 25 +++++ 3rd/pwm.h | 11 +++ 3rd/uart_redircet.c | 53 +++++++++++ 3rd/uart_redircet.h | 7 ++ README.html | 115 +++++++++++++++++++++++ README.md | 41 +++++++++ empty.c | 169 ++++++++++++++++++++++++++++++++++ empty.syscfg | 145 +++++++++++++++++++++++++++++ 20 files changed, 1169 insertions(+) create mode 100644 .gitignore create mode 100644 3rd/config.h create mode 100644 3rd/delay.c create mode 100644 3rd/delay.h create mode 100644 3rd/dfoc.c create mode 100644 3rd/dfoc.h create mode 100644 3rd/lowpass_filter.c create mode 100644 3rd/lowpass_filter.h create mode 100644 3rd/mt6701.c create mode 100644 3rd/mt6701.h create mode 100644 3rd/pid_control.c create mode 100644 3rd/pid_control.h create mode 100644 3rd/pwm.c create mode 100644 3rd/pwm.h create mode 100644 3rd/uart_redircet.c create mode 100644 3rd/uart_redircet.h create mode 100644 README.html create mode 100644 README.md create mode 100644 empty.c create mode 100644 empty.syscfg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85ba967 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.settings/ +Debug/ +targetConfigs/ +.clangd +.cproject +.project +.ccsproject diff --git a/3rd/config.h b/3rd/config.h new file mode 100644 index 0000000..a609801 --- /dev/null +++ b/3rd/config.h @@ -0,0 +1,7 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define DEBUG_ENABLED true +#define DEBUG_MT_ENABLED false +#define DEBUG_DFOC_ENABLED false +#endif \ No newline at end of file diff --git a/3rd/delay.c b/3rd/delay.c new file mode 100644 index 0000000..1b5a17f --- /dev/null +++ b/3rd/delay.c @@ -0,0 +1,9 @@ +#include "delay.h" +#include "ti_msp_dl_config.h" +void delay_ms(uint16_t ms) +{ + while(ms--) + { + delay_cycles(CPUCLK_FREQ / 1000); + } +} diff --git a/3rd/delay.h b/3rd/delay.h new file mode 100644 index 0000000..1cd521f --- /dev/null +++ b/3rd/delay.h @@ -0,0 +1,7 @@ +#ifndef delay_h +#define delay_h +#include + +void delay_ms(uint16_t ms); + +#endif /* ti_msp_dl_config_h */ \ No newline at end of file diff --git a/3rd/dfoc.c b/3rd/dfoc.c new file mode 100644 index 0000000..53e290d --- /dev/null +++ b/3rd/dfoc.c @@ -0,0 +1,186 @@ + +#include +#include +#include "pwm.h" +#include "mt6701.h" +#include "delay.h" +#include "lowpass_filter.h" +#include "pid_control.h" +#include +#include +#include "config.h" + +#define PI 3.14159265359f +#define _3PI_2 4.71238898f +#define _1_SQRT3 0.57735026919f +#define _2_SQRT3 1.15470053838f + +volatile float Ua = 0, Ub = 0, Uc = 0, Ualpha, Ubeta = 0, dc_a = 0, dc_b = 0, dc_c = 0; +const float voltage_limit = 8; +const float voltage_power_supply = 12.0f; +volatile float zero_electric_Angle = 0.0; + +extern int pp; +extern int Dir; + + + +void Motor_en() +{ + // GPIO_InitTypeDef GPIO_InitStructure; + // + // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); + // + // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + // GPIO_Init(GPIOA,&GPIO_InitStructure); + // + // GPIO_SetBits(GPIOA, GPIO_Pin_8); +} + +//限制幅值 +float constrain(float amt, float low, float high) +{ + return ((amt < low) ? (low) : ((amt) > (high) ? (high) : (amt))); +} + +//将角度归化到0-2PI +float normalizeAngle(float angle) +{ + volatile float a = fmod(angle, 2 * PI); + return ((a >= 0) ? a : (a + 2 * PI)); +} + +float electricAngle(void) +{ + return normalizeAngle((GetAngle_NoTrack() * pp * Dir) - zero_electric_Angle); +} + +void SetPwm(float Ua, float Ub, float Uc) +{ + volatile float U_a = 0.0; + volatile float U_b = 0.0; + volatile float U_c = 0.0; + + U_a = constrain(Ua, 0.0f, voltage_limit); + U_b = constrain(Ub, 0.0f, voltage_limit); + U_c = constrain(Uc, 0.0f, voltage_limit); + //printf("Ua : %f -- Ub : %f -- Uc : %f -- U_a : %f -- U_b : %f -- U_c : %f \n",Ua,Ub,Uc,U_a,U_b,U_c); + dc_a = constrain(U_a / voltage_power_supply, 0.0f, 1.0f); + dc_b = constrain(U_b / voltage_power_supply, 0.0f, 1.0f); + dc_c = constrain(U_c / voltage_power_supply, 0.0f, 1.0f); + + PWM_Channel1(dc_a * 1000.0f); // 频率15k + PWM_Channel2(dc_b * 1000.0f); + PWM_Channel3(dc_c * 1000.0f); + + + +} + +//FOC核心算法,克拉克逆变换/帕克逆变换 +volatile float test_angle = 0.0; +volatile float last_test_angle = 0.0; +void SetPhaseVoltage(float Uq, float Ud, float angle_el) +{ + // angle_el = normalizeAngle(angle_el); + test_angle = angle_el - last_test_angle; + + Ualpha = -Uq * sin(angle_el); + Ubeta = Uq * cos(angle_el); + + Ua = Ualpha + voltage_power_supply / 2; + Ub = (sqrt(3) * Ubeta - Ualpha) / 2 + voltage_power_supply / 2; + Uc = -(Ualpha + sqrt(3) * Ubeta) / 2 + voltage_power_supply / 2; + + SetPwm(Ua, Ub, Uc); + + + + last_test_angle = angle_el; +} + +void Check_Sensor(void) +{ + //SetPhaseVoltage(3, 0, _3PI_2); + //delay_ms(3000); + zero_electric_Angle = electricAngle(); + // SetPhaseVoltage(0, 0, _3PI_2); + //delay_ms(500); +} + +void FOC_Init(float power) +{ + //voltage_power_supply = power; + //PWM_Init(); + //CurrSense_Init(); + //AS5600_Init(); + + Check_Sensor(); +} + + +// 单角度环 +void Set_Angle(float Target) +{ + volatile float langle = GetAngle(); + if(DEBUG_ENABLED & DEBUG_DFOC_ENABLED) + { + printf("angle readback in dfoc.c is %f \n", langle); + } + volatile float Uq = PID_Controller(0.067, 0.01, 0, (Target - Dir * langle) * 180 / PI); + //volatile float Uq = PID_Controller(0.06, 0, 0, (Target - Dir * langle) * 180 / PI); + if(DEBUG_ENABLED& DEBUG_DFOC_ENABLED) + { + printf("Uq is %f \n", Uq); + } + SetPhaseVoltage(Uq, 0, electricAngle()); +} + +volatile double openloop_timestamp; +float velocityopenloop(float target) +{ + volatile float Uq = 0.0; + volatile double Ts = 0.0; + volatile double shaft_angle; + + volatile uint32_t now_ts = DL_SYSTICK_getValue(); + + + if(now_ts < openloop_timestamp) + { + Ts = (openloop_timestamp - now_ts) / 80.0f * 1e-6f; + } + else + { + Ts = (0xFFFFFF - now_ts + openloop_timestamp) / 80.0f * 1e-6f; + } + + if(Ts < 0 || Ts >= 0.005) + { + Ts = 0.001f; + } + + shaft_angle = normalizeAngle(shaft_angle + pp * target * Ts); + + if(DEBUG_ENABLED) + { + //printf("shaft_angle : %f -- target : %f -- Ts : %f \n",shaft_angle,target,Ts); + } + + + Uq = voltage_limit; + + SetPhaseVoltage(Uq, 0, shaft_angle); + printf("shaft_angle : %f \n", shaft_angle); + openloop_timestamp = now_ts; + + return Uq; +} + + + + + + diff --git a/3rd/dfoc.h b/3rd/dfoc.h new file mode 100644 index 0000000..bba2692 --- /dev/null +++ b/3rd/dfoc.h @@ -0,0 +1,20 @@ +#ifndef __DFOC_H +#define __DFOC_H + +void Motor_en(void); +float constrain(float amt, float low, float high); +void SetPwm(float Ua, float Ub, float Uc); +float normalizeAngle(float angle); +void SetPhaseVoltage(float Uq, float Ud, float angle_el); +void Check_Sensor(void); +void FOC_Init(float power); +float electricAngle(void); +float GetCommand(void); +void Set_Angle(float Target); +float velocityopenloop(float target); + + + +#endif + + diff --git a/3rd/lowpass_filter.c b/3rd/lowpass_filter.c new file mode 100644 index 0000000..82c95fc --- /dev/null +++ b/3rd/lowpass_filter.c @@ -0,0 +1,48 @@ + +#include +#include + +float y = 0; +float Lowpassfilter_sim(float x) +{ + float out = 0.9 * x + 0.1 * y; + y = x; + return out; +} + +uint32_t Last_Timesamp = 0.0; +float Last_y = 0.0; +float Lowpassfilter(float Tf, float x) +{ + float dt = 0.0; + + uint32_t Timesamp = DL_SYSTICK_getValue(); + if(Timesamp < Last_Timesamp) + { + dt = (float)(Last_Timesamp - Timesamp) / 80 * 1e-6; + } + else + { + dt = (float)(0xFFFFFF - Timesamp + Last_Timesamp) / 80 * 1e-6; + } + + if(dt < 0.0 || dt == 0) + { + dt = 0.0015f; + } + else if(dt > 0.005f) + { + Last_y = x; + Last_Timesamp = Timesamp; + return x; + } + float alpha = Tf / (Tf + dt); + float y = alpha * Last_y + (1.0f - alpha) * x; + + Last_y = y; + Last_Timesamp = Timesamp; + + + return y; +} + diff --git a/3rd/lowpass_filter.h b/3rd/lowpass_filter.h new file mode 100644 index 0000000..4189639 --- /dev/null +++ b/3rd/lowpass_filter.h @@ -0,0 +1,12 @@ +#ifndef __LOWPASS_FILTER_H +#define __LOWPASS_FILTER_H + + +float Lowpassfilter(float Tf, float x); +float Lowpassfilter_sim(float x); + + + +#endif + + diff --git a/3rd/mt6701.c b/3rd/mt6701.c new file mode 100644 index 0000000..2224332 --- /dev/null +++ b/3rd/mt6701.c @@ -0,0 +1,215 @@ +#include "mt6701.h" +#include "ti_msp_dl_config.h" +#include "uart_redircet.h" +#include "stdio.h" +#include "config.h" + +volatile int16_t angle; +volatile float angle_f; +volatile float angle_f_rad; + +volatile bool gIsI2cError = false; + +#define DEBUG_I2C false + +/* Data sent to the Target */ +uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = +{ + 0x03 +}; + +/* Data received from Target */ +volatile uint8_t gRxPacket[I2C_RX_PACKET_SIZE] = {0}; + +/* I2C clock configuration */ +DL_I2C_ClockConfig gI2CclockConfig; +/* Frequency of selected I2C clock*/ +volatile uint32_t gClockSelFreq; + +/* Cycles to delay after controller transfer initiated */ +volatile uint32_t gDelayCycles; + +/* I2C Target address */ +#define I2C_TARGET_ADDRESS (0x06) + +void MT6701_iic_read_angel(void) +{ + /* Get I2C clock source and clock divider to use for delay cycle calculation */ + DL_I2C_getClockConfig(I2C_1_INST, &gI2CclockConfig); + switch(gI2CclockConfig.clockSel) + { + case DL_I2C_CLOCK_BUSCLK: + gClockSelFreq = 32000000; + break; + case DL_I2C_CLOCK_MFCLK: + gClockSelFreq = 4000000; + break; + default: + break; + } + /* + * Calculate number of clock cycles to delay after controller transfer initiated + * gDelayCycles = 3 I2C functional clock cycles + * gDelayCycles = 3 * I2C clock divider * (CPU clock freq / I2C clock freq) + */ + gDelayCycles = (5 * (gI2CclockConfig.divideRatio + 1)) * + (CPUCLK_FREQ / gClockSelFreq); + if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) + { + printf("i2c before writing -------\n"); + + } + + /* + * Fill FIFO with data. This example will send a MAX of 8 bytes since it + * doesn't handle the case where FIFO is full + */ + DL_I2C_fillControllerTXFIFO(I2C_1_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE); + + /* Wait for I2C to be Idle */ + while(!( + DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) + ; + + /* Send the packet to the controller. + * This function will send Start + Stop automatically. + */ + DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, + DL_I2C_CONTROLLER_DIRECTION_TX, I2C_TX_PACKET_SIZE); + + if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) + { + printf("i2c writing done -------\n"); + } + + /* Workaround for errata I2C_ERR_13 */ + delay_cycles(gDelayCycles); + + /* Poll until the Controller writes all bytes */ + while( + DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY) + ; + + /* Trap if there was an error */ + if(DL_I2C_getControllerStatus(I2C_1_INST) & + DL_I2C_CONTROLLER_STATUS_ERROR) + { + gIsI2cError = true; + + if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) + { + printf("i2c error ------------------------------------------\n"); + } + /* LED will remain high if there is an error */ + __BKPT(0); + return; + } + + /* Wait for I2C to be Idle */ + while(!( + DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) + ; + + /* Add delay between transfers */ + delay_cycles(1000); + + if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) + { + printf("i2c before reading -------\n"); + } + + /* Send a read request to Target */ + DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, + DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE); + + /* + * Receive all bytes from target. LED will remain high if not all bytes + * are received + */ + for(uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) + { + while(DL_I2C_isControllerRXFIFOEmpty(I2C_1_INST)) + ; + gRxPacket[i] = DL_I2C_receiveControllerData(I2C_1_INST); + } + + if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) + { + printf("i2c reading done -------\n"); + } + + +} +volatile float Last_ts = 0.0; +volatile float last_angle = 0.0; + +// 单圈值 +float GetAngle_NoTrack(void) +{ + MT6701_iic_read_angel(); + angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); + angle_f_rad = (float)angle * _2PI / 16384; + if(DEBUG_ENABLED & DEBUG_MT_ENABLED) + { + printf("angle_rad read back is %f \n", angle_f_rad); + } + return angle_f_rad; +} +volatile float full_rotations = 0.0; +volatile float Last_Angle_rad = 0.0; +//多圈值 +float GetAngle(void) +{ + volatile float D_Angle_rad = 0.0; + volatile float Angle_rad = GetAngle_NoTrack(); + D_Angle_rad = Angle_rad - Last_Angle_rad; + + if(fabs(D_Angle_rad) > (0.8f * 2 * PI)) + { + full_rotations = full_rotations + ((D_Angle_rad > 0) ? -1 : 1); + } + + Last_Angle_rad = Angle_rad; + + return (full_rotations * 2 * PI + Last_Angle_rad); +} + +volatile float Last_Vel_ts = 0.0; +volatile float Vel_Last_Angle = 0.0; +float GetVelocity(void) +{ + volatile float dt = 0.0; + volatile float Vel_ts = SysTick -> VAL; + if(Vel_ts < Last_Vel_ts) + { + dt = (Last_Vel_ts - Vel_ts) / 80 * 1e-6f; + } + else + { + dt = (0xFFFFFF - Vel_ts + Last_Vel_ts) / 80 * 1e-6f; + } + + if(dt < 0.0001) + { + dt = 10000; + } + + float Vel_Angle = GetAngle(); + + float dv = Vel_Angle - Vel_Last_Angle; + + float velocity = (Vel_Angle - Vel_Last_Angle) / dt; + + Last_Vel_ts = Vel_ts; + Vel_Last_Angle = Vel_Angle; + + + return velocity; +} + +void MT6701_get_angle_degree(void) +{ + MT6701_iic_read_angel(); + angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); + angle_f = (float)angle * 360 / 16384; +} diff --git a/3rd/mt6701.h b/3rd/mt6701.h new file mode 100644 index 0000000..468a809 --- /dev/null +++ b/3rd/mt6701.h @@ -0,0 +1,32 @@ +#ifndef MT6701_H +#define MT6701_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define PI 3.14159265359f +#define _2PI 6.28318530718f + +#define I2C_TX_PACKET_SIZE (1) + +/* + * Number of bytes to received from target. + * This example uses FIFO with polling, and the maximum FIFO size is 8. + * Refer to interrupt examples to handle larger packets + */ +#define I2C_RX_PACKET_SIZE (2) +void MT6701_iic_read_angel(void); +void MT6701_get_angle_degree(void); +float GetAngle(void); +float GetAngle_NoTrack(void); +float GetVelocity(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MT6701_H */ diff --git a/3rd/pid_control.c b/3rd/pid_control.c new file mode 100644 index 0000000..8c11faa --- /dev/null +++ b/3rd/pid_control.c @@ -0,0 +1,51 @@ +#include +#include +#define limit 5.0 +#define Output_ramp 10000 + +//限幅 +float _constrain(float amt, float low, float high) +{ + return ((amt < low) ? (low) : ((amt) > (high) ? (high) : (amt))); +} + +unsigned long Timestamp_Last = 0.0; +float Last_Error = 0.0; +float Last_intergration = 0.0; +float Last_Output = 0.0; +float PID_Controller(float Kp, float Ki, float Kd, float Error) +{ + float Ts = 0.0; + uint32_t Timestamp = DL_SYSTICK_getValue(); + if(Timestamp < Timestamp_Last) + { + Ts = (float)(Timestamp_Last - Timestamp) / 80 * 1e-6; + } + else + { + Ts = (0xFFFFFF - Timestamp + Timestamp_Last) / 80 * 1e-6; + } + + if(Ts <= 0 || Ts > 0.05f) + { + Ts = 0.001; + } + + float proportion = Kp * Error;//P环 + + float intergration = Last_intergration + Ki * 0.5f * Ts * Error;//I环 + intergration = _constrain(intergration, -limit, limit); + + float differential = Kd * (Error - Last_Error) / Ts; //D环 + + float Output = proportion + intergration + differential; + Output = _constrain(Output, -limit, limit); + + Last_Error = Error; + Last_intergration = intergration; + Last_Output = Output; + Timestamp_Last = Timestamp; + + return Output; +} + diff --git a/3rd/pid_control.h b/3rd/pid_control.h new file mode 100644 index 0000000..04155c1 --- /dev/null +++ b/3rd/pid_control.h @@ -0,0 +1,9 @@ +#ifndef __PID_CONTROL_H +#define __PID_CONTROL_H + +float PID_Controller(float Kp, float Ki, float Kd, float Error); +float _constrain(float amt, float low, float high); + +#endif + + diff --git a/3rd/pwm.c b/3rd/pwm.c new file mode 100644 index 0000000..42d1d19 --- /dev/null +++ b/3rd/pwm.c @@ -0,0 +1,25 @@ +#include "pwm.h" +#include "ti_msp_dl_config.h" + +void PWM_Channel1(uint16_t Compare) +{ + DL_TimerA_setCaptureCompareValue(PWM_0_INST, Compare, GPIO_PWM_0_C0_IDX); +} + +void PWM_Channel2(uint16_t Compare) +{ + DL_TimerA_setCaptureCompareValue(PWM_0_INST, Compare, GPIO_PWM_0_C1_IDX); +} + +void PWM_Channel3(uint16_t Compare) +{ + DL_TimerA_setCaptureCompareValue(PWM_0_INST, Compare, GPIO_PWM_0_C2_IDX); +} + + + + + + + + diff --git a/3rd/pwm.h b/3rd/pwm.h new file mode 100644 index 0000000..2eb0e99 --- /dev/null +++ b/3rd/pwm.h @@ -0,0 +1,11 @@ +#ifndef __PWM_H +#define __PWM_H +#include + +void PWM_Channel1(uint16_t Compare); +void PWM_Channel2(uint16_t Compare); +void PWM_Channel3(uint16_t Compare); + +#endif + + diff --git a/3rd/uart_redircet.c b/3rd/uart_redircet.c new file mode 100644 index 0000000..8f93338 --- /dev/null +++ b/3rd/uart_redircet.c @@ -0,0 +1,53 @@ +#include "ti_msp_dl_config.h" +#include +#include + + +/* ARM Compiler 6 半主机模式禁用声明 */ +#if (__ARMCC_VERSION >= 6010050) + __asm(".global __use_no_semihosting\n\t"); + __asm(".global __ARM_use_no_argv \n\t"); +#else + #pragma import(__use_no_semihosting) +#endif + +FILE __stdout; + +/* 系统退出函数实现 */ +void _sys_exit(int x) +{ + x = x; + while(1) + ; /* 死循环防止程序异常退出 */ +} + +/* ARM Compiler 6 printf重定向实现 */ +int fputc(int c, FILE *stream) +{ + /* 等待UART发送缓冲区就绪 */ + while(DL_UART_Main_isBusy(UART_0_INST)) + ; + + /* 发送字符 */ + DL_UART_Main_transmitData(UART_0_INST, (uint8_t)c); + return c; +} + +int fputs(const char *restrict s, FILE *restrict stream) +{ + uint16_t i, len; + len = strlen(s); + for(i = 0; i < len; i++) + { + fputc(s[i], stream); + } + return len; +} + +int puts(const char *_ptr) +{ + int count = fputs(_ptr, stdout); + count += fputc('\n', stdout); /* 自动添加换行 */ + return count; +} + diff --git a/3rd/uart_redircet.h b/3rd/uart_redircet.h new file mode 100644 index 0000000..a64f228 --- /dev/null +++ b/3rd/uart_redircet.h @@ -0,0 +1,7 @@ +#ifndef Uart_h +#define Uart_h +#include + +void UART_Console_write(const uint8_t *data, uint16_t size); + +#endif /* ti_msp_dl_config_h */ \ No newline at end of file diff --git a/README.html b/README.html new file mode 100644 index 0000000..4180f14 --- /dev/null +++ b/README.html @@ -0,0 +1,115 @@ + + + + + + + Readme + + + + + + + +
+
+ +
+ +
+
+

Readme

+

Example Summary

+

Empty project using DriverLib. This example shows a basic empty project using DriverLib with just main file and SysConfig initialization.

+

Peripherals & Pin Assignments

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PeripheralPinFunction
SYSCTL
DEBUGSSPA20Debug Clock
DEBUGSSPA19Debug Data In Out
+

BoosterPacks, Board Resources & Jumper Settings

+

Visit LP_MSPM0G3507 for LaunchPad information, including user guide and hardware files.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PinPeripheralFunctionLaunchPad PinLaunchPad Settings
PA20DEBUGSSSWCLKN/A
  • PA20 is used by SWD during debugging
    • J101 15:16 ON Connect to XDS-110 SWCLK while debugging
    • J101 15:16 OFF Disconnect from XDS-110 SWCLK if using pin in application
PA19DEBUGSSSWDION/A
  • PA19 is used by SWD during debugging
    • J101 13:14 ON Connect to XDS-110 SWDIO while debugging
    • J101 13:14 OFF Disconnect from XDS-110 SWDIO if using pin in application
+

Device Migration Recommendations

+

This project was developed for a superset device included in the LP_MSPM0G3507 LaunchPad. Please visit the CCS User’s Guide for information about migrating to other MSPM0 devices.

+

Low-Power Recommendations

+

TI recommends to terminate unused pins by setting the corresponding functions to GPIO and configure the pins to output low or input with internal pullup/pulldown resistor.

+

SysConfig allows developers to easily configure unused pins by selecting BoardConfigure Unused Pins.

+

For more information about jumper configuration to achieve low-power using the MSPM0 LaunchPad, please visit the LP-MSPM0G3507 User’s Guide.

+

Example Usage

+

Compile, load and run the example.

+ +
+ + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce86fb3 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +## Example Summary + +Empty project using DriverLib. +This example shows a basic empty project using DriverLib with just main file +and SysConfig initialization. + +## Peripherals & Pin Assignments + +| Peripheral | Pin | Function | +| --- | --- | --- | +| SYSCTL | | | +| DEBUGSS | PA20 | Debug Clock | +| DEBUGSS | PA19 | Debug Data In Out | + +## BoosterPacks, Board Resources & Jumper Settings + +Visit [LP_MSPM0G3507](https://www.ti.com/tool/LP-MSPM0G3507) for LaunchPad information, including user guide and hardware files. + +| Pin | Peripheral | Function | LaunchPad Pin | LaunchPad Settings | +| --- | --- | --- | --- | --- | +| PA20 | DEBUGSS | SWCLK | N/A |
  • PA20 is used by SWD during debugging
    • `J101 15:16 ON` Connect to XDS-110 SWCLK while debugging
    • `J101 15:16 OFF` Disconnect from XDS-110 SWCLK if using pin in application
| +| PA19 | DEBUGSS | SWDIO | N/A |
  • PA19 is used by SWD during debugging
    • `J101 13:14 ON` Connect to XDS-110 SWDIO while debugging
    • `J101 13:14 OFF` Disconnect from XDS-110 SWDIO if using pin in application
| + +### Device Migration Recommendations +This project was developed for a superset device included in the LP_MSPM0G3507 LaunchPad. Please +visit the [CCS User's Guide](https://software-dl.ti.com/msp430/esd/MSPM0-SDK/latest/docs/english/tools/ccs_ide_guide/doc_guide/doc_guide-srcs/ccs_ide_guide.html#sysconfig-project-migration) +for information about migrating to other MSPM0 devices. + +### Low-Power Recommendations +TI recommends to terminate unused pins by setting the corresponding functions to +GPIO and configure the pins to output low or input with internal +pullup/pulldown resistor. + +SysConfig allows developers to easily configure unused pins by selecting **Board**→**Configure Unused Pins**. + +For more information about jumper configuration to achieve low-power using the +MSPM0 LaunchPad, please visit the [LP-MSPM0G3507 User's Guide](https://www.ti.com/lit/slau873). + +## Example Usage + +Compile, load and run the example. diff --git a/empty.c b/empty.c new file mode 100644 index 0000000..55249a3 --- /dev/null +++ b/empty.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ti_msp_dl_config.h" +#include "delay.h" +#include "mt6701.h" +#include "dfoc.h" +#include +#include +#include +#include "config.h" +#include +#include + + + +extern float angle_f; + +extern bool gIsI2cError; + +const float num_f = 0.123456f; + +volatile uint16_t count = 0 ; +volatile float Target = 0; //串口目标值 + + +const int pp = 7; //电机极对数 +const int Dir = -1; //电机编码器方向 + + +#define UART_PACKET_SIZE (6) + +/* Data received from UART */ +volatile uint8_t gUartRxPacket[UART_PACKET_SIZE] ={'a','b','c','d','e','f'}; + +volatile bool gCheckUART; + + + +void parse_uart_cmd(void) +{ + char num[10]={0}; + int i = 1; + int j = 0; + if(gUartRxPacket[0] == 'T' && gUartRxPacket[UART_PACKET_SIZE-1] == '\n')//数据第一位与数据的最后一位 + { + if(gUartRxPacket[1] != '-')//接受到的数据为正数 + { + while (gUartRxPacket[i] != '\n' && (isdigit(gUartRxPacket[i]) || gUartRxPacket[i] == '.')) {num[j++] = gUartRxPacket[i++];} + Target = atof(num); +// Serial_SendFloatNumber(Target,3,2); + } + else//接收到的数据为负数 + { + i=2; + while (gUartRxPacket[i] != '\n' && (isdigit(gUartRxPacket[i]) || gUartRxPacket[i] == '.')) {num[j++] = gUartRxPacket[i++];} + Target = -(atof(num)); +// Serial_SendFloatNumber(Target,3,2); + } + printf("%s",gUartRxPacket); + } + else + { + printf((char *)"Input format error\n"); + } +} + + + + + +int main(void) +{ + + SYSCFG_DL_init(); + + /* Configure DMA source, destination and size */ + DL_DMA_setSrcAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t)(&UART_0_INST->RXDATA)); + DL_DMA_setDestAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t) &gUartRxPacket[0]); + DL_DMA_setTransferSize(DMA, DMA_CH1_CHAN_ID, UART_PACKET_SIZE); + DL_DMA_enableChannel(DMA, DMA_CH1_CHAN_ID); + + + NVIC_EnableIRQ(UART_0_INST_INT_IRQN); + DL_TimerA_startCounter(PWM_0_INST); + + NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); + DL_TimerG_startCounter(TIMER_0_INST); + + + FOC_Init(12.6); + DL_SYSTICK_resetValue(); + + while(1) + { + //DL_GPIO_togglePins(LED_PORT, LED_PA0_PIN); + //delay_ms(10); + + //开环 + //velocityopenloop(Target); + //闭环 + //Set_Angle(Target); + if(gCheckUART) + { + gCheckUART = false; + parse_uart_cmd(); + Set_Angle(Target); + } + delay_ms(10); + + + } +} + + +void TIMER_0_INST_IRQHandler(void) +{ + switch(DL_TimerA_getPendingInterrupt(TIMER_0_INST)) + { + case DL_TIMERG_INTERRUPT_ZERO_EVENT: + + printf("Target is %f \n", Target); + //printf("%s",gUartRxPacket); + DL_GPIO_togglePins(LED_PORT, LED_PA0_PIN); + + break; + default: + break; + } +} +void UART_0_INST_IRQHandler(void) +{ + switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) { + case DL_UART_MAIN_IIDX_DMA_DONE_RX: + gCheckUART = true; + break; + default: + break; + } +} diff --git a/empty.syscfg b/empty.syscfg new file mode 100644 index 0000000..fa56caf --- /dev/null +++ b/empty.syscfg @@ -0,0 +1,145 @@ +/** + * These arguments were used when this file was generated. They will be automatically applied on subsequent loads + * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. + * @cliArgs --device "MSPM0G350X" --part "Default" --package "LQFP-48(PT)" --product "mspm0_sdk@2.07.00.05" + * @v2CliArgs --device "MSPM0G3507" --package "LQFP-48(PT)" --product "mspm0_sdk@2.07.00.05" + * @versions {"tool":"1.25.0+4268"} + */ + +/** + * Import the modules used in this configuration. + */ +const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false); +const GPIO1 = GPIO.addInstance(); +const I2C = scripting.addModule("/ti/driverlib/I2C", {}, false); +const I2C1 = I2C.addInstance(); +const PWM = scripting.addModule("/ti/driverlib/PWM", {}, false); +const PWM1 = PWM.addInstance(); +const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL"); +const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK"); +const TIMER = scripting.addModule("/ti/driverlib/TIMER", {}, false); +const TIMER1 = TIMER.addInstance(); +const UART = scripting.addModule("/ti/driverlib/UART", {}, false); +const UART1 = UART.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +const divider7 = system.clockTree["PLL_PDIV"]; +divider7.divideValue = 2; + +const divider9 = system.clockTree["UDIV"]; +divider9.divideValue = 2; + +const gate7 = system.clockTree["MFCLKGATE"]; +gate7.enable = true; + +const multiplier2 = system.clockTree["PLL_QDIV"]; +multiplier2.multiplyValue = 4; + +const mux4 = system.clockTree["EXHFMUX"]; +mux4.inputSelect = "EXHFMUX_XTAL"; + +const mux8 = system.clockTree["HSCLKMUX"]; +mux8.inputSelect = "HSCLKMUX_SYSPLL2X"; + +const mux12 = system.clockTree["SYSPLLMUX"]; +mux12.inputSelect = "zSYSPLLMUX_HFCLK"; + +const pinFunction4 = system.clockTree["HFXT"]; +pinFunction4.enable = true; +pinFunction4.inputFreq = 40; + +GPIO1.$name = "LED"; +GPIO1.associatedPins[0].$name = "PA0"; +GPIO1.associatedPins[0].pin.$assign = "PA0"; + +const Board = scripting.addModule("/ti/driverlib/Board", {}, false); +Board.peripheral.$assign = "DEBUGSS"; +Board.peripheral.swclkPin.$assign = "PA20"; +Board.peripheral.swdioPin.$assign = "PA19"; + +I2C1.$name = "I2C_1"; +I2C1.advAnalogGlitchFilter = "DISABLED"; +I2C1.basicEnableController = true; +I2C1.peripheral.sdaPin.$assign = "PB3"; +I2C1.peripheral.sclPin.$assign = "PB2"; +I2C1.sdaPinConfig.hideOutputInversion = scripting.forceWrite(false); +I2C1.sdaPinConfig.onlyInternalResistor = scripting.forceWrite(false); +I2C1.sdaPinConfig.passedPeripheralType = scripting.forceWrite("Digital"); +I2C1.sdaPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric2"; +I2C1.sclPinConfig.hideOutputInversion = scripting.forceWrite(false); +I2C1.sclPinConfig.onlyInternalResistor = scripting.forceWrite(false); +I2C1.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital"); +I2C1.sclPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric3"; + +PWM1.$name = "PWM_0"; +PWM1.ccIndex = [0,1,2]; +PWM1.clockDivider = 2; +PWM1.timerCount = 2000; +PWM1.pwmMode = "CENTER_ALIGN"; +PWM1.PWM_CHANNEL_0.$name = "ti_driverlib_pwm_PWMTimerCC0"; +PWM1.PWM_CHANNEL_1.$name = "ti_driverlib_pwm_PWMTimerCC1"; +PWM1.ccp0PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric4"; +PWM1.ccp1PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric5"; +PWM1.peripheral.$assign = "TIMA0"; +PWM1.peripheral.ccp0Pin.$assign = "PA21"; +PWM1.peripheral.ccp1Pin.$assign = "PA22"; +PWM1.peripheral.ccp2Pin.$assign = "PB20"; +PWM1.PWM_CHANNEL_2.$name = "ti_driverlib_pwm_PWMTimerCC2"; +PWM1.ccp2PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric6"; + +SYSCTL.forceDefaultClkConfig = true; +SYSCTL.peripheral.$assign = "SYSCTL"; + +SYSTICK.periodEnable = true; +SYSTICK.systickEnable = true; +SYSTICK.period = 16000000; + +TIMER1.$name = "TIMER_0"; +TIMER1.timerClkDiv = 8; +TIMER1.timerMode = "PERIODIC"; +TIMER1.timerClkPrescale = 8; +TIMER1.interrupts = ["ZERO"]; +TIMER1.timerClkSrc = "LFCLK"; +TIMER1.timerPeriod = "1"; +TIMER1.peripheral.$assign = "TIMG0"; + +UART1.$name = "UART_0"; +UART1.rxFifoThreshold = "DL_UART_RX_FIFO_LEVEL_ONE_ENTRY"; +UART1.targetBaudRate = 115200; +UART1.uartClkDiv = "8"; +UART1.enableFIFO = true; +UART1.txFifoThreshold = "DL_UART_TX_FIFO_LEVEL_ONE_ENTRY"; +UART1.enabledDMATXTriggers = "DL_UART_DMA_INTERRUPT_TX"; +UART1.enabledInterrupts = ["DMA_DONE_RX"]; +UART1.enabledDMARXTriggers = "DL_UART_DMA_INTERRUPT_RX"; +UART1.peripheral.$assign = "UART0"; +UART1.peripheral.rxPin.$assign = "PA11"; +UART1.peripheral.txPin.$assign = "PA10"; +UART1.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric0"; +UART1.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric1"; +UART1.DMA_CHANNEL_TX.$name = "DMA_CH0"; +UART1.DMA_CHANNEL_TX.addressMode = "b2f"; +UART1.DMA_CHANNEL_TX.srcLength = "BYTE"; +UART1.DMA_CHANNEL_TX.dstLength = "BYTE"; +UART1.DMA_CHANNEL_TX.peripheral.$assign = "DMA_CH0"; +UART1.DMA_CHANNEL_RX.$name = "DMA_CH1"; +UART1.DMA_CHANNEL_RX.addressMode = "f2b"; +UART1.DMA_CHANNEL_RX.srcLength = "BYTE"; +UART1.DMA_CHANNEL_RX.dstLength = "BYTE"; +UART1.DMA_CHANNEL_RX.transferMode = "FULL_CH_REPEAT_SINGLE"; + +const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig", {}, false); +ProjectConfig.migrationCondition = true; + +/** + * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future + * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to + * re-solve from scratch. + */ +pinFunction4.peripheral.$suggestSolution = "SYSCTL"; +pinFunction4.peripheral.hfxInPin.$suggestSolution = "PA5"; +pinFunction4.peripheral.hfxOutPin.$suggestSolution = "PA6"; +I2C1.peripheral.$suggestSolution = "I2C1"; +UART1.DMA_CHANNEL_RX.peripheral.$suggestSolution = "DMA_CH1";