搜索
bottom↓
回复: 0
打印 上一主题 下一主题

《ATK-DFPGL22G之FPGA开发指南_V1.0》第四十章 IIC实验

[复制链接]

出0入234汤圆

跳转到指定楼层
1
发表于 2023-8-2 14:25:55 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1)实验平台:正点原子 DFZU2EG_4EV MPSoC开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340252-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:994244016




第四十章 IIC实验


本章将介绍使用APM32E103驱动板载的EEPROM进行读写操作。通过本章的学习,读者将学习到使用GPIO模拟IIC时序以及EEPROM的驱动。
本章分为如下几个小节:
40.1 硬件设计
40.2 程序设计
40.3 下载验证


40.1 硬件设计
40.1.1 例程功能

1. 按下KEY_UP和KEY0按键,分别对24C02进行数据的写入和读取操作,读取到的数据会显示至LCD
2. 可通过USMART对24C02进行读写一字节数据的操作
3. LED0闪烁,指示程序正在运行
40.1.2 硬件资源
1. LED
        LED0 - PB5
2. 按键
        KEY0 - PE4
        KEY_UP - PA0
3. USART1(PA9、PA10连接至板载USB转串口芯片上)
4. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
5. 24C02
        IIC_SCL - PB6
        IIC_SDA - PB7
40.1.3 原理图
本章实验使用了板载的24C02芯片,该芯片是一个EEPROM,MCU是通过两个GPIO与该EEPROM进行连接与通信的,该EEPROM与MCU的连接原理图,如下图所示:
图40.1.3.1 EEPROM与MCU的连接原理图

40.2 程序设计
40.2.1 Geehy标准库的GPIO驱动

本章实验通过控制与EEPROM连接的GPIO模拟IIC时序,实现EEPROM的读写操作,对于GPIO,主要涉及GPIO的配置和读写操作,需要一下几个步骤:
①:配置GPIO引脚为通用输出模式、开漏输出和禁止上拉/下拉
②:在与EEPROM通信时,根据需求控制指定GPIO引脚输出指定电平
③:在与EEPROM通信时,根据需求读取指定GPIO引脚上的输入电平
在Geehy标准库中对应的驱动函数如下:
①:配置GPIO引脚
请见第10.2.1小节中配置GPIO引脚的相关内容。
②:设置GPIO引脚输出电平
请见第10.2.1小节中设置GPIO引脚输出电平的相关内容。
③:读取GPIO引脚输入电平
请见第11.2.1小节中读取GPIO引脚输入电平的相关内容。
40.2.2 IIC驱动
本章实验使用的IIC的软件模拟的IIC,即控制GPIO模拟IIC的时序与外部器件进行通信。IIC驱动主要负责向EEPROM驱动提供IIC操作的各种函数,例如:IIC起始信号、IIC停止信号等。本章实验中,IIC的驱动代码包括myiic.c和myiic.h两个文件。
IIC驱动中,对GPIO相关的宏定义,如下所示:
/* 引脚定义 */
#define IIC_SCL_GPIO_PORT           GPIOB
#define IIC_SCL_GPIO_PIN            GPIO_PIN_6
#define IIC_SCL_GPIO_CLK_ENABLE()   do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB); }while(0)

#define IIC_SDA_GPIO_PORT           GPIOB
#define IIC_SDA_GPIO_PIN            GPIO_PIN_7
#define IIC_SDA_GPIO_CLK_ENABLE()   do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB); }while(0)

/* IO操作 */
#define IIC_SCL(x)                  do{ x ?                           \
                                        GPIO_SetBit(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN) :           \
                                        GPIO_ResetBit(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);            \
                                    }while(0)

#define IIC_SDA(x)                  do{ x ?                           \
                                        GPIO_SetBit(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) :           \
                                        GPIO_ResetBit(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);            \
                                    }while(0)

