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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2558|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

C語(yǔ)言指針的相關(guān)問(wèn)題 程序分析

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 20 黑幣 回復(fù)本帖可獲得 20 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
跳轉(zhuǎn)到指定樓層
樓主
ID:1079270 發(fā)表于 2023-8-7 10:14 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式


#include <reg52.h>


#define LCD1602_DB  P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E  = P1^5;


bit flag500ms = 0;   //500ms定時(shí)標(biāo)志
unsigned char T0RH = 0;  //T0重載值的高字節(jié)
unsigned char T0RL = 0;  //T0重載值的低字節(jié)
//待顯示的第一行字符串
unsigned char code str1[] = "Kingst Studio";
//待顯示的第二行字符串,需保持與第一行字符串等長(zhǎng),較短的行可用空格補(bǔ)齊
unsigned char code str2[] = "Let's move...";


void ConfigTimer0(unsigned int ms);
void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y,
                unsigned char *str, unsigned char len);


void main()
{
    unsigned char i;
    unsigned char index = 0;  //移動(dòng)索引
    unsigned char pdata bufMove1[16+sizeof(str1)+16]; //移動(dòng)顯示緩沖區(qū)1
    unsigned char pdata bufMove2[16+sizeof(str2)+16]; //移動(dòng)顯示緩沖區(qū)2


    EA = 1;            //開(kāi)總中斷
    ConfigTimer0(10);  //配置T0定時(shí)10ms
    InitLcd1602();     //初始化液晶
    //緩沖區(qū)開(kāi)頭一段填充為空格
    for (i=0; i<16; i++)
    {
        bufMove1[ i] = ' ';
        bufMove2[ i] = ' ';
    }
    //待顯示字符串拷貝到緩沖區(qū)中間位置
    for (i=0; i<(sizeof(str1)-1); i++)
    {
        bufMove1[16+i] = str1[ i];
        bufMove2[16+i] = str2[ i];
    }
    //緩沖區(qū)結(jié)尾一段也填充為空格
    for (i=(16+sizeof(str1)-1); i<sizeof(bufMove1); i++)
    {
        bufMove1[ i] = ' ';
        bufMove2[ i] = ' ';
    }
   
    while (1)
    {
        if (flag500ms)  //每500ms移動(dòng)一次屏幕
        {
            flag500ms = 0;
            //從緩沖區(qū)抽出需顯示的一段字符顯示到液晶上
            LcdShowStr(0, 0, bufMove1+index, 16);
            LcdShowStr(0, 1, bufMove2+index, 16);
            //移動(dòng)索引遞增,實(shí)現(xiàn)左移
            index++;
            if (index >= (16+sizeof(str1)-1))
            {   //起始位置達(dá)到字符串尾部后即返回從頭開(kāi)始
                index = 0;
            }
        }
    }
}
/* 配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間 */
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  //臨時(shí)變量
   
    tmp = 11059200 / 12;      //定時(shí)器計(jì)數(shù)頻率
    tmp = (tmp * ms) / 1000;  //計(jì)算所需的計(jì)數(shù)值
    tmp = 65536 - tmp;        //計(jì)算定時(shí)器重載值
    tmp = tmp + 12;           //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
    T0RH = (unsigned char)(tmp>>8);  //定時(shí)器重載值拆分為高低字節(jié)
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0為模式1
    TH0 = T0RH;     //加載T0重載值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中斷
    TR0 = 1;        //啟動(dòng)T0
}
/* 等待液晶準(zhǔn)備好 */
void LcdWaitReady()
{
    unsigned char sta;
   
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;
        sta = LCD1602_DB; //讀取狀態(tài)字
        LCD1602_E = 0;
    } while (sta & 0x80); //bit7等于1表示液晶正忙,重復(fù)檢測(cè)直到其等于0為止
}
/* 向LCD1602液晶寫(xiě)入一字節(jié)命令,cmd-待寫(xiě)入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 向LCD1602液晶寫(xiě)入一字節(jié)數(shù)據(jù),dat-待寫(xiě)入數(shù)據(jù)值 */
void LcdWriteDat(unsigned char dat)
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 設(shè)置顯示RAM起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */
void LcdSetCursor(unsigned char x, unsigned char y)
{
    unsigned char addr;
   
    if (y == 0)  //由輸入的屏幕坐標(biāo)計(jì)算顯示RAM的地址
        addr = 0x00 + x;  //第一行字符地址從0x00起始
    else
        addr = 0x40 + x;  //第二行字符地址從0x40起始
    LcdWriteCmd(addr | 0x80);  //設(shè)置RAM地址
}
/* 在液晶上顯示字符串,(x,y)-對(duì)應(yīng)屏幕上的起始坐標(biāo),
   str-字符串指針,len-需顯示的字符長(zhǎng)度 */
void LcdShowStr(unsigned char x, unsigned char y,
                unsigned char *str, unsigned char len)
{
    LcdSetCursor(x, y);   //設(shè)置起始地址
    while (len--)         //連續(xù)寫(xiě)入len個(gè)字符數(shù)據(jù)
    {
        LcdWriteDat(*str++);  //先取str指向的數(shù)據(jù),然后str自加1
    }
}
/* 初始化1602液晶 */
void InitLcd1602()
{
    LcdWriteCmd(0x38);  //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
    LcdWriteCmd(0x0C);  //顯示器開(kāi),光標(biāo)關(guān)閉
    LcdWriteCmd(0x06);  //文字不動(dòng),地址自動(dòng)+1
    LcdWriteCmd(0x01);  //清屏
}
/* T0中斷服務(wù)函數(shù),定時(shí)500ms */
void InterruptTimer0() interrupt 1
{
    static unsigned char tmr500ms = 0;
   
    TH0 = T0RH;  //重新加載重載值
    TL0 = T0RL;
    tmr500ms++;
    if (tmr500ms >= 50)
    {
        tmr500ms = 0;
        flag500ms = 1;
    }
}
問(wèn):bufMove1+index代入void LcdShowStr(unsigned char x, unsigned char y,
                unsigned char *str, unsigned char len)的 LcdWriteDat(*str++)的流程是什么?

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:908826 發(fā)表于 2023-8-7 18:41 | 只看該作者
先執(zhí)行間接運(yùn)算操作,然后指針值加一指向下一個(gè)內(nèi)存地址
回復(fù)

