你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

MCU实战经验+关于mcu的IO操作问题.

[复制链接]
harvardx 提问时间:2014-4-1 17:05 /
 本文曾经在以前探讨过.现在再次来讨论一下.
 
以讲述avr单片机的io口操作。很多朋友都是由51单片机走向嵌入式系统,经历了51->430 51->pic 51->avr,这样一些转换,本人粗略学了51,后直接专攻avr,为此有一些心得,和一些雕虫小技的小伎俩,希望能抛砖引玉,引发同行反思,在工作中提供举一反三后的便利。
 
     想像51一样,在winavr中直接写上sbit KEY1 = p1^1,
 
然后用下列语句扫描键盘吗??
 
if(KEY1==0) keyval=1;
 
请看下面的宏定义,其中位段的手法来源于网络,本人纯属借鉴。之后的##,宏链接符,纯属自创,
 
各位先行使用以下宏后,有问题直接联系本人qq21332560讨论:注明验证信息:io口
 
//定义新的数据类型,方便进行IO端口操作。
typedef struct
 {
    unsigned char bit0:1 ;
    unsigned char bit1:1 ;
    unsigned char bit2:1 ;
    unsigned char bit3:1 ;
    unsigned char bit4:1 ;
    unsigned char bit5:1 ;
    unsigned char bit6:1 ;
    unsigned char bit7:1 ;
}bit_field;
 
#define GET_BIT(adr)   (*(( volatile bit_field * )(&adr)))
 
////////////////////////////////////////
#define AUTOINIT 1       //自动初始化IO方向寄存器无需在初始化程序中用PORTA=0X..;形式来初始化io控制寄存器,同时也不争的证明了avr单片机的端口输入/出切换功能
 
