找回密码
 立即注册
查看: 485|回复: 5

手焊STC15W408AS核心板及OLED动图播放

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:525
  • 最近打卡:2025-05-07 00:46:33
已绑定手机
已实名认证

46

主题

161

回帖

508

积分

高级会员

积分
508
发表于 2024-7-4 07:31:34 | 显示全部楼层 |阅读模式
手动焊接PCB并实现OLED动图播放,效果如下

细节

PCB1

PCB1

PCB2

PCB2

PCB3

PCB3

OLED 动图代码如下
  1. /*----------------------------------------------------------------*/
  2. #include "stc15.h"
  3. #include "oled.h"                //OLED引脚定义、控制函数
  4. #include "bmp.h"                //图片字模存放位置
  5. int main(void)
  6. {       
  7.         OLED_Init();                        //初始化OLED
  8.         OLED_ColorTurn(0);                //0正常显示,1 反色显示
  9.         OLED_DisplayTurn(0);        //0正常显示  1 屏幕翻转显示
  10.         while(1)
  11.         {               
  12.                 OLED_DrawBMP(0,0,128,64,BMP1);                 //图片显示
  13.                
  14.                 delay_ms(10);                                                  //延时
  15.                 //OLED_Clear();                                                  //清屏
  16.                
  17.                 OLED_DrawBMP(0,0,128,64,BMP2);
  18.                
  19.                 delay_ms(10);                                                  //延时
  20.                 //OLED_Clear();                                                  //清屏
  21.         }          
  22.        
  23. }