使用道具 舉報(bào)

板凳
ID:1079566 發(fā)表于 2023-8-7 19:07 | 只看該作者
bufMove1+index代入void LcdShowStr(unsigned char x, unsigned char y,
                unsigned char *str, unsigned char len)的 LcdWriteDat(*str++)的流程是什么?
流程: 類(lèi)似如下
LcdWriteDat( bufMove1[index])
index++ (這里只是展示效果,實(shí)際不影響函數(shù)外的index)

或:
*str = & bufMove1[index]  // 或 *str= bufMove1 + index
LcdWriteDat(*str)
str++
回復(fù)

使用道具 舉報(bào)

地板
ID:883242 發(fā)表于 2023-8-7 21:38 | 只看該作者
原來(lái)你是不知道下面兩句話是完全等效的。
  1. bufMove1+index
復(fù)制代碼
  1. &bufMove1[index]
復(fù)制代碼

bufMove1作為一個(gè)數(shù)組名,本身就是指針常量,+index運(yùn)算后得到一個(gè)指針變量,當(dāng)然可以當(dāng)成unsigned char *類(lèi)型的參數(shù)傳遞進(jìn)去。
而bufMove1[index],這就不是一個(gè)指針了,而是一個(gè)unsigned char類(lèi)型的數(shù)據(jù),必須在前面加&才能變成unsigned char *類(lèi)型的參數(shù)傳遞進(jìn)去。

評(píng)分

參與人數(shù) 1黑幣 +12 收起 理由
xnysfh + 12 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

5#
ID:844772 發(fā)表于 2023-8-8 08:36 | 只看該作者
當(dāng)bufMove1+index代入void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str, unsigned char len)的LcdWriteDat(*str++)時(shí),流程如下:

LcdSetCursor(x, y):設(shè)置LCD光標(biāo)起始地址為(x, y)。
進(jìn)入while循環(huán),len--:len是要顯示的字符數(shù)量,每循環(huán)一次,len減1。
LcdWriteDat(*str++):從str指向的地址取出一個(gè)字符數(shù)據(jù),然后str自增1,指向下一個(gè)字符。將取出的字符數(shù)據(jù)寫(xiě)入LCD的數(shù)據(jù)寄存器,顯示在LCD屏幕上。
重復(fù)步驟2和步驟3,直到len減到0,即所有字符都顯示完畢。
實(shí)際上,bufMove1+index代入*LcdShowStr(unsigned char x, unsigned char y, unsigned char *str, unsigned char len)的LcdWriteDat(*str++)時(shí),bufMove1+index的內(nèi)容會(huì)被當(dāng)作字符串的起始地址,而不是單個(gè)字符的地址。因此,函數(shù)會(huì)顯示從bufMove1+index開(kāi)始的len個(gè)字符。

評(píng)分

參與人數(shù) 1黑幣 +12 收起 理由
xnysfh + 12 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

6#
ID:1079270 發(fā)表于 2023-8-8 11:25 | 只看該作者
Hephaestus 發(fā)表于 2023-8-7 21:38
原來(lái)你是不知道下面兩句話是完全等效的。

非常感謝,沒(méi)想到我的問(wèn)題這么抽象還能明白我想表達(dá)的意思,不愧是大佬
回復(fù)

使用道具 舉報(bào)

7#
ID:372579 發(fā)表于 2023-8-12 09:11 | 只看該作者
51大神好多,逛逛就可以學(xué)到很多知識(shí)
回復(fù)

使用道具 舉報(bào)

8#
ID:385774 發(fā)表于 2023-8-14 11:01 | 只看該作者
Hephaestus 發(fā)表于 2023-8-7 21:38
原來(lái)你是不知道下面兩句話是完全等效的。

受教了。。。。謝謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久久国产一区二区三区四区 | 国产高清一二三区 | 啪啪av| 国产精品综合色区在线观看 | 在线看亚洲| 国产精品1区 | 一区二区三区四区国产 | 欧洲免费毛片 | 亚洲精品在线视频 | 成人亚洲精品久久久久软件 | 亚洲成人一区二区三区 | 久热久 | h片在线看 | 亚洲美女一区 | 一区精品在线观看 | 又黄又爽的网站 | 国产成人精品一区二区在线 | 成人免费大片黄在线播放 | 久久一区二区三区电影 | 日韩在线 | 国产精品视频一二三区 | 久久久久国产精品 | 日韩精品在线视频 | 国产精品视频偷伦精品视频 | 精品国产乱码久久久久久影片 | 在线观看国产三级 | 国产视频一二三区 | 欧美精品成人 | 国产精品免费在线 | 午夜精品在线观看 | 日韩欧美一级精品久久 | 日韩一区二区av | 欧美一级在线免费观看 | 亚洲一区久久久 | 精品一区二区电影 | 高清亚洲| 综合第一页 | 黄免费观看 | 亚洲协和影视 | 久久a久久 | 不卡视频在线 |