学习目标

  1. 掌握移植方法
  2. 掌握调试方式

学习内容

需求

240.png241.png

官方测试示例

选择对应的平台

测试示例中,找到芯片对应平台,我们选择的是STM32F407
242.png

修改例程

已知错误修改:

  1. #ifndef u8
  2. #define u8 uint8_t
  3. #endif
  4. #ifndef u16
  5. #define u16 uint16_t
  6. #endif
  7. #ifndef u32
  8. #define u32 uint32_t
  9. #endif

引脚定义修改:

  1. #define CLK_RCU RCC_AHB1Periph_GPIOB
  2. #define CLK_PORT GPIOB
  3. #define CLK_PIN GPIO_Pin_3
  4. #define MOSI_RCU RCC_AHB1Periph_GPIOB
  5. #define MOSI_PORT GPIOB
  6. #define MOSI_PIN GPIO_Pin_5
  7. #define DC_RCU RCC_AHB1Periph_GPIOB
  8. #define DC_PORT GPIOB
  9. #define DC_PIN GPIO_Pin_8
  10. #define CS1_RCU RCC_AHB1Periph_GPIOA
  11. #define CS1_PORT GPIOA
  12. #define CS1_PIN GPIO_Pin_15
  13. #define MISO_RCU RCC_AHB1Periph_GPIOB
  14. #define MISO_PORT GPIOB
  15. #define MISO_PIN GPIO_Pin_4
  16. #define CS2_RCU RCC_AHB1Periph_GPIOA
  17. #define CS2_PORT GPIOA
  18. #define CS2_PIN GPIO_Pin_4
  19. #define OLED_SCL_Clr() GPIO_ResetBits(CLK_PORT, CLK_PIN)//SCL
  20. #define OLED_SCL_Set() GPIO_SetBits(CLK_PORT, CLK_PIN)
  21. #define OLED_SDA_Clr() GPIO_ResetBits(MOSI_PORT,MOSI_PIN)//SDA
  22. #define OLED_SDA_Set() GPIO_SetBits(MOSI_PORT,MOSI_PIN)
  23. #define OLED_DC_Clr() GPIO_ResetBits(DC_PORT,DC_PIN)//DC
  24. #define OLED_DC_Set() GPIO_SetBits(DC_PORT,DC_PIN)
  25. #define OLED_CS_Clr() GPIO_ResetBits(CS1_PORT,CS1_PIN)//CS1
  26. #define OLED_CS_Set() GPIO_SetBits(CS1_PORT,CS1_PIN)
  27. #define OLED_READ_FS0() GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)//FS0
  28. #define OLED_ROM_CS_Clr() GPIO_ResetBits(CS2_PORT,CS2_PIN)//CS2
  29. #define OLED_ROM_CS_Set() GPIO_SetBits(CS2_PORT,CS2_PIN)

初始化逻辑修改:

  1. GPIO_InitTypeDef GPIO_InitStructure;
  2. RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);//使能A端口时钟
  3. GPIO_InitStructure.GPIO_Pin = CLK_PIN;
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  5. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  6. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  7. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  8. GPIO_Init(CLK_PORT, &GPIO_InitStructure);
  9. RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);
  10. GPIO_InitStructure.GPIO_Pin = MOSI_PIN;
  11. GPIO_Init(MOSI_PORT, &GPIO_InitStructure);
  12. RCC_AHB1PeriphClockCmd(DC_RCU,ENABLE);
  13. GPIO_InitStructure.GPIO_Pin = DC_PIN;
  14. GPIO_Init(DC_PORT, &GPIO_InitStructure);
  15. RCC_AHB1PeriphClockCmd(CS1_RCU,ENABLE);
  16. GPIO_InitStructure.GPIO_Pin = CS1_PIN;
  17. GPIO_Init(CS1_PORT, &GPIO_InitStructure);
  18. RCC_AHB1PeriphClockCmd(CS2_RCU,ENABLE);
  19. GPIO_InitStructure.GPIO_Pin = CS2_PIN;
  20. GPIO_Init(CS2_PORT, &GPIO_InitStructure);
  21. RCC_AHB1PeriphClockCmd(MISO_RCU,ENABLE);
  22. GPIO_InitStructure.GPIO_Pin = MISO_PIN;
  23. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
  24. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
  25. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  26. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  27. GPIO_Init(MISO_PORT, &GPIO_InitStructure); //初始化GPIOA

烧录测试

无法通过

STM32自己环境

