This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/LAUNCHXL-F28379D:(F28027F/DRV8323RS 和 F28379D) I2C 连接

Guru**** 2348500 points
Other Parts Discussed in Thread: CONTROLSUITE, MOTORWARE, DRV8301, DRV8305, DRV8323, C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/927222/ccs-launchxl-f28379d-f28027f-drv8323rs-and-f28379d-i2c-connection

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:controlSUITEMOTORWAREDRV8301DRV8305DRV8323C2000WARE

工具/软件:Code Composer Studio

您好!

我正在尝试在 F28379D 和 F28027F 之间建立 I2C 连接、我正在使用 controlSUITE 中的 I2C EEPROM 示例。 我还想使用 F28379D 读取 ADC 值、并使用 Motorware lab05b 和 F28027F 控制速度。

我的问题是、如果第一个代码正确、我正在读取 ADC 值并将其放入 MsgBufferTM

哪个变量用于控制 Lab05b 中的速度、如果它是 spdKp、我是否只需使用 MsgBuffer 将其设置为相同的值?

F28379D 代码:

//
//包含的文件
//
#include
#include
#include
#include

#include "F28x_Project.h"// DSP28x 头文件
#include "sci_io.h"

//
//定义
//

#define I2C_SLAVE_ADDR 0x50
#define I2C_NUMBYTES 2.
#define I2C_EEPROM_HIGH_ADDR 0x00
#define I2C_EEPROM_LOW_ADDR 0x30

//
//微秒等待 ADC 转换。 所需时间更长。
//
#define CONV_WAIT 1L

//
//函数原型
//
void I2CA_Init (void);
uint16 I2CA_WriteData (struct I2CMSG *msg);
uint16 I2CA_ReadData (struct I2CMSG *msg);
_interrupt void i2c_int1a_isr (void);
void pass (void);
失效失效(失效);

int16_t currentSample;

//
//全局
//
struct I2CMSG I2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP、
I2C_SLAVE_ADDR、
I2C_NUMBYTES、
I2C_EEPROM_HIGH_ADDR、
I2C_EEPROM_LOW_ADDR、
0x12、//消息字节1
0x34};//消息字节2

struct I2CMSG I2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP、
I2C_SLAVE_ADDR、
I2C_NUMBYTES、
I2C_EEPROM_HIGH_ADDR、
I2C_EEPROM_LOW_ADDR};

struct I2CMSG * CurrentMsgPtr;
UINT16传递计数;
uint16 failcount;

extern void DSP28x_usDelay (uint32计数);

const unsigned char escRed[]={0x1B、0x5B、'3'、'1'、'm'};
const unsigned char escWhite []={0x1B、0x5B、'3'、'7'、'm'};
const unsigned char Left[]={0x1B、0x5B、'3'、'7'、'm'};
const unsigned char pucTempString[]="ADCIN14样片:";

//
// samplpleADC -
//
int16_t sampleADC (空)

int16_t 采样;

//
//在 SOC0上强制转换开始
//
AdcaRegs.ADCSOCFRC1.ALL = 0x03;

//
//等待转换结束。
//
while (AdcaRegs.ADCINTFlG.bit.ADCINT1 =0)

//
//等待 ADCINT1
//

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 ADCINT1

//
//从 SOC0获取 ADC 采样结果
//
采样= AdcaResultRegs.ADCRESULT1;

return (sample);

//
// scia_init - SCIA 8位字、波特率0x000F、默认值、1个停止位、
//无奇偶校验
//
void scia_init()

//
//注意:SCIA 外设的时钟被打开
//在 InitSysCtrl()函数中
//

//
// 1停止位,无回送,无奇偶校验,8个字符位,异步模式,
//空闲线协议
//
SciaRegs.SCICCR.all =0x0007;

//
//启用 TX、RX、内部 SCICLK、禁用 RX ERR、睡眠、 TXWAKE
//
SciaRegs.SCICTL1.all =0x0003;

SciaRegs.SCICTL2.bit.TXINTENA=1;
SciaRegs.SCICTL2.bit.RXBKINTENA=1;

//
// 115200波特@LSPCLK = 22.5MHz (90MHz SYSCLK)
//
SciaRegs.SCIHBAUD.ALL =0x0000;

SciaRegs.SCILBAUD.ALL =53;

SciaRegs.SCICTL1.all =0x0023;//从复位中撤回 SCI

返回;

//
//主函
//
void main (void)

uint16错误;
uint16 i;

volatile int status = 0;

CurrentMsgPtr =&I2cMsgOut1;
//
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2837xD_SYSCTRL.c 文件中。
//
InitSysCtrl();

//
//步骤2. 初始化 GPIO:
//此示例函数位于 F2837xD_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
//
InitGpio();

//
//对于这个示例、只初始化针对 SCI-A 端口的引脚。
//这些函数可在 F2837xD_GPIO.c 文件中找到。
//
GPIO_SetupPinMux (32、GPIO_MUX_CPU1、1);
GPIO_SetupPinMux (33、GPIO_MUX_CPU1、1);

//
//步骤3. 清除所有_interrupts 并初始化 PIE 矢量表:
//禁用 CPU __interrupts
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE __interrupts 和标志
//被清除。
//此函数位于 F2837xD_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU __interrupts 并清除所有 CPU __interrupt 标志:
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是__interrupt
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable();

//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.I2CA_INT =&i2c_int1a_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//
//步骤4. 初始化器件外设:
//
I2CA_Init();

//
//步骤5. 特定于用户的代码
//

//
//清除计数器
//
PassCount = 0;
failcount = 0;

//
//清除传入消息缓冲区
//
对于(I = 0;I < I2C_MAX_BUFFER_SIZE;I++)

I2cMsgIn1.MsgBuffer[i]= 0x0000;

//
//启用此示例所需的__interrupts
//

//
//在 PIE:组8 _interrupt 1中启用 I2C _interrupt 1
//
PieCtrlRegs.PIEIER8.bit.INTx1 = 1;

