TMS320F28P550SJ9學習筆記10:軟件模擬I2C通信_驅動1.3寸OLED

現在有了具體的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

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72051.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72051.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72051.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

spring boot 發送郵件驗證碼

一、前置需求 1、準備郵箱 2、登錄授權碼 qq郵箱在–>設置–>賬號POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務 開啟服務 二、發送郵件 1、簡單郵件 包含郵件標題、郵件正文 2、引入mail啟動器 <dependency><groupId>org.springframework.boot</groupI…

塔能科技:智能機箱,為城市安防 “智” 造堅實堡壘

在當今智慧城市建設的浪潮中&#xff0c;城市安防面臨著諸多挑戰。設備管理難&#xff0c;眾多分散的安防設備猶如一盤散沙&#xff0c;難以實現高效統一的管控&#xff1b;數據傳輸不穩定&#xff0c;關鍵時刻信息的延遲或丟失&#xff0c;可能導致嚴重后果。這些問題嚴重制約…

電商數據分析 電商平臺銷售數據分析 電商平臺數據庫設計 揭秘電商怎么做數據分析

《電商參謀數據分析平臺方案》&#xff08;28頁PPT&#xff09;是一套為電商行業量身定制的一體化解決方案&#xff0c;它通過全鏈路打通從數據獲取到分析的全過程&#xff0c;幫助電商企業實現精細化運營和市場機會的挖掘。該方案針對電商行業在數據獲取、加工整合及業務賦能方…

uniapp uview 1.0 跨域h5配置多個代理、如何請求接口

參考文章&#xff1a;uniapp uView1.0跨域h5配置多個代理 官方手冊&#xff1a;http 請求 項目中使用&#xff1a; 參考其他博主的文章是在manifest.json中配置代理&#xff0c;但在官方的手冊中是直接在script請求的&#xff0c;我嘗試請求了下沒問題&#xff0c;上線后也不…

MAVEN解決版本依賴沖突

文章目錄 一、依賴沖突概念1、什么是依賴沖突2、依賴沖突的原因3、如何解決依賴沖突 二、查看依賴沖突-maven-helper1、安裝2、helper使用1、conflicts的閱讀順序&#xff08;從下向上看&#xff09;2、dependencies as List的閱讀順序&#xff08;從下向上看&#xff09;3、de…

79.ScottPlot的MVVM實現 C#例子 WPF例子

如何通過數據綁定在 WPF 中實現動態圖像顯示 在 WPF 應用程序中&#xff0c;通過數據綁定實現動態圖像顯示是一種高效且優雅的方式。以下是一個簡單的教程&#xff0c;展示如何使用 ScottPlot.WPF 庫和 MVVM 模式來實現這一功能。 第一步&#xff1a;安裝必要的 NuGet 包 首…

簡單工廠 、工廠方法模式和抽象工廠模式

簡單工廠 、工廠方法模式和抽象工廠模式 1.模式性質與定位 簡單工廠:并非正式的設計模式(屬編程習慣),通過單一工廠類根據參數判斷創建不同產品,本質是將對象創建邏輯集中管理。 工廠方法:是標準的創建型設計模式,定義抽象創建接口,由子類決定實例化哪個具體產品類,…

熱圖回歸(Heatmap Regression)

熱圖回歸(Heatmap Regression)是一種常用于關鍵點估計任務的方法,特別是在人體姿態估計中。它的基本思想是通過生成熱圖來表示某個關鍵點在圖像中出現的概率或強度。以下是熱圖回歸的主要特點和工作原理: 主要特點 熱圖表示: 每個關鍵點對應一個熱圖,熱圖中的每個像素值…

Word 小黑第15套

對應大貓16 修改樣式集 導航 -查找 第一章標題不顯示 再選中文字 點擊標題一 修改標題格式 格式 -段落 -換行和分頁 勾選與下段同頁 添加腳注 &#xff08;腳注默認位于底部 &#xff09;在腳注插入文檔屬性&#xff1a; -插入 -文檔部件 -域 類別選擇文檔信息&#xff0c;域…

Java 大視界 -- Java 大數據在智能安防視頻摘要與檢索技術中的應用(128)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

Python里matplotlib不顯示中文的問題