官方示例无法通过,切换自己的环境,进行测试。

  1. 拷贝oled文件
  2. 拷贝main中的核心逻辑
  3. 修改不兼容的api

    完整代码

    ```c

    ifndef __OLED_H

    define __OLED_H

include “stm32f4xx.h”

include “systick.h”

//SCL=SCLK //SDA=MOSI //DC=DC //CS=CS1 //FS0=MOSI //CS2=CS2

ifndef u8

define u8 uint8_t

endif

ifndef u16

define u16 uint16_t

endif

ifndef u32

define u32 uint32_t

endif

//————————-OLED端口定义————————

define CLK_RCU RCC_AHB1Periph_GPIOB

define CLK_PORT GPIOB

define CLK_PIN GPIO_Pin_3

define MOSI_RCU RCC_AHB1Periph_GPIOB

define MOSI_PORT GPIOB

define MOSI_PIN GPIO_Pin_5

define DC_RCU RCC_AHB1Periph_GPIOB

define DC_PORT GPIOB

define DC_PIN GPIO_Pin_8

define CS1_RCU RCC_AHB1Periph_GPIOA

define CS1_PORT GPIOA

define CS1_PIN GPIO_Pin_15

define MISO_RCU RCC_AHB1Periph_GPIOB

define MISO_PORT GPIOB

define MISO_PIN GPIO_Pin_4

define CS2_RCU RCC_AHB1Periph_GPIOA

define CS2_PORT GPIOA

define CS2_PIN GPIO_Pin_4

define OLED_SCL_Clr() GPIO_ResetBits(CLK_PORT, CLK_PIN)//SCL

define OLED_SCL_Set() GPIO_SetBits(CLK_PORT, CLK_PIN)

define OLED_SDA_Clr() GPIO_ResetBits(MOSI_PORT,MOSI_PIN)//SDA

define OLED_SDA_Set() GPIO_SetBits(MOSI_PORT,MOSI_PIN)

define OLED_DC_Clr() GPIO_ResetBits(DC_PORT,DC_PIN)//DC

define OLED_DC_Set() GPIO_SetBits(DC_PORT,DC_PIN)

define OLED_CS_Clr() GPIO_ResetBits(CS1_PORT,CS1_PIN)//CS1

define OLED_CS_Set() GPIO_SetBits(CS1_PORT,CS1_PIN)

define OLED_READ_FS0() GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)//FS0

define OLED_ROM_CS_Clr() GPIO_ResetBits(CS2_PORT,CS2_PIN)//CS2

define OLED_ROM_CS_Set() GPIO_SetBits(CS2_PORT,CS2_PIN)

define OLED_CMD 0 //写命令

define OLED_DATA 1 //写数据

void OLED_ColorTurn(u8 i); void OLED_DisplayTurn(u8 i); void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Clear(void); void OLED_address(u8 x,u8 y); void OLED_Display_128x64(u8 dp); void OLED_Display_16x16(u8 x,u8 y,u8 dp); void OLED_Display_8x16(u8 x,u8 y,u8 dp); void OLED_Display_5x7(u8 x,u8 y,u8 dp); void Send_Command_to_ROM(u8 dat); u8 Get_data_from_ROM(void); void OLED_get_data_from_ROM(u8 addrHigh,u8 addrMid,u8 addrLow,u8 pbuff,u8 DataLen); void OLED_Display_GB2312_string(u8 x,u8 y,u8 text); void OLED_Display_string_5x7(u8 x,u8 y,u8 *text); void OLED_ShowNum(u8 x,u8 y,float num,u8 len); void OLED_Init(void);

endif

  1. ```c
  2. #include "oled.h"
  3. #include "stdlib.h"
  4. //反显函数
  5. void OLED_ColorTurn(u8 i)
  6. {
  7. if(i==0)
  8. {
  9. OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
  10. }
  11. if(i==1)
  12. {
  13. OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
  14. }
  15. }
  16. //屏幕旋转180度
  17. void OLED_DisplayTurn(u8 i)
  18. {
  19. if(i==0)
  20. {
  21. OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
  22. OLED_WR_Byte(0xA1,OLED_CMD);
  23. }
  24. if(i==1)
  25. {
  26. OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
  27. OLED_WR_Byte(0xA0,OLED_CMD);
  28. }
  29. }
  30. //开启OLED显示
  31. void OLED_DisPlay_On(void)
  32. {
  33. OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  34. OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
  35. OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
  36. }
  37. //关闭OLED显示
  38. void OLED_DisPlay_Off(void)
  39. {
  40. OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  41. OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
  42. OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
  43. }
  44. //向SSD1306写入一个字节。
  45. //mode:数据/命令标志 0,表示命令;1,表示数据;
  46. void OLED_WR_Byte(u8 dat,u8 cmd)
  47. {
  48. u8 i;
  49. if(cmd)
  50. OLED_DC_Set();
  51. else
  52. OLED_DC_Clr();
  53. OLED_CS_Clr();
  54. for(i=0;i<8;i++)
  55. {
  56. OLED_SCL_Clr();
  57. if(dat&0x80)
  58. OLED_SDA_Set();
  59. else
  60. OLED_SDA_Clr();
  61. OLED_SCL_Set();
  62. dat<<=1;
  63. }
  64. OLED_CS_Set();
  65. OLED_DC_Set();
  66. }
  67. //清屏函数
  68. void OLED_Clear(void)
  69. {
  70. u8 i,n;
  71. for(i=0;i<8;i++)
  72. {
  73. OLED_WR_Byte(0xb0+i,OLED_CMD);//设置页地址
  74. OLED_WR_Byte(0x10,OLED_CMD); //设置列地址的高4位
  75. OLED_WR_Byte(0x00,OLED_CMD); //设置列地址的低4位
  76. for(n=0;n<128;n++)
  77. {
  78. OLED_WR_Byte(0x00,OLED_DATA);//清除所有数据
  79. }
  80. }
  81. }
  82. //设置起始地址
  83. void OLED_address(u8 x,u8 y)
  84. {
  85. OLED_WR_Byte(0xb0+y,OLED_CMD); //设置页地址
  86. OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); //设置列地址的高4位
  87. OLED_WR_Byte((x&0x0f),OLED_CMD); //设置列地址的低4位
  88. }
  89. //显示128x64点阵图像
  90. void OLED_Display_128x64(u8 *dp)
  91. {
  92. u8 i,j;
  93. for(i=0;i<8;i++)
  94. {
  95. OLED_address(0,i);
  96. for(j=0;j<128;j++)
  97. {
  98. OLED_WR_Byte(*dp,OLED_DATA); //写数据到OLED,每写完一个8位的数据后列地址自动加1
  99. dp++;
  100. }
  101. }
  102. }
  103. //显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标
  104. void OLED_Display_16x16(u8 x,u8 y,u8 *dp)
  105. {
  106. u8 i,j;
  107. for(j=0;j<2;j++)
  108. {
  109. OLED_address(x,y);
  110. for(i=0;i<16;i++)
  111. {
  112. OLED_WR_Byte(*dp,OLED_DATA); //写数据到OLED,每写完一个8位的数据后列地址自动加1
  113. dp++;
  114. }
  115. y++;
  116. }
  117. }
  118. //显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标
  119. void OLED_Display_8x16(u8 x,u8 y,u8 *dp)
  120. {
  121. u8 i,j;
  122. for(j=0;j<2;j++)
  123. {
  124. OLED_address(x,y);
  125. for(i=0;i<8;i++)
  126. {
  127. OLED_WR_Byte(*dp,OLED_DATA); //写数据到LCD,每写完一个8位的数据后列地址自动加1
  128. dp++;
  129. }
  130. y++;
  131. }
  132. }
  133. //显示5*7点阵图像、ASCII, 或5x7点阵的自造字符、其他图标
  134. void OLED_Display_5x7(u8 x,u8 y,u8 *dp)
  135. {
  136. u8 i;
  137. OLED_address(x,y);
  138. for(i=0;i<6;i++)
  139. {
  140. OLED_WR_Byte(*dp,OLED_DATA);
  141. dp++;
  142. }
  143. }
  144. //送指令到晶联讯字库IC
  145. void Send_Command_to_ROM(u8 dat)
  146. {
  147. u8 i;
  148. for(i=0;i<8;i++)
  149. {
  150. OLED_SCL_Clr();
  151. if(dat&0x80)
  152. {
  153. OLED_SDA_Set();
  154. }
  155. else
  156. {
  157. OLED_SDA_Clr();
  158. }
  159. dat<<=1;
  160. OLED_SCL_Set();
  161. }
  162. }
  163. //从晶联讯字库IC中取汉字或字符数据(1个字节)
  164. u8 Get_data_from_ROM(void)
  165. {
  166. u8 i,read=0;
  167. for(i=0;i<8;i++)
  168. {
  169. OLED_SCL_Clr();
  170. read<<=1;
  171. if(OLED_READ_FS0())
  172. {
  173. read++;
  174. }
  175. OLED_SCL_Set();
  176. }
  177. return read;
  178. }
  179. //从相关地址(addrHigh:地址高字节,addrMid:地址中字节,addrLow:地址低字节)中连续读出DataLen个字节的数据到 pbuff的地址
  180. //连续读取
  181. void OLED_get_data_from_ROM(u8 addrHigh,u8 addrMid,u8 addrLow,u8 *pbuff,u8 DataLen)
  182. {
  183. u8 i;
  184. OLED_ROM_CS_Clr();
  185. Send_Command_to_ROM(0x03);
  186. Send_Command_to_ROM(addrHigh);
  187. Send_Command_to_ROM(addrMid);
  188. Send_Command_to_ROM(addrLow);
  189. for(i=0;i<DataLen;i++)
  190. {
  191. *(pbuff+i)=Get_data_from_ROM();
  192. }
  193. OLED_ROM_CS_Set();
  194. }
  195. u32 fontaddr=0;
  196. void OLED_Display_GB2312_string(u8 x,u8 y,u8 *text)
  197. {
  198. u8 i=0;
  199. u8 addrHigh,addrMid,addrLow;
  200. u8 fontbuf[32];
  201. while(text[i]>0x00)
  202. {
  203. if((text[i]>=0xb0)&&(text[i]<=0xf7)&&(text[i+1]>=0xa1))
  204. {
  205. //国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算:
  206. //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
  207. //由于担心8位单片机有乘法溢出问题,所以分三部取地址
  208. fontaddr=(text[i]-0xb0)*94;
  209. fontaddr+=(text[i+1]-0xa1)+846;
  210. fontaddr=fontaddr*32;
  211. addrHigh=(fontaddr&0xff0000)>>16; //地址的高8位,共24位
  212. addrMid=(fontaddr&0xff00)>>8; //地址的中8位,共24位
  213. addrLow=(fontaddr&0xff); //地址的低8位,共24位
  214. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);
  215. //取32个字节的数据,存到"fontbuf[32]"
  216. OLED_Display_16x16(x,y,fontbuf);
  217. //显示汉字到LCD上,y为页地址,x为列地址,fontbuf[]为数据
  218. x+=16;
  219. i+=2;
  220. }
  221. else if((text[i]>=0xa1)&&(text[i]<=0xa3)&&(text[i+1]>=0xa1))
  222. {
  223. fontaddr=(text[i]-0xa1)*94;
  224. fontaddr+=(text[i+1]-0xa1);
  225. fontaddr=fontaddr*32;
  226. addrHigh=(fontaddr&0xff0000)>>16;
  227. addrMid=(fontaddr&0xff00)>>8;
  228. addrLow=(fontaddr&0xff);
  229. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);
  230. OLED_Display_16x16(x,y,fontbuf);
  231. x+=16;
  232. i+=2;
  233. }
  234. else if((text[i]>=0x20)&&(text[i]<=0x7e))
  235. {
  236. unsigned char fontbuf[16];
  237. fontaddr=(text[i]-0x20);
  238. fontaddr=(unsigned long)(fontaddr*16);
  239. fontaddr=(unsigned long)(fontaddr+0x3cf80);
  240. addrHigh=(fontaddr&0xff0000)>>16;
  241. addrMid=(fontaddr&0xff00)>>8;
  242. addrLow=fontaddr&0xff;
  243. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,16);
  244. OLED_Display_8x16(x,y,fontbuf);
  245. x+=8;
  246. i+=1;
  247. }
  248. else
  249. i++;
  250. }
  251. }
  252. void OLED_Display_string_5x7(u8 x,u8 y,u8 *text)
  253. {
  254. u8 i=0;
  255. u8 addrHigh,addrMid,addrLow;
  256. while(text[i]>0x00)
  257. {
  258. if((text[i]>=0x20)&&(text[i]<=0x7e))
  259. {
  260. u8 fontbuf[8];
  261. fontaddr=(text[i]-0x20);
  262. fontaddr=(unsigned long)(fontaddr*8);
  263. fontaddr=(unsigned long)(fontaddr+0x3bfc0);
  264. addrHigh=(fontaddr&0xff0000)>>16;
  265. addrMid=(fontaddr&0xff00)>>8;
  266. addrLow=fontaddr&0xff;
  267. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,8);
  268. OLED_Display_5x7(x,y,fontbuf);
  269. x+=6;
  270. i+=1;
  271. }
  272. else
  273. i++;
  274. }
  275. }
  276. //显示2个数字
  277. //x,y :起点坐标
  278. //num1:要显示的小数
  279. //len :数字的位数
  280. void OLED_ShowNum(u8 x,u8 y,float num1,u8 len)
  281. {
  282. u8 i;
  283. u32 t,num;
  284. x=x+len*8+8;//要显示的小数最低位的横坐标
  285. num=num1*100;//将小数左移两位并转化为整数
  286. OLED_Display_GB2312_string(x-24,y,".");//显示小数点
  287. for(i=0;i<len;i++)
  288. {
  289. t=num%10;//取个位数的数值
  290. num=num/10;//将整数右移一位
  291. x-=8;
  292. if(i==2){x-=8;}//当显示出来两个小数之后,空出小数点的位置
  293. switch(t)
  294. {
  295. case 0 :OLED_Display_GB2312_string(x,y,"0");break;
  296. case 1 :OLED_Display_GB2312_string(x,y,"1");break;
  297. case 2 :OLED_Display_GB2312_string(x,y,"2");break;
  298. case 3 :OLED_Display_GB2312_string(x,y,"3");break;
  299. case 4 :OLED_Display_GB2312_string(x,y,"4");break;
  300. case 5 :OLED_Display_GB2312_string(x,y,"5");break;
  301. case 6 :OLED_Display_GB2312_string(x,y,"6");break;
  302. case 7 :OLED_Display_GB2312_string(x,y,"7");break;
  303. case 8 :OLED_Display_GB2312_string(x,y,"8");break;
  304. case 9 :OLED_Display_GB2312_string(x,y,"9");break;
  305. }
  306. }
  307. }
  308. //OLED的初始化
  309. void OLED_Init(void)
  310. {
  311. GPIO_InitTypeDef GPIO_InitStructure;
  312. RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);//使能A端口时钟
  313. GPIO_InitStructure.GPIO_Pin = CLK_PIN;
  314. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  315. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  316. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  317. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  318. GPIO_Init(CLK_PORT, &GPIO_InitStructure);
  319. RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);
  320. GPIO_InitStructure.GPIO_Pin = MOSI_PIN;
  321. GPIO_Init(MOSI_PORT, &GPIO_InitStructure);
  322. RCC_AHB1PeriphClockCmd(DC_RCU,ENABLE);
  323. GPIO_InitStructure.GPIO_Pin = DC_PIN;
  324. GPIO_Init(DC_PORT, &GPIO_InitStructure);
  325. RCC_AHB1PeriphClockCmd(CS1_RCU,ENABLE);
  326. GPIO_InitStructure.GPIO_Pin = CS1_PIN;
  327. GPIO_Init(CS1_PORT, &GPIO_InitStructure);
  328. RCC_AHB1PeriphClockCmd(CS2_RCU,ENABLE);
  329. GPIO_InitStructure.GPIO_Pin = CS2_PIN;
  330. GPIO_Init(CS2_PORT, &GPIO_InitStructure);
  331. RCC_AHB1PeriphClockCmd(MISO_RCU,ENABLE);
  332. GPIO_InitStructure.GPIO_Pin = MISO_PIN;
  333. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
  334. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
  335. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  336. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  337. GPIO_Init(MISO_PORT, &GPIO_InitStructure); //初始化GPIOA
  338. GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
  339. OLED_SCL_Set();
  340. OLED_SDA_Set();
  341. OLED_DC_Set();
  342. OLED_CS_Set();
  343. OLED_ROM_CS_Set();
  344. delay_1ms(200);
  345. OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  346. OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  347. OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  348. OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
  349. OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  350. OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
  351. OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
  352. OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
  353. OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  354. OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  355. OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  356. OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
  357. OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  358. OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  359. OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  360. OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  361. OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  362. OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  363. OLED_WR_Byte(0x12,OLED_CMD);
  364. OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  365. OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  366. OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  367. OLED_WR_Byte(0x02,OLED_CMD);//
  368. OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  369. OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  370. OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  371. OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  372. OLED_Clear();
  373. OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
  374. }
  1. #include "main.h"
  2. #include "systick.h"
  3. #include <stdio.h>
  4. #include "Usart0.h"
  5. #include "oled.h"
  6. #include "bmp.h"
  7. void Usart0_recv(uint8_t* data, uint32_t len) {
  8. printf("recv: %s\r\n", data);
  9. }
  10. int main(void)
  11. {
  12. // 系统时钟初始化
  13. systick_config();
  14. Usart0_init();
  15. u8 t=0;
  16. OLED_Init(); //初始化OLED
  17. t=' ';
  18. OLED_ColorTurn(0);//0正常显示,1 反色显示
  19. OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  20. while(1)
  21. {
  22. //// t+=0.01;
  23. //// OLED_ShowNum(0,0,t,5);//显示小数
  24. OLED_Display_128x64(bmp1);
  25. delay_1ms(500);
  26. OLED_Display_GB2312_string(0,0,"12864,带中文字库"); /*在第1页,第1列,显示一串16x16点阵汉字或8x16的ASCII字*/
  27. OLED_Display_GB2312_string(0,2,"16X16简体汉字库,"); /*显示一串16x16点阵汉字或8x16的ASCII字.以下雷同*/
  28. OLED_Display_GB2312_string(0,4,"或8X16点阵ASCII,");
  29. OLED_Display_GB2312_string(0,6,"或5X7点阵ASCII码");
  30. delay_1ms(500);
  31. OLED_Clear();
  32. OLED_Display_GB2312_string(24,0,"中景园电子");
  33. OLED_Display_GB2312_string(0,2,"主要生产OLED模块");
  34. OLED_Display_GB2312_string(0,4,"顾客至上真诚服务");
  35. OLED_Display_GB2312_string(0,6,"诚信与质量第一!");
  36. delay_1ms(500);
  37. OLED_Clear();
  38. OLED_Display_GB2312_string(0,0,"GB2312简体字库及");
  39. OLED_Display_GB2312_string(0,2,"有图型功能,可自");
  40. OLED_Display_GB2312_string(0,4,"编大字或图像或生");
  41. OLED_Display_GB2312_string(0,6,"僻字,例如:");
  42. OLED_Display_16x16(97,6,jiong1); /*在第7页,第81列显示单个自编生僻汉字“囧”*/
  43. OLED_Display_16x16(113,6,lei1);
  44. delay_1ms(500);
  45. OLED_Clear();
  46. OLED_Display_GB2312_string(0,0,"<!@#$%^&*()_-+]/"); /*在第1页,第1列,显示一串16x16点阵汉字或8*16的ASCII字*/
  47. OLED_Display_string_5x7(0,2,"<!@#$%^&*()_-+]/;.,?[");/*在第3页,第1列,显示一串5x7点阵的ASCII字*/
  48. OLED_Display_string_5x7(0,3,"XY electronics Co., ");/*显示一串5x7点阵的ASCII字*/
  49. OLED_Display_string_5x7(0,4,"Ltd. established at ");/*显示一串5x7点阵的ASCII字*/
  50. OLED_Display_string_5x7(0,5,"year 2010.Focus OLED ");/*显示一串5x7点阵的ASCII字*/
  51. OLED_Display_string_5x7(0,6,"Mobile:13265585975");/*显示一串5x7点阵的ASCII字*/
  52. OLED_Display_string_5x7(0,7,"Tel:0755-32910715");/*显示一串5x7点阵的ASCII字*/
  53. delay_1ms(500);
  54. OLED_Clear();
  55. OLED_Display_GB2312_string(0,0,"啊阿埃挨哎唉哀皑"); /*在第1页,第1列,显示一串16x16点阵汉字或8x16的ASCII字*/
  56. OLED_Display_GB2312_string(0,2,"癌蔼矮艾碍爱隘鞍"); /*显示一串16x16点阵汉字或8x16的ASCII字.以下雷同*/
  57. OLED_Display_GB2312_string(0,4,"氨安俺按暗岸胺案");
  58. OLED_Display_GB2312_string(0,6,"肮昂盎凹敖熬翱袄");
  59. delay_1ms(500);
  60. OLED_Clear();
  61. OLED_Display_GB2312_string(0,0,"鬟鬣麽麾縻麂麇麈");
  62. OLED_Display_GB2312_string(0,2,"麋麒鏖麝麟黛黜黝");
  63. OLED_Display_GB2312_string(0,4,"黠黟黢黩黧黥黪黯");
  64. OLED_Display_GB2312_string(0,6,"齄鼬鼹鼷鼽鼾鼢鼯");
  65. delay_1ms(500);
  66. OLED_Clear();
  67. }
  68. }

