【MSPM0L1306 LaunchPad】i2c驱动OLED显示
<p><span style="font-size:16px;">这篇来学习下使用MSPM0L1306开发板驱动OLED显示。</span></p><p> </p>
<p><span style="font-size:16px;"><strong>一、硬件部分</strong></span></p>
<p> </p>
<p><span style="font-size:16px;">1.1、芯片内部框图</span></p>
<p> </p>
<p><span style="font-size:16px;">L1306芯片内部有两路I2C接口</span></p>
<p><span style="font-size:16px;"></span></p>
<p><span style="font-size:16px;">1.2、引脚配置</span></p>
<p><span style="font-size:16px;">测试使用I2C0端口,使用的引脚是PA1和PA10</span></p>
<p><span style="font-size:16px;"></span></p>
<p> </p>
<p> </p>
<p><span style="font-size:16px;"><strong>二、程序</strong></span></p>
<p> </p>
<p><span style="font-size:16px;">2.1、i2c.c</span></p>
<pre>
<code>#include "ti_msp_dl_config.h"
#include "i2c/i2c.h"
static const DL_I2C_ClockConfig gI2C_0ClockConfig =
{
.clockSel = DL_I2C_CLOCK_BUSCLK,
.divideRatio = DL_I2C_CLOCK_DIVIDE_1,
};
SYSCONFIG_WEAK void SYSCFG_DL_I2C_0_init(void)
{
DL_I2C_setClockConfig(I2C_0_INST,(DL_I2C_ClockConfig *) &gI2C_0ClockConfig);
DL_I2C_setAnalogGlitchFilterPulseWidth(I2C_0_INST, DL_I2C_ANALOG_GLITCH_FILTER_WIDTH_50NS);
DL_I2C_enableAnalogGlitchFilter(I2C_0_INST);
/* Configure Controller Mode */
DL_I2C_resetControllerTransfer(I2C_0_INST);
/* Set frequency to 400000 Hz*/
DL_I2C_setTimerPeriod(I2C_0_INST, 7);
DL_I2C_setControllerTXFIFOThreshold(I2C_0_INST, DL_I2C_TX_FIFO_LEVEL_EMPTY);
DL_I2C_setControllerRXFIFOThreshold(I2C_0_INST, DL_I2C_RX_FIFO_LEVEL_BYTES_1);
DL_I2C_enableControllerClockStretching(I2C_0_INST);
/* Enable module */
DL_I2C_enableController(I2C_0_INST);
}
void init_i2c(void)
{
DL_I2C_reset(I2C_0_INST);
DL_I2C_enablePower(I2C_0_INST);
DL_GPIO_initPeripheralInputFunctionFeatures(GPIO_I2C_0_IOMUX_SDA,
GPIO_I2C_0_IOMUX_SDA_FUNC, DL_GPIO_INVERSION_DISABLE,
DL_GPIO_RESISTOR_NONE, DL_GPIO_HYSTERESIS_DISABLE,
DL_GPIO_WAKEUP_DISABLE);
DL_GPIO_initPeripheralInputFunctionFeatures(GPIO_I2C_0_IOMUX_SCL,
GPIO_I2C_0_IOMUX_SCL_FUNC, DL_GPIO_INVERSION_DISABLE,
DL_GPIO_RESISTOR_NONE, DL_GPIO_HYSTERESIS_DISABLE,
DL_GPIO_WAKEUP_DISABLE);
DL_GPIO_enableHiZ(GPIO_I2C_0_IOMUX_SDA);
DL_GPIO_enableHiZ(GPIO_I2C_0_IOMUX_SCL);
SYSCFG_DL_I2C_0_init();
}
</code></pre>
<p> </p>
<p><span style="font-size:16px;">2.2、i2c.h</span></p>
<pre>
<code>#ifndef _I2C_H
#define _I2C_H
#include <ti/driverlib/driverlib.h>
/* Defines for I2C_0 */
#define I2C_0_INST I2C0
#define I2C_0_INST_IRQHandler I2C0_IRQHandler
#define I2C_0_INST_INT_IRQN I2C0_INT_IRQn
#define I2C_0_BUS_SPEED_HZ 400000
#define GPIO_I2C_0_SDA_PORT GPIOA
#define GPIO_I2C_0_SDA_PIN DL_GPIO_PIN_10
#define GPIO_I2C_0_IOMUX_SDA (IOMUX_PINCM11)
#define GPIO_I2C_0_IOMUX_SDA_FUNC IOMUX_PINCM11_PF_I2C0_SDA
#define GPIO_I2C_0_SCL_PORT GPIOA
#define GPIO_I2C_0_SCL_PIN DL_GPIO_PIN_1
#define GPIO_I2C_0_IOMUX_SCL (IOMUX_PINCM2)
#define GPIO_I2C_0_IOMUX_SCL_FUNC IOMUX_PINCM2_PF_I2C0_SCL
void init_i2c(void);
#endif
</code></pre>
<p> </p>
<p><span style="font-size:16px;">2.3、oled.c</span></p>
<pre>
<code>#include "ti_msp_dl_config.h"
#include "i2c/i2c.h"
#include "oled/oled.h"
#include "oled/codetab.h"
#include <stdio.h>
#include "systick/systick.h"
void I2C_WriteByte(uint8_t addr, uint8_t dat)
{
uint8_t temp;
temp = addr;
temp = dat;
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
}
void WriteCmd(unsigned char I2C_Command)
{
I2C_WriteByte(0x00, I2C_Command);
}
void WriteDat(unsigned char I2C_Data)
{
I2C_WriteByte(0x40, I2C_Data);
}
void OLED_WrCmd(unsigned char IIC_Command)
{
WriteCmd(IIC_Command);
}
void OLED_Init(void)
{
SysTick_Delay_ms(100);
WriteCmd(0xAE); //display off
WriteCmd(0x20); //Set Memory Addressing Mode
WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
WriteCmd(0xc8); //Set COM Output Scan Direction
WriteCmd(0x00); //---set low column address
WriteCmd(0x10); //---set high column address
WriteCmd(0x40); //--set start line address
WriteCmd(0x81); //--set contrast control register
WriteCmd(0xff); //ÁÁ¶Èµ÷½Ú 0x00~0xff
WriteCmd(0xa1); //--set segment re-map 0 to 127
WriteCmd(0xa6); //--set normal display
WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
WriteCmd(0x3F); //
WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCmd(0xd3); //-set display offset
WriteCmd(0x00); //-not offset
WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
WriteCmd(0xf0); //--set divide ratio
WriteCmd(0xd9); //--set pre-charge period
WriteCmd(0x22); //
WriteCmd(0xda); //--set com pins hardware configuration
WriteCmd(0x12);
WriteCmd(0xdb); //--set vcomh
WriteCmd(0x40); //0x20,0.77xVcc
WriteCmd(0x8d); //--set DC-DC enable
WriteCmd(0x14); //
WriteCmd(0xaf); //--turn on oled panel
}
void OLED_SetPos(unsigned char x, unsigned char y)
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)//È«ÆÁÌî³ä
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
}
}
}
void OLED_CLS(void)//ÇåÆÁ
{
OLED_Fill(0xff);
}
void OLED_ON(void)
{
WriteCmd(0X8D);//ÉèÖõçºÉ±Ã
WriteCmd(0X14);//¿ªÆôµçºÉ±Ã
WriteCmd(0XAF);//OLED»½ÐÑ
}
void OLED_OFF(void)
{
WriteCmd(0X8D);//ÉèÖõçºÉ±Ã
WriteCmd(0X10);//¹Ø±ÕµçºÉ±Ã
WriteCmd(0XAE);//OLEDÐÝÃß
}
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch != '\0')
{
c = ch - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8);
x += 6;
j++;
}
}break;
case 2:
{
while(ch != '\0')
{
c = ch - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16);
x += 8;
j++;
}
}break;
}
}
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned intadder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16);
adder += 1;
}
}
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
WriteDat(BMP);
}
}
}
</code></pre>
<p> </p>
<p><span style="font-size:16px;">2.4、oled.h</span></p>
<pre>
<code>#ifndef __OLED_I2C_H
#define __OLED_I2C_H
#define OLED_ADDRESS 0x3c //ͨ¹ýµ÷Õû0Rµç×è,ÆÁ¿ÉÒÔ0x78ºÍ0x7AÁ½¸öµØÖ· -- ĬÈÏ0x78
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
#endif
</code></pre>
<p> </p>
<p><span style="font-size:16px;">2.5、main.c</span></p>
<pre>
<code>#include "ti_msp_dl_config.h"
#include "led/led.h"
#include "systick/systick.h"
#include "uart/uart.h"
#include "key/key.h"
#include "i2c/i2c.h"
#include "i2c/I2C_communication.h"
#include "oled/oled.h"
int main(void)
{
uint8_t dd=0;
uint8_t tx_buf;
SYSCFG_DL_init();
init_systick();
init_led();
init_uart(115200);
init_i2c();
key_init();
DL_SYSCTL_disableSleepOnExit();
printf("mspm0l1306 board test! \r\n");
OLED_Init();
OLED_Fill(0x00);
OLED_ShowStr(0,0,"MSPM0L1306",2);
OLED_ShowStr(0,2,"I2C OLED",2);
while (1)
{
//key_test();
led2_g_tog();
SysTick_Delay_ms(20);
}
}
</code></pre>
<p> </p>
<p><strong><span style="font-size: 16px;">三、运行结果</span></strong></p>
<p> </p>
<p></p>
<p> </p>
<p> </p>
6666,i2c的硬件驱动的精华就在于这几个I2C_WriteByte之间,其的者是相同的。 lugl4313820 发表于 2023-11-2 21:38
6666,i2c的硬件驱动的精华就在于这几个I2C_WriteByte之间,其的者是相同的。
<p>这个板卡的i2c调试用了不少时间,库函数开始不熟悉。</p>
TL-LED 发表于 2023-11-2 22:31
这个板卡的i2c调试用了不少时间,库函数开始不熟悉。
<p>辛苦辛苦呀,大佬的文章写得非常不错,花费不少心思吧。</p>
<p>主要是IIC的速度达到不了要求,对于屏幕控制有点慢 </p>
秦天qintian0303 发表于 2023-11-6 11:03
主要是IIC的速度达到不了要求,对于屏幕控制有点慢
<p>400K的速率,屏幕小的话还可以吧</p>
TL-LED 发表于 2023-11-6 15:35
400K的速率,屏幕小的话还可以吧
<p>分辨率小点可以,我用SPI驱动屏,240*240分辨率,16M 得速度也不是很快</p>
页:
[1]