复制代码
oled.c文件代码如下
  1. #include "oled.h"
  2. #include "oledfont.h"           
  3. //OLED的显存
  4. //存放格式如下.
  5. //[0]0 1 2 3 ... 127       
  6. //[1]0 1 2 3 ... 127       
  7. //[2]0 1 2 3 ... 127       
  8. //[3]0 1 2 3 ... 127       
  9. //[4]0 1 2 3 ... 127       
  10. //[5]0 1 2 3 ... 127       
  11. //[6]0 1 2 3 ... 127       
  12. //[7]0 1 2 3 ... 127                           
  13. void delay_ms(unsigned int ms)//@24MHz
  14. {                        
  15.         unsigned char data i, j;
  16.         while(ms--)
  17.         {
  18.         i = 24;
  19.         j = 85;
  20.         do
  21.         {
  22.                 while (--j);
  23.         } while (--i);
  24.         }
  25.         return;
  26. }
  27. //反显函数
  28. void OLED_ColorTurn(u8 i)
  29. {
  30.         if(i==0)
  31.                 {
  32.                         OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
  33.                 }
  34.         if(i==1)
  35.                 {
  36.                         OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
  37.                 }
  38. }
  39. //屏幕旋转180度
  40. void OLED_DisplayTurn(u8 i)
  41. {
  42.         if(i==0)
  43.                 {
  44.                         OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
  45.                         OLED_WR_Byte(0xA1,OLED_CMD);
  46.                 }
  47.         if(i==1)
  48.                 {
  49.                         OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
  50.                         OLED_WR_Byte(0xA0,OLED_CMD);
  51.                 }
  52. }
  53. //延时
  54. void IIC_delay(void)
  55. {
  56.         u8 t=1;
  57.         while(t--);
  58. }
  59. //起始信号
  60. void I2C_Start(void)
  61. {
  62.         OLED_SDA_Set();
  63.         OLED_SCL_Set();
  64.         IIC_delay();
  65.         OLED_SDA_Clr();
  66.         IIC_delay();
  67.         OLED_SCL_Clr();
  68.          
  69. }
  70. //结束信号
  71. void I2C_Stop(void)
  72. {
  73.         OLED_SDA_Clr();
  74.         OLED_SCL_Set();
  75.         IIC_delay();
  76.         OLED_SDA_Set();
  77. }
  78. //等待信号响应
  79. void I2C_WaitAck(void) //测数据信号的电平
  80. {
  81.         OLED_SDA_Set();
  82.         IIC_delay();
  83.         OLED_SCL_Set();
  84.         IIC_delay();
  85.         OLED_SCL_Clr();
  86.         IIC_delay();
  87. }
  88. //写入一个字节
  89. void Send_Byte(u8 dat)
  90. {
  91.         u8 i;
  92.         for(i=0;i<8;i++)
  93.         {
  94.                 OLED_SCL_Clr();//将时钟信号设置为低电平
  95.                 if(dat&0x80)//将dat的8位从最高位依次写入
  96.                 {
  97.                         OLED_SDA_Set();
  98.     }
  99.                 else
  100.                 {
  101.                         OLED_SDA_Clr();
  102.     }
  103.                 IIC_delay();
  104.                 OLED_SCL_Set();
  105.                 IIC_delay();
  106.                 OLED_SCL_Clr();
  107.                 dat<<=1;
  108.   }
  109. }
  110. //发送一个字节
  111. //向SSD1306写入一个字节。
  112. //mode:数据 /命令标志 0,表示命令;1,表示数据;
  113. void OLED_WR_Byte(u8 dat,u8 mode)
  114. {
  115.         I2C_Start();
  116.         Send_Byte(0x78);
  117.         I2C_WaitAck();
  118.         if(mode){Send_Byte(0x40);}
  119.   else{Send_Byte(0x00);}
  120.         I2C_WaitAck();
  121.         Send_Byte(dat);
  122.         I2C_WaitAck();
  123.         I2C_Stop();
  124. }
  125. //坐标设置
  126. void OLED_Set_Pos(u8 x, u8 y)
  127. {
  128.         OLED_WR_Byte(0xb0+y,OLED_CMD);
  129.         OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  130.         OLED_WR_Byte((x&0x0f),OLED_CMD);
  131. }
  132. //开启OLED显示   
  133. void OLED_Display_On(void)
  134. {
  135.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  136.         OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  137.         OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  138. }
  139. //关闭OLED显示     
  140. void OLED_Display_Off(void)
  141. {
  142.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  143.         OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
  144.         OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  145. }
  146. /**                                                                                                                                                       
  147.   * @brief   清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!               
  148.   * @retval   无
  149.   * @example    OLED_Clear();
  150. **/  
  151. void OLED_Clear(void)  
  152. {  
  153.         u8 i,n;                    
  154.         for(i=0;i<8;i++)  
  155.         {  
  156.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  157.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  158.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  159.                 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  160.         }   //更新显示
  161. }
  162. /**       
  163.   * @brief   显示一个字符,包括部分字符                                                               
  164.   * @param    x    起始行位置 范围:0~127                                                               
  165.   * @param    y    起始列位置 范围:0~7       
  166.   * @param   chr   要显示的单个字符,可显示字模库在 oledfont.h 文件
  167.   * @param   sizey 要显示字体的大小,字号:8或者16
  168.   * @retval   无
  169.   * @example     OLED_ShowChar(0,2,'A',16);
  170. **/
  171. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey)
  172. {             
  173.         u8 c=0,sizex=sizey/2;
  174.         u16 i=0,size1;
  175.         if(sizey==8)size1=6;
  176.         else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);
  177.         c=chr-' ';//得到偏移后的值
  178.         OLED_Set_Pos(x,y);
  179.         for(i=0;i<size1;i++)
  180.         {
  181.                 if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);
  182.                 if(sizey==8) OLED_WR_Byte(asc2_0806[c][i],OLED_DATA);//6X8字号
  183.                 else if(sizey==16) OLED_WR_Byte(asc2_1608[c][i],OLED_DATA);//8x16字号
  184. //                else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号
  185.                 else return;
  186.         }
  187. }
  188. /**                                                                                                                                                       
  189.   * @brief  求m的n次幂       
  190. **/
  191. u32 oled_pow(u8 m,u8 n)
  192. {
  193.         u32 result=1;         
  194.         while(n--)result*=m;   
  195.         return result;
  196. }       
  197. /**                                                                                                                                                        ————————— 行(0~127)
  198.   * @brief   OLED显示数字                                                                                                        -
  199.   * @param    x    起始行位置 范围:0~127                                                                        -
  200.   * @param    y    起始列位置 范围:0~7                                                                                -
  201.   * @param   num   要显示的数字,范围:0~65535;                                                                  -(从上到下是列(0~63))
  202.                        同列显示超出5位需要更改行位置(否则显示数字会乱)。                
  203.                        如8号字体:OLED_ShowNum(0,0,65535,5,8); OLED_ShowNum(30,0,12345,5,8);可以一列同时显示 6553512345
  204.   * @param   len   要显示数字的长度,范围:1~5
  205.   * @param   sizey 要显示数字的大小,字号:8或者16
  206.   * @retval   无
  207.   * @example    OLED_ShowNum(0,0,12345,5,16);
  208. **/
  209. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey)
  210. {                
  211.         u8 t,temp,m=0;
  212.         u8 enshow=0;
  213.         if(sizey==8)m=2;
  214.         for(t=0;t<len;t++)
  215.         {
  216.                 temp=(num/oled_pow(10,len-t-1))%10;
  217.                 if(enshow==0&&t<(len-1))
  218.                 {
  219.                         if(temp==0)
  220.                         {
  221.                                 OLED_ShowChar(x+(sizey/2+m)*t,y,' ',sizey);
  222.                                 continue;
  223.                         }else enshow=1;
  224.                 }
  225.                  OLED_ShowChar(x+(sizey/2+m)*t,y,temp+'0',sizey);
  226.         }
  227. }
  228. /**       
  229.   * @brief   显示一个字符串                                                               
  230.   * @param    x    起始行位置 范围:0~127                                                               
  231.   * @param    y    起始列位置 范围:0~7       
  232.   * @param   *chr  要显示的字符串,可显示字模库在 oledfont.h 文件
  233.   * @param   sizey 要显示字体的大小,字号:8或者16
  234.   * @example     OLED_ShowString(0,4,"ABB:",16);
  235. **/
  236. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey)
  237. {
  238.         u8 j=0;
  239.         while (chr[j]!='\0')
  240.         {               
  241.                 OLED_ShowChar(x,y,chr[j++],sizey);
  242.                 if(sizey==8)x+=6;
  243.                 else x+=sizey/2;
  244.         }
  245. }
  246. /**       
  247.   * @brief   显示汉字                                                               
  248.   * @param    x    起始行位置 范围:0~127                                                               
  249.   * @param    y    起始列位置 范围:0~7       
  250.   * @param    no   要显示的汉字排序号,0就是第一个,1就是第二个,以此类推...字模库在 oledfont.h 文件
  251.   * @param   sizey 要显示字体的大小,字号:8或者16
  252.   * @example     OLED_ShowChinese(18,0,1,16);
  253. **/
  254. void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey)
  255. {
  256.         u16 i,size1=(sizey/8+((sizey%8)?1:0))*sizey;
  257.         for(i=0;i<size1;i++)
  258.         {
  259.                 if(i%sizey==0) OLED_Set_Pos(x,y++);
  260.                 if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号
  261. //                else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号
  262.                 else return;
  263.         }                               
  264. }
  265. /**       
  266.   * @brief   显示图片                                                               
  267.   * @param    x     起始行位置 范围:0~127                                                               
  268.   * @param    y     起始列位置 范围:0~7       
  269.   * @param   sizex  图片的长
  270.   * @param   sizey  图片的宽
  271.   * @param   BMP[]  要显示的图片BMP1、BMP2、BMP3... 图片字模存放在 bmp.h 文件
  272.   * @example     OLED_DrawBMP(30,0,69,64,BMP1);
  273. **/
  274. void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[])
  275. {        
  276.   u16 j=0;
  277.         u8 i,m;
  278.         sizey=sizey/8+((sizey%8)?1:0);
  279.         for(i=0;i<sizey;i++)
  280.         {
  281.                 OLED_Set_Pos(x,i+y);
  282.     for(m=0;m<sizex;m++)
  283.                 {      
  284.                         OLED_WR_Byte(BMP[j++],OLED_DATA);                   
  285.                 }
  286.         }
  287. }
  288. /************************OLED初始化***********************/                                    
  289. void OLED_Init(void)
  290. {
  291. //        OLED_RES_Clr();          //SPI接口显示屏改成IIC接口使用
  292. //        delay_ms(200);
  293. //        OLED_RES_Set();
  294.        
  295.         OLED_WR_Byte(0xAE,OLED_CMD);        //--关闭oled面板
  296.         OLED_WR_Byte(0x00,OLED_CMD);        //--设置低列地址
  297.         OLED_WR_Byte(0x10,OLED_CMD);        //--设置高列地址
  298.         OLED_WR_Byte(0x40,OLED_CMD);        //--设置起始行地址  设置映射RAM显示起始行 (0x00~0x3F)
  299.         OLED_WR_Byte(0x81,OLED_CMD);        //--设置对比度控制寄存器
  300.         OLED_WR_Byte(0xCF,OLED_CMD);        //--设置SEG输出电流亮度
  301.         OLED_WR_Byte(0xA1,OLED_CMD);        //--Set SEG/Column Mapping       0xa0左右反置 0xa1正常
  302.         OLED_WR_Byte(0xC8,OLED_CMD);        //--Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  303.         OLED_WR_Byte(0xA6,OLED_CMD);        //--设置正常显示
  304.         OLED_WR_Byte(0xA8,OLED_CMD);        //--设置多路复用率(1 to 64)
  305.         OLED_WR_Byte(0x3f,OLED_CMD);        //--1/64 duty
  306.         OLED_WR_Byte(0xD3,OLED_CMD);        //--设置显示offset,移位映射RAM计数器 (0x00~0x3F)
  307.         OLED_WR_Byte(0x00,OLED_CMD);        //--not offset
  308.         OLED_WR_Byte(0xd5,OLED_CMD);        //--设置显示时钟分率/振荡频率
  309.         OLED_WR_Byte(0x80,OLED_CMD);        //--设置分率, 设置时钟为100帧/秒
  310.         OLED_WR_Byte(0xD9,OLED_CMD);        //--set pre-charge period
  311.         OLED_WR_Byte(0xF1,OLED_CMD);        //--Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  312.         OLED_WR_Byte(0xDA,OLED_CMD);        //--设置com引脚硬件配置
  313.         OLED_WR_Byte(0x12,OLED_CMD);
  314.         OLED_WR_Byte(0xDB,OLED_CMD);        //--set vcomh
  315.         OLED_WR_Byte(0x40,OLED_CMD);        //Set VCOM Deselect Level
  316.         OLED_WR_Byte(0x20,OLED_CMD);        //-设置页面寻址方式 (0x00/0x01/0x02)
  317.         OLED_WR_Byte(0x02,OLED_CMD);
  318.         OLED_WR_Byte(0x8D,OLED_CMD);        //--设置电荷泵使能/disable
  319.         OLED_WR_Byte(0x14,OLED_CMD);        //--set(0x10) disable
  320.         OLED_WR_Byte(0xA4,OLED_CMD);        // 禁用全部显示 (0xa4/0xa5)
  321.         OLED_WR_Byte(0xA6,OLED_CMD);        // 禁用反转显示 (0xa6/a7)
  322.         OLED_Clear();                       //OLED清屏     
  323.         OLED_WR_Byte(0xAF,OLED_CMD);         /*显示打开*/
  324. }
