MCU:STM8S105K4最小系统
flash:W25Q128
OLED:SSD1306(SPI模式)
接线:
PA1:按钮
PC1:FLASH_/CS
PC2:OLED_DC
PC3:OLED_/CS
PC4:OLED_RES
PC5:OLED_D0,FLASH_CLK
PC6:OLED_D1,FLASH_DI
PC7:FLASH_DO
FLASH_/WP,FLASH_/HOLD接vcc
//
注意:IAR FOR STM8长整型位数不是32位,可能为16位
//
程序:
#include
#define u16 unsigned int
#define u8 unsigned char
#define FLASH_CS PC_ODR_ODR1 //flash片选脚
#define OLED_DC PC_ODR_ODR2 //OLED命令/数据选择
#define OLED_CS PC_ODR_ODR3 //OLED片选脚
#define OLED_RES PC_ODR_ODR4 //OLED复位脚
#define SCL PC_ODR_ODR5 //SPI总线时钟
#define MOSI PC_ODR_ODR6 //SPI_MCU数据输出
#define MISO PC_ODR_ODR7 //SPI_MCU数据输入
#define KEY PA_IDR_IDR1 //播放按钮
/*******************************************************************************/
void clk();
u8 wr(u8 all);
u8 WEL();
void W25Qxx_read(u16 add_1,u16 add_2);
void OLED_SPI_WR(u8 data_1,u8 DC_pin);
void OLED_init();
void display(u8 *poin_1);
void clean();
void delay_ms(u16 x);
void gpio_init();
void MCU_SPI_init(u8 HL);
u8 key();
/*******************************************************************************/
u8 tabe[1024]=
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xF8,0xE0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xF8,0x80,0x1F,0xFF,0xFF,0xEF,0xEF,0xE0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0xE1,0x07,
0x3F,0x3F,0x07,0x00,0xE0,0xFC,0xFF,0xFF,0xFF,0xDF,0xCF,0x80,0x80,0x8F,0x9F,0x9F,
0x8F,0x87,0xC0,0xE0,0xFF,0xFF,0xF0,0xC0,0xCF,0xBF,0xBF,0xBF,0x9F,0xC7,0xE0,0xF0,
0xFF,0xFF,0x00,0x00,0xCF,0xCF,0xCF,0xFF,0xFF,0x00,0x00,0xE7,0xDF,0x9F,0x9F,0x8F,
0xC0,0xE0,0xFF,0xFF,0xFC,0xE0,0xC0,0x9C,0xBC,0xBC,0x9C,0x80,0xC0,0xF1,0xEF,0xEF,
0xC0,0xC0,0xF3,0xEF,0xCF,0xC3,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xE0,0x02,0x3E,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x1E,0x02,0x80,0xF8,0xFE,0xFA,0xFB,0x03,0x03,0xFB,0xFF,0xFF,
0xFF,0xE3,0x03,0x03,0xFB,0xFF,0x0F,0x07,0xF3,0xFB,0xFB,0xFB,0xFB,0xE7,0x0F,0x1F,
0xFF,0xFF,0x03,0x03,0xF3,0xF3,0xF7,0xFF,0xFB,0x03,0x03,0xFB,0xFB,0xFF,0xFF,0xFF,
0x00,0x00,0xFF,0xFF,0x3F,0x0F,0x03,0xE3,0xF3,0xFB,0xFB,0xF3,0xF3,0xFF,0xFF,0xFF,
0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x3F,0x3F,0xBF,0xBF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
//tabe数组初始为开机界面,播放后存放flash读回数据
/*********************************************************************/
void main()
{
u16 icc;
u16 add_w1=0,add_w2=0;
clk(); //MCU主时钟调整为 HFI 2分频
gpio_init(); //MCU_GPIO初始化
MCU_SPI_init(1); //MCU_SPI初始化为上升沿有效
delay_ms(100);
OLED_init(); //OLED初始化
delay_ms(100);
display(tabe); //显示开机界面
while(1)
{
if(key()) //播放按钮
{
OLED_init(); //OLED初始化
clean(); //OLED清屏
for(icc=0;icc<5255;icc++)//循环5255次,每次读回一张图
{
add_w1=icc/64; //flash24位地址中高8位地址
add_w2=1024*icc; //flash24位地址中低16位地址
MCU_SPI_init(0); //MCU_SPI初始化为下降沿有效
W25Qxx_read(add_w1,add_w2);//发送flash读取数据地址
MCU_SPI_init(1); //MCU_SPI初始化上升沿有效
display(tabe); //将tabe数组发送给OLED
delay_ms(144); //延时降低播放速度
}
}
}
}
/*******************************************************************************/
void clk() //主时钟分频调整
{
CLK_CKDIVR=0x01;
}
/*******************************************************************************/
u8 wr(u8 all) //MCU_SPI单字节读写程序
{
//MCU_SPI_init(0);
while(!SPI_SR&0x02);
SPI_DR=all;
while(!SPI_SR&0x01);
return SPI_DR;
}
/*******************************************************************************/
u8 WEL() //flash忙碌判断
{
wr(0x05);
if(wr(0xff)&0x02)
return 0;
else
return 1;
}
/*******************************************************************************/
void W25Qxx_read(u16 add_1,u16 add_2)//flash地址读取程序
{
u16 i;
OLED_CS=1;
FLASH_CS=0;
MOSI=0;
MCU_SPI_init(1);
wr(0x03);
wr((add_1&0x00ff));
wr((add_2&0xff00)>>8);
wr(add_2&0x0000ff);
MCU_SPI_init(0);
for(i=0;i<1024;i++)
{
tabe[i]=wr(0xff);
//SCL=1;
// SCL=0;
}
FLASH_CS=1;
}
/*******************************************************************************/
void OLED_SPI_WR(u8 data_1,u8 DC_pin)//OLED写入命令/数据程序
{
if(DC_pin==0)
{OLED_DC=0;} //0写命令
else
{OLED_DC=1;} //1写数据
while(!(SPI_SR&0x02));
SPI_DR=data_1;
}
/*******************************************************************************/
void OLED_init() //OLED初始化程序
{
OLED_CS=0;FLASH_CS=1; //片选OLED
OLED_RES=1; //OLED上电复位
delay_ms(100);
OLED_RES=0;
delay_ms(100);
OLED_RES=1;
OLED_SPI_WR(0xAE,0); //关显示
OLED_SPI_WR(0X00,0); //页显示列起始地址
OLED_SPI_WR(0X10,0); //页显示列内位地址
OLED_SPI_WR(0X40,0); //页显示起始行地址
OLED_SPI_WR(0X81,0); //设置对比度寄存器
OLED_SPI_WR(0XCF,0); //设置对比度
OLED_SPI_WR(0XA1,0); //左右非镜像(0xa0:左右镜像)
OLED_SPI_WR(0XC0,0); //上下非镜像(0xc8:上下镜像)
OLED_SPI_WR(0XA7,0); //正常显示(0xa7:反白)0xa6
OLED_SPI_WR(0XA8,0); //多路复用
OLED_SPI_WR(0X3F,0); //设置多路复用参数
OLED_SPI_WR(0XD3,0); //上下偏移
OLED_SPI_WR(0X00,0); //设置上下偏移量
OLED_SPI_WR(0XD5,0); //时钟/振荡频率
OLED_SPI_WR(0x80,0); //设置时钟/振荡频率的参数
OLED_SPI_WR(0XD9,0); //预充电周期
OLED_SPI_WR(0XF1,0); //设置预充电周期参数
OLED_SPI_WR(0XDA,0); //设置列引脚硬件配置
OLED_SPI_WR(0X12,0); //
OLED_SPI_WR(0XDB,0); //调整VCOMH输出
OLED_SPI_WR(0X40,0); //
OLED_SPI_WR(0X20,0); //寻址模式
OLED_SPI_WR(0X02,0); //0x00:水平寻址,0x01:垂直寻址,0x02:页寻址,0x03:未定义
OLED_SPI_WR(0X8D,0); //电荷泵启停
OLED_SPI_WR(0X14,0); //0x14:电荷泵启用,0x10:电荷泵禁用
OLED_SPI_WR(0XA4,0); //ROM映射使能,0xa4:允许映射,0xa5:禁止映射(黑屏)
OLED_SPI_WR(0XAF,0); //开显示
}
/*******************************************************************************/
void display(u8 *poin) //显示程序
{
u8 i,j;
OLED_CS=0;FLASH_CS=1; //片选OLED
for(i=0;i<8;i++)
{
switch(i)
{
case 0:{OLED_SPI_WR(0XB7,0);}break;
case 1:{OLED_SPI_WR(0XB6,0);}break;
case 2:{OLED_SPI_WR(0XB5,0);}break;
case 3:{OLED_SPI_WR(0XB4,0);}break;
case 4:{OLED_SPI_WR(0XB3,0);}break;
case 5:{OLED_SPI_WR(0XB2,0);}break;
case 6:{OLED_SPI_WR(0XB1,0);}break;
case 7:{OLED_SPI_WR(0XB0,0);}break;
}
OLED_SPI_WR(0X00,0);OLED_SPI_WR(0X10,0);
for(j=0;j<128;j++)
{
OLED_SPI_WR(*poin,1);
poin++;
}
}
}
/*******************************************************************************/
void clean() //清屏程序
{
u8 i,j;
for(i=0;i<8;i++)
{
switch(i)
{
case 0:{OLED_SPI_WR(0XB7,0);}break;
case 1:{OLED_SPI_WR(0XB6,0);}break;
case 2:{OLED_SPI_WR(0XB5,0);}break;
case 3:{OLED_SPI_WR(0XB4,0);}break;
case 4:{OLED_SPI_WR(0XB3,0);}break;
case 5:{OLED_SPI_WR(0XB2,0);}break;
case 6:{OLED_SPI_WR(0XB1,0);}break;
case 7:{OLED_SPI_WR(0XB0,0);}break;
}
OLED_SPI_WR(0X00,0);OLED_SPI_WR(0X10,0);
for(j=0;j<128;j++)
{
OLED_SPI_WR(0x00,1);
}
}
}
/*******************************************************************************/
void delay_ms(u16 x) //毫秒延时程序
{
unsigned int a,b;
while(x--)
{
for (a=0;a<18;a++)
for(b=0;b<19;b++);
}
}
/*******************************************************************************/
void gpio_init() //GPIO初始化程序
{
PC_DDR_DDR1=1;PC_CR1_C11=1;PC_CR2_C21=1;FLASH_CS=0;
PC_DDR_DDR2=1;PC_CR1_C12=1;PC_CR2_C22=1;
PC_DDR_DDR3=1;PC_CR1_C13=1;PC_CR2_C23=1;
PC_DDR_DDR4=1;PC_CR1_C14=1;PC_CR2_C24=1;
PC_DDR_DDR5=1;PC_CR1_C15=1;PC_CR2_C25=1;
PC_DDR_DDR6=1;PC_CR1_C16=1;PC_CR2_C26=1;
PC_DDR_DDR7=0;PC_CR1_C17=1;PC_CR2_C27=0;
PA_DDR_DDR1=0;PA_CR1_C11=1;PA_CR2_C21=0;
}
/*******************************************************************************/
void MCU_SPI_init(u8 HL) //MCU_SPI初始化切换程序
{
SPI_CR1&=0xB0;
if(HL)
SPI_CR1=0x04; //HL=1时,上升沿读取数据
else
SPI_CR1=0x05; //HL=0时,下降沿读取数据
SPI_CR2=0x03;
SPI_ICR=0x00;
SPI_CR1|=0x40;
}
/*******************************************************************************/
u8 key() //播放按钮
{
if(KEY==0)
{
delay_ms(1);
if(KEY==0)
{
return 1;
}
return 0;
}
return 0;
}
本人初学能力有限,如有错误还请指正,谢谢。