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

网站管理后台文章排序沈阳seo排名优化软件

网站管理后台文章排序,沈阳seo排名优化软件,班级网站首页怎么做,iis如何做同时运行两个网站80端口单片机里的通信协议其实蛮多的#xff0c;IIC#xff1b;SPI#xff1b;MQTT#xff1b;CAN#xff1b;包括串口也是一种通信协议。而串口通信虽然实现了全双工#xff0c;但需要至少三根线#xff0c;为了节省这一根线的成本#xff0c;于是IIC诞生了。 目录 一.IIC…单片机里的通信协议其实蛮多的IICSPIMQTTCAN包括串口也是一种通信协议。而串口通信虽然实现了全双工但需要至少三根线为了节省这一根线的成本于是IIC诞生了。 目录 一.IIC协议 1.IIC的结构 2.IIC的特点 3.IIC的通信时序 4.具体配置32HAL库版 二.SPI协议 1.SPI的结构 2.SPI的特点 3.具体配置 三联合配置 1.OLED屏幕的配置 OLED的数据格式 OLED的写入模式 Oled的命令 代码 W25Q128配置 W25Q128的命令 W25Q128的寄存器 代码 最终配置 祝你看完就会 一.IIC协议 IIC协议其实就是一种标准外设协议其实所谓协议本质上就是各种时序电路的组合。IIC也不例外它的最大特点就是特别的轻量级。 1.IIC的结构 IIC的简便和轻量级就在于它只有两条线一条是时钟线SCL一条是数据线SDA。说白了就是在SCL的控制下在SDA上传输命令/数据。 在这张图上可以看到同时有很多设备连接在这两条线上它们之间的关系一般是一主多从。 2.IIC的特点 1.IIC是半双工通信因为SCL不负责传输数据只有一条SDA数据线无法发的同时接收信息。 2.如果你使用的是STM32芯片那么如果没有配置上拉电阻的话GPIO口必须配置为开漏输出。因为假设时序出现错误两个设备一个讲SDA拉低一个将SDA拉高那么将导致短路。 3.同步传输数据的传输是严格按照时钟线来进行的。 3.IIC的通信时序 IIC的通信主要依靠四个信号起始信号应答信号停止信号读写信号 START STOP ASK 读写 其中ASK就是在在吧SCL拉高的期间读取SDA的的电平。读取完成后立即拉低。读取到的SDA假设为1则表示有应答若为0则表示没有应答。         读写信号则是在起始信号后将SCL拉低的期间向SDA上放或者读取数据。         START和STOP比较简单不多赘述。  4.具体配置32HAL库版 头文件 #ifndef __IIC_H__ #define __IIC_H__#include sys.h#define SDA_PULL_UP() HAL_GPIO_WritePin(GPIO_POTT, SDA, GPIO_PIN_SET) #define SDA_PULL_DOWN() HAL_GPIO_WritePin(GPIO_POTT, SDA, GPIO_PIN_RESET) #define SCL_PULL_UP() HAL_GPIO_WritePin(GPIO_POTT, SCL, GPIO_PIN_SET) #define SCL_PULL_DOWN() HAL_GPIO_WritePin(GPIO_POTT, SCL, GPIO_PIN_RESET)void iic_Stop(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL); void iic_Start(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL); void iic_Ask(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL); void iic_Sendbyte(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL,uint8_t DATA);#endif首先我这里用了大量的宏定义了很多宏函数来方便控制对应线的电平高低。另外如果你看的细致的话会发现我这里宏函数中的参数也是宏然而你却在这儿找不到这个宏。其实它并不是宏我用了一种稍微怪的方式来简便我在IIC定义里的工作量但加大了一点调用的工作量。  源文件 #include IIC.hvoid iic_Stop(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL){SCL_PULL_UP();SDA_PULL_DOWN(); //先拉高SCL再拉高SDASDA_PULL_UP();}void iic_Start(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL){SCL_PULL_UP(); //SCL高电平期间SDA下降沿SDA_PULL_UP();SDA_PULL_DOWN();SCL_PULL_DOWN(); }void iic_Ask(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL){SCL_PULL_UP(); SCL_PULL_DOWN(); }void iic_Sendbyte(GPIO_TypeDef *GPIO_POTT,uint16_t SDA,uint16_t SCL,uint8_t DATA){uint8_t i,tmp DATA;//主机在SCL低电平期间在SDA上放数据for(i 0; i8; i){if((tmp 0x80) 0x80) //DATA 1000 0000 SDA_PULL_UP();elseSDA_PULL_DOWN();SCL_PULL_UP(); //从机在SCL高电平期间读取这一位 SCL_PULL_DOWN();tmp tmp 1;} }想必如果你由上面的疑问看了源文件也就理解 我定义的宏函数里的参数并不是宏而是调用它的函数里的参数。所以我增加的调用方的工作量就是传参很多IIC这里就非常简介易懂了。 另外一个点就是数据传输函数中是一位一位放的不断地放不断地左移知道8次轮回完成一字节的传输则结束。  二.SPI协议 SPI的全称是Serial Peripheral Interface。有基础的人估计一眼就看见Serial串口了。没错其实这东西它使用非常像串口。不仅如此配置起来也非常像串口。 1.SPI的结构 SPI一共由四条线组成SCKMISOMOSINSSCS 其中MISO和MOSI分别是Master Input Slave Output 这里某些同学不要想歪了哈Master这里就是主机Slave就是从机所以这两根线就很好理解了简单说就是RX和TX一样。 然而虽然这里也是两条线也是全双工但是SPI的传输数据方式却是非常的特殊的。 图中画圈的地方都是SPI的重点其中特殊就在于它的位移寄存器 。 2.SPI的特点 1.SPI最大的特点就来自于它的位移寄存器它每发送一字节的数据就必须收一字节的数据同样的它要收一字节的数据就必须发出一字节数据。 2.看了特点一你会认为SPI是强制全双工的但其实不是它完全可以配置为半双工或者只有一条数据线。 3.SPI的工作模式比较特别它的工作模式取决于时钟极性和时钟相位 第三点展开来说 时钟极性控制SPI数据线上没有数据时SCL的电平状态 CPOL为0则空闲时为低电平反之则为高电平。 CPHA为0则每一个奇数边缘采样数据第一个反之则为偶数边缘采样。 你要是看不懂也没关系总之就是CPOL和CPHA排列组合一共有四种工作模式。 3.具体配置 SPI的配置一般是依靠板子上确定的外设的因为它不像IIC那样的轻量级。它有很多的东西需要配比如分频数时钟启动工作模式是否半双工等等。 #include SPI.h SPI_HandleTypeDef spi_handle {0};void SPI_INIT(void){spi_handle.Instance SPI1;spi_handle.Init.Mode SPI_MODE_MASTER; //配置主从模式spi_handle.Init.Direction SPI_DIRECTION_2LINES; //半双工全双工选择spi_handle.Init.DataSize SPI_DATASIZE_8BIT;spi_handle.Init.CLKPolarity SPI_POLARITY_LOW; //低电平有效spi_handle.Init.CLKPhase SPI_PHASE_1EDGE; //奇数取值spi_handle.Init.NSS SPI_NSS_SOFT; //软件调控NSSspi_handle.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_256; //分频数选择spi_handle.Init.FirstBit SPI_FIRSTBIT_MSB; spi_handle.Init.TIMode SPI_TIMODE_DISABLE;spi_handle.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE;spi_handle.Init.CRCPolynomial 7; HAL_SPI_Init(spi_handle);}void HAL_SPI_MspInit(SPI_HandleTypeDef *spi_handle){if(spi_handle-Instance SPI1){GPIO_InitTypeDef gpio_initstruct;__HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_SPI1_CLK_ENABLE();gpio_initstruct.Pin GPIO_PIN_4; gpio_initstruct.Mode GPIO_MODE_OUTPUT_PP; gpio_initstruct.Pull GPIO_PULLUP; gpio_initstruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, gpio_initstruct);gpio_initstruct.Pin GPIO_PIN_5 | GPIO_PIN_7; gpio_initstruct.Mode GPIO_MODE_AF_PP; HAL_GPIO_Init(GPIOA, gpio_initstruct);gpio_initstruct.Pin GPIO_PIN_6; gpio_initstruct.Mode GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOA, gpio_initstruct);}}uint8_t SPI_swap_byte(uint8_t data){uint8_t rev_data 0;HAL_SPI_TransmitReceive(spi_handle,data,rev_data,1,1000);return rev_data; } 这里对于Instance的配置还是挺繁琐的但是也只是繁琐并没有难度。剩下的就是时钟GPIO配置然后可以看到在发送的部分它的函数叫HAL_SPI_TransmitReceive对应上了我们说的接收的同时必须发送。 三联合配置 两个协议都学会了如何应用呢IIC的入门外设还是非常经典的--OLED屏幕。那SPI呢可以采用一块存储块进行配合读写。我这里就用W25Q128的存储模块。 1.OLED屏幕的配置 Oled的配置核心其实就是显示东西嘛所以其实总结成一句话就是 告诉屏幕在哪里显示什么东西。 OLED是只可以选择亮或者灭的所以显示什么东西其实最终说白了是各种点阵这个东西其实没啥技术含量。另外OLED模块的初始化也是不需要学的你就照着把一堆命令直接复制过来用就行了。所以主要的配置重点在于如何告诉他。 那么这个时候我们就需要读一下OLED的手册了。 OLED的数据格式 以上为手册的原图可以看到它的发送全部都是 Control byte Data byte。那么这是什么意思呢 说白了就是Control byte 用来让Oled判断接下来所接收的数据到底是命令还是显示数据。 可以看到整个数据帧的格式就是 Start信号--写入数据模式--ASK--Control byte--Data byte--ASK--Stop信号 那么此时的问题就变成了写入模式是什么以及Control byte是什么 Control byte看右下角D/C的后一位写0则表示接下来的数据是Command写1则表示接下来的数据是Data。 其实自己看手册可绝望了不信 给 OLED的写入模式 一共有四种 总而言之呢其实你只记得住第一个就行因为我们用哪一个都ok第一个在不配置的情况下是被默认选定的。只需要知道它在写完后会自动向右偏移一位。当写道最右边后会返回来这一行的最左边。那么这里就需要稍微知道一下屏幕的大小了 整个屏幕是128*64的每一个字节的八位是竖着排列的逻辑为1的就亮为0就灭。 64 / 8 8,这也是为什么是8个page。 Oled的命令 Oled其实内置的是一块芯片所以它的命令其实还是蛮多的。但是可以看到这里我给你截下来的命令都是关于位置设定和写入模式的设定的。 其实这里主要的就是Page和Column 的设定Page的很简单B0~B7分别表示Page0到Page7. 主要就是Column需要给两次因为有 128位嘛所以需要两个字节。这就在编程的方面稍微有点小麻烦。 代码 #include oled.h #include delay.h #include front.hvoid OLED_INIT(){GPIO_INIT();delay_ms(100); Oled_Write_Cmd(0xAE); Oled_Write_Cmd(0xD5); Oled_Write_Cmd(0x80); Oled_Write_Cmd(0xA8); Oled_Write_Cmd(0x3F); Oled_Write_Cmd(0xD3); Oled_Write_Cmd(0x00); Oled_Write_Cmd(0x40); Oled_Write_Cmd(0xA1); Oled_Write_Cmd(0xC8); Oled_Write_Cmd(0xDA); Oled_Write_Cmd(0x12);Oled_Write_Cmd(0x81); Oled_Write_Cmd(0xCF); Oled_Write_Cmd(0xD9); Oled_Write_Cmd(0xF1);Oled_Write_Cmd(0xDB); Oled_Write_Cmd(0x30);Oled_Write_Cmd(0xA4); Oled_Write_Cmd(0xA6); Oled_Write_Cmd(0x8D); Oled_Write_Cmd(0x14);Oled_Write_Cmd(0xAF); }void GPIO_INIT(){GPIO_InitTypeDef gpio_init;gpio_init.Mode GPIO_MODE_OUTPUT_PP;gpio_init.Pin SDA_PIN|SCL_PIN;gpio_init.Pull GPIO_PULLUP;gpio_init.Speed GPIO_SPEED_FREQ_HIGH;__HAL_RCC_GPIOB_CLK_ENABLE();HAL_GPIO_Init(GPIOB, gpio_init); }void Oled_Write_Cmd(uint8_t cmd){iic_Start(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,0x78);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,0x00);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,cmd);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Stop(SDA_PORT,SDA_PIN,SCL_PIN); }void Oled_Write_Data(uint8_t data){iic_Start(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,0x78);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,0x40);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Sendbyte(SDA_PORT,SDA_PIN,SCL_PIN,data);iic_Ask(SDA_PORT,SDA_PIN,SCL_PIN);iic_Stop(SDA_PORT,SDA_PIN,SCL_PIN); }void Oled_Set_Position(uint8_t page,uint8_t column){Oled_Write_Cmd(0xB0 page); //选择页数Oled_Write_Cmd(column 0x0F); //低四位Oled_Write_Cmd(((column 0xF0) 4) | 0x10); //高四位}void Oled_clear(void){uint8_t i,j; for(i 0;i 8;i){ Oled_Set_Position(i,0);for(j 0;j128;j){Oled_Write_Data(0);} }}void Oled_show_picture(uint8_t hight,uint8_t wide,uint8_t *picture){uint8_t page,i,j;page hight / 8;for(i 0; ipage; i){Oled_Set_Position(i,0);for(j 0; jwide; j){Oled_Write_Data(picture[wide * i j]);}}}void Oled_show_char(uint8_t Ocolumn, uint8_t Opage, uint8_t num, uint8_t size) {uint8_t i, j, page;num num - ;page size / 8;if(size % 8)page;for(j 0; j page; j){Oled_Set_Position(Opage j,Ocolumn);for(i size / 2 * j; i size /2 * (j 1); i){if(size 12)Oled_Write_Data(ascii_6X12[num][i]);else if(size 16)Oled_Write_Data(ascii_8X16[num][i]);else if(size 24)Oled_Write_Data(ascii_12X24[num][i]);}} }void Oled_show_string(uint8_t column, uint8_t page, char *p, uint8_t size) {while(*p ! \0){Oled_show_char(column, page, *p, size);column size/2;p;} }W25Q128配置 对于它其实主要就是配置 读写等待空闲这就是一个FLASH储存器。 FLASH的唯一特性就是它只能写0不能写1. 并且该模块不需要初始化命令同样很多但是我们用的很少。 W25Q128的命令 0x06写使能写入数据/擦除之前必须先发送该指令0x05读 SR1判定 FLASH 是否处于空闲状态擦除用0x03读数据读取数据0x02页写写入数据最多写256字节0x20扇区擦除扇区擦除指令最小擦除单位 这里主要讲一些要点 1.在做任何通讯的操作之前必须要拉低CS也就是拉低片选。这也是它和IIC不同的地方IIC是进行寻址而它通过拉低片选。操作完成后必须再拉高。 2.在进行读/写操作是需要发送地址这个地址是三字节的而发送时每次发送的是一个字节所以就需要位操作。 void send_addr(uint32_t address){SPI_swap_byte((uint8_t)address 16); //右移的同时进行强转强转保留低位所以这里是发送高位SPI_swap_byte((uint8_t)address 8); //中间8位SPI_swap_byte((uint8_t)address); //低8位 } 3.任何和写相关的操作比如马上要写刚刚写完必须进行等待空闲。 W25Q128的寄存器 这里就介绍这个一个就是为了等待空闲操作使用。 在编程过程中步骤也很简单 拉低片选----向芯片发送读取Busy的命令----发送的同时接收----while来阻塞知道接收到BusyFlag为0----拉高片选。 void wait_busy(void){W25Q128_CS(0);SPI_swap_byte(FLASH_ReadStatusReg1); //读取状态寄存器指令SPI_swap_byte(FLASH_DummyByte); //接收状态寄存器flag while((SPI_swap_byte(0xFF) 0x01) 1); //等待知道寄存器busy位变为0 W25Q128_CS(1); } 代码   #include w25q128.huint16_t w25q128_config(void){uint16_t device_id 0;W25Q128_CS(0);SPI_swap_byte(FLASH_ManufactDeviceID);SPI_swap_byte(0x00);SPI_swap_byte(0x00);SPI_swap_byte(0x00);device_id SPI_swap_byte(FLASH_DummyByte) 8;device_id | SPI_swap_byte(FLASH_DummyByte);W25Q128_CS(1);return device_id; }void wait_busy(void){W25Q128_CS(0);SPI_swap_byte(FLASH_ReadStatusReg1); //读取状态寄存器指令SPI_swap_byte(FLASH_DummyByte); //接收状态寄存器flag while((SPI_swap_byte(0xFF) 0x01) 1); //等待知道寄存器busy位变为0 W25Q128_CS(1); }void send_addr(uint32_t address){SPI_swap_byte((uint8_t)address 16); //右移的同时进行强转强转保留低位所以这里是发送高位SPI_swap_byte((uint8_t)address 8); //中间8位SPI_swap_byte((uint8_t)address); //低8位 }void w25q128_writ_enable(void) {W25Q128_CS(0);SPI_swap_byte(FLASH_WriteEnable);W25Q128_CS(1); }void read_data(uint32_t address, uint8_t *rev_data, uint8_t size){W25Q128_CS(0);SPI_swap_byte(FLASH_ReadData);send_addr(address);uint8_t i 0; for(i 0; i size; i){rev_data[i] SPI_swap_byte(0xFF); //直接根据指针写进去了所以不需要返回值}W25Q128_CS(1); }void write_page_data(uint32_t address, uint8_t *write_data, uint8_t size){ w25q128_writ_enable();wait_busy();W25Q128_CS(0);SPI_swap_byte(FLASH_PageProgram);send_addr(address);uint16_t i 0;for(i 0; i size; i){SPI_swap_byte(write_data[i]);}W25Q128_CS(1);wait_busy();}void erase_page(uint32_t address){w25q128_writ_enable();wait_busy();W25Q128_CS(0);SPI_swap_byte(FLASH_SectorErase);send_addr(address);W25Q128_CS(1);wait_busy();} 最终配置 把文件合并接线合并初始化后在Main函数更改写法让读写操作显示在屏幕上 #include sys.h #include uart1.h #include delay.h #include led.h #include SPI.h #include w25q128.h #include oled.h #include IIC.h #include string.huint8_t data_write[4] {0xAA, 0xBB, 0xCC, 0xDD}; uint8_t data_read[4] {0}; int main(void) {HAL_Init(); stm32_clock_init(RCC_PLL_MUL9); SPI_INIT();uart1_init(115200); OLED_INIT();Oled_clear(); Oled_show_string(1,1,HELLO WKX,24); delay_ms(1000); Oled_clear();char show[8];uint16_t number w25q128_config();sprintf(show,device id :%X,number);Oled_show_string(1,1,Loading...,24); delay_ms(1000); Oled_clear();Oled_show_string(1,1,show,16);delay_ms(1000);Oled_clear(); write_page_data(0x000000, data_write, 4);Oled_show_string(1,1,Writed succes,16);delay_ms(500);Oled_clear();Oled_show_string(1,1,Reading data,16);delay_ms(500);Oled_clear();read_data(0x000000, data_read, 4);memset(show,0,8);sprintf(show,%X,data_read[0]);Oled_show_string(1,1,show,16);sprintf(show,%X,data_read[1]);Oled_show_string(40,1,show,16);sprintf(show,%X,data_read[2]);Oled_show_string(80,1,show,16);while(1){ } } 好了给看看效果 OLEDW25Q128 祝你看完就会
http://www.w-s-a.com/news/303389/