#define IIC_SDA_READ                GPIO_ReadInputBit( IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN)
IIC驱动中,IIC的初始化函数,如下所示:
/**
* @brief       初始化IIC
* @param       无
* @retval      无
*/
void iic_init(void)
{
    GPIO_Config_T gpio_init_struct;
   
    /* 使能时钟 */
    IIC_SCL_GPIO_CLK_ENABLE();                      /* 使能IIC SCL引脚端口时钟 */
    IIC_SDA_GPIO_CLK_ENABLE();                      /* 使能IIC SDA引脚端口时钟 */
   
    /* 配置IIC SCL引脚 */
    gpio_init_struct.pin = IIC_SCL_GPIO_PIN;        /* IIC SCL引脚 */
    gpio_init_struct.speed = GPIO_SPEED_50MHz;      /* 高速 */
    gpio_init_struct.mode = GPIO_MODE_OUT_OD;       /* 开漏输出 */
    GPIO_Config(IIC_SCL_GPIO_PORT, &gpio_init_struct);  
   
    /* 配置IIC SDA引脚 */
    gpio_init_struct.pin = IIC_SDA_GPIO_PIN;        /* IIC SDA引脚 */
    gpio_init_struct.speed = GPIO_SPEED_50MHz;      /* 高速 */
    gpio_init_struct.mode = GPIO_MODE_OUT_OD;       /* 开漏输出 */
    GPIO_Config(IIC_SDA_GPIO_PORT, &gpio_init_struct);  
   
    iic_stop();                                     /* 停止IIC总线上所有设备 */
}
可以看到,IIC的初始化实际上就是配置IIC时钟与数据信号对应的GPIO引脚。
IIC驱动中对IIC的各种操作,例如产生IIC起始信号、产生IIC停止信号等,请读者结合IIC的时序规定查看本实验的配套实验源码。
40.2.3 EEPROM驱动
本章实验的EEPROM驱动主要负责向应用层提供EEPROM的初始化和读写数据等操作函数。本章实验中,EEPROM的驱动代码包括24cxx.c和24cxx.h两个文件。
EEPROM驱动中,EEPROM的初始化函数,如下所示:
/**
* @brief       初始化AT24CXX
* @param       无
* @retval      无
*/
void at24cxx_init(void)
{
    iic_init();
}
可以看到,该函数实际上就是初始化了与EEPROM通讯的IIC。
EEPROM驱动中的其他对EEPROM的操作函数,例如:EEPROM的读写函数,请读者结合24C02 EEPROM芯片的数据手册查看本实验的配套实验源码。
40.2.4 实验应用代码
本章实验的应用代码,如下所示:
/* 待写入24C02的数据 */
static const uint8_t g_text_buf[] = {"APM32 IIC TEST"};

/* 待写入24C02数据的长度 */
#define TEXT_SIZE sizeof(g_text_buf)

int main(void)
{
    uint8_t t = 0;
    uint8_t key;
    uint8_t data[TEXT_SIZE];
   
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4); /* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                        /* 配置系统时钟 */
    delay_init(120);                                 /* 初始化延时功能 */
    usart_init(115200);                              /* 初始化串口 */
    usmart_dev.init(120);                            /* 初始化USMART */
    led_init();                                      /* 初始化LED */
    lcd_init();                                      /* 初始化LCD */
    key_init();                                      /* 初始化按键 */
    at24cxx_init();                                  /* 初始化AT24CXX */
   
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "IIC TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY_UP:Write  KEY0:Read", RED);
   
    while (at24cxx_check() != 0)                     /* 检测不到24C02 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "24C02 Check Failed!", RED);
        delay_ms(500);
        lcd_show_string(30, 130, 200, 16, 16, "Please Check!      ", RED);
        delay_ms(500);
        LED0_TOGGLE();
}
/* 24C02检测正常 */
    lcd_show_string(30, 130, 200, 16, 16, "24C02 Ready!       ", RED);
   
    while (1)
    {
        t++;
        key = key_scan(0);
        
        if (key == WKUP_PRES)                        /* 写入数据 */
        {
            lcd_fill(0, 150, 239, 319, WHITE);
            lcd_show_string( 30, 150, 200, 16, 16,
"Start Write 24C02....",
BLUE);
            at24cxx_write(0, (uint8_t *)g_text_buf, TEXT_SIZE);
            lcd_show_string( 30, 150, 200, 16, 16,
"24C02 Write Finished!",
BLUE);
        }
        else if (key == KEY0_PRES)                   /* 读取数据 */
        {
            lcd_show_string( 30, 150, 200, 16, 16,
"Start Read 24C02.... ",
BLUE);
            at24cxx_read(0, data, TEXT_SIZE);
            lcd_show_string(30, 150, 200, 16, 16,
"The Data Readed Is:  ",
BLUE);
            lcd_show_string(30, 170, 200, 16, 16, (char *)data, BLUE);
        }
        
        if (t == 20)
        {
            LED0_TOGGLE();
            t = 0;
        }
        
        delay_ms(10);
    }
}
从本章实验的应用代码中可以看到,在初始化完EEPROM后,会检测与EEPROM的连接是否正常,若与EEPROM的连接正常,则会不断地等待按键输入,若检测到KEY_UP按键被按下,则会往EEPROM的指定地址中写入指定的数据,若检测到KEY_0按键被按下,则会从EEPROM的指定地址中读取数据,并在LCD上进行显示。
40.3 下载验证
在完成编译和烧录操作后,若MCU与EEPROM的连接无误,则可以在LCD上看到“24C02 Ready!”的提示信息,此时可以按下KEY_UP按键往EEPROM的指定地址写入指定数据,然后再按下KEY_0按键从EEPROM的指定地址将写入的数据读回来在LCD上进行显示,此时便可以看到在LCD上显示了“APM32 IIC TEST”的提示信息,该提示信息就是从EEPROM中读回的数据。

阿莫论坛20周年了!感谢大家的支持与爱护!!

盗墓祖师爷留下的规矩:父子两人盗墓结束后,必定是父亲先出墓穴,儿子跟在后面。
如果儿子先上来,说不定想要独吞财物,可能转身一脚就将跟在后面的父亲封闭在墓穴里面。
而父亲永远不会杀死自己的儿子。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-3 01:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表