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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

關(guān)于單片機(jī)不同IO口編組程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1054576 發(fā)表于 2024-1-8 21:52 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
請問有沒有哪位大神百忙中抽點時間指點一下這一段代碼,卡了兩天了沒搞懂。下面是一段異組非順序端口編組的程序
本人業(yè)余愛好者,半路出家沒有系統(tǒng)學(xué)習(xí)過之前在網(wǎng)上學(xué)了一些89c51皮毛做了一些流水燈,4*4矩陣之類的
最近想做個實物矩陣鍵盤,但是由于之前用的是89c51,然后想著只做一個矩陣鍵盤帶幾個LED沒必要用那么多引腳的單片機(jī),
就選了個STC15W SOP16的
然后就悲劇了 STC15單組IO最多才6個P1.0-P1.5,4*4鍵盤要用8個口,跟之前學(xué)的0x**就完成掃描的程序不一樣,搞了兩天就只會分開一個一個口的寫代碼
雖然也能用,但是這樣太修飾了,然后就去網(wǎng)上找了一些資料(這方面的資料超級少),研究后發(fā)覺我看不懂代碼了(主要是運算符)
單個運算符拿出來可以理解,但是放在一起就搞不懂為什么會有這樣的結(jié)果。

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


不懂1:宏定義 P2向左移3位跟0x80進(jìn)行按位與......
       根據(jù)運算優(yōu)先級,這里的位移3位是指P2口低位往高位移3位后的結(jié)果是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) 結(jié)果為0x00 (0000 0000) ??
        P2向左移4位跟0x40進(jìn)行按位與..... .這里的位移4位是指P2口低位往高位移3位后的結(jié)果是2.3口嗎??
    之后
          P2=0X08(0000 1000) & 0x40(0100 0000)  結(jié)果為0x00 (0000 0000) ??
再之后
                   不算P3的情況 按位或結(jié)果  0000 0000 | 0000 0000 = 0000 0000   那就跟程序運行的結(jié)果就不一樣了

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進(jìn)制還是2進(jìn)制或者16進(jìn)制

}


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

使用道具 舉報

沙發(fā)
ID:57657 發(fā)表于 2024-1-9 10:36 | 只看該作者
十進(jìn)制是給人類看的,無論任何進(jìn)制,在單片機(jī)都是二進(jìn)制處理的。
回復(fù)

使用道具 舉報

板凳
ID:161164 發(fā)表于 2024-1-9 11:02 | 只看該作者
不懂1:
位數(shù)弄反了
正確順序: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進(jìn)制

不用宏定義改用函數(shù)
  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

地板
ID:485350 發(fā)表于 2024-1-9 11:02 | 只看該作者
能用最簡單易懂的辦法做出就可以了,先沒必要在意復(fù)雜的方式,等你用了幾年C之后再研究研究吧
回復(fù)

使用道具 舉報

5#
ID:1054576 發(fā)表于 2024-1-9 18:23 | 只看該作者
lkc8210 發(fā)表于 2024-1-9 11:02
不懂1:
位數(shù)弄反了
正確順序:P2.7/6/5/4/3/2/1/0

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

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

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

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


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

  3. #define MAIN_Fosc  12000000L //定義內(nèi)部時鐘為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)相當(dāng)于把P1.1的口移動到編組的第6位,也就是1000 0000                 *
  11. * (P1<<6&0x40)相當(dāng)于把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. //上函數(shù)為不用宏定義該用函數(shù)方法(未測試)
  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产麻豆一区二区三区 | 中文字幕在线看 | 久久综合888 | 国产欧美日韩精品一区 | 亚洲视频在线播放 | 国产伦精品一区二区 | 日本字幕在线观看 | 成人国产在线观看 | 色女人天堂 | 91看国产| 国产视频一区二区三区四区五区 | 欧美video| 伊人久久综合影院 | 欧美色综合一区二区三区 | 久国产 | 超碰av在线 | 9999国产精品欧美久久久久久 | 成人a在线观看 | 97国产在线观看 | 国产免费拔擦拔擦8x高清 | 亚洲36d大奶网 | 人人草人人干 | 国产一区二区影院 | 成人小视频在线观看 | 欧美中文视频 | 免费a v网站 | 中文字幕在线二区 | 欧美日一区二区 | 国产一区二区三区四区三区四 | av网站在线播放 | 精品日韩| 一区二区三区欧美大片 | 久久美女网 | 国产一区二区不卡 | 国产精品一区二区久久 | 成人精品高清 | 激情亚洲| 午夜影晥| 精品一区在线看 | 国产精品1区2区 | 夜操|