相关文章:

  • 保洁公司网站怎么做科技设计网站有哪些内容
  • 建设厅网站查询网页设计好就业吗
  • 惠东县网站建设wordpress 如何回到初始
  • 如何让公司网站网站转备案
  • 获得网站所有关键字北京网站建设116net
  • 铜陵电子商务网站建设做龙之向导网站有用吗
  • 购物网站制作费用沧州新华区
  • 信宜网站设计公司在线购物商城系统
  • 网站维护是什么样如何制作网站教程视频讲解
  • 网站建设网络推广代理公司wordpress图片防盗链
  • 网站备案关站沈阳男科医院哪家好点
  • 王者荣耀网站建设的步骤网站页面用什么软件做
  • 典型网站开发的流程房屋装修效果图三室一厅
  • 制作微网站多少钱阿里巴巴做网站的电话号码
  • 风铃建站模板安卓手机软件开发外包
  • 深圳市住房和建设局门户网站域名转移影响网站访问吗
  • 做母婴网站赚钱汕头百姓网
  • 那个网站建设好动漫制作技术升本可以升什么专业
  • 网站建设企业响应式网站模板广西建设部投诉网站
  • app营销的特点wordpress优化方案
  • 静安网站建设公司如何编辑wordpress
  • 做网站的职位叫什么问题常州金坛网站建设
  • 保健品网站模板用jsp做的网站前后端交互
  • 网站带后台品牌网页设计图片
  • 保定清苑住房和城乡建设局网站分类信息网站程序
  • 可以做视频推广的网站选择大连网站建设
  • 在线网站开发网站在哪里
  • 建站的步骤上海快速优化排名
  • 招聘网站做一下要多少钱网站设计公司 国际
  • 巩义专业网站建设公司首选seo研究院