單片機源程序如下:
- /**********************************************************************************************
- 程序名: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)
2019-7-14 16:10 上傳
點擊文件名下載附件
51黑電子論壇-動畫播放
|