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

標題: 關于單片機不同IO口編組程序 [打印本頁]

作者: xtayxwygqvhj    時間: 2024-1-8 21:52
標題: 關于單片機不同IO口編組程序
請問有沒有哪位大神百忙中抽點時間指點一下這一段代碼,卡了兩天了沒搞懂。下面是一段異組非順序端口編組的程序
本人業余愛好者,半路出家沒有系統學習過之前在網上學了一些89c51皮毛做了一些流水燈,4*4矩陣之類的
最近想做個實物矩陣鍵盤,但是由于之前用的是89c51,然后想著只做一個矩陣鍵盤帶幾個LED沒必要用那么多引腳的單片機,
就選了個STC15W SOP16的
然后就悲劇了 STC15單組IO最多才6個P1.0-P1.5,4*4鍵盤要用8個口,跟之前學的0x**就完成掃描的程序不一樣,搞了兩天就只會分開一個一個口的寫代碼
雖然也能用,但是這樣太修飾了,然后就去網上找了一些資料(這方面的資料超級少),研究后發覺我看不懂代碼了(主要是運算符)
單個運算符拿出來可以理解,但是放在一起就搞不懂為什么會有這樣的結果。

#define PD ((P2<<3&0x80)|(P2<<4&0x40)|(P3&0x3f)) //P2.4/P2.2


不懂1:宏定義 P2向左移3位跟0x80進行按位與......
       根據運算優先級,這里的位移3位是指P2口低位往高位移3位后的結果是2.2口嗎?(P2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7)
        既:P2=0X04(0000 0100) & 0x80(1000 0000) 結果為0x00 (0000 0000) ??
        P2向左移4位跟0x40進行按位與..... .這里的位移4位是指P2口低位往高位移3位后的結果是2.3口嗎??
    之后
          P2=0X08(0000 1000) & 0x40(0100 0000)  結果為0x00 (0000 0000) ??
再之后
                   不算P3的情況 按位或結果  0000 0000 | 0000 0000 = 0000 0000   那就跟程序運行的結果就不一樣了

void PX(uchar x)
{
        P3&=0xc0;                //低6位清0,P3.6、P3.7不變
        P3|=(x&0x3f);        //P3低6位賦值
        P2&=0xeb;                //P2.4、P2.2清0,其它位不變
        P2|=((x>>3&0x10)|(x>>4&0x04)); //P2.4、P2.2賦值

不懂2:  無字符型變量X 取值范圍是 0-255   這里的X移位是怎么移?0 1 2 3 -255  位移3位是2嗎?移位后的值是10進制還是2進制或者16進制

}



作者: npn    時間: 2024-1-9 10:36
十進制是給人類看的,無論任何進制,在單片機都是二進制處理的。
作者: lkc8210    時間: 2024-1-9 11:02
不懂1:
位數弄反了
正確順序:P2.7/6/5/4/3/2/1/0
P24取值放到第7位:
P2<<3 & 0x80 = 0B00010000<<3 & 0x80 = 0B10000000 & 0x80
P22取值放到第6位:
P2<<4 & 0x40 = 0B00000100<<4 & 0x40 = 0B01000000 & 0x40

不懂2:
樓上說了,所有計算都是2進制

不用宏定義改用函數
  1. uchar PD()
  2. {
  3.         u8 dat = 0;
  4.         if(P2&0x10)dat|=0x80;
  5.         if(P2&0x04)dat|=0x40;
  6.         dat|=P3&0x3F;
  7.         return dat;
  8. }
復制代碼

作者: 18680365301    時間: 2024-1-9 11:02
能用最簡單易懂的辦法做出就可以了,先沒必要在意復雜的方式,等你用了幾年C之后再研究研究吧
作者: xtayxwygqvhj    時間: 2024-1-9 18:23
lkc8210 發表于 2024-1-9 11:02
不懂1:
位數弄反了
正確順序:P2.7/6/5/4/3/2/1/0

大致搞明白了,用流水燈正反測試了一下沒發現什么問題
我的方向錯了
問題1那里是宏定義端口組(就是等于新建一個8位的組),
以原代碼為例
我錯以為是直接把P2口的2.4 2.2運算出來,然后跟P3口的P3.5-3.0或運算取出要用的io后再調用。
所以我一直以為位移之后的位置是2.4或者2.2,而不是把2.4 2.2的低位移到高位
而實際情況是直接新建一個8位的組,然后把要用的io口運算出來再通過位移調整各個位的io的高低位置再加進這個組。
再一個是位移是0(當前位)開始,我錯誤當作是1開始

