📄 i2c.c
字号:
#include "pic18.h" //* PIC18系列的头文件 */
/*************************************************************/
/*注意:广大的实验板的8583的芯片地址是0xA2 所以写的时候为0xA2 读的时候为0xA3
/* 我自己焊接的8583芯片地址是0xA2 所以写的时候为0xA2 读的时候为0xA3
/*************************************************************/
#define uchar unsigned char
#define uint unsigned int
uchar bb[8];
uchar str[6];
uint numbb;
/*************************************************************/
/************************ LCD *******************************/
/*************************************************************/
#define clear 0x01
#define home 0x02
#define dis_on 0x0f
#define in_mode 0x06
#define P_RS RD7 //4 CS
#define P_RW RD6 //5 SID
#define P_E RD5 //6 CLK
//*-----------------------------------------------------------*/
void delay_us(uint j) // time=j*10+7 (us)延时函数/
{
uint ch;
while(j--)
{
ch++; ch--;
}
}
/*----------------------- LCD --------------------------------*/
void bit8_serial_input(unsigned char ix)
{
unsigned char i,j,nc,ab;
ab=0x80;
P_RW=0;//P_RW_0();//PORTD&=0xbf;
P_E=0;//P_E_0();//PORTD&=0xdf;
for(i=0;i<8;i++)
{
if(ix&ab)P_RW=1;//P_RW_1();
else P_RW=0;//P_RW_0();
ab>>=1;
P_E=1;//P_E_1();//PORTD|=0x20;
for(j=0;j<44;j++) nc=0;
P_E=0;//P_E_0();//PORTD&=0xdf;
P_RW=0;//P_RW_0();//PORTD&=0xbf;
for(j=0;j<4;j++) nc=0;
}
}
/*---------------------------------------------------------*/
void instruct(unsigned char dat)
{
unsigned char ch;
RD7=1;//P_RS_1();
ch=0xf8;
bit8_serial_input(ch);
ch=dat&0xf0;
bit8_serial_input(ch);
ch=dat<<4;
bit8_serial_input(ch);
RD7=0;//P_RS_0();
}
/*---------------------------------------------------------*/
void write_abyte(unsigned char dat)
{
unsigned char ch;
RD7=1;//P_RS_1();//PORTD|=0x80;
ch=0xfa;
bit8_serial_input(ch);
ch=dat&0xf0;
bit8_serial_input(ch);
ch=dat<<4;
bit8_serial_input(ch);
RD7=0;//P_RS_0();//PORTD&=0x7f;
}
//*显示字母数字在x,y处*/
void dis_str(uchar x, uchar y, uchar *str,uchar number)
{
uchar loc,*p;
uchar xline[5]={0,1,3,2,4};
p=str;
x=xline[x];
instruct(home);
loc=(16*(x-1)+y-1);
if(loc&0x01){
loc/=2;
instruct(loc|0x80);
write_abyte(' ');
}else{
loc/=2;
instruct(loc|0x80);
}
while(number--){
write_abyte(*p++);
}
}
/*---------------------------------------------------------*/
void initial_screen(void)
{
unsigned char i,j;
PORTD&=0x7f; //P_RS=0;
PORTD&=0xdf;//P_E=0;
instruct(dis_on);
for(i=0;i<44;i++){;}
instruct(clear);
for(j=0;j<14;j++){
for(i=0;i<250;i++){}
}
instruct(in_mode);
for(i=0;i<44;i++){;}
instruct(home);
for(i=0;i<44;i++){;}
}
/*---------------------------------------------------------*/
void itoa(int x)
{
unsigned int n;
unsigned char chn,*p,*p2,str1[6];
unsigned char i,j;
p2=str;
if(x<0){
*p2++='-';
x=-x;
}
n=x;
p=str1;
j=0;
while(n!=0){
chn=n%10;
n=n/10;
*p++=chn+'0';
j++;
}
if(j!=0){
p--;
for(i=0;i<j;i++)*p2++=*p--;
}
else *p2++='0';
*p2=0;
return;
}
/* ****************************************************************
** 函 数 名: initial()
** 功能描述: 系统初始化子程序,放在程序首部
*************************************************************** */
void initial()
{
INTCON=0x00; //* bit7-bit0:关总中断 */
ADCON1=0X07; //* 设置数字输入输出口 */
PIE1=0; //* PIE1 的中断不使能 */
PIE2=0; //* PIE2 的中断不使能 */
PIE3=0; //* PIE3 的中断不使能 */
PORTD=0x1f;
TRISD=0x1f;
}
/* **************************************************************
** 函 数 名: I2C_Initial()
** 功 能:i2c初始化子程序,I2C用于向MAX518输出DA
****************************************************************** */
void I2C_Initial()
{ //GIE=1;
SSPCON1=0X08; //允许串行口工作,I2C主控工作方式
TRISC=TRISC|0X08;
TRISC=TRISC|0X10; //定义SCL,SDA
//SSPADD=79; //定义波特率,用40MHz时,时钟=40M/(4×(79+1))=0.125M
//SSPADD=39; //定义波特率,用40MHz时,时钟=40M/(4×(79+1))=0.100M
SSPADD=31; //定义波特率,用16MHz时,时钟=16M/(4×(31+1))=0.125M
//SSPADD=23; //定义波特率,用12MHz时,时钟=12M/(4×(23+1))=0.125M
//SSPADD=7; //定义波特率,用 4MHz时,时钟=4M /(4×( 7+1))=0.125M
SSPSTAT=0X80; //I2C模式下,关闭标准速度方式(100K和1MK)的回转率控制
SSPCON2=0; //初始化SSPCON2(该寄存器仅用于I2C方式)
//di();
SSPIF=0;
SSPEN=1; //使能串行口(SSP模块)
}
/***************************************************************/
void WrtAckTest(void) //检测应答信号
{
//SSPIF=0; //清标志
do {;}while(SSPIF==0); // 等待应答信号
SSPIF=0; //清标志
}
/***************************************************************/
void I2C_IDLE(void) //空闲检测
{
do {;}while((SSPSTAT&0X04)==1); // 检测读写标志位是否为零,为零继续
do {;}while((SSPCON2&0X1F)==1); // 等待应答信号检测五个状态位是否为零
}
/***************************************************************/
void Initial_8583(uchar address,uchar *str,uchar n)
{
char i;
I2C_IDLE();
SEN=1;
WrtAckTest(); // 等待应答信号
SSPBUF=0xA2;
WrtAckTest();
SSPBUF=address;
WrtAckTest();
//*
for(i=0;i<n;i++) //清标志
{
do {;}while(BF==1); // 等待应答信号
SSPIF=0; //清标志
SSPBUF=str[i];
WrtAckTest();
}
//*/
SSPIF=0; //清标志
PEN=1;
WrtAckTest();
SSPCON2=0X00;
}
/***************************************************************/
void Read_8583(uchar address,uchar *str,uchar n)
{
char i;
I2C_IDLE();
SEN=1;
WrtAckTest();
SSPBUF=0xA2;
WrtAckTest();
SSPBUF=address;
WrtAckTest();
I2C_IDLE();
SSPIF=0; //清标志
RSEN=1;
WrtAckTest();
SSPBUF=0xA3;
WrtAckTest();
ACKDT=0;
RCEN=1;
WrtAckTest();
str[0]=SSPBUF;
for(i=1;i<n;i++)
{
ACKEN=1;
WrtAckTest();
RCEN=1;
WrtAckTest();
str[i]=SSPBUF;
}
ACKDT=1;
ACKEN=1;
WrtAckTest();
SSPIF=0; //清标志
PEN=1;
WrtAckTest();
}
/* **************************************************************
** 函 数 名: main()
** 功 能:主函数
****************************************************************** */
main()
{
int second,minute,hour;
char aa[9]={0x00,0x00,0x04,0x03,0x02,0x11,0x11,0x11};
//uchar dd0[]="12345678910";uchar dd[]="东北农业大学";
uchar timer[12];
timer[0]=timer[1]=timer[3]=timer[4]=timer[6]=timer[7]=48;
timer[2]=timer[5]=':';
timer[8]='.';
initial(); //* 系统初始化子程序 */
initial_screen();
dis_str(1,1,dd,12);
I2C_Initial(); //* i2c初始化子程序 */
Initial_8583(0,aa,1);//注意器件地址是0xA2 所以写的时候为0xA2读的时候为0xA3
Initial_8583(0,aa,5);
while(1)
{
delay_us(5000);//delay_us(50000);
//Initial_8583(0,aa,1);
Read_8583(0x01,bb,6);//注意器件地址是0xA2 所以写的时候为0xA2读的时候为0xA3
hour=(bb[3]>>4)*10+(bb[3]&0x0f);
minute=(bb[2]>>4)*10+(bb[2]&0x0f);
second=(bb[1]>>4)*10+(bb[1]&0x0f);
delay_us(5000);delay_us(50000);
timer[0]=(bb[3]>>4)+48;
timer[1]=(bb[3]&0x0f)+48;
timer[3]=(bb[2]>>4)+48;
timer[4]=(bb[2]&0x0f)+48;
timer[6]=(bb[1]>>4)+48;
timer[7]=(bb[1]&0x0f)+48;
timer[9]=(bb[0]>>4)+48;
timer[10]=(bb[0]&0x0f)+48;
dis_str(2,3,timer,11);
itoa(numbb);
dis_str(4,3,str,5);
delay_us(5000);delay_us(50000);
numbb++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -