发新帖我要提问
12
返回列表
打印
[STM32F1]

STM32基础篇 LCD—— IIC 实验

[复制链接]
楼主: aizaixiyuanqian
手机看帖
扫描二维码
随时随地手机跟帖
21
aizaixiyuanqian|  楼主 | 2018-2-12 19:28 | 只看该作者 回帖奖励 |倒序浏览
高四位 1010 是 24Cxx 系列的固定器件地址,接下来是 A2、A1、A0 是根据器件连接来
决定,也就是我们原理图上面的 E2、E1、E0。我们的原理图都接地所以是 000。R/W 为
是选择读还是写,1 的时候是读,0 的时候是写。所以写的地址为 0xA0,读地址为 0xA1。

使用特权

评论回复
22
aizaixiyuanqian|  楼主 | 2018-2-12 19:29 | 只看该作者
STM32  的硬件 I2C  简介
STM32 的硬件 I2C 做得很复杂,而且不好用。所以大部分人都不太选择使用 STM32 的硬
件 I2C,很难调试。不过 AT24C02 有 ARM 官方的提供的例程,读写还是挺稳定的,我
们的例程使用的也是参考 ARM 官方的例程来的。接下来我们看看一下通过库函数使用硬
件 I2C 来操作 AT24C02。

使用特权

评论回复
23
aizaixiyuanqian|  楼主 | 2018-2-12 19:30 | 只看该作者
首先我们要打开时钟使能
要打开 GPIOB 的时钟使能。代码如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

使用特权

评论回复
24
aizaixiyuanqian|  楼主 | 2018-2-12 19:30 | 只看该作者
  配置 IO  的模式
GPIO_InitStructure.GPIO_Pin=I2C_SCL|I2C_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
管脚的端口定义如下:
//如果移植程序时只要改一下三个地方就行了
/* 定时使用的 IO 口 */
#define I2C_SCL GPIO_Pin_10 //PB10
#define I2C_SDA GPIO_Pin_11 //PB11
#define GPIO_I2C GPIOB

使用特权

评论回复
25
aizaixiyuanqian|  楼主 | 2018-2-12 19:30 | 只看该作者
AT24C02  写 操作
首先我们来看一下写 AT24C02。
一般步骤是:
1) 发送起始信号
2) 发送写器件地址
3) 等待应答
4) 发送要写入的 24C02 的地址
5) 等待应答
6) 发送要写入的数据
7) 等待应答
8) 发送数据结束发送结束信号

使用特权

评论回复
26
aizaixiyuanqian|  楼主 | 2018-2-12 19:31 | 只看该作者
具体程序如下:
void AT24Cxx_WriteOneByte(u16 addr,u8 dt)
{
I2C_Start();
if(EE_TYPE>AT24C16)
{
I2C_Send_Byte(0xA0);
I2C_Wait_Ack();
I2C_Send_Byte(addr>>8); //发送数据地址高位
}
else
{
I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址
}
I2C_Wait_Ack();
I2C_Send_Byte(addr%256);//双字节是数据地址低位
//单字节是数据地址低位
I2C_Wait_Ack();
I2C_Send_Byte(dt);
I2C_Wait_Ack();
I2C_Stop();
delay_ms(10);
}

使用特权

评论回复
27
aizaixiyuanqian|  楼主 | 2018-2-12 19:37 | 只看该作者
读取 AT24C02 的步骤是:
1) 发送起始信号
2) 发送写器件地址
3) 等待应答
4) 发送要读取的 AT24C02 的地址
5) 等待应答
6) 再发送其实信号
7) 发送读器件地址
8) 等待应答
9) 接收数据
10) 如果没有接收完数据,发送应答
11) 接收数据
12) 直到接收完数据,发送非应答
13) 发送结束信号

使用特权

评论回复
28
aizaixiyuanqian|  楼主 | 2018-2-12 19:37 | 只看该作者
u8 AT24Cxx_ReadOneByte(u16 addr)
{
u8 temp=0;
I2C_Start();
if(EE_TYPE>AT24C16)
{
I2C_Send_Byte(0xA0);
I2C_Wait_Ack();
I2C_Send_Byte(addr>>8);  //发送数据地址高位
}
else
{
I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址
}
I2C_Wait_Ack();
I2C_Send_Byte(addr%256);//双字节是数据地址低位
//单字节是数据地址低位
I2C_Wait_Ack();
I2C_Start();
I2C_Send_Byte(0xA1);
I2C_Wait_Ack();
temp=I2C_Read_Byte(0); // 0 代表 NACK
I2C_NAck();
I2C_Stop();
return temp;
}

使用特权

评论回复
29
aizaixiyuanqian|  楼主 | 2018-2-12 19:38 | 只看该作者
主函数
int main()
{
u8 wdata=0,value;
u8 i,j,dat[6],dat1[6];
I2C_INIT();
TFT_Init(); //TFT 彩屏初始化
LED_Init(); //端口初始化
key_init(); //按键初始化
printf_init(); //printf 初始化
TFT_ClearScreen(BLACK); //清屏
GUI_Show12ASCII(10,10,"This is a IIC-AT24C02 Check!",YELLOW,BLACK);
GUI_Show12ASCII(10,27,"PB10 PB11 is IIC Interface!",YELLOW,BLACK);
GUI_Show12ASCII(10,44,"The K_UP is:AT24C02 Write",YELLOW,BLACK);
GUI_Show12ASCII(10,61,"The K_DOWM is:AT24C02 Read",YELLOW,BLACK);
GUI_Show12ASCII(10,100,"Write data Range is: 0-255",YELLOW,BLACK);
GUI_Show12ASCII(10,150,"Write data is:",YELLOW,BLACK);
GUI_Show12ASCII(10,167,"Read data is:",YELLOW,BLACK);
while(1)
{
if(k_up==1) //按键 k_up 按下写入数据
{
delay_ms(10);
if(k_up==1)
{
AT24Cxx_WriteOneByte(0,++wdata);//写入的是单字节,0-255 取值范围
dat[0]=wdata/100+0x30;
dat[1]=wdata%100/10+0x30;
dat[2]=wdata%100%10+0x30;
dat[3]='\0';
GUI_Show12ASCII(160,150,dat,YELLOW,BLACK);
}
// while(k_up);
}
if(k_down==0)  //读取数据
{
delay_ms(10);
if(k_down==0)
{
value=AT24Cxx_ReadOneByte(0);
dat1[0]=value/100+0x30;
dat1[1]=value%100/10+0x30;
dat1[2]=value%100%10+0x30;
dat1[3]='\0';
GUI_Show12ASCII(160,167,dat1,YELLOW,BLACK);
}
while(!k_down);
}
if(j>1)
{
j=0;
GPIO_SetBits(GPIOC,GPIO_Pin_0);
}
else
{
j++;
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
}
delay_ms(200);
}
}

使用特权

评论回复
30
aizaixiyuanqian|  楼主 | 2018-2-12 19:38 | 只看该作者
该函数实现按键  按下写入数据加 1 写入到 24C02 中,当按键 K_DOWN 按下后进行 24C02
的数据读取,LED 闪烁表示系统正在运行。

使用特权

评论回复
31
aizaixiyuanqian|  楼主 | 2018-2-12 19:39 | 只看该作者
这次的实验只是在iic的基础上增加了TFT

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则