|
本帖最后由 269837846 于 2014-5-9 11:25 编辑
好心人帮忙程序如下:
/*******************************************************************************
* 文件名 : main.c
* 作者 : Losingamong
* 生成日期 : 14/09/2010
* 描述 : 主程序
*******************************************************************************/
/* 头文件 ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "stdio.h"
/* 自定义同义关键字 -------------------------------------------------------*/
/* 自定义参数宏 -------------------------------------------------------*/
void delay(unsigned int t)
{//延时函数
while(t){t--;}; //延时循环计数
}
void delay_IIC(void)
{u8 i=80; //这里可以优化速度 ,经测试最低到5还能写入
while(i)
{
i--;
}
}
#define PB7_OUT() {GPIOB->CRL&=0x0fffffff;GPIOB->CRL|=0x30000000; }
#define PB7_IN() {GPIOB->CRL&=0x0fffffff;GPIOB->CRL|=0x80000000; }
#define SDA1() {GPIO_SetBits(GPIOB, GPIO_Pin_7);}
#define SDA0() {GPIO_ResetBits(GPIOB, GPIO_Pin_7);}
#define SCL1() {GPIO_SetBits(GPIOB, GPIO_Pin_6);}
#define SCL0() {GPIO_ResetBits(GPIOB, GPIO_Pin_6);}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
SDA1();//释放IIC总线的数据线。
SCL0();//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
SDA1();//拉高数据线
SCL1();//拉高时钟线
delay_IIC();
SDA0();//在时钟线为高电平时,拉低数据线,产生起始信号。
delay_IIC();
SCL0();//拉低时钟线
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
SDA0();//拉低数据线
delay_IIC();
SCL1();//拉高时钟线。
delay_IIC();
SDA1();//时钟时线为高电平时,拉高数据线,产生停止信号。
delay_IIC();
}
//-------------------------------------------------------------------
u8 IIC_Tack(void)
{//接收应答信号函数
u8 ack;//定义一个位变量,来暂存应答状态。
SDA1();//释放数据总线,准备接收应答信号。
delay_IIC();
SCL1();//拉高时钟线。
delay_IIC();
PB7_IN();
ack= GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_7);//读取应答信号的状态。
PB7_OUT();
delay_IIC();
SCL0();//拉低时钟线。
delay_IIC();
return ack;//返回应答信号的状态,0表示应答,1表示非应答。
}
//-------------------------------------------------------------------
void IIC_write_byte(u8 Data)
{//向IIC总线写入一个字节的数据函数
u8 i;
for(i=0;i<8;i++)//有8位数据
{
if(Data&0x80)//写最高位的数据
{SDA1();}
else
{SDA0();}
delay_IIC();
SCL1(); //拉高时钟线,将数写入到设备中。
delay_IIC();
delay_IIC();
SCL0();//拉低时钟线,允许改变数据线的状态
delay_IIC();
delay_IIC();
Data=Data<<1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
}
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
u8 i;
u8 Data; //定义一个缓冲寄存器。
PB7_IN();
for(i=0;i<8;i++)//有8位数据
{
SCL1();//拉高时钟线,为读取下一位数据做准备。
delay_IIC();
Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
delay_IIC();
if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_7))//如果数据线为高平电平。
Data=Data|0x1;//则给缓冲字节的最低位写1。
SCL0();//拉低时钟线,为读取下一位数据做准备。
delay_IIC();
}
PB7_OUT();
return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(u8 Daddr,u8 Waddr,u8 Data)
{//向任意地址写入一个字节数据函数
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
IIC_Tack();//等待设备的应答
IIC_write_byte(Waddr);//写入要操作的单元地址。
IIC_Tack();//等待设备的应答。
IIC_write_byte(Data);//写入数据。
IIC_Tack();//等待设备的应答。
IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
u8 IIC_single_byte_read(u8 Daddr,u8 Waddr)
{//从任意地址读取一个字节数据函数
unsigned char Data;//定义一个缓冲寄存器。
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
IIC_Tack();//等待设备的应答
IIC_write_byte(Waddr);//写入要操作的单元地址。
IIC_Tack();//等待设备的应答。
IIC_start();//产生起始信号
IIC_write_byte(Daddr+1);//写入设备地址(读)。
IIC_Tack();//等待设备的应答。
Data=IIC_read_byte();//写入数据。
IIC_stop();//产生停止符号。
//-------------------返回读取的数据--------------------
return Data;//返回读取的一个字节数据。
}
/* 自定义函数宏 -------------------------------------------------------*/
/* 自定义变量 -------------------------------------------------------*/
/* 用户函数声明 ---------------------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
int main(void)
{
/* 设置系统时钟 */
RCC_Configuration();
/* 设置GPIO端口 */
GPIO_Configuration();
/* 设置USART */
USART_Configuration();
while(1)
{
u8 iic_data=0x00;
printf("\r\n The I2C is ready!!!\n");
IIC_single_byte_write(0xA0,0x01,0x66);
printf("\r\n The I2C write!!!\n");
iic_data=IIC_single_byte_read(0xA0,0x01);
printf("\r\n The I2C1 has read data 0x%x\r\n", iic_data);
iic_data=IIC_single_byte_read(0xA0,0x02);
printf("\r\n The I2C1 has read data 0x%x\r\n", iic_data);
}
}
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);
}
/* 开启 I2C1、I2C2 设备时钟 */
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);
/* 开启 GPIOA、GPIOB和 USART 设备时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
}
void GPIO_Configuration(void)
{
/* 定义 GPIO 初始化结构体 GPIO_InitStructure */
GPIO_InitTypeDef GPIO_InitStructure;
/* 配置 I2C1 设备的引脚为复用开漏模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 配置 I2C2 设备的引脚为复用开漏模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure); */
/* 配置 USART 设备引脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
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_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void USART_Configuration(void)
{
/* 定义USART初始化结构体 USART_InitStructure */
USART_InitTypeDef USART_InitStructure;
/* 定义USART初始化结构体 USART_ClockInitStructure */
USART_ClockInitTypeDef USART_ClockInitStructure;
/*
* 波特率为115200bps;
* 8位数据长度;
* 1个停止位,无校验;
* 禁用硬件流控制;
* 禁止USART时钟;
* 时钟极性低;
* 在第2个边沿捕获数据
* 最后一位数据的时钟脉冲不从 SCLK 输出;
*/
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
USART_ClockInit(USART1 , &USART_ClockInitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1 , &USART_InitStructure);
/* 使能USART1 */
USART_Cmd(USART1 , ENABLE);
}
#pragma import(__use_no_semihosting)
_sys_exit(int x)
{
x = x;
}
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (u8) ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|