复制代码


代码详见附件

PCB文件参考:https://oshwhub.com/wang0/stc15w408-kai-fa-ban_copy_copy


1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
MCU开发者和爱好者
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:60
  • 最近打卡:2025-05-07 11:01:36

718

主题

1万

回帖

1万

积分

管理员

积分
15682
发表于 2024-7-4 07:57:52 | 显示全部楼层
学习,可以考虑改成
STC8H8K64U-45I-SOP16/TSSOP20

STC8H8K64U-45I-LQFP32/LQFP44/LQFP48/LQFP64
STC8H8K64U-45I-SKDIP28/PDIP40

这样资料多
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)

截图202407040756592155.jpg

截图202407040757502635.jpg

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:525
  • 最近打卡:2025-05-07 00:46:33
已绑定手机
已实名认证

46

主题

161

回帖

508

积分

高级会员

积分
508
发表于 2024-7-4 08:08:11 | 显示全部楼层
神*** 发表于 2024-7-4 07:57
学习,可以考虑改成
STC8H8K64U-45I-SOP16/TSSOP20
STC8H8K64U-45I-LQFP32/LQFP44/LQFP48/LQFP64

STC8H8K64U-TSSOP20的引脚与STC15W408AS-TSSOP20定义相同吗?能不能直接替换?
这个PCB板我还有4个没焊接贴片元件,考虑直接换成STC8H8K64U那个,不知道能不能行,要不还得重新设计PCB,重新打板
MCU开发者和爱好者
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:60
  • 最近打卡:2025-05-07 11:01:36

718

主题

1万

回帖

1万

积分

管理员

积分
15682
发表于 2024-7-4 08:12:24 | 显示全部楼层
你看下管脚图
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:525
  • 最近打卡:2025-05-07 00:46:33
已绑定手机
已实名认证

46

主题

161

回帖

508

积分

高级会员

积分
508
发表于 2024-7-4 09:12:12 | 显示全部楼层


STC15W408AS-TSSOP20管脚定义图如下

STC15W408AS

STC15W408AS

STC8H8K64U-TSSOP20管脚定义图如下

STC8H8K64U

STC8H8K64U



好像可以直接替换……
附PCB原理图

SCH_PCB

SCH_PCB


MCU开发者和爱好者
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:516
  • 最近打卡:2025-05-06 19:36:57

21

主题

564

回帖

2690

积分

金牌会员

积分
2690
发表于 2024-7-4 14:41:42 | 显示全部楼层
老板不建议你用15W
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-7 12:03 , Processed in 0.145791 second(s), 90 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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