现在有了具体的I2C通信器件,一块1.3寸OLED屏幕,今日尝试移植配置一下:
本文主要讲的是,使用软件模拟I2C通信
文章提供测试代码讲解、完整工程下载、测试效果图
目录
前置文章:
I2C通信引脚:
软件I2C 引脚的初始化:
I2C_software.h
#include "OLED.h"
#include "OLED_ZK.h"
主函数文件:
测试效果:
有关软件I2C是否需要关总中断的测评与感受:
测试工程下载:
我的单片机平台是这个:
前置文章:
TMS320F28P550SJ9学习笔记8:I2C通信的结构体寄存器配置的了解-CSDN博客
I2C通信引脚:
GPIO10 SDA
GPIO11 SCL
软件I2C 引脚的初始化:
这里主要注意几个方面:
1.都要有上拉电阻 2.引脚速率 3. SDA方向可变
I2C总线速度可以是标准速率(100 kHz)、快速速率(400 kHz)或更高。引脚的速度设置应至少能满足I2C总线速率的要求。
I2C_software.h
这里初始化I2C的引脚,写了一些I2C的基本模拟函数
/** I2C_software.h** Created on: 2025年3月11日* Author: 30313*/#ifndef USER_I2C_SOFTWARE_H_
#define USER_I2C_SOFTWARE_H_#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"#define u8 unsigned char//宏定义 设定寄存器来改变SDA线的输入输出状态:
#define SDA_IN() {EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO10 = 0; EDIS;} //SDA输入模式
#define SDA_OUT() {EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO10 = 1; EDIS;} //SDA输出模式static inline void setIIC_SDA(Uint16 value) {if (value) { GpioDataRegs.GPASET.bit.GPIO10 = 1; }// GPIO10 输出1else { GpioDataRegs.GPACLEAR.bit.GPIO10 = 1; } // GPIO10 输出0
}static inline void setIIC_SCL(Uint16 value) {if (value) { GpioDataRegs.GPASET.bit.GPIO11 = 1; } // GPIO11 输出1else { GpioDataRegs.GPACLEAR.bit.GPIO11 = 1; } // GPIO11 输出0
}//IO操作函数
#define IIC_SCL setIIC_SCL
#define IIC_SDA setIIC_SDA
#define READ_SDA GpioDataRegs.GPADAT.bit.GPIO10void Init_I2C_software(void); //初始化软件I2Cvoid I2C_Start(void); //产生IIC起始信号
void I2C_Stop(void); //产生IIC停止信号
u8 I2C_Wait_Ack(void);//等待应答信号到来
void I2C_Ack(void); //产生ACK应答
void I2C_NAck(void); //不产生ACK应答
void I2C_Send_Byte(u8 txd); //IIC发送一个字节
u8 I2C_Read_Byte(unsigned char ack); //读1个字节,ack=1时,发送ACK,ack=0,发送nACK#endif /* USER_I2C_SOFTWARE_H_ */
/** I2C_software.c** Created on: 2025年3月11日* Author: 30313*/#include "I2C_software.h"//软件I2C 初始化 SCL GPIO10 SDA GPIO11
void Init_I2C_software(void)
{//设置GPIO10和GPIO11为GPIO模式EALLOW;GpioCtrlRegs.GPAGMUX1.bit.GPIO10 = 0;// 将A17/GPIO10设置为GPIO模式GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 0; // 将B17/GPIO11设置为GPIO模式//禁用模拟//GpioCtrlRegs.GPAAMSEL.bit.GPIO10 = 0; // 禁用GPIO10的模拟功能GpioCtrlRegs.GPAAMSEL.bit.GPIO11 = 0; // 禁用GPIO11的模拟功能//设置GPIO10和GPIO11为输出GpioCtrlRegs.GPADIR.bit.GPIO10 = 1; // 设置GPIO10为输出GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // 设置GPIO11为输出//设置GPIO10和GPIO11为标准输入/输出模式GpioCtrlRegs.GPAPUD.bit.GPIO10 = 1; // 启用GPIO10的上拉电阻GpioCtrlRegs.GPAPUD.bit.GPIO11 = 1; // 启用GPIO11的上拉电阻//设置GPIO10和GPIO11为同步模式(可选)GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; // 设置GPIO10为同步模式GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0; // 设置GPIO11为同步模式//GpioCtrlRegs.GPACTRL.bit.QUALPRD2=0x01 // 设置GPIO16~23 的 采样周期为 PLLSYSCLK/2EDIS;//SDA_OUT();
}//产生IIC起始信号
void I2C_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA(1);IIC_SCL(1);DEVICE_DELAY_US(4);IIC_SDA(0);//START:when CLK is high,DATA change form high to lowDEVICE_DELAY_US(4);IIC_SCL(0);//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void I2C_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL(0);IIC_SDA(0);//STOP:when CLK is high DATA change form low to highDEVICE_DELAY_US(4);IIC_SCL(1);IIC_SDA(1);//发送I2C总线结束信号DEVICE_DELAY_US(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 I2C_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN(); //SDA设置为输入IIC_SDA(1);DEVICE_DELAY_US(1);IIC_SCL(1);DEVICE_DELAY_US(1);while(READ_SDA){ucErrTime++;if(ucErrTime>250){I2C_Stop();return 1;}}IIC_SCL(0);//时钟输出0return 0;
}
//产生ACK应答
void I2C_Ack(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(0);DEVICE_DELAY_US(2);IIC_SCL(1);DEVICE_DELAY_US(2);IIC_SCL(0);
}
//不产生ACK应答
void I2C_NAck(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(1);DEVICE_DELAY_US(2);IIC_SCL(1);DEVICE_DELAY_US(2);IIC_SCL(0);
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void I2C_Send_Byte(u8 txd)
{u8 t;SDA_OUT();IIC_SCL(0);//拉低时钟开始数据传输for(t=0;t<8;t++){//IIC_SDA=(txd&0x80)>>7;if((txd&0x80)>>7)IIC_SDA(1);elseIIC_SDA(0);txd<<=1;DEVICE_DELAY_US(2); //对TEA5767这三个延时都是必须的IIC_SCL(1);DEVICE_DELAY_US(2);IIC_SCL(0);DEVICE_DELAY_US(2);}
}//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 I2C_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL(0);DEVICE_DELAY_US(2);IIC_SCL(1);receive<<=1;if(READ_SDA)receive++;DEVICE_DELAY_US(1);}if (!ack)I2C_NAck();//发送nACKelseI2C_Ack(); //发送ACKreturn receive;
}
#include "OLED.h"
这里主要是OLED的一些操作函数,要与我配置的I2C引脚联系起来
#ifndef _OLED_h_
#define _OLED_h_#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"#include "OLED_ZK.h"
#include "I2C_software.h"#define OLED_MODE 0
#define SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF
#define X_WIDTH 128
#define Y_WIDTH 64
//-----------------OLED IIC端口定义---------------- #define OLED_SCLK_Clr() IIC_SCL(0)//SCL
#define OLED_SCLK_Set() IIC_SCL(1)#define OLED_SDIN_Clr() IIC_SDA(0)//SDA
#define OLED_SDIN_Set() IIC_SDA(1)#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
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_ShowCHinese(u8 x,u8 y,u8 no);
void OLED_ShowCHinese_small(u8 x,u8 y,u8 no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);void Delay_50ms(unsigned int Del_50ms);
void Delay_1ms(unsigned int Del_1ms);void fill_picture(unsigned char fill_Data);
void Picture(void);
void IIC_Start(void);
void IIC_Stop(void);
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Byte(unsigned char IIC_Byte);void IIC_Wait_Ack(void);#endif
#include "OLED.h"//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
/**********************************************
//IIC Start
**********************************************/
/**********************************************
//IIC Start
**********************************************/
void IIC_Start(void)
{OLED_SCLK_Set() ;OLED_SDIN_Set();OLED_SDIN_Clr();OLED_SCLK_Clr();
}/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop(void)
{OLED_SCLK_Set() ;
// OLED_SCLK_Clr();OLED_SDIN_Clr();OLED_SDIN_Set();}void IIC_Wait_Ack(void)
{OLED_SCLK_Set() ;OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/void Write_IIC_Byte(unsigned char IIC_Byte)
{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;OLED_SCLK_Set();OLED_SCLK_Clr();}}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{IIC_Start();Write_IIC_Byte(0x78); //Slave address,SA0=0IIC_Wait_Ack(); Write_IIC_Byte(0x00); //write commandIIC_Wait_Ack(); Write_IIC_Byte(IIC_Command); IIC_Wait_Ack(); IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{IIC_Start();Write_IIC_Byte(0x78); //D/C#=0; R/W#=0IIC_Wait_Ack(); Write_IIC_Byte(0x40); //write dataIIC_Wait_Ack(); Write_IIC_Byte(IIC_Data);IIC_Wait_Ack(); IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{if(cmd){Write_IIC_Data(dat);}else {Write_IIC_Command(dat);}}/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{unsigned char m,n;for(m=0;m<8;m++){OLED_WR_Byte(0xb0+m,0); //page0-page1OLED_WR_Byte(0x02,0); //low column start addressOLED_WR_Byte(0x10,0); //high column start addressfor(n=0;n<128;n++){OLED_WR_Byte(fill_Data,1);}}
}/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{unsigned int m;for(;Del_50ms>0;Del_50ms--)for(m=6245;m>0;m--);
}void Delay_1ms(unsigned int Del_1ms)
{unsigned char j;while(Del_1ms--){ for(j=0;j<123;j++);}
}//坐标设置void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte(((x+2)&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD); //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{ u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)OLED_WR_Byte (0x02,OLED_CMD); //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新显示
}
void OLED_On(void)
{ u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)OLED_WR_Byte (0x02,OLED_CMD); //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); } //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{ 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);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);}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{u32 result=1; while(n--)result*=m; return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{ u8 t,temp;u8 enshow=0; for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size2/2)*t,y,' ',size2);continue;}else enshow=1; }OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); }
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{unsigned char j=0;while (chr[j]!='\0'){ OLED_ShowChar(x,y,chr[j],Char_Size);x+=8;if(x>120){x=0;y+=2;}j++;}
}//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{ u8 t,adder=0;OLED_Set_Pos(x,y); for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1;} OLED_Set_Pos(x,y+1); for(t=0;t<16;t++){ OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1;}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
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_Set_Pos(x0,y);for(x=x0;x<x1;x++){ OLED_WR_Byte(BMP[j++],OLED_DATA); }}
} void OLED_ShowCHinese_small(u8 x,u8 y,u8 no)
{u8 t,adder=0;OLED_Set_Pos(x,y); for(t=0;t<12;t++){OLED_WR_Byte(Hzk_m[no][t],OLED_DATA);adder+=1;}
}//初始化SSD1306
void OLED_Init(void)
{ DEVICE_DELAY_US(100);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 对比度值设置为128OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap 设置段重映射OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse 设置正常显示/反向显示OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) 设置多路复用比率(1到64)OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty 设置Duty值为1/32OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction 设置COM扫描方向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);// 设置振荡器分频值为80OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off 设置区域颜色模式关闭OLED_WR_Byte(0x05,OLED_CMD);// 设置区域颜色模式值为05OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period 设置预充电周期OLED_WR_Byte(0xF1,OLED_CMD);// 设置预充电周期值为F1OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion 设置COM引脚配置OLED_WR_Byte(0x12,OLED_CMD);// 设置COM引脚配置值为12OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh 设置VcomhOLED_WR_Byte(0x30,OLED_CMD);// 设置Vcomh值为30OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable 设置充电泵使能OLED_WR_Byte(0x14,OLED_CMD);// 设置充电泵使能值为14OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel 打开显示屏
}
#include "OLED_ZK.h"
这是OLED的字库,里面有我取模过的太空人图片28张,如果你的flash空间不够,请将定义的BMP1[]~BMP28[] 数组悉数删去,不影响其他字符的打印
这里就不贴出 OLED_ZK 的.c文件了,有点大
#ifndef _OLED_ZK_h_
#define _OLED_ZK_h_#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"#define u32 unsigned intextern const unsigned char F6x8[][6];
extern const unsigned char F8X16[];
extern char Hzk[][32];
extern char Hzk_m[][32];extern unsigned char BMP1[];
extern unsigned char BMP2[];
extern unsigned char BMP3[];
extern unsigned char BMP4[];
extern unsigned char BMP5[];
extern unsigned char BMP6[];
extern unsigned char BMP7[];
extern unsigned char BMP8[];
extern unsigned char BMP9[];
extern unsigned char BMP10[];
extern unsigned char BMP11[];
extern unsigned char BMP12[];
extern unsigned char BMP13[];
extern unsigned char BMP14[];
extern unsigned char BMP15[];
extern unsigned char BMP16[];
extern unsigned char BMP17[];
extern unsigned char BMP18[];
extern unsigned char BMP19[];
extern unsigned char BMP20[];
extern unsigned char BMP21[];
extern unsigned char BMP22[];
extern unsigned char BMP23[];
extern unsigned char BMP24[];
extern unsigned char BMP25[];
extern unsigned char BMP26[];
extern unsigned char BMP27[];
extern unsigned char BMP28[];#endif
主函数文件:
这是主函数文件,只要看图中三个地方,就能启用OLED打印了:
/* 名称 : 软件I2C 测试工程* 创建者 : NULL指向我* 日期 : 2025.3.12* 功能 : 软件模拟I2C 通过1.3寸OLED打印 data counts 计数(每200ms + 1)* 平台 : LAUNCHXL-F28P55x* 型号 : TMS320F28P550SJ9* 备注 :* IIC_SCL GPIO 10* IIC_SDA GPIO 11* 主函数** *///头文件
#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"
#include "sci_1.h"
#include "TIMER.h"
#include "string.h"
#include "stdio.h"
#include "I2C_software.h"#include "OLED.h"// 这个 CPU定时器的 中断服务函数貌似只能 定义在 主函数文件
__interrupt void cpuTimer0ISR(void);
__interrupt void cpuTimer1ISR(void);
__interrupt void cpuTimer2ISR(void);//主函数 main
void main(void)
{char buf[30];int data=0;Device_init(); //初始化系统时钟Device_initGPIO(); //解锁GPIO端口Init_GPIO_LEDPort(); //初始化LED端口// @LSPCLK = 37.5 MHz (150 MHz SYSCLK) HBAUD = 0x01 and LBAUD = 0xE7.Init_SCIA(9600,37500000);//初始化SCIInitCpuTimers();//初始化定时器CUPTIMER 0Init_CPU_TIMER(&CpuTimer0, 150, 100);//时钟来源 SYSCLKOUT 150Mhz / 150分频 /1000 000计数重载值 / 1000 ms溢出中断频率InitPieVectTable();Interrupt_initModule();Interrupt_initVectorTable();// 链接 中断服务函数 ISR functionsEALLOW;PieVectTable.TIMER0_INT = &cpuTimer0ISR;PieVectTable.TIMER1_INT = &cpuTimer1ISR;PieVectTable.TIMER2_INT = &cpuTimer2ISR;EDIS;CpuTimer0Regs.TCR.all = 0x4000;CpuTimer1Regs.TCR.all = 0x4000;CpuTimer2Regs.TCR.all = 0x4000;IER |= M_INT1;IER |= M_INT13;IER |= M_INT14;// Enable TINT0 in the PIE: Group 1 interrupt 7PieCtrlRegs.PIEIER1.bit.INTx7 = 1;Init_I2C_software(); //初始化软件I2COLED_Init(); //初始化OLED屏幕OLED_Clear(); //清空屏幕数据EINT;ERTM;while(1){data++;sprintf(buf,"data counts: %d",data);OLED_ShowString(2,1,(u8 *)buf,16);DEVICE_DELAY_US(200000);}
}/*
data++;
sprintf(buf,"data counts: %d",data);
OLED_ShowString(2,0,(u8 *)buf,16);
*/// cpuTimer0ISR - CPU Timer0 ISR with interrupt counter
__interrupt void cpuTimer0ISR(void)
{CpuTimer0.InterruptCount++;//DEVICE_DELAY_US(80);PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}// cpuTimer1ISR - CPU Timer1 ISR with interrupt counter
__interrupt void cpuTimer1ISR(void)
{CpuTimer1.InterruptCount++;
}// cpuTimer2ISR CPU Timer2 ISR with interrupt counter
__interrupt void cpuTimer2ISR(void)
{CpuTimer2.InterruptCount++;
}//主文件结尾
测试效果:
OLED正常打印字符:
有关软件I2C是否需要关总中断的测评与感受:
之前学习软件I2C时,被提示过需要关闭总中断,防止I2C传输出问题,这里就测试一下,我不关总中断,会出什么问题
但提前说下结果,对OLED的SSD1306芯片貌似没有什么影响
这里开了一个100us 的中断,每次进中断阻塞80us的延时:
我的I2C器件除了主循环被打断,导致打印变慢了,OLED的显示貌似没问题:
逻辑分析仪测试结果如下:
测试工程下载:
https://download.csdn.net/download/qq_64257614/90477080