//
//启用连接到 PIE 组8的 CPU INT8
//
IER |= M_INT8;
EINT;

//
//如果从闪存运行,则只将 RAM 复制到 RAM
//
#ifdef _flash
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif

//
//初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2806x_SYSCTRL.c 文件中。
//
InitSysCtrl();

//
//对于这个示例、只初始化针对 SCI-A 端口的引脚。
//
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;
GpioCtrlRegs.GPBGMUX1.bit.GPIO42 = 3;
GpioCtrlRegs.GPBGMUX1.bit.GPIO43 = 3;
EDIS;

//
//清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2837xD_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU 中断并清除所有 CPU 中断标志
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable();

//
//初始化 SCIA
//
scia_init();

//
//初始化 LED 的 GPIO 并将其关闭
//
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
GpioDataRegs.GPADAT.bit.GPIO31 = 1;
GpioDataRegs.GPBDAT.bit.GPIO34 = 1;
EDIS;

//
//启用全局中断和更高优先级的实时调试事件:
//
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

//
//配置 ADC:初始化 ADC
//
EALLOW;

//
//写入配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcbRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCB、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);

//
//将脉冲位置设置为晚期
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

//
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//
//延迟1ms 以允许 ADC 加电时间
//
DELAY_US (1000);

//
// ADCA
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0x0E;//SOC0将转换引脚 ADCIN14

//
//采样窗口为 acqps + 1个 SYSCLK 周期
//
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 25;

AdcaRegs.ADCSOC1CTL.bit.CHSEL = 0x0E;//SOC1将转换引脚 ADCIN14

//
//采样窗口为 acqps + 1个 SYSCLK 周期
//
AdcaRegs.ADCSOC1CTL.bit.ACQPS = 25;

AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;// SOC1结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除

//
//将 STDOUT 重定向到 SCI
//
状态= add_device ("scia"、_ssa、SCI_open、SCI_close、SCI_read、 SCI_WRITE、
SCI_lseek、SCI_unlink、SCI_rename);
freopen ("scia:"、"w"、stdout);
setvbuf (stdout、NULL、_IONBF、0);

//
//旋转 LED
//
GpioDataRegs.GPADAT.bit.GPIO31 = 0;
GpioDataRegs.GPBDAT.bit.GPIO34 = 1;

对于(I = 0;I < 50;I++)

GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
DELAY_US (50000);

//
// LED 关闭
//
GpioDataRegs.GPADAT.bit.GPIO31 = 1;
GpioDataRegs.GPBDAT.bit.GPIO34 = 1;

currentSample = sampleadc ();

for (;;)

//
//对 ADCIN14进行采样
//
currentSample = sampleadc ();

//
//如果样本高于中量程灯,则一个 LED
//
if (currentSample > 2048)

GpioDataRegs.GPBSET.BIO34 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;

其他

//
//以其他方式点亮另一个
//
GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
GpioDataRegs.GPASET.bit.GPIO31 = 1;

// delay_US (1000000);
//}
//
//将数据写入 EEPROM 部分
//

//
//检查外发消息是否应发送。
//在本例中,初始化后发送一个停止位。
//
if (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_SEND_WITHSTOP)

错误= I2CA_WriteData (&I2cMsgOut1);

//
//如果通信已正确启动,请将 msg 状态设置为忙
//并更新__interrupt 服务例程的 CurrentMsgPtr。
//否则,不执行任何操作,然后重试下一个循环。 发送一条消息
//启动后、I2C _interrupts 将处理其余部分。 搜索
// i2c_EEPROM_ISR.c 文件中的 ICINTR1A_ISR。
//
如果(错误= I2C_Success)

CurrentMsgPtr =&I2cMsgOut1;
I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY;

//
//从 EEPROM 部分读取数据
//

//
//检查外发消息状态。 如果状态为、则绕过读取段
//未处于非活动状态。
//
if (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_INACTIVE)

//
//检查传入消息状态。
//
if (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP)

//
// EEPROM 地址设置部分
//
while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success)

//
//可以设置一个尝试计数器来打破无限 while
//循环。 EEPROM 会在它发出否定应答时发回一个否定应答
//执行写操作。 即使是写入
//此时,EEPROM 可以完成公报
//仍忙于对数据进行编程。 因此、多个
//必须尝试。
//

//
//更新当前消息指针和消息状态
//
CurrentMsgPtr =&I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;

//
//一旦消息经过设置内部地址的过程
//在 EEPROM 中、发送重新启动以从读取数据字节
// EEPROM。 完成公报并停留一会。 MsgStatus 为
//在_interrupt 服务例程中更新。
//
否则、IF (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_RESTART)

//
//读取数据部分
//
while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success)

//
//可以设置一个尝试计数器来打破无限 while
//循环。
//

//
//更新当前消息指针和消息状态
//
CurrentMsgPtr =&I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;



}// I2C 循环结束

//
// I2CA_Init -初始化 I2CA 设置
//
空 I2CA_Init (空)

I2caRegs.I2CSAR.ALL = 0x0050;//从地址- EEPROM 控制代码

I2caRegs.I2CPSC.all = 16;//预分频器-模块时需要7-12MHz
I2caRegs.I2CCLKL = 10;//注意:必须为非零
I2caRegs.I2CCLKH = 5;//注意:必须为非零
I2caRegs.I2CIER.ALL = 0x24;//启用 SCD 和 ARDY __interrupts

I2caRegs.I2CMDR.ALL = 0x0020;//使 I2C 退出复位
//挂起时停止 I2C

I2caRegs.I2CFFTX.ALL = 0x6000;//启用 FIFO 模式和 TXFIFO
I2caRegs.I2CFFRX.ALL = 0x2040;//启用 RXFIFO、清除 RXFFINT、

返回;

//
// I2CA_WriteData -发送 I2CA 消息
//
uint16 I2CA_WriteData (struct I2CMSG *msg)

uint16 i;

