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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2686|回復: 7
打印 上一主題 下一主題
收起左側

C語言指針的相關問題 程序分析

[復制鏈接]
回帖獎勵 20 黑幣 回復本帖可獲得 20 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:1079270 發表于 2023-8-7 10:14 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式


#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定時標志
unsigned char T0RH = 0;  //T0重載值的高字節
unsigned char T0RL = 0;  //T0重載值的低字節
//待顯示的第一行字符串
unsigned char code str1[] = "Kingst Studio";
//待顯示的第二行字符串,需保持與第一行字符串等長,較短的行可用空格補齊
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;  //移動索引
    unsigned char pdata bufMove1[16+sizeof(str1)+16]; //移動顯示緩沖區1
    unsigned char pdata bufMove2[16+sizeof(str2)+16]; //移動顯示緩沖區2


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

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

使用道具 舉報

沙發
ID:908826 發表于 2023-8-7 18:41 | 只看該作者
先執行間接運算操作,然后指針值加一指向下一個內存地址
回復

使用道具 舉報

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

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

使用道具 舉報

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

bufMove1作為一個數組名,本身就是指針常量,+index運算后得到一個指針變量,當然可以當成unsigned char *類型的參數傳遞進去。
而bufMove1[index],這就不是一個指針了,而是一個unsigned char類型的數據,必須在前面加&才能變成unsigned char *類型的參數傳遞進去。

評分

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

查看全部評分

回復

使用道具 舉報

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

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

評分

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

查看全部評分

回復

使用道具 舉報

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

非常感謝,沒想到我的問題這么抽象還能明白我想表達的意思,不愧是大佬
回復

使用道具 舉報

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

使用道具 舉報

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

受教了。。。。謝謝
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品国产a级 | 欧美三级在线 | 免费国产视频 | 婷婷开心激情综合五月天 | 国产亚洲精品美女久久久久久久久久 | 五月天天丁香婷婷在线中 | 国产日韩欧美一区 | 国产亚洲精品久久久久久牛牛 | 国产伊人精品 | 国产免费看 | 91视频在线看| 狠狠躁18三区二区一区 | 黄色av网站在线免费观看 | 日日碰碰| 久久成人激情 | 精品国产一区二区 | 黄色在线| 福利片在线 | 91国产视频在线观看 | 久久久久成人精品免费播放动漫 | 91pron在线 | aaa一区 | 久久亚洲高清 | 国产成人小视频 | 国产乱码精品一区二区三区五月婷 | 一区二区三区欧美 | 亚洲精品99| 亚洲二区视频 | 日韩av一区二区在线 | 亚洲欧美激情精品一区二区 | 久久精品国产a三级三级三级 | 九九久久免费视频 | 国产高清区 | 97人人澡人人爽91综合色 | 中文字幕一区在线观看视频 | 午夜久久久 | 国产视频观看 | 91在线一区 | 国产日韩欧美一区 | 国产精品高潮呻吟久久av野狼 | 丝袜 亚洲 欧美 日韩 综合 |