在很長一段時間里用Python繪圖&#xff0c;matplotlib都不能很好的顯示中文&#xff0c;起初是認為我的pycharm里的設置問題&#xff0c;但是發現同樣的問題在spyder里也同樣的出現。 一共有兩種解決方案&#xff0c;我強烈推薦第一種&#xff0c;因為更為方便&#xff0c;繪圖…

JavaWeb-servlet6中request和response的使用

HttpServletRequest HttpServletRequest 繼承自 ServletRequest。客戶端瀏覽器發出的請求被封裝成為一個 HttpServletRequest對象。 對象包含了客戶端請求信息包括請求的地址&#xff0c;請求的參數&#xff0c;提交的數據&#xff0c;上傳的文件客戶端的ip甚至客戶端操作系統…

機器學習(吳恩達)

一, 機器學習 機器學習定義: 計算機能夠在沒有明確的編程情況下學習 特征: 特征是描述樣本的屬性或變量&#xff0c;是模型用來學習和預測的基礎。如: 房屋面積, 地理位置 標簽: 監督學習中需要預測的目標變量&#xff0c;是模型的輸出目標。如: 房屋價格 樣本: 如: {面積100㎡…

CNN的激活函數

我們來對比 Sigmoid、Softmax 和 ReLU 這三種激活函數的相同點和不同點&#xff0c;并分別說明它們相較于其他兩種激活函數的優點。 相同點 都是非線性激活函數&#xff1a; 這三種激活函數都能為神經網絡引入非線性特性&#xff0c;使網絡能夠學習復雜的模式。 廣泛應用于深度…

Oracle數據恢復:閃回查詢

Oracle數據恢復:閃回查詢 SQL語法閃回查詢:AS OF閃回版本查詢:VERSIONS BETWEEN數據恢復示例閃回查詢最佳實踐應用場景使用限制注意事項最佳實踐在誤刪除業務數據時,Oracle數據庫通常支持以下幾種數據恢復途徑。 閃回查詢(Flashback Query):閃回查詢通過查詢系統的UNDO數…

【MySQL篇】MySQL內置函數

目錄 1&#xff0c;日期函數 2&#xff0c;字符串函數 3&#xff0c;數學函數 4&#xff0c;其他函數 實戰OJ 1&#xff0c;日期函數 日期類型在之前文章【數據類型】中有描述 傳送門&#xff1a;【MySQL篇】數據類型_mysql 數據類型-CSDN博客 函數名稱描述current_dat…

蘋果iOS 18.4將強制升級HomeKit架構,舊版設備或無法使用

在科技飛速發展的當下,智能家居領域也在不斷革新。而蘋果公司作為科技行業的巨頭,其每一次動作都備受關注。近日,有消息稱蘋果計劃在iOS 18.4版本中停止對舊版HomeKit架構的支持,這一舉措意味著用戶將被迫升級,也可能對眾多使用Apple Home應用的智能家居設備用戶產生深遠影…

故障診斷——neo4j入門

文章目錄 neo4jQuickStartDemo neo4j QuickStart 詳情可見博客&#xff1a;https://www.cnblogs.com/nhdlb/p/18703804&#xff0c;使用docker拉取最近的一個版本進行創建 docker run -it -d -p 7474:7474 -p 7687:7687 \ -v /disk5/neo4j_docker/data:/data \ -v /disk5/ne…

《蒼穹外賣》SpringBoot后端開發項目核心知識點與常見問題整理(DAY1 to DAY3)

目錄 一、在本地部署并啟動Nginx服務1. 解壓Nginx壓縮包2. 啟動Nginx服務3. 驗證Nginx是否啟動成功&#xff1a; 二、導入接口文檔1. 黑馬程序員提供的YApi平臺2. YApi Pro平臺3. 推薦工具&#xff1a;Apifox 三、Swagger1. 常用注解1.1 Api與ApiModel1.2 ApiModelProperty與Ap…

大模型安全新范式:DeepSeek一體機內容安全衛士發布

2月以來&#xff0c;DeepSeek一體機幾乎成為了政企市場AI消費的最強熱點。 通過一體機的方式能夠縮短大模型部署周期&#xff0c;深度結合業務場景&#xff0c;降低中小企業對于大模型的使用門檻。據不完全統計&#xff0c;已約有超過60家企業基于DeepSeek推出一體機產品。 但…