//
//等待直到 STP 位从任何先前的主设备通信中清零。
//模块清除该位的操作被延迟到 SCD 位之后
//设置。 如果在启动新消息之前未选中此位
// I2C 可能会被混淆。
//
if (I2caRegs.I2CMDR.bit.STP==1)

返回 I2C_STP_NOT _READY_ERROR;

//
//设置从地址
//
I2caRegs.I2CSAR.all = msg->SlaveAddress;

//
//检查总线是否占线
//
if (I2cRegs.I2CSTR.bit.BB = 1)

返回 I2C_BUS_BUS_BUSY_ERROR;

//
//设置要发送的字节数
// MsgBuffer +地址
//
// currentSample = sampleadc ();
MSG->NumOfBytes = currentSample;//ADC-Sample 设置
I2caRegs.I2CCNT = msg->NumOfBytes+2;

//
//设置要发送的数据
//
I2caRegs.I2CDXR.All = msg->MemoryHighAddr;
I2caRegs.I2CDXR.All = msg->MemoryLowAddr;
// CurrentMsgPtr->MsgBuffer[i]= I2caRegs.I2CDRR.all;

for (i=0;i < msg->NumOfBytes;i++)

MSG->MsgBuffer[i]= I2caRegs.I2CDXR.all;

//
//将 START 作为主发送器发送
//
I2caRegs.I2CMDR.ALL = 0x6E20;

返回 I2C_Success;

//
// I2CA_ReadData -读取 I2CA 消息
//

uint16 I2CA_ReadData (struct I2CMSG *msg)

//
//等待直到 STP 位从任何先前的主设备通信中清零。
//模块清除该位的操作被延迟到 SCD 位之后
//设置。 如果在启动新消息之前未选中此位
// I2C 可能会被混淆。
//
if (I2caRegs.I2CMDR.bit.STP==1)

返回 I2C_STP_NOT _READY_ERROR;

I2caRegs.I2CSAR.all = msg->SlaveAddress;

if (msg->MsgStatus =I2C_MSGSTAT_SEND_NOSTOP)

//
//检查总线是否占线
//
if (I2cRegs.I2CSTR.bit.BB = 1)

返回 I2C_BUS_BUS_BUSY_ERROR;

I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR.All = msg->MemoryHighAddr;
I2caRegs.I2CDXR.All = msg->MemoryLowAddr;
I2caRegs.I2CMDR.ALL = 0x2620;//发送数据到设置 EEPROM 地址

否则 if (msg->MsgStatus =I2C_MSGSTAT_RESTART)

I2caRegs.I2CCNT = msg->NumOfBytes;//设置预期的字节数
I2caRegs.I2CMDR.ALL = 0x2C20;//作为主接收器发送重启

返回 I2C_Success;

//
// i2c_int1a_ISR - I2CA ISR
//
_interrupt void i2c_int1a_isr (void)

uint16 IntSource、I;

//
//读取__interrupt 源
//
IntSource = I2caRegs.I2CISRC.ALL;

//
//中断源=检测到停止条件
//
if (IntSource = I2C_SCD_ISRC)

//
//如果已完成的消息正在写入数据,则将 msg 重置为非活动状态
//
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_WRITE_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE;

其他

//
//如果在的地址设置部分收到 NACK 消息
// EEPROM 读取、下面的代码进一步包含在寄存器中
//访问就绪__interrupt 源代码将生成停止
//条件。 在接收到停止条件后(此处)、设置
//要重试的消息状态。 用户可能希望限制的数量
//在生成错误之前重试。
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;

//
//如果已完成消息正在读取 EEPROM 数据,则将 msg 重置为
//处于非活动状态并从 FIFO 读取数据。
//
否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_READ_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE;

for (i=0;i < I2C_NUMBYTES;i++)

CurrentMsgPtr->MsgBuffer[i]= I2caRegs.I2CDRR.all;

//
//检查接收到的数据
//
for (i=0;i < I2C_NUMBYTES;i++)

if (I2cMsgIn1.MsgBuffer[i]=I2cMsgOut1.MsgBuffer[i])

PassCount++;

其他

failcount++;


if (PassCount =I2C_NUMBYTES)

pass();

其他

fail();



//
//中断源=寄存器访问就绪
//此__interrupt 用于确定何时设置 EEPROM 地址
//读取数据通信的部分已完成。 因为没有停止位
//命令,此标志告诉我们何时发送了消息而不是消息
// SCD 标志。 如果接收到 NACK、清除 NACK 位并执行命令 A
//停止。 否则、请转到通信的读取数据部分。
//
否则、IF (IntSource = I2C_ARDY_ISRC)

if (I2caRegs.I2CSTR.bit.nack = 1)

I2caRegs.I2CMDR.bit.STP= 1;
I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit;

否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)

CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_RESTART;


其他

//
//由于无效的__interrupt 源而产生一些错误
//
_asm (" ESTOP0");

//
//启用未来的 I2C (PIE 组8)__interrupts
//
PieCtrlRegs.PIEACX.ALL = PIEACK_group8;

//
// pass -停止调试器并表示 pass
//
void pass (空传递)

_asm (" ESTOP0");
for (;;);

//
//失败-停止调试器并表示失败
//
void fail()(空失败())

_asm (" ESTOP0");
for (;;);

//
//文件结束
//

F28027F 代码:

//包括

//系统包括
#include
#include "main.h"

#include "DSP28x_Project.h"//器件头文件和示例 include 文件

ifdef 闪存
#pragma CODE_SECTION (mainISR、"ramfuncs");
#endif

//
//函数原型
//
void I2CA_Init (void);
uint16_t I2CA_WriteData (struct I2CMSG *msg);
uint16_t I2CA_ReadData (struct I2CMSG *msg);
_interrupt void i2c_int1a_isr (void);
void pass (void);
失效失效(失效);


秘书长的报告
//定义

#define LED_BLINK FREQ_Hz 5.

