树莓派4B学习笔记——IO通信篇(SPI)
文章目录SPI协议简介树莓派4B1.3寸OLEDSPI协议1.3寸OLED简介接线图开启树莓派SPI接口wiringPiSPI库简介C语言实现汉字、字符、数字、图片显示Python实现总结树莓派4B入门学习笔记汇总SPI协议简介SPI(Serial Peripheral interface)是由Motorola公司开发的串行外围设备接口是一种高速的全双工同步的通信总线。主要应用在FLASH实时时钟AD转换器还有数字信号处理器和数字信号解码器等器件。它是串行、全双工、 同步使用时钟、板级通信一般是高位先发也可以设置为低位先发。标准四线SPI引脚定义如下引脚定义功能SCLK时钟线用于主从时序的同步CS片选信号线用于选择跟哪个芯片进行通信MOSI数据线主出从入MISO数据线master input slave output 主入从出有时也会根据通信需求设计时只采取三线模式毕竟不是所有的系统都需要主从之间实现全双工的通信大多是只需要主机发送数据控制从机即可所以硬件设计时会采用舍去MISO。我们今天使用的1.3寸OLED就是使用的3线模式关于SPI这个三线四线的定义emmm有好几个说法还有种说法是根据有没有单独的片选线而定这里不纠结毕竟也没有官方的定义。。一主一从接线方式一个主机对多个从机总线挂载多个SPI从机这里的挂在数量是根据你的片选信号个数而定的。SPI的传输速度会比前面使用的I2C快其传输速度可达几Mb/s设置SPI的通信速度时一定不能大于从机的最大通信速度 。如果大于从机的通信速度会导致通信失败。SPI的通讯流程主机我要给从机1传命令主发送从接收先把从机1给叫到办公室CS片选选中从机1然后开始传送命令传输完毕后从机1离开办公室CS恢复主机可以重新选择传输对象。有关SPI的四种模式等详细介绍参考此文。树莓派4B1.3寸OLEDSPI协议1.3寸OLED简介使用的是中景原子的1.3寸OLED这种屏幕的好处在于它兼容I2C和SPI自己改一下元器件的焊接位置即可以下来自厂家描述7针和6针两种屏均支持SPI/IIC默认为SPI接口出货。将电阻SPI拆掉焊接到到IIC位置R4两端用锡短接DCCS管脚接地RES管脚通过一个IO去控制完成复位复位方法先将RES管脚保持低电平200ms然后将RES管脚操持高平完成复位操作然后对OLED进行初始化操作这样就可以用iic通信了; 时钟SCL; 数据线SDA。这里特别说明一下DC管脚在用IIC通信的时候DC管脚的高低电平是用来设置IIC设备地址的一般常用是将DC直接接地了如果IIC总线上有两个OLED屏就需要一个将DC接地另一个DC接高电平这样两个OLED屏的IIC地址就会不同了可以分时操作两个屏6针与7针的不同是将CS管脚直接接地了这样用户可以节省一个IO不过这样的话6针的屏在用SPI接口的时候就不能与其它SPI复用了7脚的可以。接线图在终端命令行输入 gpio readall 回车可以找到树莓派的板载硬件SPI接口。我们对照上面的引脚和实物接线就可以了这里我也是参考的是此博文如果是用的0.96寸屏幕直接参考链接里面接线即可。开启树莓派SPI接口打开终端命令输入ls /dev 回车发现没有SPI节点这是因为系统默认是关闭了SPI接口的需要我们自己打开。跟昨天I2C的步骤一样终端界面就是输入sudo raspi-config参考上一篇将SPI enable即可不清楚的可以去看上一篇这里不再一步一步贴图了开启后还是重启一下树莓派。打开终端命令输入 ls /dev回车可以看见有spidev0.0和spidev0.1两个节点说明SPI已经开启。wiringPiSPI库简介打开wiringPiSPI.h我们可以看见里面外部声明了四个函数也就是说我们通过这四个函数即可实现spi的使用。有关这四个函数的详细介绍参考此文。C语言实现汉字、字符、数字、图片显示打开Geany输入以下代码移植的中景园电子的源代码// An highlighted block#includewiringPi.h#includestdio.h#includewiringPiSPI.h#defineLCD_DC3// 模式选择 1写数据 0写命令#defineLCD_DIN12// 串行数据线#defineLCD_CLK14// 串行时钟线#defineLCD_RST0// 复位信号 低电平有效#defineLCD_CE10// 芯片使能 低电平有效#defineOLED_CMD0//写命令#defineOLED_DATA1//写数据#defineOLED_MODE0#defineSIZE16#define XLevelL0x00#define XLevelH0x10#define Max_Column128#define Max_Row64#define Brightness0xFF#defineX_WIDTH128#defineY_WIDTH64#define u16 unsigned int #define u8 unsigned charconstunsigned charF6x8[][6];constunsigned charF8X16[];unsigned charBMP2[];unsigned charBMP1[];unsigned char picture6[];unsigned char picture7[];unsigned char picture8[];unsigned char picture9[];char Hzk[][32];#define X_Col_addr0x80// 定位列 地址 0-83#define Y_Row_addr0x40// 定位行 地址 0-5// 初始化GPIO 端口voidgpioInit(){pinMode(LCD_DC,OUTPUT);pinMode(LCD_RST,OUTPUT);pinMode(LCD_CE,OUTPUT);}voidOLED_Set_Pos(unsigned char x,unsigned char y){lcd_writeByte(0xb0y,OLED_CMD);lcd_writeByte((((x2)0xf0)4)|0x10,OLED_CMD);lcd_writeByte(((x2)0x0f),OLED_CMD);}//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!voidlcd_clear(void){u8 i,n;for(i0;i8;i){lcd_writeByte(0xb0i,OLED_CMD);//设置页地址0~7lcd_writeByte(0x02,OLED_CMD);//设置显示位置—列低地址lcd_writeByte(0x10,OLED_CMD);//设置显示位置—列高地址for(n0;n128;n)lcd_writeByte(0,OLED_DATA);}//更新显示}//显示汉字voidOLED_ShowCHinese(u8 x,u8 y,u8 no){u8 t,adder0;OLED_Set_Pos(x,y);for(t0;t16;t){lcd_writeByte(Hzk[2*no][t],OLED_DATA);adder1;}OLED_Set_Pos(x,y1);for(t0;t16;t){lcd_writeByte(Hzk[2*no1][t],OLED_DATA);adder1;}}/***********功能描述显示显示BMP图片128×64起始点坐标(x,y),x的范围0127y为页的范围07*****************/voidOLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned charBMP[]){unsigned int j0;unsigned char x,y;if(y1%80)yy1/8;elseyy1/81;for(yy0;yy1;y){OLED_Set_Pos(x0,y);for(xx0;xx1;x){lcd_writeByte(BMP[j],OLED_DATA);}}}//在指定位置显示一个字符,包括部分字符//x:0~127//y:0~63//mode:0,反白显示;1,正常显示//size:选择字体 16/12voidOLED_ShowChar(u8 x,u8 y,u8 chr){unsigned char c0,i0;cchr- ;//得到偏移后的值if(xMax_Column-1){x0;yy2;}if(SIZE16){OLED_Set_Pos(x,y);for(i0;i8;i)lcd_writeByte(F8X16[c*16i],OLED_DATA);OLED_Set_Pos(x,y1);for(i0;i8;i)lcd_writeByte(F8X16[c*16i8],OLED_DATA);}else{OLED_Set_Pos(x,y1);for(i0;i6;i)lcd_writeByte(F6x8[c][i],OLED_DATA);}}//m^n函数unsigned intoled_pow(u8 m,u8 n){unsigned int result1;while(n--)result*m;returnresult;}//显示2个数字//x,y :起点坐标//len :数字的位数//size:字体大小//mode:模式 0,填充模式;1,叠加模式//num:数值(0~4294967295);voidOLED_ShowNum(u8 x,u8 y,unsigned int num,u8 len,u8 size){u8 t,temp;u8 enshow0;for(t0;tlen;t){temp(num/oled_pow(10,len-t-1))%10;if(enshow0t(len-1)){if(temp0){OLED_ShowChar(x(size/2)*t,y, );continue;}elseenshow1;}OLED_ShowChar(x(size/2)*t,y,temp0);}}//显示一个字符号串voidOLED_ShowString(u8 x,u8 y,u8*chr){unsigned char j0;while(chr[j]!\0){OLED_ShowChar(x,y,chr[j]);x8;if(x120){x0;y2;}j;}}// 初始化液晶voidlcd_init(){gpioInit();int isOKwiringPiSPISetup(0,1000000);if(isOK-1){printf(SPI设置失败\n);}else{printf(SPI设置OK %d\n,isOK);}digitalWrite(LCD_RST,LOW);// 液晶复位delay(200);digitalWrite(LCD_RST,HIGH);delay(20);lcd_writeByte(0xAE,OLED_CMD);//--turn off oled panellcd_writeByte(0x02,OLED_CMD);//---set low column addresslcd_writeByte(0x10,OLED_CMD);//---set high column addresslcd_writeByte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)lcd_writeByte(0x81,OLED_CMD);//--set contrast control registerlcd_writeByte(0xCF,OLED_CMD);// Set SEG Output Current Brightnesslcd_writeByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常lcd_writeByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常lcd_writeByte(0xA6,OLED_CMD);//--set normal displaylcd_writeByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)lcd_writeByte(0x3f,OLED_CMD);//--1/64 dutylcd_writeByte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)lcd_writeByte(0x00,OLED_CMD);//-not offsetlcd_writeByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequencylcd_writeByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Seclcd_writeByte(0xD9,OLED_CMD);//--set pre-charge periodlcd_writeByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks Discharge as 1 Clocklcd_writeByte(0xDA,OLED_CMD);//--set com pins hardware configurationlcd_writeByte(0x12,OLED_CMD);lcd_writeByte(0xDB,OLED_CMD);//--set vcomhlcd_writeByte(0x40,OLED_CMD);//Set VCOM Deselect Levellcd_writeByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)lcd_writeByte(0x02,OLED_CMD);//lcd_writeByte(0x8D,OLED_CMD);//--set Charge Pump enable/disablelcd_writeByte(0x14,OLED_CMD);//--set(0x10) disablelcd_writeByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)lcd_writeByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)lcd_writeByte(0xAF,OLED_CMD);//--turn on oled panellcd_writeByte(0xAF,OLED_CMD);/*display ON*/lcd_clear();// 清屏OLED_Set_Pos(0,0);}intmain(void){unsigned char t;wiringPiSetup();lcd_init();lcd_clear();// 清屏t ;while(1){lcd_clear();// LED_ON;OLED_ShowCHinese(0,0,0);//中OLED_ShowCHinese(18,0,1);//景OLED_ShowCHinese(36,0,2);//园OLED_ShowCHinese(54,0,3);//电OLED_ShowCHinese(72,0,4);//子OLED_ShowCHinese(90,0,5);//科OLED_ShowCHinese(108,0,6);//技OLED_ShowString(0,3,1.3 OLED TEST);//OLED_ShowString(8,2,ZHONGJINGYUAN);// OLED_ShowString(20,4,2014/05/01);OLED_ShowString(0,6,ASCII:);OLED_ShowString(63,6,CODE:);OLED_ShowChar(48,6,t);//显示ASCII字符t;if(t~)t ;OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值delay(2000);lcd_clear();delay(100);// LED_OFF;OLED_DrawBMP(0,0,128,8,BMP1);//图片显示(图片显示慎用生成的字表较大会占用较多空间FLASH空间8K以下慎用)delay(1000);OLED_DrawBMP(0,0,128,8,picture6);//图片显示(图片显示慎用生成的字表较大会占用较多空间FLASH空间8K以下慎用)delay(200);OLED_DrawBMP(0,0,128,8,picture7);delay(200);OLED_DrawBMP(0,0,128,8,picture8);//图片显示(图片显示慎用生成的字表较大会占用较多空间FLASH空间8K以下慎用)delay(200);OLED_DrawBMP(0,0,128,8,picture9);delay(200);OLED_DrawBMP(0,0,128,8,picture6);//图片显示(图片显示慎用生成的字表较大会占用较多空间FLASH空间8K以下慎用)delay(200);OLED_DrawBMP(0,0,128,8,BMP2);delay(1000);}}//取模部分代码太长了需要的去资源下载或者点赞收藏私信博主获取。然后保存编译效果如下Python实现此处参考此博文即可Python部分主要是调用API接口比C语言的取模要方便的多。最终效果如下所示总结有关SPI部分的使用就到这欢迎大家提出指正。树莓派4B入门学习笔记汇总树莓派4B学习笔记——系统烧录及初次开机树莓派4B学习笔记——点亮你的LED树莓派4B学习笔记——IO输入检测树莓派4B学习笔记——IO通信篇I2C树莓派4B学习笔记——IO通信篇SPI树莓派4B学习笔记——IO通信篇1-Wire树莓派4B学习笔记——IO通信篇UART
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2500485.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!