久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3282|回復: 8
收起左側

單片機LCD1602字符液晶滾動演示程序問題

[復制鏈接]
ID:668004 發表于 2020-7-28 18:15 | 顯示全部樓層 |閱讀模式

uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不

while((Busy_Check()&0x80)==0x80);------------一個變量與上一個十六進制數,啥東東


void ShowString(uchar,uchar,uchar *);----------------這個是定義一個指針變量?



//main.c
/*        名稱:LCD1602字符液晶滾動演示程序
        說明:K1~K3按鈕分別實現液晶垂直或水平滾動顯示及暫停與繼續控制。
*/
#include<reg51.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
void Initialize_LCD();
void DelayMS(uint ms);
void ShowString(uchar,uchar,uchar *);
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";
//待滾動顯示的信息段落,每行不超過80個字符,共6行
uchar const Line_Count=6;        
uchar code Msg[][80]=
{
        "Many CAD users dismiss schematic capture as a necessary evil in the ",
        "process of creating PCB layout but we have always disputed this point ",
        "of view. With PCB layout now offering automation of both component ",
        "can often be the most time consuming element of the exercise.",
        "And if you use circuit simulation to develop your ideas, ",
        "you are going to spend even more time working on the schematic."
};
//顯示緩沖(2行)
uchar Disp_Buffer[32];
//垂直滾動顯示
void V_Scroll_Display()
{
        uchar i,j,k=0;
        uchar *p=Msg[0];
        uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);
        //以下僅使用顯示緩沖的前16字節空間
        while(p<q)
        {
                for(i=0;i<16&&p<q;i++)
                {        //消除顯示緩沖中待顯示行首尾可能出現的空格
                        if((i==0||i==15)&&*p==' ') p++;
                        if(*p!='\0')
                        {
                                Disp_Buffer[ i]=*p++;
                        }
                        else
                        {
                                if(++k>Line_Count) break;
                                p=Msg[k];                                        //p指向下一串的首地址
                                Disp_Buffer[ i]=*p++;
                        }
                }
                //不足16個字符時空格補充
                for(j=i;j<16;j++) Disp_Buffer[j]=' ';
                //垂直滾動顯示
                while(F0) DelayMS(5);
                ShowString(0,0,"                 ");
                DelayMS(150);
                while(F0) DelayMS(5);
                ShowString(0,1,Disp_Buffer);
                DelayMS(150);
                while(F0) DelayMS(5);
                ShowString(0,0,Disp_Buffer);
                ShowString(0,1,"                 ");
                DelayMS(150);
        }
        //最后清屏
        ShowString(0,0,"                 ");
        ShowString(0,1,"                 ");
}
//水平滾動顯示
void H_Scroll_Display()
{
        uchar i,j,k=0,L=0;
        uchar *p=Msg[0];
        uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);
        //將32個字符的顯示緩沖前16個字符設為空格
        for(i=0;i<16;i++) Disp_Buffer[ i]=' ';
        while(p<q)
        {
                //忽略緩沖中首尾可能出現的空格
                if((i==16||i==31)&&*p==' ') p++;
                for(i=16;i<32&&p<q;i++)
                {        
                        if(*p!='\0')
                        {
                                Disp_Buffer[ i]=*p++;
                        }
                        else
                        {
                                if(++k>Line_Count) break;
                                p=Msg[k];                                        //p指向下一串的首地址
                                Disp_Buffer[ i]=*p++;
                        }
                }
                //不足32個字符時空格補充
                for(j=i;j<32;j++) Disp_Buffer[j]=' ';
                //水平滾動顯示
                for(i=0;i<=16;i++)
                {
                        while(F0) DelayMS(5);
                        ShowString(0,L,Disp_Buffer+i);
                        while(F0) DelayMS(5);
                        DelayMS(20);
                }
                L=(L==0)?1:0;                //行號在0,1間交替
                DelayMS(300);
        }
        //如果顯示結束時停留在第0行,則清除第1行的內容
        if(L==1) ShowString(0,1,"                 ");        
}
//外部中斷0,由K3控制暫停與繼續顯示
void EX_INT0() interrupt 0
{
        F0=!F0;                //暫停與繼續顯示控制標志位
}
//主程序
void main()
{
        uint Count=0;
        IE=0x81;                //允許外部中斷0
        IT0=1;                        //下降沿觸發
        F0=0;                        //暫停與繼續顯示控制標志位
        Initialize_LCD();
        ShowString(0,0,Prompt);
        ShowString(0,1,Prompt+16);
        while(1)
        {
                if(K1==0)
                {
                        V_Scroll_Display();
                        DelayMS(300);
                }
                else
                if(K2==0)
                {        
                        H_Scroll_Display();
                        DelayMS(300);        
                }
        }
}
//LCD1602.c
/*        名稱:液晶控制與顯示程序
        說明:本程序是通用的1602液晶控制程序。
*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
//延時
void DelayMS(uint ms)
{
        uchar i;
        while(ms--) for(i=0;i<120;i++);
}
//忙檢查
uchar Busy_Check()
{
        uchar LCD_Status;
        RS=0;                                //寄存器選擇
        RW=1;                                //讀狀態寄存器
        EN=1;                                //開始讀
        DelayMS(1);
        LCD_Status=P0;
        EN=0;
        return LCD_Status;
}
//寫LCD命令
void Write_LCD_Command(uchar cmd)
{
        while((Busy_Check()&0x80)==0x80);        //忙等待
        RS=0;                //選擇命令寄存器
        RW=0;                //寫
        EN=0;        
        P0=cmd;EN=1;DelayMS(1);EN=0;
}
//發送數據
void Write_LCD_Data(uchar dat)
{
        while((Busy_Check()&0x80)==0x80);        //忙等待
        RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;
}
//LCD初始化
void Initialize_LCD()
{
        Write_LCD_Command(0x38);DelayMS(1);
        Write_LCD_Command(0x01);DelayMS(1);        //清屏
        Write_LCD_Command(0x06);DelayMS(1);        //字符進入模式:屏幕不動,字符后移
        Write_LCD_Command(0x0c);DelayMS(1);        //顯示開,光標關
}
//顯示字符串
void ShowString(uchar x,uchar y,uchar *str)
{
        uchar i=0;
        if(y==0) Write_LCD_Command(0x80|x);        //設置顯示起始位置
        if(y==1) Write_LCD_Command(0xc0|x);
        for(i=0;i<16;i++)                                        //輸出字符串
        {
                Write_LCD_Data(str[ i]);
        }
}



圖片1.png
回復

使用道具 舉報

ID:804115 發表于 2020-7-28 19:38 | 顯示全部樓層
本帖最后由 1692483014 于 2020-7-28 19:40 編輯

uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不
答:有用,main函數進入后調用了
ShowString(0,0,Prompt);
ShowString(0,1,Prompt+16);
用于將"Press K1 - K3 To Start Demo Prog"字符串顯示到屏幕上。

while((Busy_Check()&0x80)==0x80);------------一個變量與上一個十六進制數,啥東東

答:這個是檢測Busy_Check()函數返回值的最高位BIT7是否為1,如果為1,那么就在這里死等,直到它為0再運行下面的代碼,那BIT7什么時候會等于0呢?當LCD_Status不忙的時候就會為0了。
整個這一行是為了保證LCD處理完了上一條指令后才能進行后面的LCD指令的操作,要不可能出錯。

void ShowString(uchar,uchar,uchar *);----------------這個是定義一個指針變量?
答:這是聲明一個函數,聲明函數要求必須列出參數的類型,但不一定非要列出變量。這個聲明類似于.h文件的聲明,只不過這是局部聲明,只能在聲明之后的函數里調用ShowString函數。
回復

使用道具 舉報

ID:668004 發表于 2020-7-29 14:44 | 顯示全部樓層
1692483014 發表于 2020-7-28 19:38
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不
答:有用,mai ...

非常的幫  給你點贊  專業
回復

使用道具 舉報

ID:668004 發表于 2020-7-29 14:55 | 顯示全部樓層
1692483014 發表于 2020-7-28 19:38
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不
答:有用,mai ...

這里有個*號是啥意思
回復

使用道具 舉報

ID:668004 發表于 2020-7-29 14:57 | 顯示全部樓層
1692483014 發表于 2020-7-28 19:38
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不
答:有用,mai ...

與上1000 0000就是為了判斷最高位是不是1 對嗎?為什么是這一位進行判斷就可以
回復

使用道具 舉報

ID:668004 發表于 2020-7-30 10:10 | 顯示全部樓層
1692483014 發表于 2020-7-28 19:38
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------這條語句有作用不
答:有用,mai ...

你是軟硬件通吃的大牛。。。。原來
回復

使用道具 舉報

ID:804115 發表于 2020-8-1 02:44 | 顯示全部樓層
QWE4562012 發表于 2020-7-29 14:55
這里有個*號是啥意思

void ShowString(uchar,uchar,uchar *);----------------這個是定義一個指針變量?

你說這個*嗎?這不就是指針嗎?
把C語言那本書再看幾遍吧!
回復

使用道具 舉報

ID:804115 發表于 2020-8-1 02:46 | 顯示全部樓層
QWE4562012 發表于 2020-7-29 14:57
與上1000 0000就是為了判斷最高位是不是1 對嗎?為什么是這一位進行判斷就可以

與上1000 0000就是為了判斷最高位是不是1 對嗎?為什么是這一位進行判斷就可以

是的,這一位對應P0口的P0.7引腳,這個腳為高電平,說明LCD在忙,你要等,等他變低,LCD就忙完了,所以要檢測這個bit。
回復

使用道具 舉報

ID:804115 發表于 2020-8-1 02:51 | 顯示全部樓層
QWE4562012 發表于 2020-7-30 10:10
你是軟硬件通吃的大牛。。。。原來

我來這里回答問題,是為了學習的,但是我發現更多的是新手提問題,能提出難一點兒問題的不多,我很期待有難度而且我很感興趣的問題,這樣我就可以百度它,思考它,解決它,從而增長知識,順便還能賺點兒金幣,哈哈。
你要努力呀!希望再過幾個月能提出更深一點兒的問題。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久精品一区 | 亚洲v日韩v综合v精品v | 自拍 亚洲 欧美 老师 丝袜 | 久久精品国产99国产精品 | 九九热国产精品视频 | 久久免费视频在线 | 韩国毛片视频 | 国产在线精品一区二区 | 亚洲精品美女视频 | 91aiai| 久久久不卡网国产精品一区 | 国产一区二区三区四区五区加勒比 | 黄视频免费观看 | 久草免费在线视频 | 欧美一区二区三区的 | 91av在线视频观看 | 天堂久久天堂综合色 | 一级毛片免费视频 | 欧美成年人 | 亚洲中字在线 | 毛片99| 色先锋影音 | 国产中文字幕av | 亚洲性视频 | 久久久久免费 | 婷婷二区 | 国产成人黄色 | 中文字幕一区二区三区在线观看 | 精品美女久久久 | 亚洲国产网站 | av一级在线观看 | 亚洲欧洲精品一区 | 国产精品福利在线观看 | 久久成人综合 | 黄色免费av | 久久久成 | 在线视频91 | 欧美在线观看一区 | 九九久久精品 | 五月婷婷 六月丁香 | 中文字幕日韩欧美 |