#define I2C_SLAVE_ADDR 0x50
#define I2C_NUMBYTES 2 //(4字节... INT?)
#define I2C_EEPROM_HIGH_ADDR 0x00
#define I2C_EEPROM_LOW_ADDR 0x30


秘书长的报告
//全局变量

UINT_least16_t gCounter_updateGlobals = 0;

bool Flag_Latch_SoftwareUpdate = true;

CTRL_Handle ctrlHandle;

#ifdef csm_enable
#pragma DATA_SECTION (halHandle、"ROM_accessed_data");
#endif
HAL_Handle halHandle;

#ifdef csm_enable
#pragma DATA_SECTION (gUserParams、"ROM_accessed_data");
#endif
USER_Params gUserParams;

HAL_PwmData_t gPwmData ={_IQ (0.0)、_IQ (0.0)、_IQ (0.0)};

HAL_AdcData_t gAdcData;

_iq gMaxCurrentSlope =_IQ (0.0);

ifdef FAST_ROM_V1p6
CTRL_Obj *控制器_obj;
其他
#ifdef csm_enable
#pragma DATA_SECTION (Ctrl、"ROM_accessed_data");
#endif
CTRL_Obj Ctrl;//v1p7格式
#endif

uint16_t gLEDcnt = 0;

volatile motor_Vars_t gMotorVars = motor_Vars_init;

ifdef 闪存
//用于在闪存中运行后台,在 RAM 中运行 ISR
extern uint16_t * RamfuncsLoadStart、* RamfuncsLoadEnd、* RamfuncsRunStart;

#ifdef csm_enable
extern uint16_t * econst_start、* econst_end、* econst_ram_load;
extern uint16_t * switch_start、* switch_end、* switch_ram_load;
#endif
#endif


#ifdef DRV8301_SPI
//连接到8301 SPI 的监视窗口接口
DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
#endif

#ifdef DRV8305_SPI
//连接到8305 SPI 的监视窗口接口
DRV_SPI_8305_Vars_t gDrvSpi8305Vars;
#endif

#ifdef DRV8323_SPI
//连接到8323 SPI 的监视窗口接口
DRV_SPI_8323_Vars_t gDrvSpi8323V;
#endif

_iq gFlux_pu_TO_WB_SF;

_iq gFlux_pu_TO_VpHz_SF;

_iq gTor紧 力_ Ls_ID_Iq_pu_TO_Nm_SF;

_iq gTorque 磁通_IQ_pu_TO_Nm_SF;

struct I2CMSG I2cMsgOut1=

// 8字节
I2C_MSGSTAT_SEND_WITHSTOP、// 1.
I2C_SLAVE_ADDR、// 1.
I2C_NUMBYTES、// 4.
I2C_EEPROM_HIGH_ADDR、// 1.
I2C_EEPROM_LOW_ADDR、// 1.

//
//消息字节1
//
0x12、

//
//消息字节2
//
0x34
};

struct I2CMSG I2cMsgIn1=

// 8字节
I2C_MSGSTAT_SEND_NOSTOP、// 1.
I2C_SLAVE_ADDR、// 1.
I2C_NUMBYTES、// 4.
I2C_EEPROM_HIGH_ADDR、// 1.
I2C_EEPROM_LOW_ADDR // 1.
};

//
//用于中断
//
struct I2CMSG * CurrentMsgPtr;
uint16_t PassCount;
uint16_t failcount;

秘书长的报告
//函数

void main (void)

UINT_least8_t estNumber = 0;

ifdef FAST_ROM_V1p6
uint_least8_t ctrlNumber = 1;
#endif

//仅在从闪存运行时使用
//请注意,变量闪存是由项目定义的
ifdef 闪存
//将时间关键代码和闪存设置代码复制到 RAM
// RamfuncsLoadStart、RamfuncsLoadEnd 和 RamfuncsRunStart
//符号由链接器创建。 请参阅链接器文件。
Memcopy ((uint16_t *)&RamfuncsLoadStart、(uint16_t *)&RamfuncsLoadEnd、(uint16_t *)&RamfuncsRunStart);

#ifdef csm_enable
//copy .econst 至 unsecure RAM
if (* econst_end -* econst_start)

Memcopy ((uint16_t *)&econst_start、(uint16_t *)&econst_end、(uint16_t *)&econst_ram_load);

//copy .switch ot unsecure RAM
if (* switch_end -* switch_start)

Memcopy ((uint16_t *)&switch_start、(uint16_t *)&switch_end、(uint16_t *)&switch_ram_load);

#endif
#endif


uint16_t writeDataWorked;
uint16_t i;

//
//警告:始终确保在运行中的任何函数之前调用 memcpy
// RAM InitSysCtrl 包括对基于 RAM 的函数的调用,而不包括
//首先调用 memcpy,处理器将进入到工作状态
#ifdef _flash
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif

CurrentMsgPtr =&I2cMsgOut1;

//
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2802x_sysctrl.c 文件中。
//
InitSysCtrl();

//
//步骤2. 初始化 GPIO:
//此示例函数位于 F2802x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
//
//InitGpio();

//
//仅针对 I2C 功能设置 GP I/O
//
InitI2CGpio();

//
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2802x_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU 中断并清除所有 CPU 中断标志
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2802x_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2802x_PieVect.c 中找到
//
InitPieVectTable();

//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.I2CINT1A =&i2c_int1a_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//
//步骤4. 初始化所有器件外设
//
I2CA_Init();//仅 I2C-A

//
//步骤5. 特定于用户的代码
//

//
//清除计数器
//
PassCount = 0;
failcount = 0;

//
//清除传入消息缓冲区
//
对于(I = 0;I <(I2C_MAX_BUFFER_SIZE - 2);I++)

I2cMsgIn1.MsgBuffer[i]= 0x0000;

//
//启用此示例所需的中断
//

//
//在 PIE:组8中断1中启用 I2C 中断1
//
// PieCtrlRegs.PIEIER8.bit.INTx1 = 1;

/*=>不需要启用中断、因为该程序充当从器件*/


