主题中讨论的其他器件:controlSUITE、 MOTORWARE、 DRV8301、 DRV8305、 DRV8323、 C2000WARE
工具/软件: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
//文件结束