如圖所示的一個16*16點陣顯示左移的示例程序,這里是主函數部分,我知道怎么靜態顯示一個漢字,但是搞不懂他這個是怎么在左移。求告知!!v4.0資料鏈接如附件
- /*-----------------------------------------------
- 名稱:16x16漢字屏流動顯示
- 編寫:shifang
- 日期:2009.5
- 修改:bob_write 2021.3
- 硬件:LY-51S V4.0 單片機開發板
- 內容:
- P1.0-P1.3分別連接A、B、C、D,用于控制16行,通過2路HC138控制
- SER接P1.4 通過2片HC595控制
- CLK時鐘連接P1.5
- LAT鎖存連接P1.6
- OE接P1.7
- 現象:使用普通速度51系列單片機。1個漢字顯示屏,向左流動顯示多個漢字,重復循環顯示。
- ------------------------------------------------*/
- #include<reg52.h>
- #include <intrins.h>
- sbit J32_LAT = P1^6; //鎖存引腳
- sbit J32_SER = P1^4; //數據引腳
- sbit J32_CLK = P1^5; //時鐘引腳
- sbit J32_OE = P1^7; //使能引腳
- sbit KEY = P0^5; //獨立按鍵
- unsigned char MoveBitNum,MoveBitNumtemp,IncNum;//移動位數,臨時移動位數,大于一個字節增加字節數
- unsigned int HzNum;//漢字個數
- unsigned char buff[10];
- /*-----------------------------------------------
- 16x16漢字取模數據
- ------------------------------------------------*/
- unsigned char code hztest[][32]= //取模選擇字節正序n行32列的數組,長度是固定的
- {
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //前面一屏大小的空字符,不顯示,這里根據屏的大小修改,這個是1個漢字屏
- //所以寫入1個漢字
- /*-- 文字: 電 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,
- 0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x0A,0x01,0x02,0x01,0x02,0x00,0xFE,
- /*-- 文字: 子 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x7F,0xF8,0x00,0x10,0x00,0x20,0x00,0x40,0x01,0x80,0x01,0x00,0xFF,0xFE,
- 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,
- /*-- 文字: 信 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x08,0x40,0x08,0x20,0x0B,0xFE,0x10,0x00,0x10,0x00,0x31,0xFC,0x30,0x00,0x50,0x00,
- 0x91,0xFC,0x10,0x00,0x10,0x00,0x11,0xFC,0x11,0x04,0x11,0x04,0x11,0xFC,0x11,0x04,
- /*-- 文字: 息 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x01,0x00,0x02,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,
- 0x1F,0xF0,0x10,0x10,0x01,0x00,0x08,0x84,0x48,0x92,0x48,0x12,0x87,0xF0,0x00,0x00,
- /*-- 文字: 工 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
- 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,
- /*-- 文字: 程 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- 0x08,0x00,0x1D,0xFC,0xF1,0x04,0x11,0x04,0x11,0x04,0xFD,0xFC,0x10,0x00,0x30,0x00,
- 0x39,0xFE,0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00,
- };
- /*-----------------------------------------------
- 向595寫入一個字節 單紅色
- ------------------------------------------------*/
- void InputByte( unsigned char DataR1) //寫一個字節用串行八位所以8次循環
- {
- unsigned char i;
- for(i=8; i>0; i--)
- {
- J32_SER = (DataR1&0x01);//分離最低位,即0000 0001和data相與取最低位
- J32_CLK = 0;
- J32_CLK = 1;
- DataR1 = DataR1 >> 1;//
- }
- }
- /*-----------------------------------------------
- 延時程序
- ------------------------------------------------*/
- void Delay(unsigned int t)
- {
- while(--t);
- }
- void Delay10ms() //@12.000MHz
- {
- unsigned char i, j;
- i = 117;
- j = 184;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay15ms() //@12.000MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 1;
- j = 176;
- k = 19;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /*-----------------------------------------------
- 主程序
- ------------------------------------------------*/
- main()
- {
- unsigned char count;//16行掃描數據,范圍0-15
- unsigned int i, j;
- unsigned char temp;
- //計算數組的元素個數,最終需要的是漢字的個數
- int lenTotal = sizeof(hztest) / sizeof(int); //所有,整個數組的大小
- int lenLow = sizeof(hztest[0]) / sizeof(int); //低位,單個數組的大小
- int lenHigh = lenTotal / lenLow; //高位,相除相當于字的個數
- while(1)
- {
- /*MoveBitNum,移動位數,
- MoveBitNumtemp,臨時移動位數,
- IncNum,大于一個字節增加字節數*/
-
- i++;
- if(i==60)//更改流動速度,1T單片機和12T單片機速度大約5-8倍,注意更改參數
- {
- i=0;
- MoveBitNum++;
- if(MoveBitNum==16)//每次移動完一個漢字大小后循環
- {
- MoveBitNum=0;
- HzNum+=1; //調用下一個漢字
- if(HzNum>=lenHigh-1)//需要顯示的漢字個數,包括前面的一屏空字符的個數,后面清屏的空字符不包含在內,這里是(漢字個數+1)
- //如果已經是最后一個了,則令漢字個數為0,即hznum指針歸零
- HzNum=0; //完全顯示完后循環調用
- }
- }
- Delay(1);//控制掃描頻率
- //讀取漢字對應屏幕緩沖區的數據,不同大小的屏幕不一樣
- for(j=0; j<2; j++) //取每個漢字的前2個字節,即32位,2/32
- {
- //漢字個數+1
- buff[j+j+1]=hztest[HzNum+j][count+count+1]; //每次移動完一個漢字后,選擇下一個漢字
- buff[j+j]=hztest[HzNum+j][count+count];
- }
- //判斷移動的位數
- if(MoveBitNum<8) // 判讀移動距離是大于一個字節還是小于一個字節,因為一個字節左移右移最大只能8位
- {
- IncNum=0;
- MoveBitNumtemp=MoveBitNum;
- }
- else
- {
- IncNum=1; //大于8就減去8得到的數值還是小于8
- MoveBitNumtemp=MoveBitNum-8;
- }
- J32_LAT=0; //鎖存無效
- for(j=2; j>0; j--) //按bit的方式移動緩沖區的內容,然后輸出到595,即取出的數值每個字節左移一定的位數,
- {
- //后面左移出的數據整合到前面的字節中,保持數據的連續性
- temp=(buff[j-1+IncNum]<<MoveBitNumtemp)|(buff[j+IncNum]>>(8-MoveBitNumtemp));//這句比較重要,需要自行拿出2個字節的數據模擬分析
- InputByte(temp);//輸出到595
- }//8個字節傳輸完鎖存輸出
- //控制使能端
- J32_OE = 1;
- P1=count;//用P0口的前4位控制16行,屏內部通過4-16譯碼器工作,循環掃描16行
- J32_LAT=1; //鎖存有效,此時一行的數據顯示到屏上
- J32_OE = 0;
- count++;
- if(count==16)
- count=0;
- }
- }
復制代碼
|