GD32环境

移植操作

只需要将API进行切换即可

  1. 换头
  2. 换外设的api

    完整代码

    ```c

    ifndef __OLED_H

    define __OLED_H

include “gd32f4xx.h”

include “systick.h”

include

ifndef u8

define u8 uint8_t

endif

ifndef u16

define u16 uint16_t

endif

ifndef u32

define u32 uint32_t

endif

//————————-OLED端口定义————————

define CLK_RCU RCU_GPIOB

define CLK_PORT GPIOB

define CLK_PIN GPIO_PIN_3

define MOSI_RCU RCU_GPIOB

define MOSI_PORT GPIOB

define MOSI_PIN GPIO_PIN_5

define DC_RCU RCU_GPIOB

define DC_PORT GPIOB

define DC_PIN GPIO_PIN_8

define CS1_RCU RCU_GPIOA

define CS1_PORT GPIOA

define CS1_PIN GPIO_PIN_15

define MISO_RCU RCU_GPIOB

define MISO_PORT GPIOB

define MISO_PIN GPIO_PIN_4

define CS2_RCU RCU_GPIOA

define CS2_PORT GPIOA

define CS2_PIN GPIO_PIN_4

// clk

define OLED_SCL_Clr() gpio_bit_write(CLK_PORT, CLK_PIN, 0)

define OLED_SCL_Set() gpio_bit_write(CLK_PORT, CLK_PIN, 1)

// mosi

define OLED_SDA_Clr() gpio_bit_write(MOSI_PORT, MOSI_PIN, 0)

define OLED_SDA_Set() gpio_bit_write(MOSI_PORT, MOSI_PIN, 1)

// dc

define OLED_DC_Clr() gpio_bit_write(DC_PORT, DC_PIN, 0)

define OLED_DC_Set() gpio_bit_write(DC_PORT, DC_PIN, 1)

// CS1

define OLED_CS_Clr() gpio_bit_write(CS1_PORT, CS1_PIN, 0)

define OLED_CS_Set() gpio_bit_write(CS1_PORT, CS1_PIN, 1)

// miso

define OLED_READ_FS0() gpio_input_bit_get(MISO_PORT, MISO_PIN)

// cs2

define OLED_ROM_CS_Clr() gpio_bit_write(CS2_PORT, CS2_PIN, 0)

define OLED_ROM_CS_Set() gpio_bit_write(CS2_PORT, CS2_PIN, 1)

define OLED_CMD 0 //写命令

define OLED_DATA 1 //写数据

void OLED_ColorTurn(u8 i); void OLED_DisplayTurn(u8 i); void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Clear(void); void OLED_address(u8 x,u8 y); void OLED_Display_128x64(u8 dp); void OLED_Display_16x16(u8 x,u8 y,u8 dp); void OLED_Display_8x16(u8 x,u8 y,u8 dp); void OLED_Display_5x7(u8 x,u8 y,u8 dp); void Send_Command_to_ROM(u8 dat); u8 Get_data_from_ROM(void); void OLED_get_data_from_ROM(u8 addrHigh,u8 addrMid,u8 addrLow,u8 pbuff,u8 DataLen); void OLED_Display_GB2312_string(u8 x,u8 y,u8 text); void OLED_Display_string_5x7(u8 x,u8 y,u8 *text); void OLED_ShowNum(u8 x,u8 y,float num,u8 len); void OLED_Init(void);

endif

  1. ```c
  2. #include "oled.h"
  3. #include "stdlib.h"
  4. //反显函数
  5. void OLED_ColorTurn(u8 i)
  6. {
  7. if(i==0)
  8. {
  9. OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
  10. }
  11. if(i==1)
  12. {
  13. OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
  14. }
  15. }
  16. //屏幕旋转180度
  17. void OLED_DisplayTurn(u8 i)
  18. {
  19. if(i==0)
  20. {
  21. OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
  22. OLED_WR_Byte(0xA1,OLED_CMD);
  23. }
  24. if(i==1)
  25. {
  26. OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
  27. OLED_WR_Byte(0xA0,OLED_CMD);
  28. }
  29. }
  30. //开启OLED显示
  31. void OLED_DisPlay_On(void)
  32. {
  33. OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  34. OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
  35. OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
  36. }
  37. //关闭OLED显示
  38. void OLED_DisPlay_Off(void)
  39. {
  40. OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  41. OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
  42. OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
  43. }
  44. //向SSD1306写入一个字节。
  45. //mode:数据/命令标志 0,表示命令;1,表示数据;
  46. void OLED_WR_Byte(u8 dat,u8 cmd)
  47. {
  48. u8 i;
  49. if(cmd)
  50. OLED_DC_Set();
  51. else
  52. OLED_DC_Clr();
  53. OLED_CS_Clr();
  54. for(i=0;i<8;i++)
  55. {
  56. OLED_SCL_Clr();
  57. if(dat&0x80)
  58. OLED_SDA_Set();
  59. else
  60. OLED_SDA_Clr();
  61. OLED_SCL_Set();
  62. dat<<=1;
  63. }
  64. OLED_CS_Set();
  65. OLED_DC_Set();
  66. }
  67. //清屏函数
  68. void OLED_Clear(void)
  69. {
  70. u8 i,n;
  71. for(i=0;i<8;i++)
  72. {
  73. OLED_WR_Byte(0xb0+i,OLED_CMD);//设置页地址
  74. OLED_WR_Byte(0x10,OLED_CMD); //设置列地址的高4位
  75. OLED_WR_Byte(0x00,OLED_CMD); //设置列地址的低4位
  76. for(n=0;n<128;n++)
  77. {
  78. OLED_WR_Byte(0x00,OLED_DATA);//清除所有数据
  79. }
  80. }
  81. }
  82. //设置起始地址
  83. void OLED_address(u8 x,u8 y)
  84. {
  85. OLED_WR_Byte(0xb0+y,OLED_CMD); //设置页地址
  86. OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); //设置列地址的高4位
  87. OLED_WR_Byte((x&0x0f),OLED_CMD); //设置列地址的低4位
  88. }
  89. //显示128x64点阵图像
  90. void OLED_Display_128x64(u8 *dp)
  91. {
  92. u8 i,j;
  93. for(i=0;i<8;i++)
  94. {
  95. OLED_address(0,i);
  96. for(j=0;j<128;j++)
  97. {
  98. OLED_WR_Byte(*dp,OLED_DATA); //写数据到OLED,每写完一个8位的数据后列地址自动加1
  99. dp++;
  100. }
  101. }
  102. }
  103. //显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标
  104. void OLED_Display_16x16(u8 x,u8 y,u8 *dp)
  105. {
  106. u8 i,j;
  107. for(j=0;j<2;j++)
  108. {
  109. OLED_address(x,y);
  110. for(i=0;i<16;i++)
  111. {
  112. OLED_WR_Byte(*dp,OLED_DATA); //写数据到OLED,每写完一个8位的数据后列地址自动加1
  113. dp++;
  114. }
  115. y++;
  116. }
  117. }
  118. //显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标
  119. void OLED_Display_8x16(u8 x,u8 y,u8 *dp)
  120. {
  121. u8 i,j;
  122. for(j=0;j<2;j++)
  123. {
  124. OLED_address(x,y);
  125. for(i=0;i<8;i++)
  126. {
  127. OLED_WR_Byte(*dp,OLED_DATA); //写数据到LCD,每写完一个8位的数据后列地址自动加1
  128. dp++;
  129. }
  130. y++;
  131. }
  132. }
  133. //显示5*7点阵图像、ASCII, 或5x7点阵的自造字符、其他图标
  134. void OLED_Display_5x7(u8 x,u8 y,u8 *dp)
  135. {
  136. u8 i;
  137. OLED_address(x,y);
  138. for(i=0;i<6;i++)
  139. {
  140. OLED_WR_Byte(*dp,OLED_DATA);
  141. dp++;
  142. }
  143. }
  144. //送指令到晶联讯字库IC
  145. void Send_Command_to_ROM(u8 dat)
  146. {
  147. u8 i;
  148. for(i=0;i<8;i++)
  149. {
  150. OLED_SCL_Clr();
  151. if(dat&0x80)
  152. {
  153. OLED_SDA_Set();
  154. }
  155. else
  156. {
  157. OLED_SDA_Clr();
  158. }
  159. dat<<=1;
  160. OLED_SCL_Set();
  161. }
  162. }
  163. //从晶联讯字库IC中取汉字或字符数据(1个字节)
  164. u8 Get_data_from_ROM(void)
  165. {
  166. u8 i,read=0;
  167. for(i=0;i<8;i++)
  168. {
  169. OLED_SCL_Clr();
  170. read<<=1;
  171. if(OLED_READ_FS0())
  172. {
  173. read++;
  174. }
  175. OLED_SCL_Set();
  176. }
  177. return read;
  178. }
  179. //从相关地址(addrHigh:地址高字节,addrMid:地址中字节,addrLow:地址低字节)中连续读出DataLen个字节的数据到 pbuff的地址
  180. //连续读取
  181. void OLED_get_data_from_ROM(u8 addrHigh,u8 addrMid,u8 addrLow,u8 *pbuff,u8 DataLen)
  182. {
  183. u8 i;
  184. OLED_ROM_CS_Clr();
  185. Send_Command_to_ROM(0x03);
  186. Send_Command_to_ROM(addrHigh);
  187. Send_Command_to_ROM(addrMid);
  188. Send_Command_to_ROM(addrLow);
  189. for(i=0;i<DataLen;i++)
  190. {
  191. *(pbuff+i)=Get_data_from_ROM();
  192. }
  193. OLED_ROM_CS_Set();
  194. }
  195. u32 fontaddr=0;
  196. void OLED_Display_GB2312_string(u8 x,u8 y,u8 *text)
  197. {
  198. u8 i=0;
  199. u8 addrHigh,addrMid,addrLow;
  200. u8 fontbuf[32];
  201. while(text[i]>0x00)
  202. {
  203. if((text[i]>=0xb0)&&(text[i]<=0xf7)&&(text[i+1]>=0xa1))
  204. {
  205. //国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算:
  206. //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
  207. //由于担心8位单片机有乘法溢出问题,所以分三部取地址
  208. fontaddr=(text[i]-0xb0)*94;
  209. fontaddr+=(text[i+1]-0xa1)+846;
  210. fontaddr=fontaddr*32;
  211. addrHigh=(fontaddr&0xff0000)>>16; //地址的高8位,共24位
  212. addrMid=(fontaddr&0xff00)>>8; //地址的中8位,共24位
  213. addrLow=(fontaddr&0xff); //地址的低8位,共24位
  214. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);
  215. //取32个字节的数据,存到"fontbuf[32]"
  216. OLED_Display_16x16(x,y,fontbuf);
  217. //显示汉字到LCD上,y为页地址,x为列地址,fontbuf[]为数据
  218. x+=16;
  219. i+=2;
  220. }
  221. else if((text[i]>=0xa1)&&(text[i]<=0xa3)&&(text[i+1]>=0xa1))
  222. {
  223. fontaddr=(text[i]-0xa1)*94;
  224. fontaddr+=(text[i+1]-0xa1);
  225. fontaddr=fontaddr*32;
  226. addrHigh=(fontaddr&0xff0000)>>16;
  227. addrMid=(fontaddr&0xff00)>>8;
  228. addrLow=(fontaddr&0xff);
  229. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);
  230. OLED_Display_16x16(x,y,fontbuf);
  231. x+=16;
  232. i+=2;
  233. }
  234. else if((text[i]>=0x20)&&(text[i]<=0x7e))
  235. {
  236. unsigned char fontbuf[16];
  237. fontaddr=(text[i]-0x20);
  238. fontaddr=(unsigned long)(fontaddr*16);
  239. fontaddr=(unsigned long)(fontaddr+0x3cf80);
  240. addrHigh=(fontaddr&0xff0000)>>16;
  241. addrMid=(fontaddr&0xff00)>>8;
  242. addrLow=fontaddr&0xff;
  243. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,16);
  244. OLED_Display_8x16(x,y,fontbuf);
  245. x+=8;
  246. i+=1;
  247. }
  248. else
  249. i++;
  250. }
  251. }
  252. void OLED_Display_string_5x7(u8 x,u8 y,u8 *text)
  253. {
  254. u8 i=0;
  255. u8 addrHigh,addrMid,addrLow;
  256. while(text[i]>0x00)
  257. {
  258. if((text[i]>=0x20)&&(text[i]<=0x7e))
  259. {
  260. u8 fontbuf[8];
  261. fontaddr=(text[i]-0x20);
  262. fontaddr=(unsigned long)(fontaddr*8);
  263. fontaddr=(unsigned long)(fontaddr+0x3bfc0);
  264. addrHigh=(fontaddr&0xff0000)>>16;
  265. addrMid=(fontaddr&0xff00)>>8;
  266. addrLow=fontaddr&0xff;
  267. OLED_get_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,8);
  268. OLED_Display_5x7(x,y,fontbuf);
  269. x+=6;
  270. i+=1;
  271. }
  272. else
  273. i++;
  274. }
  275. }
  276. //显示2个数字
  277. //x,y :起点坐标
  278. //num1:要显示的小数
  279. //len :数字的位数
  280. void OLED_ShowNum(u8 x,u8 y,float num1,u8 len)
  281. {
  282. u8 i;
  283. u32 t,num;
  284. x=x+len*8+8;//要显示的小数最低位的横坐标
  285. num=num1*100;//将小数左移两位并转化为整数
  286. OLED_Display_GB2312_string(x-24,y,".");//显示小数点
  287. for(i=0;i<len;i++)
  288. {
  289. t=num%10;//取个位数的数值
  290. num=num/10;//将整数右移一位
  291. x-=8;
  292. if(i==2){x-=8;}//当显示出来两个小数之后,空出小数点的位置
  293. switch(t)
  294. {
  295. case 0 :OLED_Display_GB2312_string(x,y,"0");break;
  296. case 1 :OLED_Display_GB2312_string(x,y,"1");break;
  297. case 2 :OLED_Display_GB2312_string(x,y,"2");break;
  298. case 3 :OLED_Display_GB2312_string(x,y,"3");break;
  299. case 4 :OLED_Display_GB2312_string(x,y,"4");break;
  300. case 5 :OLED_Display_GB2312_string(x,y,"5");break;
  301. case 6 :OLED_Display_GB2312_string(x,y,"6");break;
  302. case 7 :OLED_Display_GB2312_string(x,y,"7");break;
  303. case 8 :OLED_Display_GB2312_string(x,y,"8");break;
  304. case 9 :OLED_Display_GB2312_string(x,y,"9");break;
  305. }
  306. }
  307. }
  308. //OLED的初始化
  309. void OLED_Init(void)
  310. {
  311. rcu_periph_clock_enable(CLK_RCU);
  312. gpio_mode_set(CLK_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CLK_PIN);
  313. gpio_output_options_set(CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CLK_PIN);
  314. rcu_periph_clock_enable(MOSI_RCU);
  315. gpio_mode_set(MOSI_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MOSI_PIN);
  316. gpio_output_options_set(MOSI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MOSI_PIN);
  317. rcu_periph_clock_enable(DC_RCU);
  318. gpio_mode_set(DC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DC_PIN);
  319. gpio_output_options_set(DC_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, DC_PIN);
  320. rcu_periph_clock_enable(CS1_RCU);
  321. gpio_mode_set(CS1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CS1_PIN);
  322. gpio_output_options_set(CS1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CS1_PIN);
  323. rcu_periph_clock_enable(MISO_RCU);
  324. gpio_mode_set(MISO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, MISO_PIN);
  325. //gpio_output_options_set(MISO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MISO_PIN);
  326. rcu_periph_clock_enable(CS2_RCU);
  327. gpio_mode_set(CS2_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CS2_PIN);
  328. gpio_output_options_set(CS2_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CS2_PIN);
  329. delay_1ms(200);
  330. OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  331. OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  332. OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  333. OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
  334. OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  335. OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
  336. OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
  337. OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
  338. OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  339. OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  340. OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  341. OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
  342. OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  343. OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  344. OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  345. OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  346. OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  347. OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  348. OLED_WR_Byte(0x12,OLED_CMD);
  349. OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  350. OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  351. OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  352. OLED_WR_Byte(0x02,OLED_CMD);//
  353. OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  354. OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  355. OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  356. OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  357. OLED_Clear();
  358. OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
  359. }
  1. #include "gd32f4xx.h"
  2. #include "systick.h"
  3. #include <stdio.h>
  4. #include "main.h"
  5. #include "oled.h"
  6. #include "bmp.h"
  7. #include "Usart.h"
  8. void Usart0_recv(uint8_t *data, uint32_t len) {
  9. }
  10. int main(void)
  11. {
  12. systick_config();
  13. Usart0_init();
  14. OLED_Init(); //初始化OLED
  15. OLED_ColorTurn(0);//0正常显示,1 反色显示
  16. OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  17. while(1)
  18. {
  19. OLED_Display_128x64(bmp1);
  20. delay_1ms(500);
  21. OLED_Display_GB2312_string(0,0,"12864,带中文字库"); /*在第1页,第1列,显示一串16x16点阵汉字或8x16的ASCII字*/
  22. OLED_Display_GB2312_string(0,2,"16X16简体汉字库,"); /*显示一串16x16点阵汉字或8x16的ASCII字.以下雷同*/
  23. OLED_Display_GB2312_string(0,4,"或8X16点阵ASCII,");
  24. OLED_Display_GB2312_string(0,6,"或5X7点阵ASCII码");
  25. delay_1ms(500);
  26. OLED_Clear();
  27. OLED_Display_GB2312_string(24,0,"中景园电子");
  28. OLED_Display_GB2312_string(0,2,"主要生产OLED模块");
  29. OLED_Display_GB2312_string(0,4,"顾客至上真诚服务");
  30. OLED_Display_GB2312_string(0,6,"诚信与质量第一!");
  31. delay_1ms(500);
  32. OLED_Clear();
  33. OLED_Display_GB2312_string(0,0,"GB2312简体字库及");
  34. OLED_Display_GB2312_string(0,2,"有图型功能,可自");
  35. OLED_Display_GB2312_string(0,4,"编大字或图像或生");
  36. OLED_Display_GB2312_string(0,6,"僻字,例如:");
  37. OLED_Display_16x16(97,6,jiong1); /*在第7页,第81列显示单个自编生僻汉字“囧”*/
  38. OLED_Display_16x16(113,6,lei1);
  39. delay_1ms(500);
  40. OLED_Clear();
  41. OLED_Display_GB2312_string(0,0,"<!@#$%^&*()_-+]/"); /*在第1页,第1列,显示一串16x16点阵汉字或8*16的ASCII字*/
  42. OLED_Display_string_5x7(0,2,"<!@#$%^&*()_-+]/;.,?[");/*在第3页,第1列,显示一串5x7点阵的ASCII字*/
  43. OLED_Display_string_5x7(0,3,"XY electronics Co., ");/*显示一串5x7点阵的ASCII字*/
  44. OLED_Display_string_5x7(0,4,"Ltd. established at ");/*显示一串5x7点阵的ASCII字*/
  45. OLED_Display_string_5x7(0,5,"year 2010.Focus OLED ");/*显示一串5x7点阵的ASCII字*/
  46. OLED_Display_string_5x7(0,6,"Mobile:13265585975");/*显示一串5x7点阵的ASCII字*/
  47. OLED_Display_string_5x7(0,7,"Tel:0755-32910715");/*显示一串5x7点阵的ASCII字*/
  48. delay_1ms(500);
  49. OLED_Clear();
  50. OLED_Display_GB2312_string(0,0,"啊阿埃挨哎唉哀皑"); /*在第1页,第1列,显示一串16x16点阵汉字或8x16的ASCII字*/
  51. OLED_Display_GB2312_string(0,2,"癌蔼矮艾碍爱隘鞍"); /*显示一串16x16点阵汉字或8x16的ASCII字.以下雷同*/
  52. OLED_Display_GB2312_string(0,4,"氨安俺按暗岸胺案");
  53. OLED_Display_GB2312_string(0,6,"肮昂盎凹敖熬翱袄");
  54. delay_1ms(500);
  55. OLED_Clear();
  56. OLED_Display_GB2312_string(0,0,(uint8_t *)"鬟鬣麽麾縻麂麇麈");
  57. OLED_Display_GB2312_string(0,2,(uint8_t *)"麋麒鏖麝麟黛黜黝");
  58. OLED_Display_GB2312_string(0,4,(uint8_t *)"黠黟黢黩黧黥黪黯");
  59. OLED_Display_GB2312_string(0,6,(uint8_t *)"齄鼬鼹鼷鼽鼾鼢鼯");
  60. delay_1ms(500);
  61. OLED_Clear();
  62. }
  63. }

