你(们)好
我正在修改显示在 OLED SSD1308上的69M 代码、信息
遗憾的是、在运行速度慢得多且没有 FPU 的27F 上、我的 ADC ISR 需要大量时间、因此恰好会切断在 I2C 上发送屏幕的主循环的传输。
在硬件 问题中运行后 、我现在正在修改代码并将其更改为使用 TX FIFO 中断
代码必须发送、命令(2个字节或3个字节和数据9个字节)、因此 FIFO 不能立即使用、我需要在 FIFO TX 上生成一个中断、以查看发送9个字节4 x 4……
我设法使用 TX FIFO 中断(它被触发)、但它不会对9个字节进行切片并仅发送4个字节...
enable_protected_register_write_mode; PieCtrlRegs.PIEIER8.bit.INTx2 = 1;//在 PIE 中启用 I2C 中断2:组8中断2 IER |= M_INT8;//启用连接到 PIE 组8 的 CPU INT8 disable_protected_register_write_mode;
///----------------------------------
// InitI2C -此函数将 I2C 初始化为已知状态。
void InitI2C()
{
//初始化 I2C-A
I2cRegs.I2CMDR.ALL = 0x0000;
I2cRegs.I2SAR = I2C_SLAVE_ADDR;//从地址
// 90 MHz/(((8+1)(10+5 + 5+5))= 400 kHz
// 60 MHz/((5+1)(10+5 + I2CSC+5)
= 2 I2CCPLESC+5 = 4 /全部2 I2LCPL5 / I2LCPL5 = 4。//预分频器-在模块 clk
I2cRegs.I2CCLKL = 10上需要7-12MHz;//注:必须是非零
I2cRegs.I2CCLKH = 5;//注:必须是非零
// I2cirRegs.I2CIER = 0x24;// SCD & I2AR.0100
;中断= 0X0X0XI2AR.I2CIER = 0100;/中断= 0X0XI2AR.I2AR.I2AR.I0100//寻址为从机中断使能位
// I2cirRegs.I2CIER.bit.SCD = 1;//停止条件检测到的中断使能位
// I2cirRegs.I2CIER.bit.XRDY = 0;//发送数据就绪中断使能位
// I2cir.bit.I2r.I2I
=
0;//接收数据就绪中断就绪= 0;I2CIEr.I2I2I2ARRn = 0//无确认中断使能位
// I2caRegs.I2CIER.bit.ARBL = 0;//仲裁丢失中断使能位
// I2caRegs.I2CFFTX.ALL = 0x6000;//启用 FIFO 模式和 TXFIFO
I2caRegs.I2CFFTX.BIS= 1
;//启用 TX2CFI2RF1.I1/ TXIF.I2RFIF.I2RFIF.I1/ TXIF.I2RFIF.I2RFIF.I2RF1.T1.T1.I2RFIF.I2RFIF.I1/位发送 FIFO
//清除 TXFFINT 标志
I2CARegs.I2CFFTX.bit.TXFFIENA=1;// TXFFINT 标志在置
位 I2CARegs.I2CFFTX.bit.TXFFIL = 0时生成中断;//发送 FIFO 中断级别
//I2CARFX.ALL = 0xCFFI2RFIF.BIT.0**
无 RXFFI2RFIFT.I2RFIFT.TX.I2RFIF0**位;//发送 FIFO 中断 RFIFT.I2RFIF0**
//清除 RXFFINT 标志
I2CARegs.I2CFFRX.bit.RXFFIENA=0;//当置位
I2CARegs.I2CFFRX.bit.RXFFIL = 0时、RXFFINT 标志会生成一个中断;//接收 FIFO 中断级别
//I2CARegs.I2CMDR.ALL = 0xI2CMDR.0时、RXFFIL = 0;//接收 FIFO 中断位/I2CA.I2CMDR.I2CMDR.0;当暂停
时、I2I2I2CMDR.I2I2CMDR.0 = 0 =
0;/停止 I2I2I2I2I2I2CMDR.I2I2I2CMDR.I2I2CMDR//暂停
I2caRegs.I2CMDR.bit.STT = 0时停止 I2C;//开始条件位
I2caRegs.I2CMDR.bit.STP = 0;//停止条件位
I2caRegs.I2CMDR.bit.MST = 0;//从模式
I2caRegs.I2CMDR.0 =
0;/ I2c.I2c.I2e.I2c.0;/ I2ca-R2.I2e.I2e.I2c.R2.ICMT.0 = 0;/位重复模式
//数字回送模式被禁用
I2caRegs.I2CMDR.bit.IRS = 1;// I2C 模块被启用
I2caRegs.I2CMDR.bit.STB = 0;// I2C 模块不在起始字节模式
I2caRegs.I2CMDR.bit.FDF = 0;//自由数据格式
I2cA.BC.0被禁用//每个数据字节8位
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;//清除 TXFFINT 标志
oledInit ();
//oledClear ();
}
//-----
// i2c_int2a_isr - I2C-ATX FIFO 为 int2a
中断空 i2c_int2a_isr (void)
{
uint8 fin、i;
uint16 IntSource = I2cRegs.I2CISRC.all;//读取中断源
/GPIO_setHigh (halRunle->gpioHandle、GPIO_Number= I2C_RUNIT/GPIOLED.
)
;//读取中断源/GPIORUN/GPIOUNIT.S34 = GPIOLED/中断源/GPIOUN/GPIOLED/中断源代码= GPIORUN/GPIOUN/GPIOLED/中断状态= GPIOUN/GPIOUN/GPIOUN/GPIOUNIT
//中断源=寄存器访问就绪
//此中断用于确定 EEPROM 地址设置//
读取数据通信的一部分何时完成。 由于
没有命令的停止位//、这个标志告诉我们何时发送消息而不是
// SCD 标志。 如果接收到 NACK、清除 NACK 位并命令 A
//停止。 否则、请转到通信的读取数据部分。
如果(Regerpos >= bufferend)I2cRegs.I2CMDR.bit.STP= 1;//手动设置停止
//if (((IntSource = I2C_TX_ISRC)&&(bufferpos < bufferend)
) if ((I2casRegs.I2CFFTX.bit.TXFFRC);
&I = 1
)(对于 bufferfin = 1);(对于 bufferfin = 1)/fin =
1);(对于 bufferfin = 1、I = 1);对于 bufferfin 2 (对于 bufferfin = 1、I = 1) =bufferend)I2cRegs.I2CMDR.bit.STP = 1;//手动设置停止
}
//启用未来的 I2C (PIE 组8)中断
PieCtrlRegs.PIEACK.all = PIEACK_group8;
//GPIO_setLow (halHandle->gpioDataHandle、GPIO_Number_GPIO34)
---1----
void i2c_Xfer (
uint8 address、
uint8* wdata、int wsize、
uint8* RDATA、int rsize)
{
uint16 i;
//I2cRegs.I2CMDR.bit.IRS = 0;
//usDelay (10);
//I2cRegs.I2CMDR.bit.I2b
= 1;//确保 I2CSTR/忙/中断//忙环路
//I2cRegs.I2CSTR.bit.SCD = 1;//清除 SCD 位(停止条件位)
//while (I2cRegs.I2CMDR.bit.STP = 1);//停止位环路
I2cRegs.I2CSAR =地址;// I2C 从器件地址
//while (I2cRegs.I2CSTR.bit.BB = 1);//仍然忙?
I2caRegs.I2CCNT = wsize;//设置要发送的字节数
//I2caRegs.I2CMDR.ALL = 0x6E20;//发送 TX FIFO:0110 1110 0010 0000
//I2caRegs.I2CMDR.ALL = 0x6620;// STT=1:0110 0110
I2CR.0000
= 0110 I2110.TCLR = 0110.I2CART.0110//清除 TXFFINT 标志
//I2cRegs.I2CMDR.BICKMOD = 0;// NACK 模式位
//I2cRegs.I2CMDR.BIT.FREE = 1;//在挂起时运行免费 I2C
//I2cRegs.bit.STT = 1;// I2CMT.I2CMT.BIS.R=
1;//停止条件// I2CMT.BICMP= 1
;/位/ I2CMP= 1//发送器模式
//I2cRegs.I2CMDR.bit.xa = 0;// 7位寻址模式
//I2cRegs.I2CMDR.bit.RM = 0;//非重复模式
//I2cRegs.I2CMDR.bit.DLB = 0;//数字回路模式被禁用
// I2cA.I2CMDR.I2I= 0
;I2I2I2CMDR.I2I = 0;I2AR.I2ARM.I2I2ARM.I2ARM.I2I2ARM.I2ARM.I2ART.I2ARM.A = 0// I2C 模块不在起始字节模式
//I2cRegs.I2CMDR.bit.FDF = 0;//禁用自由数据格式模式
//I2cRegs.I2CMDR.bit.BC = 0;//每个数据字节8位
//int WaitOut Timet=0;
bufferpos = 0;
I size = 0;I size = 4;for transfer end 4) fin=4;
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;//清除
(i=0;i = bufferend)I2cRegs.I2CMDR.bit.STP= 1;//手动停止集
}
/../../---------------
void i2c_wait (int cycles)
{
I2C_WaitCount = 0;
while (I2C_WaitCount < cycles);
}
//---------------
void i2c_Reset()
{}//------------------
// SSD1308 OLED 例程
//
#define SSD1308_Address I2C_SLAVE_ADDR
#define SSD1308_Command_Mode0x80
#define SSD1308_Data_Mode 0x40
#define SSD1308_Display_OFF_Cmd 0xAE
#define SSD1308_Display_ON_Cmd 0xAF
#define SSD1308_Normal_Display_Cmd 0xA6
#define SSD1308_Invise_Display_Cmd0xA7
#define SSD1308_Active_Scroll _Cmd0x2F
#define SSD1308_DecTIVATE_Scroll _Cmd 0x2E
#define SSD1308_Set_Brightness_Cmd 0x81
const UINT8 OledFont[][8]=
{..
(笑声)
};
void oledCommand( uint8 ch ){
uint8字节[2];
字节[0]= SSD1308_Command_Mode;
字节[1]=通道;
I2C_Xfer (SSD1308_Address、bytes、2、NULL、0);
I2C_WAIT (2);
}
void oledDisplayOffset (uint8 offset)
{
uint8字节[3];
字节[0]= SSD1308_Command_Mode;
字节[1]= 0xD3;
字节[2]=偏移量;
I2C_Xfer (SSD1308_Address、bytes、3、NULL、0);
I2C_WAIT (3);
}
void oledData( uint8 data )
{
uint8字节[2];
字节[0]= SSD1308_Data_Mode;
字节[1]=数据;
I2C_Xfer (SSD1308_Address、bytes、2、NULL、0);
I2C_WAIT (3);
}
void oledGotoYX (unsigned char 行、unsigned char 列)
{
oledCommand (0xB0 + Row);
oledCommand( 0x00+(8*Column & 0x0F));
oledCommand( 0x10 +((8*Column>>4)&0x0F)));
}
void oledPutChar( char ch ){
if ((ch < 32)||(ch > 127))
CH =';
const uint8 * base =&OledFont[ch - 32][0];
uint8字节[9];
字节[0]= SSD1308_Data_Mode;
memmove (bytes + 1、base、8);
I2C_Xfer (SSD1308_Address、Bytes、9、NULL、0);
I2C_WAIT (9);
}
。
(笑声)
//我使用
oledPutChar ('a')调用例程;
似乎它在开始时进入2倍于 ISR TX FIFO、在这里、我只期望在发送的前4个字节时进入 FIFO、所以我可以添加4个字节、然后是剩余的1个字节
(如果 出现错误、i2c_wait 函数将等待命令或数据发送、转到下一个字节块
I2C_WaitCount 由 ADC ISR 更新、但实际上不需要、_仅从先前使用的中断 XRDY 函数/中断 XRDY 函数尝试更新)
关于如何解决该问题或其他解决方案的任何想法或建议?
谢谢


