请教各位大大:由于近期要用STM32做一个项目用到I2C协议,调用固件库I2C协议编程,最后发现是I2C部分程序问题,单独测试I2C读写24C02失败.好几天了没有查出原因,请教各位是怎么回事?谢谢了!!!
下面是我写的代码:
/*-------------------------------------------------------------------------------
1 STM32F103C8T6 i2c1(at24c02) TEST HSE8M*9M=72m;
2 display:max7219模块;
------------------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#define uchar unsigned char
#define uint unsigned int
uchar leddula[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,
0x77,0x1f,0x4e,0x3d,0x4f,0x47,0x67,0x3e};//0123456789ABCDEFPU
uchar cf=0x20;
void sysinit(void);
void clock(void);
void sgpio(void);
void sysspi(void);
void init7219(void);
void i2cinit(void);
void delay(vu32 nCount);
void ackst(void);//ACK
void i2cwritebyte(uchar addr,uchar date);
uchar i2creadbyte(uchar addr);
void display(void);
void maxdisp(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h);
void clear7219(void);
void sendbyte(uchar datt);
void sendword(uchar addr,uchar dat);
int main(void)
{
sysinit();
while(1)
{
display();
}
}
void sysinit(void)
{
clock();
sgpio();
sysspi();
i2cinit();
}
void clock(void)
{
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET);
RCC_PLLCmd(ENABLE);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);//8m*9m=72m
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
RCC_HSICmd(DISABLE);
}
void sgpio(void)//GPIO
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_Initstructure;
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;//5 clk,6 mosi
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstructure);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_6;//6 miso
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;;
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstructure);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_4;//4 cs
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstructure);
GPIO_SetBits(GPIOA, GPIO_Pin_4);//cs=1
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//I2C1 6SCL 7SDA
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_Initstructure);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_Initstructure);
}
void i2cinit(void)//I2C
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed=50000;//50khz
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1=0xcd;
I2C_InitStructure.I2C_Ack=I2C_Ack_Disable;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_6|GPIO_Pin_7);
I2C_Cmd(I2C1, ENABLE);
i2cwritebyte(0x40,0x20);
}
void sysspi(void)//SPI
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode=SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial=7;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_Cmd(SPI1,ENABLE);
init7219();
}
void ackst(void)//ACK
{
if(I2C_GetFlagStatus(I2C1,I2C_FLAG_AF)==RESET)
{
I2C_ClearFlag(I2C1,I2C_FLAG_AF);
I2C_GenerateSTOP(I2C1,ENABLE);
}
}
void i2cwritebyte(uchar addr,uchar date)
{
I2C_GenerateSTART(I2C1,ENABLE);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==RESET);//START OK
I2C_ClearFlag(I2C1,I2C_FLAG_SB);
I2C_Send7bitAddress(I2C1,0xa0,I2C_Direction_Transmitter);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR)==RESET);//addr OK
I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
ackst();
I2C_SendData(I2C1, addr);
ackst();
I2C_SendData(I2C1, addr);
ackst();
I2C_GenerateSTOP(I2C1,ENABLE);
I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
}
uchar i2creadbyte(uchar addr)
{
uchar data;
I2C_GenerateSTART(I2C1,ENABLE);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==RESET);//START OK
I2C_ClearFlag(I2C1,I2C_FLAG_SB);
I2C_Send7bitAddress(I2C1,0xa0,I2C_Direction_Transmitter);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR)==RESET);//addr OK
I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
ackst();
I2C_SendData(I2C1, addr);
ackst();
I2C_GenerateSTART(I2C1,ENABLE);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==RESET);//R START OK
I2C_ClearFlag(I2C1,I2C_FLAG_SB);
I2C_Send7bitAddress(I2C1,0xa1,I2C_Direction_Receiver);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR)==RESET);//addr CMD OK
I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BTF)==RESET);//等待数据接收完成
delay(20);
data=I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1,ENABLE);
I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
return data;
}
void display(void)//显示
{
uchar second,t0,t1,t4,t5;
second=i2creadbyte(0x40);
t0=second/10;
t1=second%10;
t4=cf/10;
t5=cf%10;
maxdisp(leddula[t1],leddula[t0],0x01,0x01,0x01,0x01,leddula[t5],leddula[t4]);
}
void init7219(void)//显示初始化
{
sendword(0x0c,0x01);
sendword(0x0a,0x01);
sendword(0x0b,0x07);
sendword(0x09,0x00);
sendword(0x0f,0x00);
}
void delay(vu32 nCount)//廷时
{
while(nCount--);
}
void sendbyte(uchar datt)
{
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI1,datt);
delay(20);
}
void sendword(uchar addr,uchar dat)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
sendbyte(addr);
sendbyte(dat);
GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
void clear7219(void)
{
uchar i;
for(i=1;i<9;i++)
{
sendword(i,0x00);
}
}
void maxdisp(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h)
{
clear7219();
sendword(0x01,a);
sendword(0x02,b);
sendword(0x03,c);
sendword(0x04,d);
sendword(0x05,e);
sendword(0x06,f);
sendword(0x07,g);
sendword(0x08,h);
} |