单片机源程序如下:
- /**********************************************************************************************
- 程序名:STC单片机驱动OLED12864播放动画程序
- 编写人:黑色蒲公英
- 编写时间:2019年1月22日
- 硬件支持:STC12C5A60S2单片机,7针SPI通信方式OLED12864显示屏,128M内存卡(也可使用2G以下的),TF卡座模块(5V供电,带电平转换芯片)
- 备注:本程序是本人整理修改而来共享给大家,希望大家分享时保留原作者(黑色蒲公英)的网名。
- 播放视频效果可在快手搜索x手号码(昵称@黑色蒲公英)查看,如需制作可
- 在我的快手小店买到制作所需要的所有配件,如需指导可添加QQ群:7297 33027,欢迎你加入
- STC单片机学习交流群,一起学习交流电子技术。
- **********************************************************************************************/
- //Modle :
- //Driver IC:SSD1306
- //Interfaces:SPI-4
- #include<reg51.h>
- //以下是OLED12864引脚接线定义(根据自己的实际接线可修改)
- sbit _CS=P3^4;
- sbit RES=P3^3;
- sbit RS=P3^2;
- sbit _SCL=P3^0;/*serial clock input(D6)*/
- sbit _SI=P3^1;/*serial data input(D7)*/
- //以下是内存卡接线定义(根据自己的实际接线可修改)
- sbit SI=P1^1;
- sbit SO=P1^0;
- sbit CS=P1^3;
- sbit SCL=P1^2;/*serial clock input(D6)*/
- #define uchar unsigned char
- #define uint unsigned int
- #define Page0 0xb0 //第0页地址
- #define Page_max 0xb8 //最大页地址,第8页
- #define Column_h 0x10 //列地址(高位)
- #define Column_l 0x00 //列地址(低位)
- //错误码定义
- #define INIT_CMD0_ERROR 0x01
- #define INIT_CMD1_ERROR 0x02
- #define WRITE_BLOCK_ERROR 0x03
- #define READ_BLOCK_ERROR 0x04
- //变量定义
- unsigned char is_init;//初始化标志位
- unsigned char xdata pbuf[512];//数据缓冲区
- typedef signed char s8;
- typedef signed int s16;
- typedef signed long s32;
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- //延时函数
- void delay(unsigned int time){
- while(time--);
- }
- //SPI写入一个字节
- void spi_write(unsigned char x){
- unsigned char i;
- for(i=0;i<8;i++){
- SI = ((x<<i)&0x80);
- SCL = 0;
- if(is_init)delay(8);//is_init为1时,初始化时延时以降低时钟
- SCL = 1;
- if(is_init)delay(8);//is_init为1时,初始化时延时以降低时钟
- }
- }
- //SPI读取一个字节
- unsigned char spi_read(){
- unsigned char temp = 0,i;
- SO = 1;
- for(i=0;i<8;i++){
- SCL = 0;
- if(is_init)delay(8);//is_init为1时,初始化时延时以降低时钟
- if(SO)temp|=(0x80>>i);
- SCL = 1;
- if(is_init)delay(8);//is_init为1时,初始化时延时以降低时钟
- }
- return (temp);
- }
- //向SD卡写命令
- unsigned char Write_Cmd(unsigned char *pcmd){
- unsigned char temp,time = 0,i;
- for(i=0;i<6;i++){//发送6个字节命令字节序列
- spi_write(pcmd[i]);
- }
- do{
- temp = spi_read();//一直读,直到读到不是0xff或超时
- time++;
- }
- while((temp==0xff)&&(time<100));
- return(temp);
- }
- //SD卡复位函数 使用CMD0命令
- unsigned char SD_Reset(){
- unsigned char time,temp,i;
- unsigned char pcmd[]={//CMD0命令
- 0x40,0x00,0x00,0x00,0x00,0x95
- };
- is_init = 1;//set the init flag
- CS = 1;
- for(i=0;i<0x0f;i++){//初始化时至少发送74个时钟信号,这是必须的
- spi_write(0xff);//0x0f*0xff=15*8=120CLK
- }
- CS = 0;
- time = 0;
- do{
- temp = Write_Cmd(pcmd);//写入CMD0命令
- time++;
- if(time==200){
- return(INIT_CMD0_ERROR);//CMD0写入失败
- }
- }
- while(temp!=0x01);
- CS = 1;
- spi_write(0xff);//补8个CLK(SD卡时序要求)
- return 0;//返回0说明复位成功
- }
- //SD卡初始化函数 使用CMD1命令
- unsigned char SD_Init(){
- unsigned char temp,time;
- unsigned char pcmd[]={//CMD1命令
- 0x41,0x00,0x00,0x00,0x00,0xff
- };
- CS = 0;
- time = 0;
- do{
- temp = Write_Cmd(pcmd);
- time++;
- if(time==100){
- return(INIT_CMD1_ERROR);//CMD1命令写入失败
- }
- }
- while(temp!=0);
- is_init = 0;//初始化完毕,将is_init置0,提高数据传输速度
- CS = 1;//关SD卡片选
- spi_write(0xff);//补8个CLK
- return (0);//返回0说明初始化成功
- }
- //读SD卡扇区 使用CMD17命令
- unsigned char SD_read_sector(unsigned long addr,unsigned char *buffer){
- unsigned int i;
- unsigned char temp,time;
- unsigned char pcmd[]={//CMD17命令
- 0x51,0x00,0x00,0x00,0x00,0xff
- };
- addr <<= 9;//addr= addr*512;将块地址(扇区地址)转换为字节地址
- pcmd[1]=((addr&0xff000000)>>24);
- pcmd[2]=((addr&0x00ff0000)>>16);
- pcmd[3]=((addr&0x0000ff00)>>8);
- CS = 0;//开SD卡片选
- time = 0;
- do{
- temp = Write_Cmd(pcmd);//写入CMD17命令
- time++;
- if(time==100){
- return(READ_BLOCK_ERROR);//读块失败
- }
- }
- while(temp!=0);
- while(spi_read()!=0xfe);//一直读,当读到0xfe时,说明后面是512字节数据
- for(i=0;i<512;i++){
- buffer[i] = spi_read();//将数据写入到缓冲区中
- }
- spi_read();//读两个字节CRC校验码
- spi_read();
- CS = 1;//关SD卡片选
- spi_write(0xff);//补8个CLK
- return 0;
- }
- void Delayt(unsigned int time)
- {
- unsigned int i,j;
- for(i=0;i<time;i++)
- for(j=0;j<20000;j++)
- {;}
- }
- void Ins_trans(unsigned char command) //写命令函数
- {
- unsigned char counter;
- _CS=0;
- RS=0;
- for(counter=0;counter<8;counter++)
- {
- _SCL=0;
- _SI=(command&0x80)>>7;
- command=command<<1;
- _SCL=1;
- _SCL=0;
- }
- RS=1;
- _CS=1;
- }
- void Data_trans(unsigned char command)//写数据函数
- {
- unsigned char counter;
- _CS=0;
- RS=1;
- for(counter=0;counter<8;counter++)
- {
- _SCL=0;
- _SI=(command&0x80)>>7;
- command=command<<1;
- _SCL=1;
- _SCL=0;
- }
- RS=1;
- _CS=1;
- }
- void Column_set(unsigned char column)
- {
- Ins_trans(0x10|(column>>4));
- Ins_trans(0x02|(column&0x0f));
- }
- void Page_set(unsigned char page)
- {
- Ins_trans(0xb0+page);
- }
- void lcdinit(){ //SSD1306初始化函数
- RES=1;
- Delayt(10);
- RES=0;
- Delayt(10);
- RES=1;
- Delayt(10);
- Ins_trans(0xAE); /*display off*/
- Ins_trans(0x00); /*set lower column address*/
- Ins_trans(0x10); /*set higher column address*/
- Ins_trans(0x40); /*set display start line*/
- Ins_trans(0xB0); /*set page address*/
- Ins_trans(0x81); /*contract control*/
- Ins_trans(0x66); /*128*/
- Ins_trans(0xA1); /*set segment remap*/
- Ins_trans(0xA6); /*normal / reverse*/
- Ins_trans(0xA8); /*multiplex ratio*/
- Ins_trans(0x3F); /*duty = 1/64*/
- Ins_trans(0xC8); /*Com scan direction*/
- Ins_trans(0xD3); /*set display offset*/
- Ins_trans(0x00);
- Ins_trans(0xD5); /*set osc division*/
- Ins_trans(0x80);
- Ins_trans(0xD9); /*set pre-charge period*/
- Ins_trans(0x1f);
- Ins_trans(0xDA); /*set COM pins*/
- Ins_trans(0x12);
- Ins_trans(0xdb); /*set vcomh*/
- Ins_trans(0x30);
- Ins_trans(0x8d); /*set charge pump enable*/
- Ins_trans(0x14);
- Ins_trans(0xAF); /*display ON*/
- }
- void Picture_display_on(unsigned char *ptr_pic)//显示上半屏
- {
- unsigned char page,column;
- for(page=0;page<4;page++) //page loop
- {
- Page_set(page);
- Column_set(2);
- for(column=2;column<130;column++) //column loop
- {
- Data_trans(*ptr_pic++);
- }
- }
- }
- void Picture_display_down(unsigned char *ptr_pic)//显示下半屏
- {
- unsigned char page,column;
- for(page=4;page<8;page++) //page loop
- {
- Page_set(page);
- Column_set(2);
- for(column=2;column<130;column++) //column loop
- {
- Data_trans(*ptr_pic++);
- }
- }
- }
- void main(void)
- {
- unsigned int i;
- SD_Reset();//复位SD卡,进入SPI模式
- SD_Init();//初始化SD卡
- lcdinit();//OLED12864初始化
-
- while(1)
- {
- for(i=0;i<14706;i+=2){
- SD_read_sector(8195+i,pbuf);//从SD卡8193扇区读取512字节数据(扇区号用winhex打开内存卡查看,把你看到的扇区号替换掉8193即可)
- Picture_display_down(&pbuf); //打印下半屏
- Ins_trans(0xA7); /*normal / reverse*///A7反色显示,A6正常显示
- SD_read_sector(8195+i+1,pbuf);//从SD卡8194扇区读取512字节数据(扇区号用winhex打开内存卡查看,把你看到的扇区号替换掉8193即可)
- Picture_display_on(&pbuf);//打印上半屏
- }
- }
- }
-
复制代码
所有程序51hei提供下载:
1.rar
(37.23 KB, 下载次数: 72)
|