//
//启用连接到 PIE 组8的 CPU INT8
//
//IER |= M_INT8;
//EINT;


//初始化硬件抽象层
halHandle = HAL_init (&hal、sizeof (hal));


//检查用户参数中的错误
USER_checkForErrors (&gUserParams);


//将用户参数错误存储在全局变量中
gMotorVars.UserErrorCode = USER_getErrorCode (&gUserParams);


//如果存在用户参数错误,则不允许执行代码
if (gMotorVars.UserErrorCode!= USER_ErrorCode_NoError)

for (;;)

gMotorVars.Flag_enableSys = false;


//初始化用户参数
USER_setParams (&gUserParams);


//设置硬件抽象层参数
HAL_setParams (halHandle、&gUserParams);


//初始化控制器
ifdef FAST_ROM_V1p6
ctrlHandle = CTRL_initCtrl (ctrlNumber、estNumber);//v1p6格式(06xF 和06xM 器件)
controller_obj =(CTRL_Obj *) ctrlHandle;
其他
ctrlHandle = CTRL_initCtrl (estNumber、&ctrl、sizeof (ctrl));//v1p7格式默认值
#endif



CTRL_Version 版本;

//获取版本号
CTRL_getversion (ctrlHandle、&version);

gMotorVars.CtrlVersion =版本;


//设置默认控制器参数
CTRL_setParams (ctrlHandle、&gUserParams);


//设置故障
HAL_setupFaults (halHandle);


//初始化中断矢量表
HAL_initIntVectorTable (halHandle);


//启用 ADC 中断
HAL_enableAdcInts (halHandle);


//启用全局中断
HAL_enableGlobalInts (halHandle);


//启用调试中断
HAL_enableDebugInt (halHandle);


//禁用 PWM
HAL_disablePwm (halHandle);


#ifdef DRV8301_SPI
//打开 DRV8301 (如果存在)
HAL_enableDrv (halHandle);
//初始化 DRV8301接口
HAL_setupDrvSpi (halHandle、&gDrvSpi8301Vars);
#endif

#ifdef DRV8305_SPI
//打开 DRV8305 (如果有)
HAL_enableDrv (halHandle);
//初始化 DRV8305接口
HAL_setupDrvSpi (halHandle、&G);
#endif

#ifdef DRV8323_SPI
//打开 DRV8323 (如果有)
HAL_enableDrv (halHandle);
//初始化 DRV8323接口
HAL_setupDrvSpi (halHandle、&gDrvSpi8323Vars);
gDrvSpi8323Vars.ctrl_Reg_06.ca_gain = gain_20VpV;
gDrvSpi8323Vars.Ctrl_Reg_06.VREF_DIV = 1;
gDrvSpi8323Vars.WriteCmd = true;
HAL_writeDrvData (halHandle、&gDrvSpi8323Vars);
gDrvSpi8323Vars.ReadCmd = true;
HAL_readDrvData (halHandle、&gDrvSpi8323Vars);
#endif

//启用直流总线补偿
CTRL_setFlag_enableDcBusComp (ctrlHandle、true);


//计算磁通和扭矩计算的比例因子
gFlux_pu_TO_WB_SF = USER_computeFlux_pu_TO_WB_SF ();
gFlux_pu_TO_VpHz_SF = USER_computeFlux_pu_TO_VpHz_SF ();
gTorte_LS_ID_IQ_pu_TO_Nm_SF = USER_computeTorte_LS_ID_IQ_pu_TO_Nm_SF ();
gTorture_Flux_IQ_pu_TO_Nm_SF = USER_computeTorte_Flux_IQ_pu_TO_Nm_SF ();

for (;;)

//
//将数据写入 EEPROM 部分
//

//
//检查外发消息是否应发送。
//在本例中,初始化后发送一个停止位。
//
if (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_SEND_WITHSTOP)

writeDataWorked = I2CA_WriteData (&I2cMsgOut1);

//
//如果通信已正确启动,请将 msg 状态设置为忙
//并更新中断服务例程的 CurrentMsgPtr。
//否则,不执行任何操作,然后重试下一个循环。 发送一条消息
//启动后、I2C 中断将处理其余中断。 搜索
// i2c_EEPROM_ISR.c 文件中的 ICINTR1A_ISR。
//
if (writeDataWorked =I2C_Success)

CurrentMsgPtr =&I2cMsgOut1;
I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY;

//
//从 EEPROM 部分读取数据
//

//
//检查外发消息状态。 如果状态为、则绕过读取段
//未处于非活动状态。
//
IF (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_INACTIVE)

//
//检查传入消息状态。
//
if (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP)

//
// EEPROM 地址设置部分
//
while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success)

//
//可以设置一个尝试计数器来打破无穷大
// while 循环。 EEPROM 会在它发出否定应答时发回一个否定应答
//执行写操作。 即使是写入
//此时,EEPROM 可以完成公报
//仍忙于对数据进行编程。 因此、多个
//必须尝试。
//

//
//更新当前消息指针和消息状态
//
CurrentMsgPtr =&I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;

//
//一旦消息经过设置内部地址的过程
//在 EEPROM 中、发送重新启动以从读取数据字节
// EEPROM。 完成公报并停留一会。 MsgStatus 为
//在中断服务例程中更新。
//
否则、IF (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_RESTART)

//
//读取数据部分
//
while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success)

//
//可以设置一个尝试计数器来打破无穷大
// while 循环。
//

//
//更新当前消息指针和消息状态
//
CurrentMsgPtr =&I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;


//等待使能系统标志被置位
while (!(gMotorVars.Flag_enableSys));

//启用库内部 PI。 Iq 现在以速度 PI 为基准
CTRL_setFlag_enableSpeedCtrl (ctrlHandle、true);

//循环、同时使能系统标志为 true
while (gMotorVars.Flag_enableSys)

CTRL_Obj * obj =(CTRL_Obj *) ctrlHandle;

//递增计数器
gCounter_updateGlobals++;

