当前位置: 首页 > news >正文

上海企业网站排名优化万宁网站建设

上海企业网站排名优化,万宁网站建设,陕西网站维护,公司手机版网站制作写在前面#xff1a;在前面的学习过程中#xff0c;我们学习了串口通信的USART#xff08;通用同步异步收发器#xff09;#xff0c;本节我们将继续学习一种串行通信协议——IIC通信协议。之前我使用51单片机也分享过相关的IIC通信的知识#xff0c;其实本质的知识是相通… 写在前面在前面的学习过程中我们学习了串口通信的USART通用同步异步收发器本节我们将继续学习一种串行通信协议——IIC通信协议。之前我使用51单片机也分享过相关的IIC通信的知识其实本质的知识是相通的本节我们继续探讨STM32关于IIC的基础知识。 一、IIC总线协议介绍 1.1基础介绍 常见的通信协议有串口、SPI、IIC、CAN以及USB IIC集成电路总线是一种同步、串行、半双工通信总线 同步含有时钟线SCL串行:数据的传输是一位一位传送的半双工单方向发、单方向收 什么是总线什么又是协议呢 这其实是一种说法总线就是从硬件层面看是传输数据的通道协议是从软件层面看是传输数据的规则。总线就好比是一条道路而协议是通过这条道路的交规。 IIC总线的特点 1、总线由数据线 SDA 和时钟线 SCL 构成的串行总线数据线用来传输数据时钟线用来 同步数据收发。并且都接有上拉电阻保证总线在空闲状态为高电平。 2、总线支持多设备连接允许多主机并存每个设备都有属于自己的设备地址所以我们只需要知道器件的地址根据时序就可以实现微控制器与器件之间的通信。 3、连接到总线上的数目受总线的最大电容400pf限制寄生电容每个设备都有电容 4、数据的传输速率 标准模式100kbit/s快速模式400kbit/s高速模式3.4Mbit/s IIC协议 三个信号起始信号、停止信号与应答信号 两个注意数据的有效性数据的传输顺序 一个状态空闲状态 I2C两设备进行通信的流程为首先主机控制总线通过总线时序找到想要通信的从设备每个从设备都有固定地址被选中的从机准备发送/接收收据未被选中的从机打开上述开关断绝同总线的联系。主机与从机传递数据如果传递1直接打开开关通过上拉电阻实现总线高电平如果传递0关闭开关使总线达到低电平。主从机设备传递信息严格遵循相应的时序。 1.2 IIC协议 下图为:IIC协议的时序图 其中主要为 1、起始信号2、终止信号3、应答信号4、数据有效性5、 数据传输6、空闲状态 1、起始信号与终止信号 起始条件SCL高电平期间SDA从高电平切换到低电平 结束条件SCL高电平期间SDA从低电平切换到高电平 2、应答信号 应答条件在上拉电阻的影响下SDA默认为高电平而从机拉低SDA表示收到信号即ACK若没有收到则不用拉低NACK;发送完一个字节之后主机在下一个时钟接收一位数据判断从机是否应答数据0表示应答数据1表示非应答主机在接收之前应该释放SDA 3、数据收发 数据在低电平期间准备好高电平期间数据发送高电平期间保持有效数据先发送高8、位数据以8位1bit为一个单位进行发送。数据在SCL高电平期间保持稳定主句发送完数据释放数据线不影响从机的应答 1.3相关驱动代码 起始信号 void iic_start(void) {         IIC_SDA(1);         IIC_SCL(1);         iic_delay();         IIC_SDA(0);         iic_delay();         IIC_SCL(0);         iic_delay() } 停止信号 void iic_stop(void) {         IIC_SDA(0);         iic_delay();         IIC_SCL(1);         iic_delay();         IIC_SDA(1);         iic_delay(); } 发送应答信号 void iic_ackvoid {         IIC_SCL(0);         iic_delay();         IIC_SDA(0);         iic_delay();         IIC_SCL(1);         iic_delay(); } 发送非应答信号 void iic_nack(void) {           IIC_SCL(0);           iic_delay();           IIC_SDA(0);           iic_delay();           IIC_SCL(1);           iic_delay(); } 检测应答信号 uint8_t iic_wait_ack(void) {         IIC_SDA(1);         iic_delay();         IIC_SCL(1);         iic_delay();         if(IIC_READ_SDA)                 {                  iic_stop();                 return 1;                 }           IIC_SCL(1);             iic_delay();             reutn 0;   } 发送一个字节 void iic_send_byte(uint8_t data) {     uint8_t i;     for (i0;i8;i)     {         IIC_SDA((data0x80)7); /* 高位先发送 */         iic_delay();         IIC_SCL(1);         iic_delay();         IIC_SCL(0);         iic_delay();         data1;     }     IIC_SDA(1);      /* 发送完成释放数据线 */ } 接收一个字节 uint8_t icc_recive_byte(uint8_t ack) {       uint8_t i,recive;     for(i0;i8;i)     {         recive1;  /* 高位先输出,所以先收到的数据位要左移 */         IIC_SCL(1);         iic_delay();         if(IIC_READ_SDA)         {         recive;          }           IIC_SCL(0);         iic_delay();           }     if(ack1)     {         iic_ack();/* 发送 ACK */     }    else     {         iic_nack();/* 发送 nACK */     } return recive; } 二、AT2402介绍 2.1基础介绍 24C02 是一个 2K bit 的串行 EEPROM 存储器内部含有 256 个字节。在 24C02 里面还有 一个 8 字节的页写缓冲器。该设备的通信方式 IIC通过其 SCL 和 SDA 与其他设备通信。 存储介质E2PROM; 通讯接口I2C通信接口 容量256字节 1A0地址输入2A1地址输入3A2地址输入4VSS电源地5SDA串行地址和数据输入输出6SCL串行时钟输入7WP写保护8VCC电源正极 AT24C02 器件地址为 7 位高 4 位固定为 1010低 3 位由 A0/A1/A2 信号线的电平决定。 因为传输地址或数据是以字节为单位传送的当传送地址时 器件地址占 7 位还有最后一位最低位 R/W用来选择读写方向它与地址 无关。其格式如下 1010A2A1A0R/W 2.2 AT24C02读写时序 写操作起始信号——地址和方向设备地址写——应答——内存地址——数据内容——应答——停止 读操作起始信号——地址和方向设备地址写——应答——内存地址——应答——起始信号——地址和方向设备地址读——应答——数据——应答······——停止 2.3 AT24C02驱动与步骤 IIC配置 1、使能SCL和SDA引脚的时钟 2、GPIO配置模式SDA:复用开漏SCL:复用推挽 3、编写基本信息起始停止应答接收应答 4、编写读写函数 AT24C02驱动步骤 1、初始化IIC接口 2、编写写入/读取一个字节数据函数 3、编写连续读写函数 三、程序设计  每按下 KEY1MCU 通过 IIC 总线向 24C02 写入数据通过按下 KEY0 来控制 24C02 读 取数据。同时在 LCD 上面显示相关信息。LED0 闪烁用于提示程序正在运行。 源码文件 链接https://pan.baidu.com/s/1JtCEJ4oTfy6Da-Rffr93qg  提取码1022 myiic.c #include ./BSP/IIC/myiic.h #include ./SYSTEM/delay/delay.h/*** brief 初始化IIC* param 无* retval 无*/ void iic_init()// {__HAL_RCC_GPIOB_CLK_ENABLE();/* 使能 IIC 的 SCL 和 SDA 对应的 GPIO 时钟 */GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.ModeGPIO_MODE_OUTPUT_PP;gpio_init_struct.PinGPIO_PIN_6;gpio_init_struct.SpeedGPIO_SPEED_FREQ_LOW;gpio_init_struct.PullGPIO_PULLUP; HAL_GPIO_Init(GPIOB, gpio_init_struct);/* 设置对应 GPIO 工作模式SCL 推挽输出 SDA 开漏输出 */gpio_init_struct.ModeGPIO_MODE_OUTPUT_OD;gpio_init_struct.PinGPIO_PIN_7;gpio_init_struct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, gpio_init_struct);}/*** brief IIC延时函数用于IIC读写的速度IIC在进行数据传递时时钟信号为高电平期间数据线必须保持稳定延时的作用就是保持在高电平期间的数据稳定。* param 无* retval 无*/ static void iic_delay(void) {delay_us(2);/* 2us 的延时, 读写速度在 250Khz 以内 */ }/*** brief IIC起始信号* param 无* retval 无*/ void icc_start() {IIC_SCL(1);IIC_SDA(1);iic_delay();IIC_SDA(0);/* 在时钟为高电平期间数据线由高电平变为低电平表示起始信号 */iic_delay();IIC_SCL(0); /* 钳住I2C总线并没有把数据线释放准备发送或接收数据因为紧接着还是主机进行操作 */iic_delay(); }/*** brief IIC停止信号* param 无* retval 无*/ void icc_stop() { IIC_SDA(0);iic_delay();IIC_SCL(1);iic_delay();IIC_SDA(1);/* 在时钟为高电平期间数据线由低电平变高低电平表示停止信号 */iic_delay(); }/*** brief IIC发送一个字节* param data: 要发送的数据* retval 无*/ void iic_send_byte(uint8_t data) {uint8_t i;for (i0;i8;i){IIC_SDA((data0x80)7); /* 高位先发送 */iic_delay();IIC_SCL(1);iic_delay();IIC_SCL(0);iic_delay();data1;}IIC_SDA(1); /* 发送完成释放数据线 */ }/*** brief IIC读取一个字节* param ack: ck1时发送ack; ack0时发送nack* retval 接收到的数据*/ uint8_t icc_recive_byte(uint8_t ack) {uint8_t i,recive;for(i0;i8;i){recive1; /* 高位先输出,所以先收到的数据位要左移 */IIC_SCL(1);iic_delay();if(IIC_READ_SDA){recive; } IIC_SCL(0);iic_delay(); }if(ack1){iic_ack();/* 发送 ACK */}else{iic_nack();/* 发送 nACK */}return recive;} /*** brief 等待应答信号* param 无* retval 返回0接收应答成功返回1接收应答失败*/ uint8_t icc_wait_ack(void) {uint8_t wattime0;uint8_t rack0;IIC_SDA(1); /* 主机释放数据线由对应的从机进行拉低 */ iic_delay();IIC_SCL(1); /* 高电平期间从机发送应答信号 */iic_delay();while(IIC_READ_SDA) /* 主等待应答 */{wattime;if(wattime250){icc_stop();rack1; /* 超时应答失败 */break; }}IIC_SCL(0); /*时钟结束应答成功 */iic_delay();return rack; }/*** brief 产生应答信号* param 无* retval 无*/ void iic_ack(void) {IIC_SDA(0); /* 产生应答信号 */iic_delay();IIC_SCL(1); /* 高电平期间发送应答信号 */iic_delay();IIC_SCL(0);iic_delay();IIC_SDA(1); /* 释放数据线 */iic_delay();}/*** brief 产生不应答信号* param 无* retval 无*/ void iic_nack(void) {IIC_SDA(1); /* 产生不应答信号 */iic_delay();IIC_SCL(1);iic_delay(); /* 高电平期间发送不应答信号 */IIC_SCL(0);iic_delay(); }AT24Cxx.c #include ./BSP/AT24CXX/AT24Cxx.h #include ./BSP/IIC/myiic.h #include ./SYSTEM/delay/delay.h /*** brief 初始化IIC接口* param 无* retval 无*/ void at24cxx_init(void) {iic_init(); } /*** brief 在AT24CXX指定地址写入一个数据* param arr: 写入数据的目的地址* param data: 要写入的数据* retval 无*/ void at24cxx_write_onebyte(uint16_t arr,uint8_t data) {icc_start(); /* 发送起始信号 */if(EE_typeAT24C16) /* 24C16以上的型号, 分2个字节发送地址 */{iic_send_byte(0XA0);icc_wait_ack();iic_send_byte(arr8);}else{iic_send_byte(0XA0 ((arr 8) 1)); /* 24C16以下信号发送器件 0XA0 高位a8/a9/a10地址,写数据 */ }icc_wait_ack();/* 每次发送完一个字节,都要等待ACK */iic_send_byte(arr%256);/* 内存地址低位 */icc_wait_ack();iic_send_byte(data); /* 发送1字节 */icc_wait_ack(); /* 要等待ACK */icc_stop(); /* 产生一个停止条件 */delay_ms(10); /* 注意: EEPROM 写入比较慢,必须等到10ms后再写下一个字节 */ }/** * brief 在 AT24CXX 指定地址读出一个数据 * param readaddr: 开始读数的地址 * retval读到的数据 */ uint8_t at24cxx_read_onebyte(uint16_t arr) {uint8_t temp;icc_start();if(EE_typeAT24C16){iic_send_byte(0XA0);icc_wait_ack();iic_send_byte(arr8);}else{iic_send_byte(0XA0 ((arr 8) 1)); }icc_wait_ack();iic_send_byte(arr%256);icc_wait_ack();icc_start();iic_send_byte(0XA1);icc_wait_ack();tempicc_recive_byte(0);icc_stop();return temp; } /** * brief 检查 AT24CXX 是否正常 * note 检测原理: 在器件的末地址写如 0X55, 然后再读取, 如果读取值为 0X55 * 则表示检测正常. 否则,则表示检测失败. * param无 * retval检测结果 *0: 检测成功 *1: 检测失败 */ uint8_t at24cxx_chack(void) {uint8_t temp;uint16_t add EE_type;temp at24cxx_read_onebyte(add);if(temp0x55){return 0;}else{at24cxx_write_onebyte(add,0x55);temp at24cxx_read_onebyte(add);if(temp0x55) return 0;}return 1; }void at24cxx_read(uint16_t add,uint8_t *pbuf,uint16_t datalen){while(datalen--){*pbufat24cxx_read_onebyte(add);} }void at24cxx_write(uint16_t add,uint8_t *pbuf,uint16_t datalen){while(datalen--){at24cxx_write_onebyte(add,*pbuf);add;pbuf;} } main.c #include ./SYSTEM/sys/sys.h #include ./SYSTEM/usart/usart.h #include ./SYSTEM/delay/delay.h #include ./BSP/LED/led.h #include ./BSP/KEY/key.h #include ./BSP/LCD/lcd.h #include ./BSP/AT24CXX/AT24Cxx.h const uint8_t g_text_buf[] {STM32 IIC TEST}; #define TEXT_SIZE sizeof(g_text_buf) /* TEXT字符串长度 */ int main(void) {uint8_t key;uint8_t datatemp[TEXT_SIZE];HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */usart_init(115200); /* 串口初始化为115200 */delay_init(72); /* 延时初始化 */LED_init(); lcd_init(); /* LED初始化 */key_init();at24cxx_init();lcd_show_string(30, 50, 200, 16, 16, STM32, RED);lcd_show_string(30, 70, 200, 16, 16, IIC TEST, RED);lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED);lcd_show_string(30, 110, 200, 16, 16, KEY1:Write KEY0:Read, RED); /* 显示提示信息 */while (at24cxx_chack()) /* 检测不到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); }lcd_show_string(30, 130, 200, 16, 16, 24C02 Ready!, RED);while(1){ keykey_scan();if (key 1) /* KEY1按下,写入24C02 */{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); /* 提示传送完成 */}if (key 2) /* KEY0按下,读取字符串并显示 */{lcd_show_string(30, 150, 200, 16, 16, Start Read 24C02.... , BLUE);at24cxx_read(0, datatemp, TEXT_SIZE);lcd_show_string(30, 150, 200, 16, 16, The Data Readed Is: , BLUE); /* 提示传送完成 */lcd_show_string(30, 170, 200, 16, 16, (char *)datatemp, BLUE); /* 显示读到的字符串 */}} }key.c #include ./BSP/KEY/key.h #include ./SYSTEM/delay/delay.h void key_init(void) {GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();gpio_init_struct.ModeGPIO_MODE_INPUT;gpio_init_struct.PullGPIO_PULLUP;gpio_init_struct.PinGPIO_PIN_4;HAL_GPIO_Init(GPIOE,gpio_init_struct);gpio_init_struct.ModeGPIO_MODE_INPUT;gpio_init_struct.PullGPIO_PULLUP;gpio_init_struct.PinGPIO_PIN_3;HAL_GPIO_Init(GPIOE,gpio_init_struct);gpio_init_struct.ModeGPIO_MODE_INPUT;gpio_init_struct.PullGPIO_PULLDOWN;gpio_init_struct.PinGPIO_PIN_0;HAL_GPIO_Init(GPIOA,gpio_init_struct);}uint8_t key_scan(void) {uint8_t keyval 0;if (KEY0 0|| KEY10 || WK_UP1){delay_ms(10); if(KEY00){while(KEY00); keyval1;}if(KEY10){while(KEY10); keyval2;}if(WK_UP1){while(WK_UP0); keyval3;}}return keyval;} led.c #include ./BSP/LED/led.hvoid LED_init() {__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitTypeDef gpiob_init_struct;gpiob_init_struct.ModeGPIO_MODE_OUTPUT_PP;gpiob_init_struct.PinGPIO_PIN_5;gpiob_init_struct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, gpiob_init_struct);__HAL_RCC_GPIOE_CLK_ENABLE();GPIO_InitTypeDef gpioe_init_struct;gpioe_init_struct.ModeGPIO_MODE_OUTPUT_PP;gpioe_init_struct.PinGPIO_PIN_5;gpioe_init_struct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOE, gpioe_init_struct);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);}lcd.c 此驱动代码太长就不在展示在百度网盘中的文件里面都有 实验现象 iic实验 总结本节我们再次学习了STM32的IIC通信协议的基本知识结合AT24C02的EEPROM进行了数据的读取实验大家需要对IIC的时序十分熟悉对代码的操作也需要亲自动手。有问题欢迎在评论区探讨。 创作不易还请大家多多点赞支持
http://www.pierceye.com/news/664166/