#if     AUTOINIT==1
 
    #define PORT(m,n)   GET_BIT(DDR##m).bit##n=1;\
                       GET_BIT(PORT##m).bit##n
#else
 
    #define PORT(m,n)  GET_BIT(PORT##m).bit##n
 
#endif 
////////////////////////////////////////
 
#if AUTOINIT==1
 
#define PIN(m,n) 
 
    (!(u08)(GET_BIT(DDR##m).bit##n=0) 
 
         &&\
     (u08)(GET_BIT(PORT##m).bit##n=1)
 
         &&\
              GET_BIT(PIN ##m).bit##n )
#else
 
    #define PIN(m,n)      GET_BIT(PIN##m).bit##n
 
#endif 
 //方便直观操作 自由设定单个io口的方向
#define DRA(n)            GET_BIT(DDRA).bit##n 
#define DRB(n)            GET_BIT(DDRB).bit##n
#define DRC(n)            GET_BIT(DDRC).bit##n
#define DRD(n)            GET_BIT(DDRD).bit##n
#define DDR(m,n)        GET_BIT(DDR##m).bit##n
 
在我们实际项目中,需要用到按键输入,继电器,SPI器件输出,
 
两者分别为输入,和输出之用,这时候可以方面的在各自c文件对应的.h文件中写下如下语句:
 
#define KEY1 PIN(C,3)//定义三个按键,使能上拉
#define KEY2 PIN(C,4)
#define KEY3 PIN(C,5)
 
#define SCLK_SPI  PORT(B,5)//定义spi口的两个控制引脚
#define CS_SPI      PORT(C,0)
 
上述PIN PORT 自动化定义的方法中,有些不足,如:在DS18B20这样的应用中,需要切换引脚的输入输出,就必须为18B20的引脚安排两套定义,
 
类似于:#define DS18B20_IN     PIN(A,1)
 
             #define DS18B20_OUT  PORT(A,1)
 
此外:PORT和PIN的自动化定义中,含有DDR的操作,凡是用到PIN和PORT定义过的端口的地方都需要重复DDR操作,带来冗余代码。
 
以上是对单片机端口的位操作的一点浅显认识;.在avr中有不错的便利应用.
 
可以看本人的一些实例代码;,
例程1:         定义3个按键输入口;
       #define KEY1 PIN(A,5)//
        #define KEY2 PIN(A,4)/
        #define KEY3 PIN(A,3)
        那么 : 按键读取就可以按照以下方式来进行:
u08 keyinput(void)
{
        u08 KeyVal=0;
        if(KEY_SET==0) KeyVal=        3;
        if(KEY_DEC==0) KeyVal=        2;
        if(KEY_ADD==0) KeyVal=        1;
         return KeyVal;
}
例程2:         定义:2个数据口,操作hc164,若干位选, 共同用于led数码管扫描显示;
#define HC164CLK                  PORT(B,4)//Hardware:4703v1.0
#define HC164DIO                  PORT(B,3) 
#define BIT1                          PORT(B,2) 
#define BIT2                          PORT(B,1)
#define BIT3                          PORT(B,0) 
#define BIT4                          PORT(A,0) 
#define BIT5                          PORT(A,1) 
#define BIT6                          PORT(A,2) 
/* 功能:发送一个字节8段码至hc164
*| 注意:HC164CLK为自定义位域字段,
*|
*/
void HC164_send_byte(unsigned char a)
{       
     unsigned char i;
 
     HC164_DIGRST();//传送数据时候的消隐处理 
 
    for( i = 0 ; i < 8 ; i++ )
    {       
            HC164CLK = 0;
 
            if( a & 0x80 )
         {
                HC164DIO = 1;
         }
            else
         {
                HC164DIO = 0;
         }

             a
收藏 评论11 发布时间:2014-4-1 17:05

举报

11个回答
witnessiz 回答时间:2014-4-16 13:22:42

RE:MCU实战经验+关于mcu的IO操作问题.

顶!
harvardx 回答时间:2014-4-16 13:25:02

RE:MCU实战经验+关于mcu的IO操作问题.

谢谢wit群  希望对同行兄弟们有用
qzwx741 回答时间:2014-4-16 13:27:13

RE:MCU实战经验+关于mcu的IO操作问题.

顶一下
clx1223 回答时间:2014-4-16 13:31:32

RE:MCU实战经验+关于mcu的IO操作问题.

赞一个,谢谢分享
mcu-354561 回答时间:2014-4-16 13:40:11

RE:MCU实战经验+关于mcu的IO操作问题.

LZ 厉害
用单个IO口操作 不论是8位机还是32位都感觉非常方便。
下面是stm8s 我常用的IO操作方式,其实地址修改一下,应该是可以
在其他8位IC里面的。
typedef struct GPIOX_struct
{
    union
    {
        volatile unsigned char DDR_;
        volatile unsigned char CR1_;
        volatile unsigned char CR2_;
        volatile unsigned char ODR_;
        volatile unsigned char IDR_;
        struct
        {
            volatile unsigned char R0:1;
            volatile unsigned char R1:1;
            volatile unsigned char R2:1;
            volatile unsigned char R3:1;
            volatile unsigned char R4:1;
            volatile unsigned char R5:1;
            volatile unsigned char R6:1;
            volatile unsigned char R7:1;
        }BIT_;
    };
}GPIOX_TypeDef;
#define GPIO_PAOUT    ((GPIOX_TypeDef *)0X5000)
#define PA            (GPIO_PAOUT->ODR_)
#define PA0           (GPIO_PAOUT->BIT_.R0)
#define PA1           (GPIO_PAOUT->BIT_.R1)
#define PA2           (GPIO_PAOUT->BIT_.R2)
#define PA3           (GPIO_PAOUT->BIT_.R3)
#define PA4           (GPIO_PAOUT->BIT_.R4)
#define PA5           (GPIO_PAOUT->BIT_.R5)
#define PA6           (GPIO_PAOUT->BIT_.R6)
#define PA7           (GPIO_PAOUT->BIT_.R7)
。。。。。。。
。。。。。。。
32位的 例如st 已经有大侠全部写好了 类似:
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)
harvardx 回答时间:2014-4-18 11:44:11

RE:MCU实战经验+关于mcu的IO操作问题.

楼上的又让我学习了 多谢
oipk 回答时间:2015-1-9 09:14:30
我记得S12的寄存器就是这么定义的,有感觉。
qianfan 回答时间:2015-1-9 12:20:52
有bitband的直接使用bitband就行,何必这么麻烦
dear祝子 回答时间:2015-1-25 17:57:03
大哥,你太牛了,我会把你的帖子全部看完!
lkl0305 回答时间:2015-1-25 18:03:39
讲的不错,顶一个
harvardx 回答时间:2020-3-2 13:50:56

  1. ///////////////////////////////////////////////////////////////
  2. //位带操作,实现51类似的GPIO控制功能
  3. //具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
  4. //IO口操作宏定义
  5. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
  6. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  7. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
  8. //IO口地址映射
  9. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
  10. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
  11. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
  12. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
  13. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
  14. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
  15. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   

  16. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
  17. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08
  18. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
  19. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
  20. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
  21. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
  22. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08
  23. ;
  24. /* shine 改进版本 */
  25. #define PIN(m,n) BIT_ADDR(GPIO##m##_BASE+8,n)        
  26. #define PORT(m,n) BIT_ADDR(GPIO##m##_BASE+12,n)        
  27. //IO口操作,只对单一的IO口!
  28. //确保n的值小于16!

  29. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
  30. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

  31. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
  32. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

  33. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
  34. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

  35. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
  36. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

  37. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
  38. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

  39. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
  40. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

  41. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出
  42. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入
复制代码

  1. // ********举例说明**********
  2. //
  3. //定义输入按键:

  4. #define KEY1 PIN(C,3)
  5. #define KEY2 PIN(A,0)
  6. #define KEY3 PIN(A,1)
  7. #define KEY4 PIN(A,2)
  8. #define KEY5 PIN(A,3)

  9. //定义输出功能;
  10.         #define SDI_5460       PORT(C,2)
  11.         #define SDO_5460       PIN(A,6)
  12.         #define SCLK_5460      PORT(A,5)
  13.         #define RST_5460       PORT(C,4)
  14.         #define CS_5460        PORT(A,4)
  15.         #define CS_U1                   CS_5460
复制代码


所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版