//启用/禁用使用从 user.h 加载的电机参数
CTRL_setFlag_enableUserMotorParams (ctrlHandle、gMotorVars.Flag_enableUserParams);

//启用/禁用电机启动期间的 Rs 重校准
EST_setFlag_enableRsRecalc (obj->estHandle、gMotorVars.Flag_enableRsRecalc);

//启用/禁用偏置值的自动计算
CTRL_setFlag_enableOffset (ctrlHandle、gMotorVars.Flag_enableOffsetcalc);


IF (CTRL_ISERROR (ctrlHandle))

//将使能控制器标志设置为 false
CTRL_setFlag_enableCtrl (ctrlHandle、false);

//将使能系统标志设置为 false
gMotorVars.Flag_enableSys = false;

//禁用 PWM
HAL_disablePwm (halHandle);

其他

//更新控制器状态
bool flag_ctrlStateChanged = CTRL_updateState (ctrlHandle);

//启用或禁用控件
CTRL_setFlag_enableCtrl (ctrlHandle、gMotorVars.Flag_Run_Identify);

if (flag_ctrlStateChanged)

CTRL_State_e ctrlState = CTRL_getState (ctrlHandle);

if (ctrlState = CTRL_State_OffLine)

//启用 PWM
HAL_enablePwm (halHandle);

否则、如果(ctrlState = CTRL_State_OnLine)

if (gMotorVars.Flag_enableOffsetcalc = true)

//更新 ADC 偏置值
HAL_updateAdcBias (halHandle);

其他

//设置电流偏置
HAL_setBias (halHandle、HAL_SensorType_Current、0、_IQ (I_A_offset));
HAL_setBias (halHandle、HAL_SensorType_Current、1、_IQ (I_B_OFFSET));
HAL_setBias (halHandle、HAL_SensorType_Current、2、_IQ (I_C_OFFSET));

//设置电压偏置
HAL_setBias (halHandle、HAL_SensorType_Voltage、0、_IQ (V_A_offset));
HAL_setBias (halHandle、HAL_SensorType_Voltage、1、_IQ (V_B_OFFSET));
HAL_setBias (halHandle、HAL_SensorType_Voltage、2、_IQ (V_C_offset));

//返回电流的偏置值
gMotorVars.I_BIAS.value[0]= HAL_getBias (halHandle、HAL_SensorType_Current、0);
gMotorVars.I_BIAS.Value[1]= HAL_getBias (halHandle、HAL_SensorType_Current、1);
gMotorVars.I_BIAS.value[2]= HAL_getBias (halHandle、HAL_SensorType_Current、2);

//返回电压的偏置值
gMotorVars.V_BIAS.Value[0]= HAL_getBias (halHandle、HAL_SensorType_Voltage、0);
gMotorVars.V_BIAS.Value[1]= HAL_getBias (halHandle、HAL_SensorType_Voltage、1);
gMotorVars.V_BIAS.Value[2]= HAL_getBias (halHandle、HAL_SensorType_Voltage、2);

//启用 PWM
HAL_enablePwm (halHandle);

否则、如果(ctrlState = CTRL_State_Idle)

//禁用 PWM
HAL_disablePwm (halHandle);
gMotorVars.Flag_Run_Identify = false;

if ((CTRL_getFlag_enableUserMotorParams (ctrlHandle)=true)&&
(ctrlState > CTRL_State_Idle)&&
(gMotorVars.CtrlVersion.Minor == 6))

//调用此函数来修复1p6
USER_softwareUpdate1p6 (ctrlHandle);



if (EST_isMotorIdentified (obj->estHandle))

//设置电流斜坡
EST_setMaxCurrentSlope _pu (obj->estHandle、gMaxCurrentSlope);
gMotorVars.Flag_MotorIdentified = true;

//设置速度参考
CTRL_setSpd_ref_krpm (ctrlHandle、gMotorVars.SpeedRef_krpm);

//设置速度加速度
CTRL_setMaxAccel_pu (ctrlHandle、_IQmpy (MAX_ACCEL_KRPMPS_SF、gMotorVars.MaxAccel_krpmps));
if (Flag_Latch_SoftwareUpdate)

Flag_Latch_SoftwareUpdate = false;

USER_calcPIGains (ctrlHandle);

//使用预计算值初始化监视窗口 Kp 和 Ki 电流值
gMotorVars.KP_idq = CTRL_getKp (ctrlHandle、CTRL_Type_PID_ID);
gMotorVars.KI_idq = CTRL_getKi (ctrlHandle、CTRL_Type_PID_ID);

//使用预计算值初始化监视窗口 Kp 和 Ki 值
gMotorVars.KP_SPD = CTRL_getKp (ctrlHandle、CTRL_Type_PID_SPD);
gMotorVars.KI_SPD = CTRL_getKi (ctrlHandle、CTRL_Type_PID_SPD);


其他

Flag_Latch_SoftwareUpdate = true;

//估算器设置识别期间的最大电流斜率
gMaxCurrentSlope = EST_getMaxCurrentSlope _pu (obj->estHandle);


//适当时,更新全局变量
if (gCounter_updateGlobals >= NUM_MAIN_TICKS_for_GLOBAL_variable 更新)

//重置计数器
gCounter_updateGlobals = 0;

updateGlobalVariables_motor (ctrlHandle);


//更新 Kp 和 Ki 增益
updateKpKiGains (ctrlHandle);

//启用/禁用强制角
EST_setFlag_enableForceAngle (obj->estHandle、gMotorVars.Flag_enableForceAngle);

//启用或禁用电源扭曲
CTRL_setFlag_enablePowerWarp (ctrlHandle、gMotorVars.Flag_enablePowerWarp);

#ifdef DRV8301_SPI
HAL_writeDrvData (halHandle、&gDrvSpi8301Vars);

HAL_readDrvData (halHandle、&gDrvSpi8301Vars);
#endif
#ifdef DRV8305_SPI
HAL_writeDrvData (halHandle、&G);