软件和硬件SPI

SPI是主设备和从设备通讯的协议和桥梁,spi通常管理时钟,输入,输出。设备的切换,交给具体的设备,也就是片选交给具体的设备。

完整代码

  1. #ifndef __SOFT_SPI0_H__
  2. #define __SOFT_SPI0_H__
  3. #include "gd32f4xx.h"
  4. #include "systick.h"
  5. /*************** pin config *****************/
  6. #define CLK_RCU RCU_GPIOB
  7. #define CLK_PORT GPIOB
  8. #define CLK_PIN GPIO_PIN_3
  9. #define MOSI_RCU RCU_GPIOB
  10. #define MOSI_PORT GPIOB
  11. #define MOSI_PIN GPIO_PIN_5
  12. #define MISO_RCU RCU_GPIOB
  13. #define MISO_PORT GPIOB
  14. #define MISO_PIN GPIO_PIN_4
  15. /************** spi config *******************/
  16. // clock polarity: hight(0) or low(1)
  17. #define SPI0_CPOL 0
  18. // clock phase: leading(0) or trailing(1)
  19. #define SPIO_CPHA 0
  20. /*************** gpio opt ********************/
  21. #define CLK(bit) gpio_bit_write(CLK_PORT, CLK_PIN, bit ? SET : RESET)
  22. #define MOSI(bit) gpio_bit_write(MOSI_PORT, MOSI_PIN, bit ? SET : RESET)
  23. #define MISO_STATE() gpio_input_bit_get(MISO_PORT, MISO_PIN)
  24. void SoftSPI0_init();
  25. void SoftSPI0_write_byte(uint8_t data);
  26. uint8_t SoftSPI0_read_byte();
  27. #endif
  1. #include "Soft_SPI0.h"
  2. void SoftSPI0_init() {
  3. /******************* GPIO **********************/
  4. // clk
  5. rcu_periph_clock_enable(CLK_RCU);
  6. gpio_mode_set(CLK_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CLK_PIN);
  7. gpio_output_options_set(CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CLK_PIN);
  8. // mosi
  9. rcu_periph_clock_enable(MOSI_RCU);
  10. gpio_mode_set(MOSI_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MOSI_PIN);
  11. gpio_output_options_set(MOSI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MOSI_PIN);
  12. // miso
  13. rcu_periph_clock_enable(MISO_RCU);
  14. gpio_mode_set(MISO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, MISO_PIN);
  15. /******************* io state ****************/
  16. #if SPI0_CPOL
  17. CLK(1);
  18. #else
  19. CLK(0);
  20. #endif
  21. }
  22. static void CLK_START() {
  23. #if SPI0_CPOL
  24. CLK(1);
  25. #else
  26. CLK(0);
  27. #endif
  28. }
  29. static void CLK_END() {
  30. #if SPI0_CPOL
  31. CLK(0);
  32. #else
  33. CLK(1);
  34. #endif
  35. }
  36. void SoftSPI0_write_byte(uint8_t data) {
  37. uint8_t i;
  38. for(i = 0; i < 8; i++)
  39. {
  40. CLK_START();
  41. if(data&0x80)
  42. MOSI(1);
  43. else
  44. MOSI(0);
  45. CLK_END();
  46. data <<= 1;
  47. }
  48. CLK_START();
  49. }
  50. uint8_t SoftSPI0_read_byte() {
  51. uint8_t i,read=0;
  52. for(i = 0; i < 8; i++)
  53. {
  54. CLK_START();
  55. read<<=1;
  56. if(MISO_STATE())
  57. {
  58. read++;
  59. }
  60. CLK_END();
  61. }
  62. return read;
  63. }
  1. #ifndef __SPI0_H__
  2. #define __SPI0_H__
  3. #include "gd32f4xx.h"
  4. #include "systick.h"
  5. /*************** pin config *****************/
  6. #define CLK_RCU RCU_GPIOB
  7. #define CLK_PORT GPIOB
  8. #define CLK_PIN GPIO_PIN_3
  9. #define CLK_AF GPIO_AF_5
  10. #define MOSI_RCU RCU_GPIOB
  11. #define MOSI_PORT GPIOB
  12. #define MOSI_PIN GPIO_PIN_5
  13. #define MOSI_AF GPIO_AF_5
  14. #define MISO_RCU RCU_GPIOB
  15. #define MISO_PORT GPIOB
  16. #define MISO_PIN GPIO_PIN_4
  17. #define MISO_AF GPIO_AF_5
  18. void SPI0_init();
  19. void SPI0_write_byte(uint8_t data);
  20. uint8_t SPI0_read_byte();
  21. #endif
  1. #include "SPI0.h"
  2. #include <stdio.h>
  3. void SPI0_init() {
  4. uint32_t spix = SPI0;
  5. uint32_t spix_rcu = RCU_SPI0;
  6. /************************** GPIO **********************/
  7. // sclk
  8. rcu_periph_clock_enable(CLK_RCU);
  9. gpio_mode_set(CLK_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, CLK_PIN);
  10. gpio_output_options_set(CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, CLK_PIN);
  11. gpio_af_set(CLK_PORT, CLK_AF, CLK_PIN);
  12. // mosi
  13. rcu_periph_clock_enable(MOSI_RCU);
  14. gpio_mode_set(MOSI_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MOSI_PIN);
  15. gpio_output_options_set(MOSI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MOSI_PIN);
  16. gpio_af_set(MOSI_PORT, MOSI_AF, MOSI_PIN);
  17. // miso
  18. rcu_periph_clock_enable(MISO_RCU);
  19. gpio_mode_set(MISO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MISO_PIN);
  20. gpio_output_options_set(MISO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, MISO_PIN);
  21. gpio_af_set(MISO_PORT, MISO_AF, MISO_PIN);
  22. gpio_bit_set(MISO_PORT, MISO_PIN);
  23. /************************** SPI **********************/
  24. rcu_periph_clock_enable(spix_rcu);
  25. spi_i2s_deinit(spix);
  26. spi_parameter_struct sps;
  27. spi_struct_para_init(&sps);
  28. sps.device_mode = SPI_MASTER; //设备模式
  29. sps.frame_size = SPI_FRAMESIZE_8BIT;
  30. sps.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
  31. sps.nss = SPI_NSS_SOFT;
  32. sps.prescale = SPI_PSC_32;
  33. sps.endian = SPI_ENDIAN_MSB;
  34. spi_init(spix, &sps);
  35. //spi_nss_internal_high(spix);
  36. spi_enable(spix);
  37. }
  38. void SPI0_write_byte(uint8_t data) {
  39. while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {};
  40. spi_i2s_data_transmit(SPI0, data);
  41. while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {};
  42. spi_i2s_data_receive(SPI0);
  43. }
  44. uint8_t SPI0_read_byte() {
  45. while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {};
  46. spi_i2s_data_transmit(SPI0, 0x00);
  47. while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {};
  48. return spi_i2s_data_receive(SPI0);
  49. }

忽略指定警告

要在Keil中配置忽略-Winvalid-source-encoding警告,您可以按照以下步骤进行操作:

  1. 打开Keil软件并打开您的项目。
  2. 在Keil的菜单栏中,选择 “Project” > “Options for Target”。
  3. 在弹出的对话框中,选择 “C/C++” 选项卡。
  4. 在 “Misc Controls” 部分的 “Other Compiler Options” 字段中添加以下内容:

    1. -Wno-invalid-source-encoding

    这将告诉编译器忽略-Winvalid-source-encoding警告。

  5. 单击 “OK” 保存更改并关闭对话框。

  6. 重新编译您的项目,编译器将不再显示-Winvalid-source-encoding警告。

请注意,这只是忽略该特定警告的方法。确保在忽略警告之前了解其含义,并确保您的代码没有潜在的问题。

练习题

  1. 实现stm32的spi屏幕移植
  2. 实现gd32的spi屏幕移植