問題2
我是直接理解為把位移的步數轉換成2進制直接進行&運算
修改后 我的理解為把宏定義移位到高位的位(2.4 2.2)移位回原來的位并賦值
(不知道有沒理解錯,畢竟宏定義都的IO組為PD,這里的移位的是P2口,有點小迷惘)

最后是修改后測試代碼,我把P2的2.4 2.2改成P1的1.1 1.0(運行沒問題,不知道有沒有錯誤)
如有不當,萬望指正。

另外函數的那個方法因為沒學到dat,暫時沒辦法測試了 (不過我保存下來了)


  1. #include "RELA.H"
  2. #include"delay.h"

  3. #define MAIN_Fosc  12000000L //定義內部時鐘為12MHz
  4. #define uchar unsigned char
  5. void DelayXms(unsigned int xms);       

  6. #define PD ((P1<<6&0x80)|(P1<<6&0x40)|(P3&0x3f))//宏定義IO口并排列順序           
  7. /*********************************************************************************
  8. * P1.1/P1.0 定義IO組并排列順序從高到低位依次為P1.1 1.0 P3.5 3.4 3.3 3.2 3.1 3.0  *
  9. * 把想編組的IO口移動到想要的IO口組的位置重并排列順序                             *
  10. * (P1<<6&0x80)相當于把P1.1的口移動到編組的第6位,也就是1000 0000                 *
  11. * (P1<<6&0x40)相當于把P1.0的口移動到編組的第6位,也就是0100 0000                 *
  12. **********************************************************************************/

  13. void PX(uchar x)
  14. {
  15.         P3&=0xc0;                //低6位清0,P3.6、P3.7不變
  16.         P3|=(x&0x3f);        //P3低6位賦值
  17.         P1&=0xfc;                //P1.1、P1.0清0,其它位不變
  18.         P1|=((x>>6&0x02)|(x>>6&0x01));//P1.1、P1.0賦值,X的取值范圍 0-255
  19.         }
  20. /**************************************************************************************       
  21.         //(x>>6&0x02)等于把宏定義的第7位右移6位0000 0010&0x02運算后等P1口的P1.1位置并賦值
  22.         //(x>>6&0x01)等于宏定義后的第6位右移6位0000 0001&0x10運算后等P1口的P1.0位置并賦值
  23. ***************************************************************************************/

  24. /***************************************************************************************
  25. uchar PD()
  26. {
  27.         u8 dat = 0;
  28.         if(P2&0x10)dat|=0x80;
  29.         if(P2&0x04)dat|=0x40;
  30.         dat|=P3&0x3F;
  31.         return dat;
  32. }
  33. //上函數為不用宏定義該用函數方法(未測試)
  34. ******************************************************************************************/       
  35. void main()
  36. {  
  37.         unsigned char temp = 0x80;
  38.         unsigned char i;
  39.         while(1)
  40.         {
  41.                 for(i=0;i<8;i++)
  42.                 {
  43.       PX(~(temp>>i));  
  44.                   DelayXms(3000);
  45.                 }
  46.   }
  47. }
復制代碼





歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 国产91一区二区三区 | 久久久久九九九女人毛片 | 国产日本精品视频 | 黄网在线观看 | 亚洲天堂精品一区 | 日本 欧美 三级 高清 视频 | 一级黄色生活视频 | 国产精品成av人在线视午夜片 | 亚洲国产精品一区二区三区 | 91精品国产91久久久久久最新 | 亚洲视频在线播放 | www亚洲精品 | 国产一级淫片a直接免费看 免费a网站 | 国产高清一区二区三区 | 99国产精品久久久 | 91新视频| 国产精品美女久久久久aⅴ国产馆 | 欧美一区二区三区在线观看 | a级大片免费观看 | 亚洲精品乱码久久久久久蜜桃 | 日本人和亚洲人zjzjhd | 亚洲性综合网 | 99热热99 | 日本亚洲一区二区 | 日韩在线免费电影 | 久久三区| 午夜久久 | 国产欧美日韩 | 免费人成激情视频在线观看冫 | 欧美日韩国产一区二区 | 久久精品视频在线播放 | 91日韩在线 | 偷拍自拍网站 | 久久精品免费一区二区 | 国产精品久久影院 | 欧美色综合天天久久综合精品 | 欧美日韩精选 | 91深夜福利视频 | 国产精品成人一区二区三区 | 99久久日韩精品免费热麻豆美女 | 久久蜜桃av |