HAL_readDrvData (halHandle、&G);
#endif
#ifdef DRV8323_SPI
HAL_writeDrvData (halHandle、&gDrvSpi8323Vars);
HAL_readDrvData (halHandle、&gDrvSpi8323Vars);
#endif
}// while 结束(gFlag_enableSys)循环


//禁用 PWM
HAL_disablePwm (halHandle);

//设置默认控制器参数(重置控件以重新识别电机)
CTRL_setParams (ctrlHandle、&gUserParams);
gMotorVars.Flag_Run_Identify = false;

}// for (;)循环结束

}// main()函数的末尾

中断空 mainISR (空)

//切换状态 LED
if (++gLEDcnt >=(uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK FREQ_Hz)

HAL_TOGLELed (halHandle、(GPIO_Number_e) HAL_GPIO_LED2);
gLEDcnt = 0;


//确认 ADC 中断
HAL_acqAdcInt (halHandle、ADC_IntNumber_1);


//转换 ADC 数据
HAL_readAdcData (halHandle、&gAdcData);


//运行控制器
CTRL_run (ctrlHandle、halHandle、&gAdcData、&gPwmData);


//写入 PWM 比较值
HAL_writePwmData (halHandle、&gPwmData);


//设置控制器
CTRL_setup (ctrlHandle);


返回;
}// mainISR()函数结束


void updateGlobalVariables_motor (CTRL_Handle handle)

CTRL_Obj * obj =(CTRL_Obj *)句柄;

//获取速度估计值
gMotorVars.Speed_KRPM = EST_getSpeed_KRPM (obj->estHandle);

//从速度轨迹发生器获取实时速度基准
gMotorVars.SpeedTraj_krpm =_IQmpy (CTRL_getSpd_int_ref_pu (handle)、EST_get_pu_TO_krpm_SF (obj->estHandle));

//获取转矩估计值
gMotorVars.Torture_Nm = USER_computeTorture_Nm (handle、gTorture_Flux_IQ_pu_TO_Nm_SF、gTorte_LS_ID_IQ_pu_TO_Nm_SF);

//获得磁化电流
gMotorVars.MagnCurr_A = EST_getIdRated (obj->estHandle);

//获取转子电阻
gMotorVars.RR_Ohm = EST_getRr_Ohm (obj->estHandle);

//获得定子电阻
gMotorVars.Rs_Ohm = EST_getRs_Ohm (obj->estHandle);

//获得直接坐标方向的定子电感
gMotorVars.LSD_H = EST_getLs_d_H (obj->estHandle);

//获得正交坐标方向的定子电感
gMotorVars.LSQ_H = EST_getLs_q_H (obj->estHandle);

//以浮点方式获得以 V/Hz 为单位的磁通
gMotorVars.Flux_VpHz = EST_getFlux_VpHz (obj->estHandle);

//以定点获得 WB 中的磁通
gMotorVars.Flux_WB = USER_computeFlux (handle、gFlux_pu_TO_WB_SF);

//获取控制器状态
gMotorVars.CtrlState = CTRL_getState (handle);

//获取估算器状态
gMotorVars.EstState = EST_getState (obj->estHandle);

//获取直流总线电压
gMotorVars.VdcBus_kV =_IQmpy (gAdcData.DCBus、_IQ (USER_IQ_FULL_SCALE_VOLTAGE_V/1000.0));

返回;
}// updateGlobalVariables_motor()函数结束


void updateKpKiGains (CTRL_Handle handle)

if ((gMotorVars.CtrlState =CTRL_State_OnLine)&&(gMotorVars.Flag_MotorIdentified == true)&&(Flag_Latch_SoftwareUpdate == false)

//从观察窗口设置 Kp 和 Ki 速度值
CTRL_setKp (handle、CTRL_Type_PID_SPD、gMotorVars.KP_SPD);
CTRL_setKi (handle、CTRL_Type_PID_SPD、gMotorVars.KI_SPD);

//从观察窗口中设置 Id 和 Iq 的 Kp 和 ki 电流值
CTRL_setKp (handle、CTRL_Type_PID_ID、gMotorVars.KP_idq);
CTRL_setKi (handle、CTRL_Type_PID_ID、gMotorVars.KI_Idq);
CTRL_setKp (handle、CTRL_Type_PID_IQ、gMotorVars.KP_idq);
CTRL_setKi (handle、CTRL_Type_PID_IQ、gMotorVars.KI_idq);

返回;
}// updateKpKiGains()函数结束

//
// I2CA_Init -
//
无效
I2CA_Init (空)

//
//初始化 I2C
//
I2caRegs.I2CSAR = 0x0050;//从器件地址- EEPROM 控制代码

//
// I2CCLK = SYSCLK/(I2CPSC+1)
//
#IF (CPU_FRQ_40MHz||CPU_FRQ_50MHz)
I2caRegs.I2CPSC.all = 4;//预分频器-模块时需要7-12MHz
#endif

#IF (CPU_FRQ_60MHz)
I2caRegs.I2CPSC.all = 6;//预分频器-模块时需要7-12MHz
#endif
I2caRegs.I2CCLKL = 10;//注意:必须为非零
I2caRegs.I2CCLKH = 5;//注意:必须为非零
I2caRegs.I2CIER.ALL = 0x24;//启用 SCD 和 ARDY 中断

//
//使 I2C 退出复位。 暂停时停止 I2C
//
I2caRegs.I2CMDR.ALL = 0x0020;

I2caRegs.I2CFFTX.ALL = 0x6000;//启用 FIFO 模式和 TXFIFO
I2caRegs.I2CFFRX.ALL = 0x2040;//启用 RXFIFO、清除 RXFFINT、

返回;

//
// I2CA_WriteData -
//

uint16_t I2CA_WriteData (struct I2CMSG *msg)

uint16_t i;

