|
PIC18f4680 SPI和IIC同时使用,SPI 驱动字库芯片,IIC驱动OLED。SPI和IIC都是使用的RC3 和RC4引脚,可以进行分时复用吗?怎么实现?
这是4680引脚图
void main(void)
{
unsigned char NixieNum =0 ,Temp1 = 0;
GPIO_Init();
Timer0_int();
OLED_Init();
OLED_Clear(0xf0);
OLED_Clear(0x00);
OLED_Clear(0x0F);
OLED_Clear(0x00);
OLED_ShowString(1,1,"KeyNum:");
OLED_ShowString(2,1,"Nixie:");
OLED_ShowString(3,1,"0x");
// OLED_GB2312_15x16_ShowChar(4,1,"按键");
while(1)
{
NixieNum = Key_NIXIE_Num();
if(NixieNum)
{
Temp1 = NixieNum;
OLED_ShowBinNum(2,8,Temp1,8 );
OLED_ShowHexNum(3,3,Temp1,2);
if(Temp1 == 0xDF){ LED_RGB_G_ON();}
if(Temp1 == 0xEF){ LED_RGB_B_ON();}
if(Temp1 == 0xF7){ LED_RGB_R_ON();}
if(Temp1 == 0x5F){ LED_RGB_G_OFF();}
if(Temp1 == 0x6F){ LED_RGB_B_OFF();}
if(Temp1 == 0x77){ LED_RGB_R_OFF();}
}
}
}
void IIC_Init(void)
{
LATCbits.LC0 = 1; //SPI_CS_PIN LATCbits.LC0(字库片选)
TRISCbits.RC0 = 0; //CS 1:输入 0:输出(字库片选)
/*********************************
**** 硬件IIC GPIO初始化****
*********************************/
LATCbits.LC3 = 0; //IIC_SCL
LATCbits.LC4 = 0; //IIC_SDA
TRISCbits.RC3 = 1; //设置为输入
TRISCbits.RC4 = 1; //设置为输入
SSPSTAT = 0x80; //设置通讯速率100K;Disable SMBus
SSPCON1 = 0x38; //使能串口,主控模式,时钟=Fosc/(4*(SSPADD+1)
SSPCON2 = 0x00; //
PIR1bits.SSPIF=0; //中断标志清零
SSPADD = 0x27; // 频率 = Focs/(4 * (SSPADD + 1)) ;100K频率 16M晶振 SSPADD= 0x27;
}
void SPI_Init(void)
{
/*********************************
**** SPI__GPIO初始化****
*********************************/
LATCbits.LC0 = 1; //SPI_CS_PIN LATCbits.LC0(字库片选)
LATCbits.LC2 = 1; //SPI_CS_PIN LATCbits.LC0(FLASH片选)
LATCbits.LC3 = 0; //SPI_SCK_PIN LATCbits.LC3
PORTCbits.RC4 = 0; //SPI_MISO_PIN PORTCbits.RC4 //数据输入
LATCbits.LC5 = 0; //SPI_MOSI_PIN LATCbits.LC5 //数据输出
TRISCbits.RC0 = 0; //CS 1:输入 0:输出(字库片选)
TRISCbits.RC2 = 0; //flash_CS 1:输入 0:输出(FLASH片选)
TRISCbits.RC3 = 0; //CLK 1:输入 0:输出
TRISCbits.RC4 = 1; //SDI 1:输入 0:输出
TRISCbits.RC5 = 0; //SDO 设置RC5端口为输出
//SCLK开始高电平上升沿发送数据,下降沿接收数据。
//0000 0000
SSPSTAT = 0x80; //bit7 = 1; 0:在数据输出时间的中间采样输入数据 1:在数据输出时间的末端采样输入数据
//bit6 = 0; 0:时钟状态从空闲换到有效时发送 1:时钟从有效换到空闲时发送
//bit0 = 0; 接收未完成,SSBUF空
SSPCON1 = 0x32; //bit5 = 1; 使能SPI, bit4 = 1;空闲状态时,时钟为高电平
//bit3-0 = 0010,SPI主控模式,时钟=Fosc/64
// SSPCON1bits.WCOL = 0; //写冲突检测 0:未发生冲突 1:
// SSPCON1bits.CKP = 1; //bit4 = 1;空闲状态时,时钟为高电平
// SSPCON1bits.SSPM3 = 0; //bit3-0 = 0011,SPI主控模式,时钟=TMR2输出/2
// SSPCON1bits.SSPM2 = 0; // 0010,SPI主控模式,时钟=Fosc/16
// SSPCON1bits.SSPM1 = 1; // 0001,SPI主控模式,时钟=Fosc/16
// SSPCON1bits.SSPM0 = 0; // 0000,SPI主控模式,时钟=Fosc/4
SSPIF = 0; //中断标志位清零
SSPCON1bits.SSPEN = 1; //使能SPI
}
/**
* @brief OLED写命令
* @param Command 要写入的命令
* @retval 无
*/
void oled_cmd(char cmd)
{
IIC_Init();
IIC_STAT();
IIC_SendByte(0x78);
IIC_SendByte(0x00);
IIC_SendByte(cmd);
IIC_STOP();
}
/**
* @brief OLED写数据
* @param Data 要写入的数据
* @retval 无
*/
void oled_data(char Data)
{
IIC_Init();
IIC_STAT();
IIC_SendByte(0x78);
IIC_SendByte(0x40);
IIC_SendByte(Data);
IIC_STOP();
}
/**
* @brief OLED显示汉字
* @param Line 行位置,范围:1~4
* @param Column 列位置,范围:1~16
* @param text 要显示的一个字符,范围:字库芯片
* @retval 无
*/
void OLED_GB2312_15x16_ShowChar(unsigned char Line, unsigned char Column, unsigned char *text)
{
unsigned char i,j;
unsigned char SZHPArray[32];
unsigned char HZHPArray[32];
while(*text != 0)
{
// SPI_Init();
GT30L32S4W_Get_Bytes_GB2312_15x16(text,HZHPArray);
GB2312_15x16_HengZhiHengPai_to_ShuZhiHengPai(SZHPArray,HZHPArray);
// IIC_Init();
for(j = 0; j < 32; j ++)
{
OLED_SetCursor((unsigned char)((Line - 1) * 2), (unsigned char)((Column - 1) * 8)); //设置光标位置在上半部分
for (i = 0; i < 16; i++)
{
oled_data(SZHPArray[ i]); //显示上半部分内容
}
OLED_SetCursor((unsigned char)((Line - 1) * 2 + 1), (unsigned char)((Column - 1) * 8)); //设置光标位置在下半部分
for (i = 0; i < 16; i++)
{
oled_data(SZHPArray[i + 16]); //显示下半部分内容
}
}
text += 2; //下个字
Column += 2;
}
}
|
|