|
本帖最后由 DebugLab 于 2024-8-19 12:39 编辑
/* 8H8K64U*的i2c.c代码/
#include "iic.h"
bit isda; //设备地址标志
bit isma; //存储地址标志
char rx_data;
unsigned char addr;
unsigned char pdata buffer[256];
void Delay500ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void I2C_Isr() interrupt 24
{
_push_(P_SW2);
P_SW2 |= 0x80;
if (I2CSLST & 0x40)
{
I2CSLST &= ~0x40; //处理START事件
}
else if (I2CSLST & 0x20)
{
I2CSLST &= ~0x20; //处理RECV事件
if (isda)
{
isda = 0; //处理RECV事件(RECV DEVICE ADDR)
}
else if (isma)
{
isma = 0; //处理RECV事件(RECV MEMORY ADDR)
addr = I2CRXD;
I2CTXD = buffer[addr];
}
else
{
buffer[++addr]= I2CRXD; //处理RECV事件(RECV DATA)
rx_data=buffer[addr];
if(buffer[addr]==0x0e)
{
P62=~P62;
P63=~P63;
Delay500ms();
}
}
}
else if (I2CSLST & 0x10)
{
I2CSLST &= ~0x10; //处理SEND事件
if (I2CSLST & 0x02)
{
I2CTXD = 0xff; //接收到NAK则停止读取数据
}
else
{
I2CTXD = buffer[++addr]; //接收到ACK则继续读取数据
}
}
else if (I2CSLST & 0x08)
{
I2CSLST &= ~0x08; //处理STOP事件
isda = 1;
isma = 1;
}
_pop_(P_SW2);
}
void iic_init(void)
{
P1M0 = 0x00;
P1M1 = 0x00;
P_SW2 = 0x80;
I2CCFG = 0x81; //使能I2C从机模式
I2CSLADR = 0x5a; //设置从机设备地址寄存器I2CSLADR=0101_1010B
//即I2CSLADR[7:1]=010_1101B,MA=0B。
//由于MA为0,主机发送的的设备地址必须与
//I2CSLADR[7:1]相同才能访问此I2C从机设备。
//主机若需要写数据则要发送5AH(0101_1010B)
//主机若需要读数据则要发送5BH(0101_1011B)
I2CSLST = 0x00;
I2CSLCR = 0x78; //使能从机模式中断
EA = 1;
isda = 1; //用户变量初始化
isma = 1;
addr = 0;
I2CTXD = buffer[addr];
}
/* STC8H8K64U main.c*/
void main()
{
Led_init();
iic_init();
while(1);
}
/*基于STM32的主机代码*/
/*STM32 main.c*/
#include <stdio.h>
#include <string.h>
#include "stm32f4xx.h"
#include "MySysTick.h"
#include "myiic.h"
#include "uart.h"
int main(void)
{
SCL();
USART1_Config(115200);
while(1)
{
STC8H_Write(0x0e);
MySysTick_s(1);
STC8H_Read();
MySysTick_s(1);
}
}
/*STM32 iic.c*/
void SDA(GPIOMode_TypeDef mode)
{
//定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
/*配置灯的引脚*/
/* GPIOG Peripheral clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Configure PG6 and PG8 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = mode; //输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //输出模式的具体方式:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SCL(void)
{
//定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
/*配置灯的引脚*/
/* GPIOG Peripheral clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Configure PG6 and PG8 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //输出模式的具体方式:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void IIC_start()
{
SDA(OUT);
SCL_Send(1);
SDA_Send(1);
MySysTick_us(5);
SDA_Send(0);
MySysTick_us(10);
SCL_Send(0);
}
void IIC_end()
{
SDA(OUT);
SDA_Send(0);
SCL_Send(0);
MySysTick_us(5);
SCL_Send(1);
MySysTick_us(5);
SDA_Send(1);
}
void IIC_send(char data)
{
int i=0;
SDA(OUT);
for(;i<8;i++)
{
SCL_Send(0);
MySysTick_us(5);
SDA_Send(data>>(7-i) & 0x01);
MySysTick_us(5);
//printf("data fragment:%d\r\n",data>>(7-i) & 0x01);
SCL_Send(1);
MySysTick_us(5);
}
SCL_Send(0);
}
char IIC_Receive()
{
int i=0;
char data=0;
SDA(IN);
for(;i<8;i++)
{
SCL_Send(0);
MySysTick_us(5);
SCL_Send(1);
MySysTick_us(5);
if(SDA_Polar)
{
data |= (0x01<<(7-i));
}
MySysTick_ms(500);
}
return data;
}
void IIC_SACK(char ack)
{
SDA(OUT);
SCL_Send(0);
MySysTick_us(2);
SDA_Send(ack);
MySysTick_us(5);
SCL_Send(1);
MySysTick_us(5);
SCL_Send(0);
}
char IIC_RACK()
{
char ack=0;
SDA(IN);
SCL_Send(0);
MySysTick_us(5);
SCL_Send(1);
MySysTick_us(5);
if(SDA_Polar)
{
ack=1;
}
MySysTick_us(5);
return ack;
}
void STC8H_Write(char data)
{
IIC_start();
IIC_send(0x5a);
if(IIC_RACK()==1)
{
printf("写:发送设备地址写命令失败\r\n");
IIC_end();
return ;
}
MySysTick_us(5);
IIC_send(0x00);
if(IIC_RACK()==1)
{
printf("写:发送存储地址失败\r\n");
IIC_end();
return ;
}
MySysTick_us(5);
IIC_send(data);
MySysTick_us(5);
if(IIC_RACK()==1)
{
printf("发送数据失败\r\n");
IIC_end();
return ;
}
else
{
printf("发送数据成功\r\n");
}
IIC_end();
}
void STC8H_Read()
{
char data=0;
IIC_start();
IIC_send(0x5a);
if(IIC_RACK()==1)
{
printf("读:发送设备地址写命令失败\r\n");
IIC_end();
return ;
}
IIC_send(0x00);
if(IIC_RACK()==1)
{
printf("读:发送存储地址高字节地址失败\r\n");
IIC_end();
return ;
}
IIC_start();
IIC_send(0x5b);
if(IIC_RACK()==1)
{
printf("读:发送设备地址读命令失败\r\n");
IIC_end();
return ;
}
data=IIC_Receive();
IIC_SACK(1);
IIC_end();
printf("读取成功,data:%c\r\n",data);
}
//发送的数据是0x0e,但接收到的数据是?,我的代码有什么问题啊,感觉问题主要是在STC8H的发送代码,求大神们指正
|
|