//
//等待直到 STP 位从任何先前的主设备通信中清零
//模块清除该位的操作被延迟到 SCD 位之后
//设置。 如果在启动新消息之前未选中此位
// I2C 可能会被混淆。
//
IF (I2caRegs.I2CMDR.bit.STP==1)

返回 I2C_STP_NOT _READY_ERROR;

//
//设置从地址
//
I2caRegs.I2CSAR = msg->SlaveAddress;

//
//检查总线是否占线
//
IF (I2cRegs.I2CSTR.bit.BB = 1)

返回 I2C_BUS_BUS_BUSY_ERROR;

//
//设置要发送 MsgBuffer + Address 的字节数
//
I2caRegs.I2CCNT = msg->NumOfBytes+2;

//
//设置要发送的数据
//
I2caRegs.I2CDXR = msg->MemoryHighAddr;
I2caRegs.I2CDXR = msg->MemoryLowAddr;

对于(i=0;i NumOfBytes;i++)

I2caRegs.I2CDXR =*(msg->MsgBuffer+I);

//
//将 START 作为主发送器发送
//
I2caRegs.I2CMDR.ALL = 0x6E20;

返回 I2C_Success;


//
// I2CA_ReadData -
//
uint16_t
I2CA_ReadData (struct I2CMSG *msg)

//
//等待直到 STP 位从任何先前的主设备通信中清零
//模块清除该位的操作被延迟到 SCD 位之后
//设置。 如果在启动新消息之前未选中此位
// I2C 可能会被混淆。
//
IF (I2caRegs.I2CMDR.bit.STP==1)

返回 I2C_STP_NOT _READY_ERROR;

I2caRegs.I2CSAR = msg->SlaveAddress;

if (msg->MsgStatus =I2C_MSGSTAT_SEND_NOSTOP)

//
//检查总线是否占线
//
IF (I2cRegs.I2CSTR.bit.BB = 1)

返回 I2C_BUS_BUS_BUSY_ERROR;

I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = msg->MemoryHighAddr;
I2caRegs.I2CDXR = msg->MemoryLowAddr;
I2caRegs.I2CMDR.ALL = 0x2620;//发送数据到设置 EEPROM 地址

否则 if (msg->MsgStatus =I2C_MSGSTAT_RESTART)

//
//设置预期的字节数
//
I2caRegs.I2CCNT = msg->NumOfBytes;

//
//将重新启动作为主接收器发送
//
I2caRegs.I2CMDR.ALL = 0x2C20;

返回 I2C_Success;

//
// i2c_int1a_isr - I2C-A
//
_interrupt void
I2C_int1a_ISR (空)

uint16_t IntSource、i;

//
//读取中断源
//
IntSource = I2caRegs.I2CISRC.ALL;

//
//中断源=检测到停止条件
//
if (IntSource = I2C_SCD_ISRC)

//
//如果已完成的消息正在写入数据,则将 msg 重置为非活动状态
//
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_WRITE_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE;

其他

//
//如果在地址设置部分收到 NACK 消息
//读取 EEPROM 时、下面的代码包含在中
//寄存器访问就绪中断源代码将生成停止
//条件。 在接收到停止条件后(此处)、设置
//要重试的消息状态。 用户可能希望限制该数字
//在生成错误之前重试次数。
//
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;

//
//如果已完成消息正在读取 EEPROM 数据,则将 msg 重置为
//处于非活动状态并从 FIFO 读取数据。
//
否则(CurrentMsgPTR->MsgStatus =I2C_MSGSTAT_READ_BUSY)

CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE;
for (i=0;i < I2C_NUMBYTES;i++)

CurrentMsgPtr->MsgBuffer[i]= I2caRegs.I2CDRR;

//
//检查接收到的数据
//
for (i=0;i < I2C_NUMBYTES;i++)

if (I2cMsgIn1.MsgBuffer[i]=I2cMsgOut1.MsgBuffer[i])

PassCount++;

其他

failcount++;

if (PassCount =I2C_NUMBYTES)

pass();

其他

fail();



//
//中断源=寄存器访问就绪
//此中断用于确定何时设置 EEPROM 地址
//读取数据通信的部分已完成。 因为没有停止位
//命令,此标志告诉我们何时发送了消息而不是消息
// SCD 标志。 如果接收到 NACK、清除 NACK 位并执行命令 A
//停止。 否则、请转到通信的读取数据部分。
//
否则、IF (IntSource = I2C_ARDY_ISRC)

if (I2caRegs.I2CSTR.bit.nack = 1)

I2caRegs.I2CMDR.bit.STP= 1;
I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit;

否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)

CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_RESTART;

其他

//
//由于中断源无效而产生一些错误
//
_asm (" ESTOP0");

//
//启用未来的 I2C (PIE 组8)中断
//
PieCtrlRegs.PIEACX.ALL = PIEACK_group8;

//
//通过-
//
无效
通过()

_asm (" ESTOP0");
for (;;);

//
//失败-
//
无效
失败()

_asm (" ESTOP0");
for (;;);

//@}// defgroup
//文件结束

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以查看 MotorWare 下一个文件夹中的指南 motorware_hal_tutorial.pdf、在实验中添加相关的通信功能。

    \ti\motorware\motorware_1_01_00_18\docs\Tutorials

    您可以在适用于 C2000器件的 controlSUITE 和 C2000Ware 中找到相关的 I2C 示例。

    将目标值设置为 gMotorVars.SpeedRef_KRPM 要控制速度、您应该将目标值转换为_IQ24格式。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢罗燕明、

    但 controlSUITE 和 C2000Ware 中没有有关示例的信息。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这只是 I2C 应用示例、您需要将这些代码移植到您自己的项目中。

    F28027 I2C: \ti\controlSUITE\device_support\f2802x\v230\F2802x_examples_structs\i2c_EEPROM

    F28379: \ti\controlSUITE\device_support\F2837xD\V210\F2837xD_Examples_CPU1\i2c_EEPROM

    \ti\c2000\C2000Ware_3_02_00_00\driverlib\f2837xd\examples\cpu1\i2c