DSP28335使用OLED12864

关于12864oled(IIC)

OLED
OLEDIIC模块一共有两个版本,他们的GND和VCC是相反的,要注意手上屏幕的引脚顺序。

IIC接口

IIC接口采用SCL作为时钟管脚,SDA作为数据管脚。单片机上一般有对应的两个管脚,可用于硬件IIC通讯。但是我们一般采用软件模拟IIC通讯,好处是代码移植性更高,而且,可以采用任意两个IO口进行通讯,不需要特定的接口。
DSP28335系统时钟为150Mhz,速度太快,需要在每次操作时加入3US延时-

DSP28335 IIC模拟

gpio32:SCL
gpio33:SDA
1.时钟使能,GPIO口配置。只需要向屏幕发送数据,所以两个io都配置为输出
2.IIC_Start。发送开始信号
3. Write_IIC_Byte。发送需要的数据
4. IIC_Wait_Ack。等待屏幕应答
5. IIC_Stop。数据发送完毕,发送终止信号

1.配置gpio

#define OLED_SCLK_Clr() GpioDataRegs.GPBCLEAR.bit.GPIO32=1;
#define OLED_SCLK_Set() GpioDataRegs.GPBSET.bit.GPIO32=1;

#define OLED_SDIN_Clr() GpioDataRegs.GPBCLEAR.bit.GPIO33=1;
#define OLED_SDIN_Set() GpioDataRegs.GPBSET.bit.GPIO33=1;
void Gpio_Init()
{
	EALLOW;	//打开写保护
	SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;//开启gpio时钟
	GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;	  	//启用上拉电阻
	GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;   	//配置为输出方向
	GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;  	//普通io口使用
	GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; 	//不同步

	GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;	  	//
	GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;   	//
	GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0;  	//
	GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;   //
	EDIS;	//关闭保护
}

2.
void IIC_Start()		//产生起始信号,SCL在高电平时,SDA:1->0
{
	OLED_SDIN_Set();
	OLED_SCLK_Set();	
	DELAY_US(5);	//延时,调用28335自带延时
	OLED_SDIN_Clr();
	DELAY_US(6);
	OLED_SCLK_Clr();
}

3.
void Write_IIC_Byte(unsigned char IIC_Byte)		//向SDA写入一个字节(8位)
{
	unsigned char i;
	unsigned char m,da;
	da=IIC_Byte;
	OLED_SCLK_Clr();
	for(i=0;i<8;i++)
	{
			m=da;
		//	OLED_SCLK_Clr();
		m=m&0x80;
		if(m==0x80)
		{
			OLED_SDIN_Set();
		}
		else
		{
			OLED_SDIN_Clr();
		}
			da=da<<1;
		DELAY_US(2);
		OLED_SCLK_Set();
		DELAY_US(2);
		OLED_SCLK_Clr();
		DELAY_US(2);
		}
}

4.
void IIC_Wait_Ack()		//只管写入不接收,等待应答过去
{
	OLED_SDIN_Set();
	OLED_SCLK_Set() ;
	DELAY_US(3);
	OLED_SCLK_Clr();
	DELAY_US(3);
}
5.
void IIC_Stop()		//产生停止信号,SCL高电平时,SDA:0->1
{
	OLED_SCLK_Clr();
	OLED_SDIN_Clr();
	OLED_SCLK_Set() ;
	DELAY_US(6);
	OLED_SDIN_Set();
	DELAY_US(6);
}


OLED初始化

向屏幕发送的数据分为command和data,command是对屏幕参数设定,初始化等。data则是我们需要显示的内容。

1 Write_IIC_Command。写入设定
2.Write_IIC_Data写入数据,即显示内容
3.OLED_ShowChar。屏幕显示
4.Oled_Init.。初始化屏幕,直接采用例程就可以

