DMA I2C 驱动OLED黑屏 | 已解决
不知道为啥用DMA IIC驱动就会黑屏有哪位写过案例分享一下硬件IIC就没有问题void IIC_Write_NByte(uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
while (I2CMSST & 0x80); // 检查I2C控制器忙碌状态
DmaTxBuffer = DevAddress;
memcpy(&DmaTxBuffer, pData, Size);
I2CMSST = 0x00;
I2CMSCR = 0x09; // set cmd //write_start_combo
DMA_I2C_CR = 0x01;
DMA_I2CT_AMT = (uint8_t)Size; // 设置传输总字节数(低8位):Size + 设备地址
DMA_I2CT_AMTH = 0x00; // 设置传输总字节数(高8位)
DMA_I2C_ST1 = (uint8_t)Size;// 设置需要传输字节数(低8位):Size + 设备地址
DMA_I2C_ST2 = 0x00; // 设置需要传输字节数(高8位)
DMA_I2CT_CR |= 0x40; // bit7 1:使能 I2CT_DMA, bit6 1:开始 I2CT_DMA
while (DMA_I2CT_STA & 0x01); // DMA忙检测
DMA_I2CT_STA &= ~0x01; // 清除标志位
DMA_I2C_CR = 0x00;
}
void DMA_Config(void)
{
DMA_I2CT_STA = 0x00;
DMA_I2CT_CFG = 0x00; // bit7 1:Enable Interrupt
DMA_I2CT_AMT = 0x80; // 设置传输总字节数(低8位):n+1
DMA_I2CT_AMTH = 0x00; // 设置传输总字节数(高8位):n+1
DMA_I2CT_TXAH = (uint8_t)((uint16_t)&DmaTxBuffer >> 8); // I2C发送数据存储地址
DMA_I2CT_TXAL = (uint8_t)((uint16_t)&DmaTxBuffer);
DMA_I2CT_CR = 0x80; // bit7 1:使能 I2CT_DMA, bit6 1:开始 I2CT_DMA
DMA_I2C_ST1 = 0x80; // 设置需要传输字节数(低8位):n+1
DMA_I2C_ST2 = 0x00; // 设置需要传输字节数(高8位):n+1
}
#IIC配置
OLED刷新函数
请大佬们看看是哪里出了问题
从正确的程序开始,见 屠龙刀程序包
===从巨人的肩上起飞
www.stcai.com/hxgnsyb
神农鼎 发表于 2023-12-27 23:27
从正确的程序开始,见 屠龙刀程序包
===从巨人的肩上起飞
我不需要U8G2我只想要正常的实现DMA IIC驱动OLED nmdpkvs 发表于 2023-12-28 00:29
我不需要U8G2我只想要正常的实现DMA IIC驱动OLED
不需要U8G2就不用看U8G2代码,跟IIC DMA相关的程序都在"iic.c"文件里面,只要看这里面的程序就可以了。
IIC初始化:
void HAL_I2C_Init()
{
I2C_S1 =0; //I2C功能脚选择,00:P1.5,P1.4; 01:P2.5,P2.4; 11:P3.2,P3.3
I2C_S0 =1;
I2CCFG = 0xe0; //使能I2C主机模式
I2CMSST = 0x00;
EA = 1; //打开总中断
}
DMA初始化:
void DMA_Config(void)
{
#if(USE_I2C_DMA == 1)
DMA_I2CT_STA = 0x00;
DMA_I2CT_CFG = 0x00; //bit7 1:Enable Interrupt
DMA_I2CT_AMT = 0x1f; //设置传输总字节数(低8位):n+1
DMA_I2CT_AMTH = 0x00; //设置传输总字节数(高8位):n+1
DMA_I2CT_TXAH = (u8)((u16)&DmaTxBuffer >> 8); //I2C发送数据存储地址
DMA_I2CT_TXAL = (u8)((u16)&DmaTxBuffer);
DMA_I2CT_CR = 0x80; //bit7 1:使能 I2CT_DMA, bit6 1:开始 I2CT_DMA
// DMA_I2CR_STA = 0x00;
// DMA_I2CR_CFG = 0x80; //bit7 1:Enable Interrupt
// DMA_I2CR_AMT = 0x1f; //设置传输总字节数(低8位):n+1
// DMA_I2CR_AMTH = 0x00; //设置传输总字节数(高8位):n+1
// DMA_I2CR_RXAH = (u8)((u16)&DmaRxBuffer >> 8); //I2C接收数据存储地址
// DMA_I2CR_RXAL = (u8)((u16)&DmaRxBuffer);
// DMA_I2CR_CR = 0x81; //bit7 1:使能 I2CT_DMA, bit5 1:开始 I2CT_DMA, bit0 1:清除 FIFO
DMA_I2C_ST1 = 0x1f; //设置需要传输字节数(低8位):n+1
DMA_I2C_ST2 = 0x00; //设置需要传输字节数(高8位):n+1
#endif
}
DMA发送数据到IIC接口使用"HAL_I2C_Mem_Write"函数,你可以根据自己需要重新封装发送函数,主要代码:
DmaTxBuffer = (uint8_t)DevAddress;
// DmaTxBuffer = (uint8_t)MemAddress;
memcpy(&DmaTxBuffer,pData,Size); //设置发送数据
while(I2CMSST & 0x80); //检查I2C控制器忙碌状态
I2CMSST = 0x00;
I2CMSCR = 0x09; //set cmd
DMA_I2C_CR = 0x01;
DMA_I2CT_AMT = Size; //设置传输总字节数(低8位):Size + 设备地址
DMA_I2CT_AMTH = 0x00; //设置传输总字节数(高8位)
DMA_I2C_ST1 = Size; //设置需要传输字节数(低8位):Size + 设备地址
DMA_I2C_ST2 = 0x00; //设置需要传输字节数(高8位)
DMA_I2CT_CR |= 0x40; //bit7 1:使能 I2CT_DMA, bit6 1:开始 I2CT_DMA
while((DMA_I2CT_STA & 0x01)==0);//DMA忙检测
DMA_I2CT_STA &= ~0x01;//清除标志位
DMA_I2C_CR = 0x00; 提供一个简单的IIC+DMA驱动OLED屏例程,供参考
来晚了
页:
[1]
2