相关文章:

  • 工商银行与建设银行网站对比石嘴山网站seo
  • seo快速建站自学程序员的步骤
  • 做旅行网站的依据及意义如何制作自己想要的图片
  • 电子商务网站怎么做网站建设企业建站哪家好?来这里看看
  • 网站备案电话号码购物商城网站建设方案
  • 手机商城系统徐州seo计费管理
  • 西安网站公司哪家好信息推广的方式有哪些
  • 网站开发注意的事项商丘网站制作软件
  • 51zwd一起做网站广州广东省网站备案查询
  • 如何生成一个网站自己弄公司网站
  • 企业信用信息查询网官网孝感网站seo
  • 中淼建设工程有限公司网站分类用wordpress
  • 腾讯建设网站首页做销售网站
  • 推广引流网站聚名网注册
  • 原来做网站后来跑国外了多伦多网站建设多少钱
  • 手机建站平台做母婴网站设计思路
  • 免费个人手机网站九八智能建站
  • 中山网站备案如何做购物网站
  • 常见的简单的网站制作建设网站的好公司
  • 邯郸网站制作建设wordpress+怎么迁移
  • 设计创意广告上海企业网站优化
  • 自己做网站需要购买服务器吗WordPress文章相册修改
  • 校园招聘哪个网站做的好学做川菜网站
  • 大足网站建设公司医院网站建设熊掌号
  • 做网站编辑是不是也要做推广做蛋白go分析网站
  • 免费品牌网站制作云南电商网站建设
  • 宿迁莱布拉网站建设常州做网站建设的公司
  • 广东网站建站系统哪家好常州网站搭建公司
  • 400网站建设推广软件工程师工资
  • 专门做正品的网站手机版深圳市门户网站建设怎么样