1.
void Write_IIC_Command(unsigned char IIC_Command)
{
   IIC_Start();
   Write_IIC_Byte(0x78);            //找到oled。0x78为oled在IIC上的地址,可以查询数据手册
	IIC_Wait_Ack();
   Write_IIC_Byte(0x00);			//声明是写入命令(command)
	IIC_Wait_Ack();
   Write_IIC_Byte(IIC_Command);		//写入命令内容
	IIC_Wait_Ack();
   IIC_Stop();
}
2.
void Write_IIC_Data(unsigned char IIC_Data)	//同上
{
   IIC_Start();
   Write_IIC_Byte(0x78);			
	IIC_Wait_Ack();
   Write_IIC_Byte(0x40);			//声明是写入数据(data)
	IIC_Wait_Ack();
   Write_IIC_Byte(IIC_Data);		//写入数据内容
	IIC_Wait_Ack();
   IIC_Stop();
}
3.
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)	//x,y为显示位置,chr为类容,ascii码形式。size为大小,8or16
{
	unsigned char c=0,i=0;
		c=chr-' ';//µÃµ½Æ«ÒƺóµÄÖµ
		if(x>Max_Column-1){x=0;y=y+2;}
		if(Char_Size ==16)
			{
			OLED_Set_Pos(x,y);
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);		//在F8x16的表中找到字模
			OLED_Set_Pos(x,y+1);
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
			}
			else {
				OLED_Set_Pos(x,y);
				for(i=0;i<6;i++)
				OLED_WR_Byte(F6x8[c][i],OLED_DATA);

			}
}
4.
void Oled_Init()	//复制例程,有两处可设定
{
	OLED_WR_Byte(0xAE,OLED_CMD);//--display off
	OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
	OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
	OLED_WR_Byte(0x81,OLED_CMD); // contract control
	OLED_WR_Byte(0xFF,OLED_CMD);//--128
	OLED_WR_Byte(0xA0,OLED_CMD);//!!!!设定x方向,0xA0选择正常方向(0xA1为反方向)
	OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
	OLED_WR_Byte(0xC0,OLED_CMD);//!!!!设定Y方向,0xC8正常反向,0xC0为正常方向
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
	OLED_WR_Byte(0x00,OLED_CMD);//

	OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
	OLED_WR_Byte(0x80,OLED_CMD);//

	OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
	OLED_WR_Byte(0x05,OLED_CMD);//

	OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
	OLED_WR_Byte(0xF1,OLED_CMD);//

	OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
	OLED_WR_Byte(0x12,OLED_CMD);//

	OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
	OLED_WR_Byte(0x30,OLED_CMD);//

	OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
	OLED_WR_Byte(0x14,OLED_CMD);//

	OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}


main()最终使用

#include “DSP2833x_Device.h”
#include “DSP2833x_Examples.h”
#include “Oled.h”
#include “led.h”

头文件不能忘

/*********************
x:0-127,每次+1,移动1个点
y:0-7,每次+1,移动8个点
**********************/
void main()
{
	InitSysCtrl();	//初始化系统时钟
	Led_Init();		//初始化led,可以开一个灯,判断系统是否正在运行
	OLED_Init();	//oled初始化
	OLED_Clear();	//清屏,例程种都有
	int t='0';		//直接给t赋值为0的ascii码
	int a=48;		//手动赋值0的ascii码
	while(1)
	{

		OLED_ShowString(8,1,"alphashe",16);
		OLED_ShowChar(16,6,t,16);		//均显示数字0,在x:16(1*16),y:48(8*6)处
		OLED_ShowChar(16,4,a,16);		//均显示数字0,在x:16(1*16),y:32(8*4)处
		t++;	//直接对t++,得到0在ascii码中的下一位。
		if(t>'z')
			t='0';
		Delay_1ms(1000);
		LED0_TOG;		//led0反转,指示系统正常运行。
	}

}

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
void OLED_ShowString(u8 x,u8 y, u8 p,u8 Char_Size);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);

等,均为例程函数,内容均是调用上面提到的函数,就不介绍了

总结

1.DSP速度过快,IIC需要时间响应,所以每次拉高拉低SDA,SCL需要延时几微秒。
2.显示位置设定,X每次1格,范围(0-127),但是Y每次8格,所以范围(0-7)。超出范围会乱码。
3.显示内容为Char型,十进制数字对应ASCII码表,可以参照码表,设置显示内容。

猜你喜欢

转载自blog.csdn.net/weixin_44449886/article/details/106996556